1d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright/*
2d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * Copyright (C) 2010 The Android Open Source Project
3d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *
4d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * Licensed under the Apache License, Version 2.0 (the "License");
5d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * you may not use this file except in compliance with the License.
6d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * You may obtain a copy of the License at
7d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *
8d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *      http://www.apache.org/licenses/LICENSE-2.0
9d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *
10d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * Unless required by applicable law or agreed to in writing, software
11d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * distributed under the License is distributed on an "AS IS" BASIS,
12d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * See the License for the specific language governing permissions and
14d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * limitations under the License.
15d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright */
16d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
17d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define LOG_TAG "InputReader"
18d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
19d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright//#define LOG_NDEBUG 0
20d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
21d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Log debug messages for each raw event received from the EventHub.
22d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define DEBUG_RAW_EVENTS 0
23d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
24d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Log debug messages about touch screen filtering hacks.
25d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define DEBUG_HACKS 0
26d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
27d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Log debug messages about virtual key processing.
28d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define DEBUG_VIRTUAL_KEYS 0
29d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
30d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Log debug messages about pointers.
31d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define DEBUG_POINTERS 0
32d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
33d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Log debug messages about pointer assignment calculations.
34d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define DEBUG_POINTER_ASSIGNMENT 0
35d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
36d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Log debug messages about gesture detection.
37d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define DEBUG_GESTURES 0
38d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
39d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Log debug messages about the vibrator.
40d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define DEBUG_VIBRATOR 0
41d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
42842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright// Log debug messages about fusing stylus data.
43842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright#define DEBUG_STYLUS_FUSION 0
44842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
45d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include "InputReader.h"
46d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
47a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <errno.h>
48842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright#include <inttypes.h>
49a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <limits.h>
50a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <math.h>
51d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <stddef.h>
52d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <stdlib.h>
53d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <unistd.h>
54a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn
557823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h>
56a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn
57a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <input/Keyboard.h>
58a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <input/VirtualKeyMap.h>
59d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
60d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define INDENT "  "
61d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define INDENT2 "    "
62d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define INDENT3 "      "
63d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define INDENT4 "        "
64d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define INDENT5 "          "
65d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
66d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightnamespace android {
67d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
68d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- Constants ---
69d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
70d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Maximum number of slots supported when using the slot-based Multitouch Protocol B.
71d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic const size_t MAX_SLOTS = 32;
72d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
73842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright// Maximum amount of latency to add to touch events while waiting for data from an
74842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright// external stylus.
755e17a5de888632c7e72171765bc70c8b9169f7edMichael Wrightstatic const nsecs_t EXTERNAL_STYLUS_DATA_TIMEOUT = ms2ns(72);
76842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
7743fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright// Maximum amount of time to wait on touch data before pushing out new pressure data.
7843fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wrightstatic const nsecs_t TOUCH_DATA_TIMEOUT = ms2ns(20);
7943fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright
8043fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright// Artificial latency on synthetic events created from stylus data without corresponding touch
8143fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright// data.
8243fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wrightstatic const nsecs_t STYLUS_DATA_LATENCY = ms2ns(10);
8343fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright
84d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- Static Functions ---
85d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
86d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrighttemplate<typename T>
87d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightinline static T abs(const T& value) {
88d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return value < 0 ? - value : value;
89d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
90d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
91d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrighttemplate<typename T>
92d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightinline static T min(const T& a, const T& b) {
93d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return a < b ? a : b;
94d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
95d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
96d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrighttemplate<typename T>
97d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightinline static void swap(T& a, T& b) {
98d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    T temp = a;
99d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    a = b;
100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    b = temp;
101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightinline static float avg(float x, float y) {
104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return (x + y) / 2;
105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightinline static float distance(float x1, float y1, float x2, float y2) {
108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return hypotf(x1 - x2, y1 - y2);
109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightinline static int32_t signExtendNybble(int32_t value) {
112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return value >= 8 ? value - 16 : value;
113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic inline const char* toString(bool value) {
116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return value ? "true" : "false";
117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation,
120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const int32_t map[][4], size_t mapSize) {
121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (orientation != DISPLAY_ORIENTATION_0) {
122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < mapSize; i++) {
123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (value == map[i][0]) {
124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return map[i][orientation];
125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return value;
129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic const int32_t keyCodeRotationMap[][4] = {
132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // key codes enumerated counter-clockwise with the original (unrotated) key first
133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // no rotation,        90 degree rotation,  180 degree rotation, 270 degree rotation
134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        { AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT },
135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        { AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN },
136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        { AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT },
137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        { AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP },
138e7a57d128038492445caac998d55983fb6085dfaJim Miller        { AKEYCODE_SYSTEM_NAVIGATION_DOWN, AKEYCODE_SYSTEM_NAVIGATION_RIGHT,
139e7a57d128038492445caac998d55983fb6085dfaJim Miller            AKEYCODE_SYSTEM_NAVIGATION_UP, AKEYCODE_SYSTEM_NAVIGATION_LEFT },
140e7a57d128038492445caac998d55983fb6085dfaJim Miller        { AKEYCODE_SYSTEM_NAVIGATION_RIGHT, AKEYCODE_SYSTEM_NAVIGATION_UP,
141e7a57d128038492445caac998d55983fb6085dfaJim Miller            AKEYCODE_SYSTEM_NAVIGATION_LEFT, AKEYCODE_SYSTEM_NAVIGATION_DOWN },
142e7a57d128038492445caac998d55983fb6085dfaJim Miller        { AKEYCODE_SYSTEM_NAVIGATION_UP, AKEYCODE_SYSTEM_NAVIGATION_LEFT,
143e7a57d128038492445caac998d55983fb6085dfaJim Miller            AKEYCODE_SYSTEM_NAVIGATION_DOWN, AKEYCODE_SYSTEM_NAVIGATION_RIGHT },
144e7a57d128038492445caac998d55983fb6085dfaJim Miller        { AKEYCODE_SYSTEM_NAVIGATION_LEFT, AKEYCODE_SYSTEM_NAVIGATION_DOWN,
145e7a57d128038492445caac998d55983fb6085dfaJim Miller            AKEYCODE_SYSTEM_NAVIGATION_RIGHT, AKEYCODE_SYSTEM_NAVIGATION_UP },
146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright};
147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic const size_t keyCodeRotationMapSize =
148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return rotateValueUsingRotationMap(keyCode, orientation,
152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            keyCodeRotationMap, keyCodeRotationMapSize);
153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic void rotateDelta(int32_t orientation, float* deltaX, float* deltaY) {
156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float temp;
157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (orientation) {
158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case DISPLAY_ORIENTATION_90:
159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        temp = *deltaX;
160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *deltaX = *deltaY;
161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *deltaY = -temp;
162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case DISPLAY_ORIENTATION_180:
165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *deltaX = -*deltaX;
166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *deltaY = -*deltaY;
167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case DISPLAY_ORIENTATION_270:
170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        temp = *deltaX;
171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *deltaX = -*deltaY;
172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *deltaY = temp;
173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Returns true if the pointer should be reported as being down given the specified
182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// button states.  This determines whether the event is reported as a touch event.
183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic bool isPointerDown(int32_t buttonState) {
184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return buttonState &
185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            (AMOTION_EVENT_BUTTON_PRIMARY | AMOTION_EVENT_BUTTON_SECONDARY
186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    | AMOTION_EVENT_BUTTON_TERTIARY);
187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic float calculateCommonVector(float a, float b) {
190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (a > 0 && b > 0) {
191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return a < b ? a : b;
192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (a < 0 && b < 0) {
193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return a > b ? a : b;
194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return 0;
196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic void synthesizeButtonKey(InputReaderContext* context, int32_t action,
200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        nsecs_t when, int32_t deviceId, uint32_t source,
201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState,
202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t buttonState, int32_t keyCode) {
203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (
204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            (action == AKEY_EVENT_ACTION_DOWN
205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && !(lastButtonState & buttonState)
206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && (currentButtonState & buttonState))
207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || (action == AKEY_EVENT_ACTION_UP
208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && (lastButtonState & buttonState)
209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && !(currentButtonState & buttonState))) {
210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyKeyArgs args(when, deviceId, source, policyFlags,
211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                action, 0, keyCode, 0, context->getGlobalMetaState(), when);
212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        context->getListener()->notifyKey(&args);
213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic void synthesizeButtonKeys(InputReaderContext* context, int32_t action,
217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        nsecs_t when, int32_t deviceId, uint32_t source,
218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState) {
219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            lastButtonState, currentButtonState,
221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            AMOTION_EVENT_BUTTON_BACK, AKEYCODE_BACK);
222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            lastButtonState, currentButtonState,
224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            AMOTION_EVENT_BUTTON_FORWARD, AKEYCODE_FORWARD);
225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- InputReaderConfiguration ---
229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
23006936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordonbool InputReaderConfiguration::getDisplayViewport(ViewportType viewportType,
23106936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        const String8* uniqueDisplayId, DisplayViewport* outViewport) const {
23206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    const DisplayViewport* viewport = NULL;
23306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    if (viewportType == ViewportType::VIEWPORT_VIRTUAL && uniqueDisplayId != NULL) {
23406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        for (DisplayViewport currentViewport : mVirtualDisplays) {
23506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            if (currentViewport.uniqueId == *uniqueDisplayId) {
23606936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon                viewport = &currentViewport;
23706936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon                break;
23806936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            }
23906936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        }
24006936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    } else if (viewportType == ViewportType::VIEWPORT_EXTERNAL) {
24106936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        viewport = &mExternalDisplay;
24206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    } else if (viewportType == ViewportType::VIEWPORT_INTERNAL) {
24306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        viewport = &mInternalDisplay;
24406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    }
24506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon
24606936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    if (viewport != NULL && viewport->displayId >= 0) {
24706936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        *outViewport = *viewport;
248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return true;
249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return false;
251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
25306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordonvoid InputReaderConfiguration::setPhysicalDisplayViewport(ViewportType viewportType,
25406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        const DisplayViewport& viewport) {
25506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    if (viewportType == ViewportType::VIEWPORT_EXTERNAL) {
25606936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        mExternalDisplay = viewport;
25706936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    } else if (viewportType == ViewportType::VIEWPORT_INTERNAL) {
25806936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        mInternalDisplay = viewport;
25906936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    }
26006936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon}
26106936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon
26206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordonvoid InputReaderConfiguration::setVirtualDisplayViewports(
26306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        const Vector<DisplayViewport>& viewports) {
26406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    mVirtualDisplays = viewports;
26506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon}
26606936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon
26706936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordonvoid InputReaderConfiguration::dump(String8& dump) const {
26806936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    dump.append(INDENT4 "ViewportInternal:\n");
26906936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    dumpViewport(dump, mInternalDisplay);
27006936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    dump.append(INDENT4 "ViewportExternal:\n");
27106936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    dumpViewport(dump, mExternalDisplay);
27206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    dump.append(INDENT4 "ViewportVirtual:\n");
27306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    for (const DisplayViewport& viewport : mVirtualDisplays) {
27406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        dumpViewport(dump, viewport);
27506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    }
27606936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon}
27706936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon
27806936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordonvoid InputReaderConfiguration::dumpViewport(String8& dump, const DisplayViewport& viewport) const {
27906936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    dump.appendFormat(INDENT5 "Viewport: displayId=%d, orientation=%d, uniqueId='%s', "
28006936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            "logicalFrame=[%d, %d, %d, %d], "
28106936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            "physicalFrame=[%d, %d, %d, %d], "
28206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            "deviceSize=[%d, %d]\n",
28306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            viewport.displayId, viewport.orientation, viewport.uniqueId.c_str(),
28406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            viewport.logicalLeft, viewport.logicalTop,
28506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            viewport.logicalRight, viewport.logicalBottom,
28606936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            viewport.physicalLeft, viewport.physicalTop,
28706936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            viewport.physicalRight, viewport.physicalBottom,
28806936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            viewport.deviceWidth, viewport.deviceHeight);
289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
292af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke// -- TouchAffineTransformation --
293af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gereckevoid TouchAffineTransformation::applyTo(float& x, float& y) const {
294af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    float newX, newY;
295af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    newX = x * x_scale + y * x_ymix + x_offset;
296af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    newY = x * y_xmix + y * y_scale + y_offset;
297af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke
298af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    x = newX;
299af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    y = newY;
300af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke}
301af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke
302af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke
303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- InputReader ---
304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputReader::InputReader(const sp<EventHubInterface>& eventHub,
306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const sp<InputReaderPolicyInterface>& policy,
307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const sp<InputListenerInterface>& listener) :
308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mContext(this), mEventHub(eventHub), mPolicy(policy),
309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mGlobalMetaState(0), mGeneration(1),
310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mConfigurationChangesToRefresh(0) {
312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mQueuedListener = new QueuedInputListener(listener);
313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    { // acquire lock
315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        AutoMutex _l(mLock);
316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        refreshConfigurationLocked(0);
318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        updateGlobalMetaStateLocked();
319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } // release lock
320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputReader::~InputReader() {
323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < mDevices.size(); i++) {
324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        delete mDevices.valueAt(i);
325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::loopOnce() {
329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t oldGeneration;
330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t timeoutMillis;
331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool inputDevicesChanged = false;
332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    Vector<InputDeviceInfo> inputDevices;
333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    { // acquire lock
334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        AutoMutex _l(mLock);
335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        oldGeneration = mGeneration;
337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        timeoutMillis = -1;
338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t changes = mConfigurationChangesToRefresh;
340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (changes) {
341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfigurationChangesToRefresh = 0;
342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            timeoutMillis = 0;
343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            refreshConfigurationLocked(changes);
344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (mNextTimeout != LLONG_MAX) {
345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } // release lock
349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    { // acquire lock
353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        AutoMutex _l(mLock);
354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mReaderIsAliveCondition.broadcast();
355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (count) {
357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            processEventsLocked(mEventBuffer, count);
358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mNextTimeout != LLONG_MAX) {
361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (now >= mNextTimeout) {
363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_RAW_EVENTS
364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mNextTimeout = LLONG_MAX;
367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                timeoutExpiredLocked(now);
368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (oldGeneration != mGeneration) {
372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            inputDevicesChanged = true;
373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getInputDevicesLocked(inputDevices);
374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } // release lock
376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Send out a message that the describes the changed input devices.
378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (inputDevicesChanged) {
379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPolicy->notifyInputDevicesChanged(inputDevices);
380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Flush queued events out to the listener.
383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // This must happen outside of the lock because the listener could potentially call
384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // back into the InputReader's methods, such as getScanCodeState, or become blocked
385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // on another thread similarly waiting to acquire the InputReader lock thereby
386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // resulting in a deadlock.  This situation is actually quite plausible because the
387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // listener is actually the input dispatcher, which calls into the window manager,
388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // which occasionally calls into the input reader.
389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mQueuedListener->flush();
390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (const RawEvent* rawEvent = rawEvents; count;) {
394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t type = rawEvent->type;
395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t batchSize = 1;
396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t deviceId = rawEvent->deviceId;
398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            while (batchSize < count) {
399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT
400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        || rawEvent[batchSize].deviceId != deviceId) {
401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    break;
402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                batchSize += 1;
404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_RAW_EVENTS
406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("BatchSize: %d Count: %d", batchSize, count);
407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            switch (rawEvent->type) {
411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case EventHubInterface::DEVICE_ADDED:
412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                addDeviceLocked(rawEvent->when, rawEvent->deviceId);
413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case EventHubInterface::DEVICE_REMOVED:
415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case EventHubInterface::FINISHED_DEVICE_SCAN:
418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                handleConfigurationChangedLocked(rawEvent->when);
419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            default:
421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOG_ASSERT(false); // can't happen
422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        count -= batchSize;
426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        rawEvent += batchSize;
427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceIndex >= 0) {
433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t classes = mEventHub->getDeviceClasses(deviceId);
439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    device->configure(when, &mConfig, 0);
443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    device->reset(when);
444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (device->isIgnored()) {
446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                identifier.name.string());
448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId,
450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                identifier.name.string(), device->getSources());
451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mDevices.add(deviceId, device);
454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bumpGenerationLocked();
455842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
456842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
457842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        notifyExternalStylusPresenceChanged();
458842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputDevice* device = NULL;
463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceIndex < 0) {
465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    device = mDevices.valueAt(deviceIndex);
470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mDevices.removeItemsAt(deviceIndex, 1);
471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bumpGenerationLocked();
472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (device->isIgnored()) {
474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)",
475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                device->getId(), device->getName().string());
476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Device removed: id=%d, name='%s', sources=0x%08x",
478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                device->getId(), device->getName().string(), device->getSources());
479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
481842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
482842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        notifyExternalStylusPresenceChanged();
483842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
484842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    device->reset(when);
486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    delete device;
487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const InputDeviceIdentifier& identifier, uint32_t classes) {
491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            controllerNumber, identifier, classes);
493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // External devices.
495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->setExternal(true);
497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
499063ff53d0b0a0d670ea0185e687526d8fd302820Tim Kilbourn    // Devices with mics.
500063ff53d0b0a0d670ea0185e687526d8fd302820Tim Kilbourn    if (classes & INPUT_DEVICE_CLASS_MIC) {
501063ff53d0b0a0d670ea0185e687526d8fd302820Tim Kilbourn        device->setMic(true);
502063ff53d0b0a0d670ea0185e687526d8fd302820Tim Kilbourn    }
503063ff53d0b0a0d670ea0185e687526d8fd302820Tim Kilbourn
504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Switch-like devices.
505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_SWITCH) {
506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->addMapper(new SwitchInputMapper(device));
507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5091941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    // Scroll wheel-like devices.
5101941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) {
5111941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani        device->addMapper(new RotaryEncoderInputMapper(device));
5121941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    }
5131941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Vibrator-like devices.
515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->addMapper(new VibratorInputMapper(device));
517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Keyboard-like devices.
520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t keyboardSource = 0;
521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        keyboardSource |= AINPUT_SOURCE_KEYBOARD;
524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_DPAD) {
529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        keyboardSource |= AINPUT_SOURCE_DPAD;
530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        keyboardSource |= AINPUT_SOURCE_GAMEPAD;
533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (keyboardSource != 0) {
536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Cursor-like devices.
540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_CURSOR) {
541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->addMapper(new CursorInputMapper(device));
542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Touchscreens and touchpad devices.
545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->addMapper(new MultiTouchInputMapper(device));
547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->addMapper(new SingleTouchInputMapper(device));
549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Joystick-like devices.
552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->addMapper(new JoystickInputMapper(device));
554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
556842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // External stylus-like devices.
557842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (classes & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
558842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        device->addMapper(new ExternalStylusInputMapper(device));
559842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
560842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return device;
562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::processEventsForDeviceLocked(int32_t deviceId,
565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const RawEvent* rawEvents, size_t count) {
566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceIndex < 0) {
568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGW("Discarding event for unknown deviceId %d.", deviceId);
569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputDevice* device = mDevices.valueAt(deviceIndex);
573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (device->isIgnored()) {
574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        //ALOGD("Discarding event for ignored deviceId %d.", deviceId);
575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    device->process(rawEvents, count);
579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::timeoutExpiredLocked(nsecs_t when) {
582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < mDevices.size(); i++) {
583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device = mDevices.valueAt(i);
584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!device->isIgnored()) {
585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            device->timeoutExpired(when);
586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::handleConfigurationChangedLocked(nsecs_t when) {
591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Reset global meta state because it depends on the list of all configured devices.
592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    updateGlobalMetaStateLocked();
593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Enqueue configuration changed.
595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    NotifyConfigurationChangedArgs args(when);
596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mQueuedListener->notifyConfigurationChanged(&args);
597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::refreshConfigurationLocked(uint32_t changes) {
600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPolicy->getReaderConfiguration(&mConfig);
601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (changes) {
604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Reconfiguring input devices.  changes=0x%08x", changes);
605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mEventHub->requestReopenDevices();
609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            for (size_t i = 0; i < mDevices.size(); i++) {
611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                InputDevice* device = mDevices.valueAt(i);
612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                device->configure(now, &mConfig, changes);
613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::updateGlobalMetaStateLocked() {
619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mGlobalMetaState = 0;
620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < mDevices.size(); i++) {
622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device = mDevices.valueAt(i);
623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mGlobalMetaState |= device->getMetaState();
624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::getGlobalMetaStateLocked() {
628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mGlobalMetaState;
629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
631842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid InputReader::notifyExternalStylusPresenceChanged() {
632842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    refreshConfigurationLocked(InputReaderConfiguration::CHANGE_EXTERNAL_STYLUS_PRESENCE);
633842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
634842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
635842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid InputReader::getExternalStylusDevicesLocked(Vector<InputDeviceInfo>& outDevices) {
636842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    for (size_t i = 0; i < mDevices.size(); i++) {
637842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        InputDevice* device = mDevices.valueAt(i);
638842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS && !device->isIgnored()) {
639842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            outDevices.push();
640842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            device->getDeviceInfo(&outDevices.editTop());
641842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        }
642842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
643842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
644842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
645842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid InputReader::dispatchExternalStylusState(const StylusState& state) {
646842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    for (size_t i = 0; i < mDevices.size(); i++) {
647842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        InputDevice* device = mDevices.valueAt(i);
648842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        device->updateExternalStylusState(state);
649842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
650842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
651842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mDisableVirtualKeysTimeout = time;
654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputReader::shouldDropVirtualKeyLocked(nsecs_t now,
657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device, int32_t keyCode, int32_t scanCode) {
658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (now < mDisableVirtualKeysTimeout) {
659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Dropping virtual key from device %s because virtual keys are "
660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "temporarily disabled for the next %0.3fms.  keyCode=%d, scanCode=%d",
661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                device->getName().string(),
662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                (mDisableVirtualKeysTimeout - now) * 0.000001,
663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                keyCode, scanCode);
664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return true;
665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return false;
667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::fadePointerLocked() {
671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < mDevices.size(); i++) {
672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device = mDevices.valueAt(i);
673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->fadePointer();
674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
675d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (when < mNextTimeout) {
679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mNextTimeout = when;
680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mEventHub->wake();
681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::bumpGenerationLocked() {
685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return ++mGeneration;
686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::getInputDevices(Vector<InputDeviceInfo>& outInputDevices) {
689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getInputDevicesLocked(outInputDevices);
691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices) {
694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    outInputDevices.clear();
695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numDevices = mDevices.size();
697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numDevices; i++) {
698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device = mDevices.valueAt(i);
699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!device->isIgnored()) {
700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            outInputDevices.push();
701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            device->getDeviceInfo(&outInputDevices.editTop());
702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t keyCode) {
708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t scanCode) {
715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        GetStateFunc getStateFunc) {
728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t result = AKEY_STATE_UNKNOWN;
729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceId >= 0) {
730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (deviceIndex >= 0) {
732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            InputDevice* device = mDevices.valueAt(deviceIndex);
733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                result = (device->*getStateFunc)(sourceMask, code);
735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t numDevices = mDevices.size();
739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < numDevices; i++) {
740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            InputDevice* device = mDevices.valueAt(i);
741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // value.  Otherwise, return AKEY_STATE_UP as long as one device reports it.
744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                int32_t currentResult = (device->*getStateFunc)(sourceMask, code);
745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (currentResult >= AKEY_STATE_DOWN) {
746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    return currentResult;
747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else if (currentResult == AKEY_STATE_UP) {
748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    result = currentResult;
749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return result;
754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
756763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulianvoid InputReader::toggleCapsLockState(int32_t deviceId) {
757763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
758763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    if (deviceIndex < 0) {
759763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian        ALOGW("Ignoring toggleCapsLock for unknown deviceId %" PRId32 ".", deviceId);
760763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian        return;
761763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    }
762763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian
763763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    InputDevice* device = mDevices.valueAt(deviceIndex);
764763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    if (device->isIgnored()) {
765763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian        return;
766763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    }
767763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian
768763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    device->updateMetaState(AKEYCODE_CAPS_LOCK);
769763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian}
770763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian
771d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    memset(outFlags, 0, numCodes);
776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool result = false;
782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceId >= 0) {
783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (deviceIndex >= 0) {
785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            InputDevice* device = mDevices.valueAt(deviceIndex);
786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                result = device->markSupportedKeyCodes(sourceMask,
788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        numCodes, keyCodes, outFlags);
789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t numDevices = mDevices.size();
793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < numDevices; i++) {
794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            InputDevice* device = mDevices.valueAt(i);
795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                result |= device->markSupportedKeyCodes(sourceMask,
797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        numCodes, keyCodes, outFlags);
798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return result;
802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::requestRefreshConfiguration(uint32_t changes) {
805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (changes) {
808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool needWake = !mConfigurationChangesToRefresh;
809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mConfigurationChangesToRefresh |= changes;
810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (needWake) {
812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mEventHub->wake();
813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ssize_t repeat, int32_t token) {
819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceIndex >= 0) {
823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device = mDevices.valueAt(deviceIndex);
824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->vibrate(pattern, patternSize, repeat, token);
825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceIndex >= 0) {
833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device = mDevices.valueAt(deviceIndex);
834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->cancelVibrate(token);
835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::dump(String8& dump) {
839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mEventHub->dump(dump);
842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append("\n");
843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append("Input Reader State:\n");
845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < mDevices.size(); i++) {
847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDevices.valueAt(i)->dump(dump);
848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT "Configuration:\n");
851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT2 "ExcludedDeviceNames: [");
852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (i != 0) {
854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dump.append(", ");
855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(mConfig.excludedDeviceNames.itemAt(i).string());
857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append("]\n");
859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.virtualKeyQuietTime * 0.000001f);
861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "PointerVelocityControlParameters: "
863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerVelocityControlParameters.scale,
865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerVelocityControlParameters.lowThreshold,
866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerVelocityControlParameters.highThreshold,
867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerVelocityControlParameters.acceleration);
868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "WheelVelocityControlParameters: "
870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.wheelVelocityControlParameters.scale,
872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.wheelVelocityControlParameters.lowThreshold,
873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.wheelVelocityControlParameters.highThreshold,
874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.wheelVelocityControlParameters.acceleration);
875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "PointerGesture:\n");
877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Enabled: %s\n",
878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mConfig.pointerGesturesEnabled));
879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "QuietInterval: %0.1fms\n",
880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureQuietInterval * 0.000001f);
881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureDragMinSwitchSpeed);
883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "TapInterval: %0.1fms\n",
884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureTapInterval * 0.000001f);
885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "TapDragInterval: %0.1fms\n",
886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureTapDragInterval * 0.000001f);
887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "TapSlop: %0.1fpx\n",
888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureTapSlop);
889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureMultitouchMinDistance);
893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureSwipeTransitionAngleCosine);
895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureSwipeMaxWidthRatio);
897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "MovementSpeedRatio: %0.1f\n",
898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureMovementSpeedRatio);
899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "ZoomSpeedRatio: %0.1f\n",
900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureZoomSpeedRatio);
90106936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon
90206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    dump.append(INDENT3 "Viewports:\n");
90306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    mConfig.dump(dump);
904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::monitor() {
907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Acquire and release the lock to ensure that the reader has not deadlocked.
908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLock.lock();
909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mEventHub->wake();
910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mReaderIsAliveCondition.wait(mLock);
911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLock.unlock();
912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Check the EventHub
914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mEventHub->monitor();
915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- InputReader::ContextImpl ---
919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputReader::ContextImpl::ContextImpl(InputReader* reader) :
921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mReader(reader) {
922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::ContextImpl::updateGlobalMetaState() {
925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // lock is already held by the input loop
926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mReader->updateGlobalMetaStateLocked();
927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::ContextImpl::getGlobalMetaState() {
930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // lock is already held by the input loop
931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mReader->getGlobalMetaStateLocked();
932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // lock is already held by the input loop
936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mReader->disableVirtualKeysUntilLocked(time);
937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now,
940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device, int32_t keyCode, int32_t scanCode) {
941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // lock is already held by the input loop
942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::ContextImpl::fadePointer() {
946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // lock is already held by the input loop
947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mReader->fadePointerLocked();
948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // lock is already held by the input loop
952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mReader->requestTimeoutAtTimeLocked(when);
953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::ContextImpl::bumpGeneration() {
956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // lock is already held by the input loop
957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mReader->bumpGenerationLocked();
958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
960842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid InputReader::ContextImpl::getExternalStylusDevices(Vector<InputDeviceInfo>& outDevices) {
961842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // lock is already held by whatever called refreshConfigurationLocked
962842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mReader->getExternalStylusDevicesLocked(outDevices);
963842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
964842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
965842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid InputReader::ContextImpl::dispatchExternalStylusState(const StylusState& state) {
966842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mReader->dispatchExternalStylusState(state);
967842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
968842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mReader->mPolicy.get();
971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputListenerInterface* InputReader::ContextImpl::getListener() {
974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mReader->mQueuedListener.get();
975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightEventHubInterface* InputReader::ContextImpl::getEventHub() {
978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mReader->mEventHub.get();
979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- InputReaderThread ---
983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Thread(/*canCallJava*/ true), mReader(reader) {
986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputReaderThread::~InputReaderThread() {
989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputReaderThread::threadLoop() {
992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mReader->loopOnce();
993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return true;
994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- InputDevice ---
998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
1000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes) :
1001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mContext(context), mId(id), mGeneration(generation), mControllerNumber(controllerNumber),
1002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mIdentifier(identifier), mClasses(classes),
1003063ff53d0b0a0d670ea0185e687526d8fd302820Tim Kilbourn        mSources(0), mIsExternal(false), mHasMic(false), mDropUntilNextSync(false) {
1004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputDevice::~InputDevice() {
1007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        delete mMappers[i];
1010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mMappers.clear();
1012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::dump(String8& dump) {
1015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputDeviceInfo deviceInfo;
1016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getDeviceInfo(& deviceInfo);
1017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(),
1019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            deviceInfo.getDisplayName().string());
1020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "Generation: %d\n", mGeneration);
1021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
1022063ff53d0b0a0d670ea0185e687526d8fd302820Tim Kilbourn    dump.appendFormat(INDENT2 "HasMic:     %s\n", toString(mHasMic));
1023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
1024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
1025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
1027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!ranges.isEmpty()) {
1028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT2 "Motion Ranges:\n");
1029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < ranges.size(); i++) {
1030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
1031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const char* label = getAxisLabel(range.axis);
1032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            char name[32];
1033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (label) {
1034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                strncpy(name, label, sizeof(name));
1035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                name[sizeof(name) - 1] = '\0';
1036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
1037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                snprintf(name, sizeof(name), "%d", range.axis);
1038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
1039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dump.appendFormat(INDENT3 "%s: source=0x%08x, "
1040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, resolution=%0.3f\n",
1041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    name, range.source, range.min, range.max, range.flat, range.fuzz,
1042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    range.resolution);
1043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mapper->dump(dump);
1050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::addMapper(InputMapper* mapper) {
1054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mMappers.add(mapper);
1055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) {
1058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mSources = 0;
1059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!isIgnored()) {
1061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!changes) { // first time only
1062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
1063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
1066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
1067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                sp<KeyCharacterMap> keyboardLayout =
1068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier);
1069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (mContext->getEventHub()->setKeyboardLayoutOverlay(mId, keyboardLayout)) {
1070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    bumpGeneration();
1071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
1072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
1073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
1076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
1077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                String8 alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
1078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (mAlias != alias) {
1079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mAlias = alias;
1080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    bumpGeneration();
1081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
1082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
1083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t numMappers = mMappers.size();
1086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < numMappers; i++) {
1087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            InputMapper* mapper = mMappers[i];
1088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mapper->configure(when, config, changes);
1089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSources |= mapper->getSources();
1090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::reset(nsecs_t when) {
1095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mapper->reset(when);
1099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mContext->updateGlobalMetaState();
1102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    notifyReset(when);
1104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::process(const RawEvent* rawEvents, size_t count) {
1107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Process all of the events in order for each mapper.
1108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // We cannot simply ask each mapper to process them in bulk because mappers may
1109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // have side-effects that must be interleaved.  For example, joystick movement events and
1110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // gamepad button presses are handled by different mappers but they should be dispatched
1111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // in the order received.
1112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
1114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_RAW_EVENTS
1115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%lld",
1116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,
1117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                rawEvent->when);
1118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
1119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mDropUntilNextSync) {
1121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
1122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mDropUntilNextSync = false;
1123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_RAW_EVENTS
1124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Recovered from input event buffer overrun.");
1125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
1126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
1127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_RAW_EVENTS
1128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Dropped input event while waiting for next input sync.");
1129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
1130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
1131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
1132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGI("Detected input event buffer overrun for device %s.", getName().string());
1133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mDropUntilNextSync = true;
1134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            reset(rawEvent->when);
1135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
1136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            for (size_t i = 0; i < numMappers; i++) {
1137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                InputMapper* mapper = mMappers[i];
1138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mapper->process(rawEvent);
1139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
1140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::timeoutExpired(nsecs_t when) {
1145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mapper->timeoutExpired(when);
1149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1152842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid InputDevice::updateExternalStylusState(const StylusState& state) {
1153842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    size_t numMappers = mMappers.size();
1154842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    for (size_t i = 0; i < numMappers; i++) {
1155842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        InputMapper* mapper = mMappers[i];
1156842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mapper->updateExternalStylusState(state);
1157842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
1158842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
1159842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
1160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
1161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias,
1162063ff53d0b0a0d670ea0185e687526d8fd302820Tim Kilbourn            mIsExternal, mHasMic);
1163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mapper->populateDeviceInfo(outDeviceInfo);
1167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
1171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState);
1172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
1175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getState(sourceMask, scanCode, & InputMapper::getScanCodeState);
1176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
1179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getState(sourceMask, switchCode, & InputMapper::getSwitchState);
1180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
1183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t result = AKEY_STATE_UNKNOWN;
1184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
1188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
1189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // value.  Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
1190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t currentResult = (mapper->*getStateFunc)(sourceMask, code);
1191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (currentResult >= AKEY_STATE_DOWN) {
1192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return currentResult;
1193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (currentResult == AKEY_STATE_UP) {
1194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                result = currentResult;
1195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
1196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return result;
1199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
1202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const int32_t* keyCodes, uint8_t* outFlags) {
1203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool result = false;
1204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
1208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
1209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return result;
1212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
1215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t token) {
1216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mapper->vibrate(pattern, patternSize, repeat, token);
1220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::cancelVibrate(int32_t token) {
1224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mapper->cancelVibrate(token);
1228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1231c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brownvoid InputDevice::cancelTouch(nsecs_t when) {
1232c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown    size_t numMappers = mMappers.size();
1233c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
1234c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown        InputMapper* mapper = mMappers[i];
1235c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown        mapper->cancelTouch(when);
1236c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown    }
1237c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown}
1238c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown
1239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputDevice::getMetaState() {
1240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t result = 0;
1241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        result |= mapper->getMetaState();
1245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return result;
1247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1249763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulianvoid InputDevice::updateMetaState(int32_t keyCode) {
1250763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    size_t numMappers = mMappers.size();
1251763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    for (size_t i = 0; i < numMappers; i++) {
1252763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian        mMappers[i]->updateMetaState(keyCode);
1253763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    }
1254763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian}
1255763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian
1256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::fadePointer() {
1257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mapper->fadePointer();
1261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::bumpGeneration() {
1265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mGeneration = mContext->bumpGeneration();
1266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::notifyReset(nsecs_t when) {
1269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    NotifyDeviceResetArgs args(when, mId);
1270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mContext->getListener()->notifyDeviceReset(&args);
1271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- CursorButtonAccumulator ---
1275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightCursorButtonAccumulator::CursorButtonAccumulator() {
1277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearButtons();
1278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorButtonAccumulator::reset(InputDevice* device) {
1281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnLeft = device->isKeyPressed(BTN_LEFT);
1282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnRight = device->isKeyPressed(BTN_RIGHT);
1283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnMiddle = device->isKeyPressed(BTN_MIDDLE);
1284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnBack = device->isKeyPressed(BTN_BACK);
1285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnSide = device->isKeyPressed(BTN_SIDE);
1286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnForward = device->isKeyPressed(BTN_FORWARD);
1287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnExtra = device->isKeyPressed(BTN_EXTRA);
1288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnTask = device->isKeyPressed(BTN_TASK);
1289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorButtonAccumulator::clearButtons() {
1292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnLeft = 0;
1293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnRight = 0;
1294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnMiddle = 0;
1295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnBack = 0;
1296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnSide = 0;
1297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnForward = 0;
1298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnExtra = 0;
1299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnTask = 0;
1300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorButtonAccumulator::process(const RawEvent* rawEvent) {
1303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_KEY) {
1304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (rawEvent->code) {
1305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_LEFT:
1306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnLeft = rawEvent->value;
1307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_RIGHT:
1309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnRight = rawEvent->value;
1310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_MIDDLE:
1312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnMiddle = rawEvent->value;
1313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_BACK:
1315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnBack = rawEvent->value;
1316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_SIDE:
1318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnSide = rawEvent->value;
1319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_FORWARD:
1321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnForward = rawEvent->value;
1322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_EXTRA:
1324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnExtra = rawEvent->value;
1325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TASK:
1327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnTask = rawEvent->value;
1328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t CursorButtonAccumulator::getButtonState() const {
1334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t result = 0;
1335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnLeft) {
1336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        result |= AMOTION_EVENT_BUTTON_PRIMARY;
1337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnRight) {
1339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        result |= AMOTION_EVENT_BUTTON_SECONDARY;
1340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnMiddle) {
1342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        result |= AMOTION_EVENT_BUTTON_TERTIARY;
1343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnBack || mBtnSide) {
1345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        result |= AMOTION_EVENT_BUTTON_BACK;
1346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnForward || mBtnExtra) {
1348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        result |= AMOTION_EVENT_BUTTON_FORWARD;
1349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return result;
1351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- CursorMotionAccumulator ---
1355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightCursorMotionAccumulator::CursorMotionAccumulator() {
1357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearRelativeAxes();
1358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorMotionAccumulator::reset(InputDevice* device) {
1361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearRelativeAxes();
1362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorMotionAccumulator::clearRelativeAxes() {
1365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mRelX = 0;
1366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mRelY = 0;
1367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorMotionAccumulator::process(const RawEvent* rawEvent) {
1370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_REL) {
1371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (rawEvent->code) {
1372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case REL_X:
1373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mRelX = rawEvent->value;
1374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case REL_Y:
1376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mRelY = rawEvent->value;
1377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorMotionAccumulator::finishSync() {
1383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearRelativeAxes();
1384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- CursorScrollAccumulator ---
1388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightCursorScrollAccumulator::CursorScrollAccumulator() :
1390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mHaveRelWheel(false), mHaveRelHWheel(false) {
1391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearRelativeAxes();
1392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorScrollAccumulator::configure(InputDevice* device) {
1395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveRelWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_WHEEL);
1396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveRelHWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_HWHEEL);
1397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorScrollAccumulator::reset(InputDevice* device) {
1400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearRelativeAxes();
1401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorScrollAccumulator::clearRelativeAxes() {
1404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mRelWheel = 0;
1405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mRelHWheel = 0;
1406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorScrollAccumulator::process(const RawEvent* rawEvent) {
1409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_REL) {
1410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (rawEvent->code) {
1411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case REL_WHEEL:
1412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mRelWheel = rawEvent->value;
1413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case REL_HWHEEL:
1415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mRelHWheel = rawEvent->value;
1416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorScrollAccumulator::finishSync() {
1422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearRelativeAxes();
1423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- TouchButtonAccumulator ---
1427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightTouchButtonAccumulator::TouchButtonAccumulator() :
1429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mHaveBtnTouch(false), mHaveStylus(false) {
1430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearButtons();
1431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchButtonAccumulator::configure(InputDevice* device) {
1434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveBtnTouch = device->hasKey(BTN_TOUCH);
1435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveStylus = device->hasKey(BTN_TOOL_PEN)
1436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || device->hasKey(BTN_TOOL_RUBBER)
1437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || device->hasKey(BTN_TOOL_BRUSH)
1438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || device->hasKey(BTN_TOOL_PENCIL)
1439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || device->hasKey(BTN_TOOL_AIRBRUSH);
1440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchButtonAccumulator::reset(InputDevice* device) {
1443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnTouch = device->isKeyPressed(BTN_TOUCH);
1444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnStylus = device->isKeyPressed(BTN_STYLUS);
1445842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // BTN_0 is what gets mapped for the HID usage Digitizers.SecondaryBarrelSwitch
1446842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mBtnStylus2 =
1447842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            device->isKeyPressed(BTN_STYLUS2) || device->isKeyPressed(BTN_0);
1448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolFinger = device->isKeyPressed(BTN_TOOL_FINGER);
1449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolPen = device->isKeyPressed(BTN_TOOL_PEN);
1450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolRubber = device->isKeyPressed(BTN_TOOL_RUBBER);
1451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolBrush = device->isKeyPressed(BTN_TOOL_BRUSH);
1452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolPencil = device->isKeyPressed(BTN_TOOL_PENCIL);
1453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolAirbrush = device->isKeyPressed(BTN_TOOL_AIRBRUSH);
1454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolMouse = device->isKeyPressed(BTN_TOOL_MOUSE);
1455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolLens = device->isKeyPressed(BTN_TOOL_LENS);
1456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolDoubleTap = device->isKeyPressed(BTN_TOOL_DOUBLETAP);
1457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolTripleTap = device->isKeyPressed(BTN_TOOL_TRIPLETAP);
1458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolQuadTap = device->isKeyPressed(BTN_TOOL_QUADTAP);
1459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchButtonAccumulator::clearButtons() {
1462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnTouch = 0;
1463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnStylus = 0;
1464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnStylus2 = 0;
1465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolFinger = 0;
1466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolPen = 0;
1467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolRubber = 0;
1468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolBrush = 0;
1469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolPencil = 0;
1470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolAirbrush = 0;
1471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolMouse = 0;
1472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolLens = 0;
1473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolDoubleTap = 0;
1474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolTripleTap = 0;
1475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolQuadTap = 0;
1476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchButtonAccumulator::process(const RawEvent* rawEvent) {
1479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_KEY) {
1480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (rawEvent->code) {
1481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOUCH:
1482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnTouch = rawEvent->value;
1483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_STYLUS:
1485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnStylus = rawEvent->value;
1486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_STYLUS2:
1488842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        case BTN_0:// BTN_0 is what gets mapped for the HID usage Digitizers.SecondaryBarrelSwitch
1489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnStylus2 = rawEvent->value;
1490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_FINGER:
1492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolFinger = rawEvent->value;
1493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_PEN:
1495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolPen = rawEvent->value;
1496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_RUBBER:
1498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolRubber = rawEvent->value;
1499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_BRUSH:
1501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolBrush = rawEvent->value;
1502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_PENCIL:
1504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolPencil = rawEvent->value;
1505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_AIRBRUSH:
1507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolAirbrush = rawEvent->value;
1508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_MOUSE:
1510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolMouse = rawEvent->value;
1511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_LENS:
1513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolLens = rawEvent->value;
1514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_DOUBLETAP:
1516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolDoubleTap = rawEvent->value;
1517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_TRIPLETAP:
1519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolTripleTap = rawEvent->value;
1520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_QUADTAP:
1522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolQuadTap = rawEvent->value;
1523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t TouchButtonAccumulator::getButtonState() const {
1529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t result = 0;
1530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnStylus) {
15317b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        result |= AMOTION_EVENT_BUTTON_STYLUS_PRIMARY;
1532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnStylus2) {
15347b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        result |= AMOTION_EVENT_BUTTON_STYLUS_SECONDARY;
1535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return result;
1537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t TouchButtonAccumulator::getToolType() const {
1540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnToolMouse || mBtnToolLens) {
1541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AMOTION_EVENT_TOOL_TYPE_MOUSE;
1542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnToolRubber) {
1544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AMOTION_EVENT_TOOL_TYPE_ERASER;
1545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnToolPen || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush) {
1547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AMOTION_EVENT_TOOL_TYPE_STYLUS;
1548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnToolFinger || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap) {
1550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AMOTION_EVENT_TOOL_TYPE_FINGER;
1551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
1553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchButtonAccumulator::isToolActive() const {
1556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mBtnTouch || mBtnToolFinger || mBtnToolPen || mBtnToolRubber
1557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush
1558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mBtnToolMouse || mBtnToolLens
1559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap;
1560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchButtonAccumulator::isHovering() const {
1563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mHaveBtnTouch && !mBtnTouch;
1564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchButtonAccumulator::hasStylus() const {
1567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mHaveStylus;
1568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- RawPointerAxes ---
1572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightRawPointerAxes::RawPointerAxes() {
1574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clear();
1575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid RawPointerAxes::clear() {
1578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    x.clear();
1579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    y.clear();
1580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pressure.clear();
1581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    touchMajor.clear();
1582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    touchMinor.clear();
1583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    toolMajor.clear();
1584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    toolMinor.clear();
1585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    orientation.clear();
1586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    distance.clear();
1587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    tiltX.clear();
1588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    tiltY.clear();
1589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    trackingId.clear();
1590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    slot.clear();
1591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- RawPointerData ---
1595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightRawPointerData::RawPointerData() {
1597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clear();
1598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid RawPointerData::clear() {
1601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCount = 0;
1602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearIdBits();
1603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid RawPointerData::copyFrom(const RawPointerData& other) {
1606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCount = other.pointerCount;
1607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    hoveringIdBits = other.hoveringIdBits;
1608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    touchingIdBits = other.touchingIdBits;
1609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t i = 0; i < pointerCount; i++) {
1611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointers[i] = other.pointers[i];
1612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int id = pointers[i].id;
1614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        idToIndex[id] = other.idToIndex[id];
1615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const {
1619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float x = 0, y = 0;
1620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t count = touchingIdBits.count();
1621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (count) {
1622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (BitSet32 idBits(touchingIdBits); !idBits.isEmpty(); ) {
1623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = idBits.clearFirstMarkedBit();
1624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const Pointer& pointer = pointerForId(id);
1625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            x += pointer.x;
1626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            y += pointer.y;
1627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        x /= count;
1629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        y /= count;
1630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    *outX = x;
1632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    *outY = y;
1633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- CookedPointerData ---
1637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightCookedPointerData::CookedPointerData() {
1639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clear();
1640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CookedPointerData::clear() {
1643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCount = 0;
1644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    hoveringIdBits.clear();
1645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    touchingIdBits.clear();
1646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CookedPointerData::copyFrom(const CookedPointerData& other) {
1649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCount = other.pointerCount;
1650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    hoveringIdBits = other.hoveringIdBits;
1651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    touchingIdBits = other.touchingIdBits;
1652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t i = 0; i < pointerCount; i++) {
1654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerProperties[i].copyFrom(other.pointerProperties[i]);
1655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords[i].copyFrom(other.pointerCoords[i]);
1656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int id = pointerProperties[i].id;
1658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        idToIndex[id] = other.idToIndex[id];
1659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- SingleTouchMotionAccumulator ---
1664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightSingleTouchMotionAccumulator::SingleTouchMotionAccumulator() {
1666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearAbsoluteAxes();
1667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SingleTouchMotionAccumulator::reset(InputDevice* device) {
1670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsX = device->getAbsoluteAxisValue(ABS_X);
1671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsY = device->getAbsoluteAxisValue(ABS_Y);
1672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsPressure = device->getAbsoluteAxisValue(ABS_PRESSURE);
1673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsToolWidth = device->getAbsoluteAxisValue(ABS_TOOL_WIDTH);
1674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsDistance = device->getAbsoluteAxisValue(ABS_DISTANCE);
1675d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsTiltX = device->getAbsoluteAxisValue(ABS_TILT_X);
1676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsTiltY = device->getAbsoluteAxisValue(ABS_TILT_Y);
1677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SingleTouchMotionAccumulator::clearAbsoluteAxes() {
1680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsX = 0;
1681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsY = 0;
1682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsPressure = 0;
1683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsToolWidth = 0;
1684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsDistance = 0;
1685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsTiltX = 0;
1686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsTiltY = 0;
1687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SingleTouchMotionAccumulator::process(const RawEvent* rawEvent) {
1690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_ABS) {
1691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (rawEvent->code) {
1692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case ABS_X:
1693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mAbsX = rawEvent->value;
1694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case ABS_Y:
1696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mAbsY = rawEvent->value;
1697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case ABS_PRESSURE:
1699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mAbsPressure = rawEvent->value;
1700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case ABS_TOOL_WIDTH:
1702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mAbsToolWidth = rawEvent->value;
1703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case ABS_DISTANCE:
1705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mAbsDistance = rawEvent->value;
1706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case ABS_TILT_X:
1708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mAbsTiltX = rawEvent->value;
1709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case ABS_TILT_Y:
1711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mAbsTiltY = rawEvent->value;
1712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- MultiTouchMotionAccumulator ---
1719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightMultiTouchMotionAccumulator::MultiTouchMotionAccumulator() :
1721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentSlot(-1), mSlots(NULL), mSlotCount(0), mUsingSlotsProtocol(false),
1722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mHaveStylus(false) {
1723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightMultiTouchMotionAccumulator::~MultiTouchMotionAccumulator() {
1726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    delete[] mSlots;
1727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchMotionAccumulator::configure(InputDevice* device,
1730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t slotCount, bool usingSlotsProtocol) {
1731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mSlotCount = slotCount;
1732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mUsingSlotsProtocol = usingSlotsProtocol;
1733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveStylus = device->hasAbsoluteAxis(ABS_MT_TOOL_TYPE);
1734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    delete[] mSlots;
1736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mSlots = new Slot[slotCount];
1737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchMotionAccumulator::reset(InputDevice* device) {
1740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Unfortunately there is no way to read the initial contents of the slots.
1741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // So when we reset the accumulator, we must assume they are all zeroes.
1742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mUsingSlotsProtocol) {
1743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Query the driver for the current slot index and use it as the initial slot
1744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // before we start reading events from the device.  It is possible that the
1745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // current slot index will not be the same as it was when the first event was
1746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // written into the evdev buffer, which means the input mapper could start
1747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // out of sync with the initial state of the events in the evdev buffer.
1748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // In the extremely unlikely case that this happens, the data from
1749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // two slots will be confused until the next ABS_MT_SLOT event is received.
1750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // This can cause the touch point to "jump", but at least there will be
1751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // no stuck touches.
1752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t initialSlot;
1753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        status_t status = device->getEventHub()->getAbsoluteAxisValue(device->getId(),
1754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ABS_MT_SLOT, &initialSlot);
1755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (status) {
1756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Could not retrieve current multitouch slot index.  status=%d", status);
1757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            initialSlot = -1;
1758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        clearSlots(initialSlot);
1760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
1761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        clearSlots(-1);
1762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1765d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchMotionAccumulator::clearSlots(int32_t initialSlot) {
1766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mSlots) {
1767d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < mSlotCount; i++) {
1768d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSlots[i].clear();
1769d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1771d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentSlot = initialSlot;
1772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
1775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_ABS) {
1776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool newSlot = false;
1777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mUsingSlotsProtocol) {
1778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (rawEvent->code == ABS_MT_SLOT) {
1779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentSlot = rawEvent->value;
1780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                newSlot = true;
1781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
1782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (mCurrentSlot < 0) {
1783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentSlot = 0;
1784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) {
1787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_POINTERS
1788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (newSlot) {
1789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGW("MultiTouch device emitted invalid slot index %d but it "
1790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        "should be between 0 and %d; ignoring this slot.",
1791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mCurrentSlot, mSlotCount - 1);
1792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
1793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
1794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
1795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            Slot* slot = &mSlots[mCurrentSlot];
1796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            switch (rawEvent->code) {
1798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_POSITION_X:
1799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTPositionX = rawEvent->value;
1801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_POSITION_Y:
1803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTPositionY = rawEvent->value;
1805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_TOUCH_MAJOR:
1807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTTouchMajor = rawEvent->value;
1809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_TOUCH_MINOR:
1811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTTouchMinor = rawEvent->value;
1813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mHaveAbsMTTouchMinor = true;
1814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_WIDTH_MAJOR:
1816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTWidthMajor = rawEvent->value;
1818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_WIDTH_MINOR:
1820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTWidthMinor = rawEvent->value;
1822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mHaveAbsMTWidthMinor = true;
1823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_ORIENTATION:
1825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTOrientation = rawEvent->value;
1827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_TRACKING_ID:
1829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (mUsingSlotsProtocol && rawEvent->value < 0) {
1830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    // The slot is no longer in use but it retains its previous contents,
1831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    // which may be reused for subsequent touches.
1832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    slot->mInUse = false;
1833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
1834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    slot->mInUse = true;
1835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    slot->mAbsMTTrackingId = rawEvent->value;
1836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
1837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_PRESSURE:
1839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTPressure = rawEvent->value;
1841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_DISTANCE:
1843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTDistance = rawEvent->value;
1845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_TOOL_TYPE:
1847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTToolType = rawEvent->value;
1849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mHaveAbsMTToolType = true;
1850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
1852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
1854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
1855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentSlot += 1;
1856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchMotionAccumulator::finishSync() {
1860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!mUsingSlotsProtocol) {
1861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        clearSlots(-1);
1862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool MultiTouchMotionAccumulator::hasStylus() const {
1866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mHaveStylus;
1867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- MultiTouchMotionAccumulator::Slot ---
1871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightMultiTouchMotionAccumulator::Slot::Slot() {
1873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clear();
1874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchMotionAccumulator::Slot::clear() {
1877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mInUse = false;
1878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveAbsMTTouchMinor = false;
1879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveAbsMTWidthMinor = false;
1880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveAbsMTToolType = false;
1881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTPositionX = 0;
1882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTPositionY = 0;
1883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTTouchMajor = 0;
1884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTTouchMinor = 0;
1885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTWidthMajor = 0;
1886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTWidthMinor = 0;
1887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTOrientation = 0;
1888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTTrackingId = -1;
1889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTPressure = 0;
1890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTDistance = 0;
1891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTToolType = 0;
1892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t MultiTouchMotionAccumulator::Slot::getToolType() const {
1895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mHaveAbsMTToolType) {
1896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mAbsMTToolType) {
1897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case MT_TOOL_FINGER:
1898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return AMOTION_EVENT_TOOL_TYPE_FINGER;
1899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case MT_TOOL_PEN:
1900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return AMOTION_EVENT_TOOL_TYPE_STYLUS;
1901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1902d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
1904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- InputMapper ---
1908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputMapper::InputMapper(InputDevice* device) :
1910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDevice(device), mContext(device->getContext()) {
1911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputMapper::~InputMapper() {
1914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
1917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    info->addSource(getSources());
1918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::dump(String8& dump) {
1921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::configure(nsecs_t when,
1924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const InputReaderConfiguration* config, uint32_t changes) {
1925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::reset(nsecs_t when) {
1928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::timeoutExpired(nsecs_t when) {
1931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
1934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AKEY_STATE_UNKNOWN;
1935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
1938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AKEY_STATE_UNKNOWN;
1939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
1942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AKEY_STATE_UNKNOWN;
1943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
1946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const int32_t* keyCodes, uint8_t* outFlags) {
1947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return false;
1948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
1951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t token) {
1952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::cancelVibrate(int32_t token) {
1955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1957c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brownvoid InputMapper::cancelTouch(nsecs_t when) {
1958c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown}
1959c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown
1960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputMapper::getMetaState() {
1961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return 0;
1962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1964763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulianvoid InputMapper::updateMetaState(int32_t keyCode) {
1965763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian}
1966763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian
1967842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid InputMapper::updateExternalStylusState(const StylusState& state) {
1968842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
1969842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
1970842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
1971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::fadePointer() {
1972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo) {
1975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
1976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::bumpGeneration() {
1979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mDevice->bumpGeneration();
1980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::dumpRawAbsoluteAxisInfo(String8& dump,
1983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const RawAbsoluteAxisInfo& axis, const char* name) {
1984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (axis.valid) {
1985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d, resolution=%d\n",
1986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz, axis.resolution);
1987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
1988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "%s: unknown range\n", name);
1989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1992842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid InputMapper::dumpStylusState(String8& dump, const StylusState& state) {
1993842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dump.appendFormat(INDENT4 "When: %" PRId64 "\n", state.when);
1994842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dump.appendFormat(INDENT4 "Pressure: %f\n", state.pressure);
1995842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dump.appendFormat(INDENT4 "Button State: 0x%08x\n", state.buttons);
1996842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dump.appendFormat(INDENT4 "Tool Type: %" PRId32 "\n", state.toolType);
1997842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
1998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- SwitchInputMapper ---
2000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightSwitchInputMapper::SwitchInputMapper(InputDevice* device) :
2002bcbf97ef8fb6eaf527014ed9e7d979ad4fe9fdd2Michael Wright        InputMapper(device), mSwitchValues(0), mUpdatedSwitchMask(0) {
2003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightSwitchInputMapper::~SwitchInputMapper() {
2006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t SwitchInputMapper::getSources() {
2009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AINPUT_SOURCE_SWITCH;
2010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SwitchInputMapper::process(const RawEvent* rawEvent) {
2013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (rawEvent->type) {
2014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case EV_SW:
2015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        processSwitch(rawEvent->code, rawEvent->value);
2016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
2017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case EV_SYN:
2019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (rawEvent->code == SYN_REPORT) {
2020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            sync(rawEvent->when);
2021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SwitchInputMapper::processSwitch(int32_t switchCode, int32_t switchValue) {
2026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (switchCode >= 0 && switchCode < 32) {
2027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (switchValue) {
2028bcbf97ef8fb6eaf527014ed9e7d979ad4fe9fdd2Michael Wright            mSwitchValues |= 1 << switchCode;
2029bcbf97ef8fb6eaf527014ed9e7d979ad4fe9fdd2Michael Wright        } else {
2030bcbf97ef8fb6eaf527014ed9e7d979ad4fe9fdd2Michael Wright            mSwitchValues &= ~(1 << switchCode);
2031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mUpdatedSwitchMask |= 1 << switchCode;
2033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SwitchInputMapper::sync(nsecs_t when) {
2037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mUpdatedSwitchMask) {
20383da3b8436c743e4ba16ce6802b499a5bb7cd07bdMichael Wright        uint32_t updatedSwitchValues = mSwitchValues & mUpdatedSwitchMask;
2039bcbf97ef8fb6eaf527014ed9e7d979ad4fe9fdd2Michael Wright        NotifySwitchArgs args(when, 0, updatedSwitchValues, mUpdatedSwitchMask);
2040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifySwitch(&args);
2041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mUpdatedSwitchMask = 0;
2043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
2047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getEventHub()->getSwitchState(getDeviceId(), switchCode);
2048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2050bcbf97ef8fb6eaf527014ed9e7d979ad4fe9fdd2Michael Wrightvoid SwitchInputMapper::dump(String8& dump) {
2051bcbf97ef8fb6eaf527014ed9e7d979ad4fe9fdd2Michael Wright    dump.append(INDENT2 "Switch Input Mapper:\n");
2052bcbf97ef8fb6eaf527014ed9e7d979ad4fe9fdd2Michael Wright    dump.appendFormat(INDENT3 "SwitchValues: %x\n", mSwitchValues);
2053bcbf97ef8fb6eaf527014ed9e7d979ad4fe9fdd2Michael Wright}
2054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- VibratorInputMapper ---
2056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightVibratorInputMapper::VibratorInputMapper(InputDevice* device) :
2058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper(device), mVibrating(false) {
2059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightVibratorInputMapper::~VibratorInputMapper() {
2062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t VibratorInputMapper::getSources() {
2065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return 0;
2066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
2069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::populateDeviceInfo(info);
2070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    info->setVibrator(true);
2072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::process(const RawEvent* rawEvent) {
2075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // TODO: Handle FF_STATUS, although it does not seem to be widely supported.
2076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
2079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t token) {
2080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIBRATOR
2081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 patternStr;
2082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < patternSize; i++) {
2083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (i != 0) {
2084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            patternStr.append(", ");
2085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        patternStr.appendFormat("%lld", pattern[i]);
2087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ALOGD("vibrate: deviceId=%d, pattern=[%s], repeat=%ld, token=%d",
2089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getDeviceId(), patternStr.string(), repeat, token);
2090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
2091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mVibrating = true;
2093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    memcpy(mPattern, pattern, patternSize * sizeof(nsecs_t));
2094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPatternSize = patternSize;
2095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mRepeat = repeat;
2096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mToken = token;
2097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mIndex = -1;
2098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    nextStep();
2100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::cancelVibrate(int32_t token) {
2103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIBRATOR
2104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ALOGD("cancelVibrate: deviceId=%d, token=%d", getDeviceId(), token);
2105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
2106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mVibrating && mToken == token) {
2108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        stopVibrating();
2109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::timeoutExpired(nsecs_t when) {
2113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mVibrating) {
2114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (when >= mNextStepTime) {
2115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            nextStep();
2116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
2117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getContext()->requestTimeoutAtTime(mNextStepTime);
2118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::nextStep() {
2123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mIndex += 1;
2124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (size_t(mIndex) >= mPatternSize) {
2125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mRepeat < 0) {
2126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // We are done.
2127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            stopVibrating();
2128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return;
2129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mIndex = mRepeat;
2131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool vibratorOn = mIndex & 1;
2134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    nsecs_t duration = mPattern[mIndex];
2135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (vibratorOn) {
2136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIBRATOR
2137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("nextStep: sending vibrate deviceId=%d, duration=%lld",
2138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                getDeviceId(), duration);
2139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
2140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getEventHub()->vibrate(getDeviceId(), duration);
2141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
2142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIBRATOR
2143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("nextStep: sending cancel vibrate deviceId=%d", getDeviceId());
2144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
2145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getEventHub()->cancelVibrate(getDeviceId());
2146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
2148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mNextStepTime = now + duration;
2149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getContext()->requestTimeoutAtTime(mNextStepTime);
2150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIBRATOR
2151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ALOGD("nextStep: scheduled timeout in %0.3fms", duration * 0.000001f);
2152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
2153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::stopVibrating() {
2156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mVibrating = false;
2157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIBRATOR
2158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
2159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
2160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getEventHub()->cancelVibrate(getDeviceId());
2161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::dump(String8& dump) {
2164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT2 "Vibrator Input Mapper:\n");
2165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Vibrating: %s\n", toString(mVibrating));
2166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- KeyboardInputMapper ---
2170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightKeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
2172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t source, int32_t keyboardType) :
2173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper(device), mSource(source),
2174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mKeyboardType(keyboardType) {
2175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightKeyboardInputMapper::~KeyboardInputMapper() {
2178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t KeyboardInputMapper::getSources() {
2181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mSource;
2182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
2185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::populateDeviceInfo(info);
2186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    info->setKeyboardType(mKeyboardType);
2188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    info->setKeyCharacterMap(getEventHub()->getKeyCharacterMap(getDeviceId()));
2189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::dump(String8& dump) {
2192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT2 "Keyboard Input Mapper:\n");
2193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpParameters(dump);
2194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
2195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
219641d2f80739700a56fd6a670923a2966add8dae61Mark Salyzyn    dump.appendFormat(INDENT3 "KeyDowns: %zu keys currently down\n", mKeyDowns.size());
2197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mMetaState);
219841d2f80739700a56fd6a670923a2966add8dae61Mark Salyzyn    dump.appendFormat(INDENT3 "DownTime: %lld\n", (long long)mDownTime);
2199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::configure(nsecs_t when,
2203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const InputReaderConfiguration* config, uint32_t changes) {
2204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::configure(when, config, changes);
2205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes) { // first time only
2207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure basic parameters.
2208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        configureParameters();
2209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
2212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
2213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            DisplayViewport v;
221406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            if (config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, NULL, &v)) {
2215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientation = v.orientation;
2216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
2217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientation = DISPLAY_ORIENTATION_0;
2218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
2219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
2220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientation = DISPLAY_ORIENTATION_0;
2221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::configureParameters() {
2226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.orientationAware = false;
2227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"),
2228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.orientationAware);
2229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.hasAssociatedDisplay = false;
2231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.orientationAware) {
2232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.hasAssociatedDisplay = true;
2233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2234dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright
2235dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright    mParameters.handlesKeyRepeat = false;
2236dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright    getDevice()->getConfiguration().tryGetProperty(String8("keyboard.handlesKeyRepeat"),
2237dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright            mParameters.handlesKeyRepeat);
2238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::dumpParameters(String8& dump) {
2241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT3 "Parameters:\n");
2242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
2243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mParameters.hasAssociatedDisplay));
2244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
2245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mParameters.orientationAware));
2246dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright    dump.appendFormat(INDENT4 "HandlesKeyRepeat: %s\n",
2247dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright            toString(mParameters.handlesKeyRepeat));
2248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::reset(nsecs_t when) {
2251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mMetaState = AMETA_NONE;
2252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mDownTime = 0;
2253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mKeyDowns.clear();
2254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentHidUsage = 0;
2255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    resetLedState();
2257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::reset(when);
2259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::process(const RawEvent* rawEvent) {
2262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (rawEvent->type) {
2263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case EV_KEY: {
2264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t scanCode = rawEvent->code;
2265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t usageCode = mCurrentHidUsage;
2266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentHidUsage = 0;
2267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (isKeyboardOrGamepadKey(scanCode)) {
22690faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov            processKey(rawEvent->when, rawEvent->value != 0, scanCode, usageCode);
2270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
2272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case EV_MSC: {
2274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (rawEvent->code == MSC_SCAN) {
2275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentHidUsage = rawEvent->value;
2276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
2278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case EV_SYN: {
2280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (rawEvent->code == SYN_REPORT) {
2281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentHidUsage = 0;
2282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
2288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return scanCode < BTN_MOUSE
2289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        || scanCode >= KEY_OK
2290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        || (scanCode >= BTN_MISC && scanCode < BTN_MOUSE)
2291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI);
2292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
22940faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhovvoid KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t scanCode,
22950faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov        int32_t usageCode) {
22960faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov    int32_t keyCode;
22970faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov    int32_t keyMetaState;
22980faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov    uint32_t policyFlags;
22990faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov
23000faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov    if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, mMetaState,
23010faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov                              &keyCode, &keyMetaState, &policyFlags)) {
23020faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov        keyCode = AKEYCODE_UNKNOWN;
23030faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov        keyMetaState = mMetaState;
23040faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov        policyFlags = 0;
23050faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov    }
2306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (down) {
2308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Rotate key codes according to orientation if needed.
2309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
2310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            keyCode = rotateKeyCode(keyCode, mOrientation);
2311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Add key down.
2314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ssize_t keyDownIndex = findKeyDown(scanCode);
2315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (keyDownIndex >= 0) {
2316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // key repeat, be sure to use same keycode as before in case of rotation
2317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
2318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
2319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // key down
2320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if ((policyFlags & POLICY_FLAG_VIRTUAL)
2321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && mContext->shouldDropVirtualKey(when,
2322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            getDevice(), keyCode, scanCode)) {
2323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return;
2324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
2325c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown            if (policyFlags & POLICY_FLAG_GESTURE) {
2326c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown                mDevice->cancelTouch(when);
2327c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown            }
2328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mKeyDowns.push();
2330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            KeyDown& keyDown = mKeyDowns.editTop();
2331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            keyDown.keyCode = keyCode;
2332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            keyDown.scanCode = scanCode;
2333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDownTime = when;
2336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
2337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Remove key down.
2338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ssize_t keyDownIndex = findKeyDown(scanCode);
2339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (keyDownIndex >= 0) {
2340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // key up, be sure to use same keycode as before in case of rotation
2341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
2342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mKeyDowns.removeAt(size_t(keyDownIndex));
2343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
2344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // key was not actually down
2345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGI("Dropping key up from device %s because the key was not down.  "
2346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "keyCode=%d, scanCode=%d",
2347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    getDeviceName().string(), keyCode, scanCode);
2348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return;
2349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2352763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    if (updateMetaStateIfNeeded(keyCode, down)) {
23530faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov        // If global meta state changed send it along with the key.
23540faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov        // If it has not changed then we'll use what keymap gave us,
23550faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov        // since key replacement logic might temporarily reset a few
23560faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov        // meta bits for given key.
2357763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian        keyMetaState = mMetaState;
2358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    nsecs_t downTime = mDownTime;
2361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Key down on external an keyboard should wake the device.
2363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // We don't do this for internal keyboards to prevent them from waking up in your pocket.
2364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // For internal keyboards, the key layout file should specify the policy flags for
2365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // each wake key individually.
2366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // TODO: Use the input device configuration to control this behavior more finely.
2367872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright    if (down && getDevice()->isExternal()) {
2368872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright        policyFlags |= POLICY_FLAG_WAKE;
2369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2371dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright    if (mParameters.handlesKeyRepeat) {
2372dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright        policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
2373dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright    }
2374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
2376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
23770faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov            AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState, downTime);
2378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getListener()->notifyKey(&args);
2379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
2382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t n = mKeyDowns.size();
2383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < n; i++) {
2384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mKeyDowns[i].scanCode == scanCode) {
2385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return i;
2386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return -1;
2389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
2392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
2393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
2396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
2397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
2400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const int32_t* keyCodes, uint8_t* outFlags) {
2401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
2402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t KeyboardInputMapper::getMetaState() {
2405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mMetaState;
2406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2408763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulianvoid KeyboardInputMapper::updateMetaState(int32_t keyCode) {
2409763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    updateMetaStateIfNeeded(keyCode, false);
2410763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian}
2411763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian
2412763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulianbool KeyboardInputMapper::updateMetaStateIfNeeded(int32_t keyCode, bool down) {
2413763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    int32_t oldMetaState = mMetaState;
2414763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    int32_t newMetaState = android::updateMetaState(keyCode, down, oldMetaState);
2415763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    bool metaStateChanged = oldMetaState != newMetaState;
2416763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    if (metaStateChanged) {
2417763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian        mMetaState = newMetaState;
2418763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian        updateLedState(false);
2419763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian
2420763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian        getContext()->updateGlobalMetaState();
2421763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    }
2422763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian
2423763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian    return metaStateChanged;
2424763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian}
2425763a3a46eecafc5a713f9a0bd4ff08388dc97f98Andrii Kulian
2426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::resetLedState() {
2427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    initializeLedState(mCapsLockLedState, ALED_CAPS_LOCK);
2428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    initializeLedState(mNumLockLedState, ALED_NUM_LOCK);
2429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    initializeLedState(mScrollLockLedState, ALED_SCROLL_LOCK);
2430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    updateLedState(true);
2432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
2435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
2436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ledState.on = false;
2437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::updateLedState(bool reset) {
2440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    updateLedStateForModifier(mCapsLockLedState, ALED_CAPS_LOCK,
2441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            AMETA_CAPS_LOCK_ON, reset);
2442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    updateLedStateForModifier(mNumLockLedState, ALED_NUM_LOCK,
2443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            AMETA_NUM_LOCK_ON, reset);
2444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    updateLedStateForModifier(mScrollLockLedState, ALED_SCROLL_LOCK,
2445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            AMETA_SCROLL_LOCK_ON, reset);
2446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::updateLedStateForModifier(LedState& ledState,
2449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t led, int32_t modifier, bool reset) {
2450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (ledState.avail) {
2451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool desiredState = (mMetaState & modifier) != 0;
2452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (reset || ledState.on != desiredState) {
2453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getEventHub()->setLedState(getDeviceId(), led, desiredState);
2454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ledState.on = desiredState;
2455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- CursorInputMapper ---
2461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightCursorInputMapper::CursorInputMapper(InputDevice* device) :
2463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper(device) {
2464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightCursorInputMapper::~CursorInputMapper() {
2467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t CursorInputMapper::getSources() {
2470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mSource;
2471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
2474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::populateDeviceInfo(info);
2475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.mode == Parameters::MODE_POINTER) {
2477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float minX, minY, maxX, maxY;
2478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
2479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f, 0.0f);
2480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f, 0.0f);
2481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
2483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale, 0.0f);
2484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale, 0.0f);
2485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
2487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCursorScrollAccumulator.haveRelativeVWheel()) {
2489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
2490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCursorScrollAccumulator.haveRelativeHWheel()) {
2492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
2493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::dump(String8& dump) {
2497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT2 "Cursor Input Mapper:\n");
2498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpParameters(dump);
2499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
2500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
2501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
2502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
2503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
2504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mCursorScrollAccumulator.haveRelativeVWheel()));
2505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
2506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mCursorScrollAccumulator.haveRelativeHWheel()));
2507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
2508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
2509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
2510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
2511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
251241d2f80739700a56fd6a670923a2966add8dae61Mark Salyzyn    dump.appendFormat(INDENT3 "DownTime: %lld\n", (long long)mDownTime);
2513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::configure(nsecs_t when,
2516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const InputReaderConfiguration* config, uint32_t changes) {
2517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::configure(when, config, changes);
2518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes) { // first time only
2520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCursorScrollAccumulator.configure(getDevice());
2521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure basic parameters.
2523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        configureParameters();
2524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure device mode.
2526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mParameters.mode) {
252778f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev        case Parameters::MODE_POINTER_RELATIVE:
252878f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev            // Should not happen during first time configuration.
252978f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev            ALOGE("Cannot start a device in MODE_POINTER_RELATIVE, starting in MODE_POINTER");
253078f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev            mParameters.mode = Parameters::MODE_POINTER;
253178f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev            // fall through.
2532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Parameters::MODE_POINTER:
2533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSource = AINPUT_SOURCE_MOUSE;
2534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mXPrecision = 1.0f;
2535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mYPrecision = 1.0f;
2536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mXScale = 1.0f;
2537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mYScale = 1.0f;
2538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController = getPolicy()->obtainPointerController(getDeviceId());
2539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
2540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Parameters::MODE_NAVIGATION:
2541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSource = AINPUT_SOURCE_TRACKBALL;
2542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
2543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
2544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
2545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
2546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
2547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mVWheelScale = 1.0f;
2550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mHWheelScale = 1.0f;
2551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
255378f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev    if ((!changes && config->pointerCapture)
255478f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev            || (changes & InputReaderConfiguration::CHANGE_POINTER_CAPTURE)) {
255578f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev        if (config->pointerCapture) {
255678f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev            if (mParameters.mode == Parameters::MODE_POINTER) {
255778f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev                mParameters.mode = Parameters::MODE_POINTER_RELATIVE;
255878f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev                mSource = AINPUT_SOURCE_MOUSE_RELATIVE;
255978f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev                // Keep PointerController around in order to preserve the pointer position.
256078f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev                mPointerController->fade(PointerControllerInterface::TRANSITION_IMMEDIATE);
256178f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev            } else {
256278f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev                ALOGE("Cannot request pointer capture, device is not in MODE_POINTER");
256378f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev            }
256478f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev        } else {
256578f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev            if (mParameters.mode == Parameters::MODE_POINTER_RELATIVE) {
256678f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev                mParameters.mode = Parameters::MODE_POINTER;
256778f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev                mSource = AINPUT_SOURCE_MOUSE;
256878f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev            } else {
256978f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev                ALOGE("Cannot release pointer capture, device is not in MODE_POINTER_RELATIVE");
257078f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev            }
257178f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev        }
257278f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev        bumpGeneration();
257378f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev        if (changes) {
257478f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev            getDevice()->notifyReset(when);
257578f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev        }
257678f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev    }
257778f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev
2578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
2579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
2580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
2581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
2582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
2585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
2586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            DisplayViewport v;
258706936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            if (config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, NULL, &v)) {
2588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientation = v.orientation;
2589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
2590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientation = DISPLAY_ORIENTATION_0;
2591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
2592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
2593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientation = DISPLAY_ORIENTATION_0;
2594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bumpGeneration();
2596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::configureParameters() {
2600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.mode = Parameters::MODE_POINTER;
2601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 cursorModeString;
2602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (getDevice()->getConfiguration().tryGetProperty(String8("cursor.mode"), cursorModeString)) {
2603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (cursorModeString == "navigation") {
2604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.mode = Parameters::MODE_NAVIGATION;
2605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (cursorModeString != "pointer" && cursorModeString != "default") {
2606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
2607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.orientationAware = false;
2611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
2612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.orientationAware);
2613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.hasAssociatedDisplay = false;
2615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
2616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.hasAssociatedDisplay = true;
2617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::dumpParameters(String8& dump) {
2621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT3 "Parameters:\n");
2622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
2623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mParameters.hasAssociatedDisplay));
2624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mParameters.mode) {
2626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Parameters::MODE_POINTER:
2627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "Mode: pointer\n");
2628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
262978f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev    case Parameters::MODE_POINTER_RELATIVE:
263078f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev        dump.append(INDENT4 "Mode: relative pointer\n");
263178f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev        break;
2632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Parameters::MODE_NAVIGATION:
2633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "Mode: navigation\n");
2634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
2635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
2636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(false);
2637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
2640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mParameters.orientationAware));
2641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::reset(nsecs_t when) {
2644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mButtonState = 0;
2645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mDownTime = 0;
2646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerVelocityControl.reset();
2648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mWheelXVelocityControl.reset();
2649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mWheelYVelocityControl.reset();
2650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorButtonAccumulator.reset(getDevice());
2652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorMotionAccumulator.reset(getDevice());
2653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorScrollAccumulator.reset(getDevice());
2654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::reset(when);
2656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::process(const RawEvent* rawEvent) {
2659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorButtonAccumulator.process(rawEvent);
2660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorMotionAccumulator.process(rawEvent);
2661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorScrollAccumulator.process(rawEvent);
2662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
2664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        sync(rawEvent->when);
2665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::sync(nsecs_t when) {
2669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t lastButtonState = mButtonState;
2670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
2671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mButtonState = currentButtonState;
2672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool wasDown = isPointerDown(lastButtonState);
2674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool down = isPointerDown(currentButtonState);
2675d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool downChanged;
2676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!wasDown && down) {
2677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDownTime = when;
2678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        downChanged = true;
2679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (wasDown && !down) {
2680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        downChanged = true;
2681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
2682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        downChanged = false;
2683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    nsecs_t downTime = mDownTime;
2685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool buttonsChanged = currentButtonState != lastButtonState;
26867b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    int32_t buttonsPressed = currentButtonState & ~lastButtonState;
26877b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    int32_t buttonsReleased = lastButtonState & ~currentButtonState;
2688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
2690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
2691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool moved = deltaX != 0 || deltaY != 0;
2692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Rotate delta according to orientation if needed.
2694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.orientationAware && mParameters.hasAssociatedDisplay
2695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && (deltaX != 0.0f || deltaY != 0.0f)) {
2696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        rotateDelta(mOrientation, &deltaX, &deltaY);
2697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Move the pointer.
2700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    PointerProperties pointerProperties;
2701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerProperties.clear();
2702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerProperties.id = 0;
2703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
2704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    PointerCoords pointerCoords;
2706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCoords.clear();
2707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float vscroll = mCursorScrollAccumulator.getRelativeVWheel();
2709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float hscroll = mCursorScrollAccumulator.getRelativeHWheel();
2710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool scrolled = vscroll != 0 || hscroll != 0;
2711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mWheelYVelocityControl.move(when, NULL, &vscroll);
2713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mWheelXVelocityControl.move(when, &hscroll, NULL);
2714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerVelocityControl.move(when, &deltaX, &deltaY);
2716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t displayId;
271878f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev    if (mSource == AINPUT_SOURCE_MOUSE) {
2719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (moved || scrolled || buttonsChanged) {
2720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->setPresentation(
2721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    PointerControllerInterface::PRESENTATION_POINTER);
2722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (moved) {
2724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerController->move(deltaX, deltaY);
2725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
2726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (buttonsChanged) {
2728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerController->setButtonState(currentButtonState);
2729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
2730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
2732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float x, y;
2735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->getPosition(&x, &y);
2736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
2737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
2738fa1706afaf12b48fe0ab6d4b061b614bf901b173Jun Mukai        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, deltaX);
2739fa1706afaf12b48fe0ab6d4b061b614bf901b173Jun Mukai        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, deltaY);
2740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        displayId = ADISPLAY_ID_DEFAULT;
2741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
2742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
2743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
2744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        displayId = ADISPLAY_ID_NONE;
2745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
2748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Moving an external trackball or mouse should wake the device.
2750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // We don't do this for internal cursor devices to prevent them from waking up
2751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // the device in your pocket.
2752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // TODO: Use the input device configuration to control this behavior more finely.
2753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t policyFlags = 0;
2754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if ((buttonsPressed || moved || scrolled) && getDevice()->isExternal()) {
2755872db4f11e407accccba9d37c335ef7e3597eba4Michael Wright        policyFlags |= POLICY_FLAG_WAKE;
2756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Synthesize key down from buttons if needed.
2759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
2760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            policyFlags, lastButtonState, currentButtonState);
2761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Send motion event.
2763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (downChanged || moved || scrolled || buttonsChanged) {
2764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t metaState = mContext->getGlobalMetaState();
27657b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        int32_t buttonState = lastButtonState;
2766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t motionEventAction;
2767d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (downChanged) {
2768d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
276978f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev        } else if (down || (mSource != AINPUT_SOURCE_MOUSE)) {
2770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            motionEventAction = AMOTION_EVENT_ACTION_MOVE;
2771d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
2772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
2773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
27757b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        if (buttonsReleased) {
27767b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright            BitSet32 released(buttonsReleased);
27777b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright            while (!released.isEmpty()) {
27787b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                int32_t actionButton = BitSet32::valueForBit(released.clearFirstMarkedBit());
27797b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                buttonState &= ~actionButton;
27807b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                NotifyMotionArgs releaseArgs(when, getDeviceId(), mSource, policyFlags,
27817b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                        AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton, 0,
27827b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                        metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
27837b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                        displayId, 1, &pointerProperties, &pointerCoords,
27847b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                        mXPrecision, mYPrecision, downTime);
27857b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                getListener()->notifyMotion(&releaseArgs);
27867b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright            }
27877b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        }
27887b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright
2789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
27907b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                motionEventAction, 0, 0, metaState, currentButtonState,
27917b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                AMOTION_EVENT_EDGE_FLAG_NONE,
2792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                displayId, 1, &pointerProperties, &pointerCoords,
2793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mXPrecision, mYPrecision, downTime);
2794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifyMotion(&args);
2795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
27967b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        if (buttonsPressed) {
27977b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright            BitSet32 pressed(buttonsPressed);
27987b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright            while (!pressed.isEmpty()) {
27997b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                int32_t actionButton = BitSet32::valueForBit(pressed.clearFirstMarkedBit());
28007b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                buttonState |= actionButton;
28017b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                NotifyMotionArgs pressArgs(when, getDeviceId(), mSource, policyFlags,
28027b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                        AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton, 0,
28037b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                        metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
28047b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                        displayId, 1, &pointerProperties, &pointerCoords,
28057b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                        mXPrecision, mYPrecision, downTime);
28067b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                getListener()->notifyMotion(&pressArgs);
28077b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright            }
28087b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        }
28097b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright
28107b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        ALOG_ASSERT(buttonState == currentButtonState);
28117b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright
2812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send hover move after UP to tell the application that the mouse is hovering now.
2813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (motionEventAction == AMOTION_EVENT_ACTION_UP
281478f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev                && (mSource == AINPUT_SOURCE_MOUSE)) {
2815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
28167b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
2817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
2818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    displayId, 1, &pointerProperties, &pointerCoords,
2819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mXPrecision, mYPrecision, downTime);
2820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getListener()->notifyMotion(&hoverArgs);
2821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send scroll events.
2824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (scrolled) {
2825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
2826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
2827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
28297b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, currentButtonState,
2830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_EDGE_FLAG_NONE,
2831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    displayId, 1, &pointerProperties, &pointerCoords,
2832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mXPrecision, mYPrecision, downTime);
2833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getListener()->notifyMotion(&scrollArgs);
2834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Synthesize key up from buttons if needed.
2838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
2839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            policyFlags, lastButtonState, currentButtonState);
2840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorMotionAccumulator.finishSync();
2842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorScrollAccumulator.finishSync();
2843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
2846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
2847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
2848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
2849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AKEY_STATE_UNKNOWN;
2850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::fadePointer() {
2854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerController != NULL) {
2855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
2856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
28591941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani// --- RotaryEncoderInputMapper ---
28601941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
28611941ff5815e9f8a09f6ae643addbb4119482cf16Prashant MalaniRotaryEncoderInputMapper::RotaryEncoderInputMapper(InputDevice* device) :
28621941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani        InputMapper(device) {
28631941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    mSource = AINPUT_SOURCE_ROTARY_ENCODER;
28641941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani}
28651941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
28661941ff5815e9f8a09f6ae643addbb4119482cf16Prashant MalaniRotaryEncoderInputMapper::~RotaryEncoderInputMapper() {
28671941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani}
28681941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
28691941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malaniuint32_t RotaryEncoderInputMapper::getSources() {
28701941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    return mSource;
28711941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani}
28721941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
28731941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malanivoid RotaryEncoderInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
28741941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    InputMapper::populateDeviceInfo(info);
28751941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
28761941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    if (mRotaryEncoderScrollAccumulator.haveRelativeVWheel()) {
2877dae627a509817fa4668ca86e95a7a2b0ef60435ePrashant Malani        float res = 0.0f;
2878dae627a509817fa4668ca86e95a7a2b0ef60435ePrashant Malani        if (!mDevice->getConfiguration().tryGetProperty(String8("device.res"), res)) {
2879dae627a509817fa4668ca86e95a7a2b0ef60435ePrashant Malani            ALOGW("Rotary Encoder device configuration file didn't specify resolution!\n");
2880dae627a509817fa4668ca86e95a7a2b0ef60435ePrashant Malani        }
2881dae627a509817fa4668ca86e95a7a2b0ef60435ePrashant Malani        if (!mDevice->getConfiguration().tryGetProperty(String8("device.scalingFactor"),
2882dae627a509817fa4668ca86e95a7a2b0ef60435ePrashant Malani            mScalingFactor)) {
2883dae627a509817fa4668ca86e95a7a2b0ef60435ePrashant Malani            ALOGW("Rotary Encoder device configuration file didn't specify scaling factor,"
2884dae627a509817fa4668ca86e95a7a2b0ef60435ePrashant Malani              "default to 1.0!\n");
2885dae627a509817fa4668ca86e95a7a2b0ef60435ePrashant Malani            mScalingFactor = 1.0f;
2886dae627a509817fa4668ca86e95a7a2b0ef60435ePrashant Malani        }
2887dae627a509817fa4668ca86e95a7a2b0ef60435ePrashant Malani        info->addMotionRange(AMOTION_EVENT_AXIS_SCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
2888dae627a509817fa4668ca86e95a7a2b0ef60435ePrashant Malani            res * mScalingFactor);
28891941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    }
28901941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani}
28911941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
28921941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malanivoid RotaryEncoderInputMapper::dump(String8& dump) {
28931941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    dump.append(INDENT2 "Rotary Encoder Input Mapper:\n");
28941941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    dump.appendFormat(INDENT3 "HaveWheel: %s\n",
28951941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani            toString(mRotaryEncoderScrollAccumulator.haveRelativeVWheel()));
28961941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani}
28971941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
28981941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malanivoid RotaryEncoderInputMapper::configure(nsecs_t when,
28991941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani        const InputReaderConfiguration* config, uint32_t changes) {
29001941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    InputMapper::configure(when, config, changes);
29011941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    if (!changes) {
29021941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani        mRotaryEncoderScrollAccumulator.configure(getDevice());
29031941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    }
29041941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani}
29051941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
29061941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malanivoid RotaryEncoderInputMapper::reset(nsecs_t when) {
29071941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    mRotaryEncoderScrollAccumulator.reset(getDevice());
29081941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
29091941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    InputMapper::reset(when);
29101941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani}
29111941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
29121941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malanivoid RotaryEncoderInputMapper::process(const RawEvent* rawEvent) {
29131941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    mRotaryEncoderScrollAccumulator.process(rawEvent);
29141941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
29151941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
29161941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani        sync(rawEvent->when);
29171941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    }
29181941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani}
29191941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
29201941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malanivoid RotaryEncoderInputMapper::sync(nsecs_t when) {
29211941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    PointerCoords pointerCoords;
29221941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    pointerCoords.clear();
29231941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
29241941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    PointerProperties pointerProperties;
29251941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    pointerProperties.clear();
29261941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    pointerProperties.id = 0;
29271941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
29281941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
29291941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    float scroll = mRotaryEncoderScrollAccumulator.getRelativeVWheel();
29301941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    bool scrolled = scroll != 0;
29311941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
29321941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    // This is not a pointer, so it's not associated with a display.
29331941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    int32_t displayId = ADISPLAY_ID_NONE;
29341941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
29351941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    // Moving the rotary encoder should wake the device (if specified).
29361941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    uint32_t policyFlags = 0;
29371941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    if (scrolled && getDevice()->isExternal()) {
29381941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani        policyFlags |= POLICY_FLAG_WAKE;
29391941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    }
29401941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
29411941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    // Send motion event.
29421941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    if (scrolled) {
29431941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani        int32_t metaState = mContext->getGlobalMetaState();
2944dae627a509817fa4668ca86e95a7a2b0ef60435ePrashant Malani        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_SCROLL, scroll * mScalingFactor);
29451941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
29461941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani        NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
29471941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani                AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, 0,
29481941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani                AMOTION_EVENT_EDGE_FLAG_NONE,
29491941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani                displayId, 1, &pointerProperties, &pointerCoords,
29501941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani                0, 0, 0);
29511941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani        getListener()->notifyMotion(&scrollArgs);
29521941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    }
29531941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani
29541941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani    mRotaryEncoderScrollAccumulator.finishSync();
29551941ff5815e9f8a09f6ae643addbb4119482cf16Prashant Malani}
2956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- TouchInputMapper ---
2958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightTouchInputMapper::TouchInputMapper(InputDevice* device) :
2960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper(device),
2961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
2962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSurfaceWidth(-1), mSurfaceHeight(-1), mSurfaceLeft(0), mSurfaceTop(0),
2963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSurfaceOrientation(DISPLAY_ORIENTATION_0) {
2964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightTouchInputMapper::~TouchInputMapper() {
2967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t TouchInputMapper::getSources() {
2970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mSource;
2971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
2974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::populateDeviceInfo(info);
2975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mDeviceMode != DEVICE_MODE_DISABLED) {
2977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(mOrientedRanges.x);
2978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(mOrientedRanges.y);
2979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(mOrientedRanges.pressure);
2980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mOrientedRanges.haveSize) {
2982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.size);
2983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mOrientedRanges.haveTouchSize) {
2986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.touchMajor);
2987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.touchMinor);
2988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mOrientedRanges.haveToolSize) {
2991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.toolMajor);
2992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.toolMinor);
2993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mOrientedRanges.haveOrientation) {
2996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.orientation);
2997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mOrientedRanges.haveDistance) {
3000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.distance);
3001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mOrientedRanges.haveTilt) {
3004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.tilt);
3005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCursorScrollAccumulator.haveRelativeVWheel()) {
3008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
3009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    0.0f);
3010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCursorScrollAccumulator.haveRelativeHWheel()) {
3012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
3013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    0.0f);
3014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_BOX) {
3016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const InputDeviceInfo::MotionRange& x = mOrientedRanges.x;
3017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const InputDeviceInfo::MotionRange& y = mOrientedRanges.y;
3018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_1, mSource, x.min, x.max, x.flat,
3019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    x.fuzz, x.resolution);
3020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_2, mSource, y.min, y.max, y.flat,
3021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    y.fuzz, y.resolution);
3022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_3, mSource, x.min, x.max, x.flat,
3023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    x.fuzz, x.resolution);
3024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_4, mSource, y.min, y.max, y.flat,
3025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    y.fuzz, y.resolution);
3026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->setButtonUnderPad(mParameters.hasButtonUnderPad);
3028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dump(String8& dump) {
303206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    dump.appendFormat(INDENT2 "Touch Input Mapper (mode - %s):\n", modeToString(mDeviceMode));
3033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpParameters(dump);
3034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpVirtualKeys(dump);
3035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawPointerAxes(dump);
3036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpCalibration(dump);
3037af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dumpAffineTransformation(dump);
3038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpSurface(dump);
3039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
3041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "XTranslate: %0.3f\n", mXTranslate);
3042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "YTranslate: %0.3f\n", mYTranslate);
3043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "XScale: %0.3f\n", mXScale);
3044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "YScale: %0.3f\n", mYScale);
3045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision);
3046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mYPrecision);
3047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mGeometricScale);
3048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mPressureScale);
3049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mSizeScale);
3050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mOrientationScale);
3051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mDistanceScale);
3052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "HaveTilt: %s\n", toString(mHaveTilt));
3053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "TiltXCenter: %0.3f\n", mTiltXCenter);
3054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "TiltXScale: %0.3f\n", mTiltXScale);
3055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "TiltYCenter: %0.3f\n", mTiltYCenter);
3056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "TiltYScale: %0.3f\n", mTiltYScale);
3057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
30587b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    dump.appendFormat(INDENT3 "Last Raw Button State: 0x%08x\n", mLastRawState.buttonState);
3059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Last Raw Touch: pointerCount=%d\n",
3060842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            mLastRawState.rawPointerData.pointerCount);
3061842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    for (uint32_t i = 0; i < mLastRawState.rawPointerData.pointerCount; i++) {
3062842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        const RawPointerData::Pointer& pointer = mLastRawState.rawPointerData.pointers[i];
3063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
3064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
3065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "orientation=%d, tiltX=%d, tiltY=%d, distance=%d, "
3066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "toolType=%d, isHovering=%s\n", i,
3067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointer.id, pointer.x, pointer.y, pointer.pressure,
3068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointer.touchMajor, pointer.touchMinor,
3069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointer.toolMajor, pointer.toolMinor,
3070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointer.orientation, pointer.tiltX, pointer.tiltY, pointer.distance,
3071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointer.toolType, toString(pointer.isHovering));
3072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
30747b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    dump.appendFormat(INDENT3 "Last Cooked Button State: 0x%08x\n", mLastCookedState.buttonState);
3075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Last Cooked Touch: pointerCount=%d\n",
3076842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            mLastCookedState.cookedPointerData.pointerCount);
3077842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    for (uint32_t i = 0; i < mLastCookedState.cookedPointerData.pointerCount; i++) {
3078842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        const PointerProperties& pointerProperties =
3079842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mLastCookedState.cookedPointerData.pointerProperties[i];
3080842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        const PointerCoords& pointerCoords = mLastCookedState.cookedPointerData.pointerCoords[i];
3081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "[%d]: id=%d, x=%0.3f, y=%0.3f, pressure=%0.3f, "
3082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "touchMajor=%0.3f, touchMinor=%0.3f, toolMajor=%0.3f, toolMinor=%0.3f, "
3083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "orientation=%0.3f, tilt=%0.3f, distance=%0.3f, "
3084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "toolType=%d, isHovering=%s\n", i,
3085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerProperties.id,
3086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getX(),
3087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getY(),
3088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
3094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TILT),
3095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE),
3096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerProperties.toolType,
3097842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                toString(mLastCookedState.cookedPointerData.isHovering(i)));
3098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3100842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dump.append(INDENT3 "Stylus Fusion:\n");
3101842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dump.appendFormat(INDENT4 "ExternalStylusConnected: %s\n",
3102842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            toString(mExternalStylusConnected));
3103842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dump.appendFormat(INDENT4 "External Stylus ID: %" PRId64 "\n", mExternalStylusId);
3104842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dump.appendFormat(INDENT4 "External Stylus Data Timeout: %" PRId64 "\n",
310543fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright            mExternalStylusFusionTimeout);
3106842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dump.append(INDENT3 "External Stylus State:\n");
3107842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dumpStylusState(dump, mExternalStylusState);
3108842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
3109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mDeviceMode == DEVICE_MODE_POINTER) {
3110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
3111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
3112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerXMovementScale);
3113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
3114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerYMovementScale);
3115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
3116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerXZoomScale);
3117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
3118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerYZoomScale);
3119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
3120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGestureMaxSwipeWidth);
3121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
312406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordonconst char* TouchInputMapper::modeToString(DeviceMode deviceMode) {
312506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    switch (deviceMode) {
312606936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    case DEVICE_MODE_DISABLED:
312706936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        return "disabled";
312806936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    case DEVICE_MODE_DIRECT:
312906936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        return "direct";
313006936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    case DEVICE_MODE_UNSCALED:
313106936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        return "unscaled";
313206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    case DEVICE_MODE_NAVIGATION:
313306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        return "navigation";
313406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    case DEVICE_MODE_POINTER:
313506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        return "pointer";
313606936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    }
313706936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    return "unknown";
313806936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon}
313906936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon
3140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::configure(nsecs_t when,
3141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const InputReaderConfiguration* config, uint32_t changes) {
3142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::configure(when, config, changes);
3143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mConfig = *config;
3145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes) { // first time only
3147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure basic parameters.
3148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        configureParameters();
3149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure common accumulators.
3151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCursorScrollAccumulator.configure(getDevice());
3152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mTouchButtonAccumulator.configure(getDevice());
3153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure absolute axis information.
3155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        configureRawPointerAxes();
3156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Prepare input device calibration.
3158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        parseCalibration();
3159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        resolveCalibration();
3160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3162842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (!changes || (changes & InputReaderConfiguration::CHANGE_TOUCH_AFFINE_TRANSFORMATION)) {
316312d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke        // Update location calibration to reflect current settings
316412d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke        updateAffineTransformation();
316512d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke    }
316612d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke
3167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
3168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Update pointer speed.
3169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerVelocityControl.setParameters(mConfig.pointerVelocityControlParameters);
3170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mWheelXVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
3171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mWheelYVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
3172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool resetNeeded = false;
3175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes || (changes & (InputReaderConfiguration::CHANGE_DISPLAY_INFO
3176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            | InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT
3177842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            | InputReaderConfiguration::CHANGE_SHOW_TOUCHES
3178842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            | InputReaderConfiguration::CHANGE_EXTERNAL_STYLUS_PRESENCE))) {
3179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure device sources, surface dimensions, orientation and
3180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // scaling factors.
3181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        configureSurface(when, &resetNeeded);
3182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (changes && resetNeeded) {
3185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send reset, unless this is the first time the device has been configured,
3186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // in which case the reader will call reset itself after all mappers are ready.
3187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getDevice()->notifyReset(when);
3188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3191842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid TouchInputMapper::resolveExternalStylusPresence() {
3192842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    Vector<InputDeviceInfo> devices;
3193842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mContext->getExternalStylusDevices(devices);
3194842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mExternalStylusConnected = !devices.isEmpty();
3195842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
3196842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (!mExternalStylusConnected) {
3197842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        resetExternalStylus();
3198842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
3199842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
3200842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
3201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::configureParameters() {
3202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Use the pointer presentation mode for devices that do not support distinct
3203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // multitouch.  The spot-based presentation relies on being able to accurately
3204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // locate two or more fingers on the touch pad.
3205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.gestureMode = getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_SEMI_MT)
32063dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour            ? Parameters::GESTURE_MODE_SINGLE_TOUCH : Parameters::GESTURE_MODE_MULTI_TOUCH;
3207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 gestureModeString;
3209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"),
3210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            gestureModeString)) {
32113dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour        if (gestureModeString == "single-touch") {
32123dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour            mParameters.gestureMode = Parameters::GESTURE_MODE_SINGLE_TOUCH;
32133dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour        } else if (gestureModeString == "multi-touch") {
32143dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour            mParameters.gestureMode = Parameters::GESTURE_MODE_MULTI_TOUCH;
3215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (gestureModeString != "default") {
3216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.string());
3217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) {
3221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The device is a touch screen.
3222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
3223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_POINTER)) {
3224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The device is a pointing device like a track pad.
3225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
3226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (getEventHub()->hasRelativeAxis(getDeviceId(), REL_X)
3227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || getEventHub()->hasRelativeAxis(getDeviceId(), REL_Y)) {
3228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The device is a cursor device with a touch pad attached.
3229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // By default don't use the touch pad to move the pointer.
3230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
3231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The device is a touch pad of unknown purpose.
3233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
3234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.hasButtonUnderPad=
3237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_BUTTONPAD);
3238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 deviceTypeString;
3240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
3241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            deviceTypeString)) {
3242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (deviceTypeString == "touchScreen") {
3243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
3244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (deviceTypeString == "touchPad") {
3245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
3246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (deviceTypeString == "touchNavigation") {
3247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_NAVIGATION;
3248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (deviceTypeString == "pointer") {
3249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
3250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (deviceTypeString != "default") {
3251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
3252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
3256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
3257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.orientationAware);
3258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.hasAssociatedDisplay = false;
3260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.associatedDisplayIsExternal = false;
3261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.orientationAware
3262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
3263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
3264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.hasAssociatedDisplay = true;
326506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
326606936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            mParameters.associatedDisplayIsExternal = getDevice()->isExternal();
326706936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            getDevice()->getConfiguration().tryGetProperty(String8("touch.displayId"),
326806936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon                    mParameters.uniqueDisplayId);
326906936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        }
3270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3271c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown
3272c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown    // Initial downs on external touch devices should wake the device.
3273c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown    // Normally we don't do this for internal touch screens to prevent them from waking
3274c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown    // up in your pocket but you can enable it using the input device configuration.
3275c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown    mParameters.wake = getDevice()->isExternal();
3276c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown    getDevice()->getConfiguration().tryGetProperty(String8("touch.wake"),
3277c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown            mParameters.wake);
3278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dumpParameters(String8& dump) {
3281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT3 "Parameters:\n");
3282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mParameters.gestureMode) {
32843dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour    case Parameters::GESTURE_MODE_SINGLE_TOUCH:
32853dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour        dump.append(INDENT4 "GestureMode: single-touch\n");
3286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
32873dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour    case Parameters::GESTURE_MODE_MULTI_TOUCH:
32883dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour        dump.append(INDENT4 "GestureMode: multi-touch\n");
3289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
3291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        assert(false);
3292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mParameters.deviceType) {
3295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
3296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "DeviceType: touchScreen\n");
3297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Parameters::DEVICE_TYPE_TOUCH_PAD:
3299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "DeviceType: touchPad\n");
3300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Parameters::DEVICE_TYPE_TOUCH_NAVIGATION:
3302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "DeviceType: touchNavigation\n");
3303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Parameters::DEVICE_TYPE_POINTER:
3305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "DeviceType: pointer\n");
3306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
3308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(false);
3309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
331106936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    dump.appendFormat(
331206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s, displayId='%s'\n",
3313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mParameters.hasAssociatedDisplay),
331406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            toString(mParameters.associatedDisplayIsExternal),
331506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            mParameters.uniqueDisplayId.c_str());
3316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
3317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mParameters.orientationAware));
3318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::configureRawPointerAxes() {
3321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mRawPointerAxes.clear();
3322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dumpRawPointerAxes(String8& dump) {
3325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT3 "Raw Touch Axes:\n");
3326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.x, "X");
3327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.y, "Y");
3328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.pressure, "Pressure");
3329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMajor, "TouchMajor");
3330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMinor, "TouchMinor");
3331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMajor, "ToolMajor");
3332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMinor, "ToolMinor");
3333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.orientation, "Orientation");
3334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.distance, "Distance");
3335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltX, "TiltX");
3336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltY, "TiltY");
3337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.trackingId, "TrackingId");
3338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.slot, "Slot");
3339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3341842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightbool TouchInputMapper::hasExternalStylus() const {
3342842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    return mExternalStylusConnected;
3343842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
3344842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
3345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
3346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t oldDeviceMode = mDeviceMode;
3347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3348842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    resolveExternalStylusPresence();
3349842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
3350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Determine device mode.
3351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER
3352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && mConfig.pointerGesturesEnabled) {
3353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSource = AINPUT_SOURCE_MOUSE;
3354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDeviceMode = DEVICE_MODE_POINTER;
3355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (hasStylus()) {
3356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSource |= AINPUT_SOURCE_STYLUS;
3357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
3359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && mParameters.hasAssociatedDisplay) {
3360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSource = AINPUT_SOURCE_TOUCHSCREEN;
3361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDeviceMode = DEVICE_MODE_DIRECT;
33622f78b68cf15c3d96eccbb242316d174ed739dc69Michael Wright        if (hasStylus()) {
3363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSource |= AINPUT_SOURCE_STYLUS;
3364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
33652f78b68cf15c3d96eccbb242316d174ed739dc69Michael Wright        if (hasExternalStylus()) {
33662f78b68cf15c3d96eccbb242316d174ed739dc69Michael Wright            mSource |= AINPUT_SOURCE_BLUETOOTH_STYLUS;
33672f78b68cf15c3d96eccbb242316d174ed739dc69Michael Wright        }
3368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_NAVIGATION) {
3369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSource = AINPUT_SOURCE_TOUCH_NAVIGATION;
3370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDeviceMode = DEVICE_MODE_NAVIGATION;
3371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSource = AINPUT_SOURCE_TOUCHPAD;
3373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDeviceMode = DEVICE_MODE_UNSCALED;
3374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Ensure we have valid X and Y axes.
3377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) {
3378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGW(INDENT "Touch device '%s' did not report support for X or Y axis!  "
3379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "The device will be inoperable.", getDeviceName().string());
3380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDeviceMode = DEVICE_MODE_DISABLED;
3381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
3382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Raw width and height in the natural orientation.
3385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
3386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
3387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Get associated display dimensions.
3389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    DisplayViewport newViewport;
3390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.hasAssociatedDisplay) {
339106936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        const String8* uniqueDisplayId = NULL;
339206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        ViewportType viewportTypeToUse;
339306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon
339406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        if (mParameters.associatedDisplayIsExternal) {
339506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            viewportTypeToUse = ViewportType::VIEWPORT_EXTERNAL;
339606936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        } else if (!mParameters.uniqueDisplayId.isEmpty()) {
339706936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            // If the IDC file specified a unique display Id, then it expects to be linked to a
339806936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            // virtual display with the same unique ID.
339906936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            uniqueDisplayId = &mParameters.uniqueDisplayId;
340006936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            viewportTypeToUse = ViewportType::VIEWPORT_VIRTUAL;
340106936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        } else {
340206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            viewportTypeToUse = ViewportType::VIEWPORT_INTERNAL;
340306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        }
340406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon
340506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        if (!mConfig.getDisplayViewport(viewportTypeToUse, uniqueDisplayId, &newViewport)) {
3406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGI(INDENT "Touch device '%s' could not query the properties of its associated "
3407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "display.  The device will be inoperable until the display size "
3408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "becomes available.",
3409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    getDeviceName().string());
3410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mDeviceMode = DEVICE_MODE_DISABLED;
3411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return;
3412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        newViewport.setNonDisplayViewport(rawWidth, rawHeight);
3415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool viewportChanged = mViewport != newViewport;
3417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (viewportChanged) {
3418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mViewport = newViewport;
3419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mDeviceMode == DEVICE_MODE_DIRECT || mDeviceMode == DEVICE_MODE_POINTER) {
3421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Convert rotated viewport to natural surface coordinates.
3422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t naturalLogicalWidth, naturalLogicalHeight;
3423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t naturalPhysicalWidth, naturalPhysicalHeight;
3424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t naturalPhysicalLeft, naturalPhysicalTop;
3425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t naturalDeviceWidth, naturalDeviceHeight;
3426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            switch (mViewport.orientation) {
3427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case DISPLAY_ORIENTATION_90:
3428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
3429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
3430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
3431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
3432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom;
3433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalTop = mViewport.physicalLeft;
3434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceWidth = mViewport.deviceHeight;
3435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceHeight = mViewport.deviceWidth;
3436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
3437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case DISPLAY_ORIENTATION_180:
3438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
3439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
3440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
3441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
3442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight;
3443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom;
3444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceWidth = mViewport.deviceWidth;
3445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceHeight = mViewport.deviceHeight;
3446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
3447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case DISPLAY_ORIENTATION_270:
3448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
3449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
3450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
3451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
3452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalLeft = mViewport.physicalTop;
3453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight;
3454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceWidth = mViewport.deviceHeight;
3455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceHeight = mViewport.deviceWidth;
3456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
3457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case DISPLAY_ORIENTATION_0:
3458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            default:
3459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
3460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
3461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
3462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
3463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalLeft = mViewport.physicalLeft;
3464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalTop = mViewport.physicalTop;
3465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceWidth = mViewport.deviceWidth;
3466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceHeight = mViewport.deviceHeight;
3467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
3468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
3471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
3472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
3473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceTop = naturalPhysicalTop * naturalLogicalHeight / naturalPhysicalHeight;
3474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceOrientation = mParameters.orientationAware ?
3476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mViewport.orientation : DISPLAY_ORIENTATION_0;
3477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
3478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceWidth = rawWidth;
3479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceHeight = rawHeight;
3480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceLeft = 0;
3481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceTop = 0;
3482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceOrientation = DISPLAY_ORIENTATION_0;
3483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // If moving between pointer modes, need to reset some state.
3487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool deviceModeChanged = mDeviceMode != oldDeviceMode;
3488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceModeChanged) {
3489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.clear();
3490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Create pointer controller if needed.
3493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mDeviceMode == DEVICE_MODE_POINTER ||
3494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            (mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches)) {
3495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerController == NULL) {
3496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController = getPolicy()->obtainPointerController(getDeviceId());
3497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController.clear();
3500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (viewportChanged || deviceModeChanged) {
3503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
3504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "display id %d",
3505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                getDeviceId(), getDeviceName().string(), mSurfaceWidth, mSurfaceHeight,
3506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mSurfaceOrientation, mDeviceMode, mViewport.displayId);
3507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure X and Y factors.
3509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mXScale = float(mSurfaceWidth) / rawWidth;
3510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mYScale = float(mSurfaceHeight) / rawHeight;
3511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mXTranslate = -mSurfaceLeft;
3512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mYTranslate = -mSurfaceTop;
3513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mXPrecision = 1.0f / mXScale;
3514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mYPrecision = 1.0f / mYScale;
3515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
3517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.x.source = mSource;
3518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
3519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.y.source = mSource;
3520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        configureVirtualKeys();
3522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Scale factor for terms that are not oriented in a particular axis.
3524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // If the pixels are square then xScale == yScale otherwise we fake it
3525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // by choosing an average.
3526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mGeometricScale = avg(mXScale, mYScale);
3527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Size of diagonal axis.
3529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float diagonalSize = hypotf(mSurfaceWidth, mSurfaceHeight);
3530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Size factors.
3532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
3533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mRawPointerAxes.touchMajor.valid
3534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && mRawPointerAxes.touchMajor.maxValue != 0) {
3535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mSizeScale = 1.0f / mRawPointerAxes.touchMajor.maxValue;
3536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (mRawPointerAxes.toolMajor.valid
3537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && mRawPointerAxes.toolMajor.maxValue != 0) {
3538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mSizeScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
3539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
3540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mSizeScale = 0.0f;
3541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.haveTouchSize = true;
3544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.haveToolSize = true;
3545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.haveSize = true;
3546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
3548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMajor.source = mSource;
3549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMajor.min = 0;
3550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMajor.max = diagonalSize;
3551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMajor.flat = 0;
3552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMajor.fuzz = 0;
3553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMajor.resolution = 0;
3554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
3556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
3557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
3559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMajor.source = mSource;
3560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMajor.min = 0;
3561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMajor.max = diagonalSize;
3562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMajor.flat = 0;
3563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMajor.fuzz = 0;
3564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMajor.resolution = 0;
3565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMinor = mOrientedRanges.toolMajor;
3567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
3568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
3570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.size.source = mSource;
3571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.size.min = 0;
3572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.size.max = 1.0;
3573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.size.flat = 0;
3574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.size.fuzz = 0;
3575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.size.resolution = 0;
3576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
3577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSizeScale = 0.0f;
3578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Pressure factors.
3581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPressureScale = 0;
3582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
3583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                || mCalibration.pressureCalibration
3584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
3585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mCalibration.havePressureScale) {
3586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPressureScale = mCalibration.pressureScale;
3587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (mRawPointerAxes.pressure.valid
3588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && mRawPointerAxes.pressure.maxValue != 0) {
3589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPressureScale = 1.0f / mRawPointerAxes.pressure.maxValue;
3590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
3594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.pressure.source = mSource;
3595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.pressure.min = 0;
3596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.pressure.max = 1.0;
3597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.pressure.flat = 0;
3598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.pressure.fuzz = 0;
3599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.pressure.resolution = 0;
3600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Tilt
3602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mTiltXCenter = 0;
3603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mTiltXScale = 0;
3604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mTiltYCenter = 0;
3605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mTiltYScale = 0;
3606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mHaveTilt = mRawPointerAxes.tiltX.valid && mRawPointerAxes.tiltY.valid;
3607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mHaveTilt) {
3608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mTiltXCenter = avg(mRawPointerAxes.tiltX.minValue,
3609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mRawPointerAxes.tiltX.maxValue);
3610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mTiltYCenter = avg(mRawPointerAxes.tiltY.minValue,
3611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mRawPointerAxes.tiltY.maxValue);
3612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mTiltXScale = M_PI / 180;
3613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mTiltYScale = M_PI / 180;
3614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.haveTilt = true;
3616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.tilt.axis = AMOTION_EVENT_AXIS_TILT;
3618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.tilt.source = mSource;
3619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.tilt.min = 0;
3620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.tilt.max = M_PI_2;
3621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.tilt.flat = 0;
3622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.tilt.fuzz = 0;
3623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.tilt.resolution = 0;
3624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Orientation
3627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientationScale = 0;
3628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mHaveTilt) {
3629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.haveOrientation = true;
3630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
3632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.source = mSource;
3633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.min = -M_PI;
3634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.max = M_PI;
3635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.flat = 0;
3636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.fuzz = 0;
3637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.resolution = 0;
3638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (mCalibration.orientationCalibration !=
3639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                Calibration::ORIENTATION_CALIBRATION_NONE) {
3640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mCalibration.orientationCalibration
3641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
3642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (mRawPointerAxes.orientation.valid) {
3643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (mRawPointerAxes.orientation.maxValue > 0) {
3644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mOrientationScale = M_PI_2 / mRawPointerAxes.orientation.maxValue;
3645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    } else if (mRawPointerAxes.orientation.minValue < 0) {
3646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mOrientationScale = -M_PI_2 / mRawPointerAxes.orientation.minValue;
3647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    } else {
3648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mOrientationScale = 0;
3649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
3650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
3651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.haveOrientation = true;
3654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
3656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.source = mSource;
3657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.min = -M_PI_2;
3658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.max = M_PI_2;
3659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.flat = 0;
3660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.fuzz = 0;
3661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.resolution = 0;
3662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Distance
3665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDistanceScale = 0;
3666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.distanceCalibration != Calibration::DISTANCE_CALIBRATION_NONE) {
3667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mCalibration.distanceCalibration
3668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    == Calibration::DISTANCE_CALIBRATION_SCALED) {
3669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (mCalibration.haveDistanceScale) {
3670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mDistanceScale = mCalibration.distanceScale;
3671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
3672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mDistanceScale = 1.0f;
3673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
3674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3675d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.haveDistance = true;
3677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
3679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.distance.source = mSource;
3680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.distance.min =
3681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mRawPointerAxes.distance.minValue * mDistanceScale;
3682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.distance.max =
3683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mRawPointerAxes.distance.maxValue * mDistanceScale;
3684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.distance.flat = 0;
3685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.distance.fuzz =
3686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mRawPointerAxes.distance.fuzz * mDistanceScale;
3687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.distance.resolution = 0;
3688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Compute oriented precision, scales and ranges.
3691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Note that the maximum value reported is an inclusive maximum value so it is one
3692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // unit less than the total width or height of surface.
3693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mSurfaceOrientation) {
3694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case DISPLAY_ORIENTATION_90:
3695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case DISPLAY_ORIENTATION_270:
3696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedXPrecision = mYPrecision;
3697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedYPrecision = mXPrecision;
3698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.min = mYTranslate;
3700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.max = mSurfaceHeight + mYTranslate - 1;
3701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.flat = 0;
3702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.fuzz = 0;
3703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.resolution = mRawPointerAxes.y.resolution * mYScale;
3704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.min = mXTranslate;
3706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.max = mSurfaceWidth + mXTranslate - 1;
3707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.flat = 0;
3708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.fuzz = 0;
3709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.resolution = mRawPointerAxes.x.resolution * mXScale;
3710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
3711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        default:
3713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedXPrecision = mXPrecision;
3714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedYPrecision = mYPrecision;
3715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.min = mXTranslate;
3717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.max = mSurfaceWidth + mXTranslate - 1;
3718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.flat = 0;
3719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.fuzz = 0;
3720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.resolution = mRawPointerAxes.x.resolution * mXScale;
3721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.min = mYTranslate;
3723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.max = mSurfaceHeight + mYTranslate - 1;
3724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.flat = 0;
3725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.fuzz = 0;
3726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.resolution = mRawPointerAxes.y.resolution * mYScale;
3727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
3728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
373071b16e81f9cbf2e288611f32c43ea7fb4a331fcfJason Gerecke        // Location
373171b16e81f9cbf2e288611f32c43ea7fb4a331fcfJason Gerecke        updateAffineTransformation();
373271b16e81f9cbf2e288611f32c43ea7fb4a331fcfJason Gerecke
3733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mDeviceMode == DEVICE_MODE_POINTER) {
3734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Compute pointer gesture detection parameters.
3735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float rawDiagonal = hypotf(rawWidth, rawHeight);
3736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);
3737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Scale movements such that one whole swipe of the touch pad covers a
3739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // given area relative to the diagonal size of the display when no acceleration
3740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // is applied.
3741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Assume that the touch pad has a square aspect ratio such that movements in
3742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // X and Y of the same number of raw units cover the same physical distance.
3743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerXMovementScale = mConfig.pointerGestureMovementSpeedRatio
3744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    * displayDiagonal / rawDiagonal;
3745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerYMovementScale = mPointerXMovementScale;
3746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Scale zooms to cover a smaller range of the display than movements do.
3748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // This value determines the area around the pointer that is affected by freeform
3749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // pointer gestures.
3750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerXZoomScale = mConfig.pointerGestureZoomSpeedRatio
3751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    * displayDiagonal / rawDiagonal;
3752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerYZoomScale = mPointerXZoomScale;
3753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Max width between pointers to detect a swipe gesture is more than some fraction
3755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // of the diagonal axis of the touch pad.  Touches that are wider than this are
3756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // translated into freeform gestures.
3757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGestureMaxSwipeWidth =
3758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
3759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Abort current pointer usages because the state has changed.
3761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            abortPointerUsage(when, 0 /*policyFlags*/);
3762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Inform the dispatcher about the changes.
3765d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *outResetNeeded = true;
3766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bumpGeneration();
3767d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3768d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3769d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dumpSurface(String8& dump) {
3771d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Viewport: displayId=%d, orientation=%d, "
3772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            "logicalFrame=[%d, %d, %d, %d], "
3773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            "physicalFrame=[%d, %d, %d, %d], "
3774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            "deviceSize=[%d, %d]\n",
3775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mViewport.displayId, mViewport.orientation,
3776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mViewport.logicalLeft, mViewport.logicalTop,
3777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mViewport.logicalRight, mViewport.logicalBottom,
3778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mViewport.physicalLeft, mViewport.physicalTop,
3779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mViewport.physicalRight, mViewport.physicalBottom,
3780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mViewport.deviceWidth, mViewport.deviceHeight);
3781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
3783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
3784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
3785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
3786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
3787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::configureVirtualKeys() {
3790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    Vector<VirtualKeyDefinition> virtualKeyDefinitions;
3791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
3792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mVirtualKeys.clear();
3794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (virtualKeyDefinitions.size() == 0) {
3796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
3797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
3800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t touchScreenLeft = mRawPointerAxes.x.minValue;
3802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t touchScreenTop = mRawPointerAxes.y.minValue;
3803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t touchScreenWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
3804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t touchScreenHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
3805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
3807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const VirtualKeyDefinition& virtualKeyDefinition =
3808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                virtualKeyDefinitions[i];
3809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mVirtualKeys.add();
3811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        VirtualKey& virtualKey = mVirtualKeys.editTop();
3812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        virtualKey.scanCode = virtualKeyDefinition.scanCode;
3814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t keyCode;
38150faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov        int32_t dummyKeyMetaState;
3816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t flags;
38170faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov        if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, 0,
38180faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov                                  &keyCode, &dummyKeyMetaState, &flags)) {
3819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
3820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    virtualKey.scanCode);
3821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mVirtualKeys.pop(); // drop the key
3822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            continue;
3823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        virtualKey.keyCode = keyCode;
3826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        virtualKey.flags = flags;
3827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // convert the key definition's display coordinates into touch coordinates for a hit box
3829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t halfWidth = virtualKeyDefinition.width / 2;
3830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t halfHeight = virtualKeyDefinition.height / 2;
3831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
3833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
3834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
3835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
3836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
3837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                * touchScreenHeight / mSurfaceHeight + touchScreenTop;
3838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
3839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                * touchScreenHeight / mSurfaceHeight + touchScreenTop;
3840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dumpVirtualKeys(String8& dump) {
3844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!mVirtualKeys.isEmpty()) {
3845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT3 "Virtual Keys:\n");
3846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < mVirtualKeys.size(); i++) {
3848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const VirtualKey& virtualKey = mVirtualKeys.itemAt(i);
384941d2f80739700a56fd6a670923a2966add8dae61Mark Salyzyn            dump.appendFormat(INDENT4 "%zu: scanCode=%d, keyCode=%d, "
3850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
3851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    i, virtualKey.scanCode, virtualKey.keyCode,
3852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    virtualKey.hitLeft, virtualKey.hitRight,
3853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    virtualKey.hitTop, virtualKey.hitBottom);
3854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::parseCalibration() {
3859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    const PropertyMap& in = getDevice()->getConfiguration();
3860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    Calibration& out = mCalibration;
3861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Size
3863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
3864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 sizeCalibrationString;
3865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) {
3866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (sizeCalibrationString == "none") {
3867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
3868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (sizeCalibrationString == "geometric") {
3869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
3870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (sizeCalibrationString == "diameter") {
3871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeCalibration = Calibration::SIZE_CALIBRATION_DIAMETER;
3872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (sizeCalibrationString == "box") {
3873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeCalibration = Calibration::SIZE_CALIBRATION_BOX;
3874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (sizeCalibrationString == "area") {
3875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeCalibration = Calibration::SIZE_CALIBRATION_AREA;
3876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (sizeCalibrationString != "default") {
3877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for touch.size.calibration: '%s'",
3878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    sizeCalibrationString.string());
3879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.haveSizeScale = in.tryGetProperty(String8("touch.size.scale"),
3883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeScale);
3884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.haveSizeBias = in.tryGetProperty(String8("touch.size.bias"),
3885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeBias);
3886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.haveSizeIsSummed = in.tryGetProperty(String8("touch.size.isSummed"),
3887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeIsSummed);
3888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Pressure
3890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
3891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 pressureCalibrationString;
3892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) {
3893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (pressureCalibrationString == "none") {
3894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
3895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (pressureCalibrationString == "physical") {
3896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
3897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (pressureCalibrationString == "amplitude") {
3898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
3899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (pressureCalibrationString != "default") {
3900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for touch.pressure.calibration: '%s'",
3901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    pressureCalibrationString.string());
3902d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
3906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.pressureScale);
3907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Orientation
3909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
3910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 orientationCalibrationString;
3911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) {
3912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (orientationCalibrationString == "none") {
3913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
3914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (orientationCalibrationString == "interpolated") {
3915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
3916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (orientationCalibrationString == "vector") {
3917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR;
3918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (orientationCalibrationString != "default") {
3919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for touch.orientation.calibration: '%s'",
3920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    orientationCalibrationString.string());
3921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Distance
3925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_DEFAULT;
3926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 distanceCalibrationString;
3927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (in.tryGetProperty(String8("touch.distance.calibration"), distanceCalibrationString)) {
3928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (distanceCalibrationString == "none") {
3929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
3930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (distanceCalibrationString == "scaled") {
3931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
3932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (distanceCalibrationString != "default") {
3933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for touch.distance.calibration: '%s'",
3934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    distanceCalibrationString.string());
3935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.haveDistanceScale = in.tryGetProperty(String8("touch.distance.scale"),
3939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.distanceScale);
3940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_DEFAULT;
3942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 coverageCalibrationString;
3943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (in.tryGetProperty(String8("touch.coverage.calibration"), coverageCalibrationString)) {
3944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (coverageCalibrationString == "none") {
3945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_NONE;
3946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (coverageCalibrationString == "box") {
3947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_BOX;
3948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (coverageCalibrationString != "default") {
3949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for touch.coverage.calibration: '%s'",
3950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    coverageCalibrationString.string());
3951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::resolveCalibration() {
3956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Size
3957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mRawPointerAxes.touchMajor.valid || mRawPointerAxes.toolMajor.valid) {
3958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DEFAULT) {
3959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
3960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
3963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Pressure
3966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mRawPointerAxes.pressure.valid) {
3967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_DEFAULT) {
3968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
3969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
3972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Orientation
3975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mRawPointerAxes.orientation.valid) {
3976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.orientationCalibration == Calibration::ORIENTATION_CALIBRATION_DEFAULT) {
3977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
3978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
3981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Distance
3984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mRawPointerAxes.distance.valid) {
3985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.distanceCalibration == Calibration::DISTANCE_CALIBRATION_DEFAULT) {
3986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
3987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
3990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Coverage
3993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_DEFAULT) {
3994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCalibration.coverageCalibration = Calibration::COVERAGE_CALIBRATION_NONE;
3995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dumpCalibration(String8& dump) {
3999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT3 "Calibration:\n");
4000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Size
4002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mCalibration.sizeCalibration) {
4003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::SIZE_CALIBRATION_NONE:
4004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.size.calibration: none\n");
4005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::SIZE_CALIBRATION_GEOMETRIC:
4007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.size.calibration: geometric\n");
4008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::SIZE_CALIBRATION_DIAMETER:
4010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.size.calibration: diameter\n");
4011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::SIZE_CALIBRATION_BOX:
4013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.size.calibration: box\n");
4014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::SIZE_CALIBRATION_AREA:
4016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.size.calibration: area\n");
4017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
4019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(false);
4020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCalibration.haveSizeScale) {
4023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "touch.size.scale: %0.3f\n",
4024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCalibration.sizeScale);
4025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCalibration.haveSizeBias) {
4028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "touch.size.bias: %0.3f\n",
4029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCalibration.sizeBias);
4030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCalibration.haveSizeIsSummed) {
4033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "touch.size.isSummed: %s\n",
4034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toString(mCalibration.sizeIsSummed));
4035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Pressure
4038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mCalibration.pressureCalibration) {
4039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::PRESSURE_CALIBRATION_NONE:
4040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.pressure.calibration: none\n");
4041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
4043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.pressure.calibration: physical\n");
4044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
4046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.pressure.calibration: amplitude\n");
4047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
4049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(false);
4050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCalibration.havePressureScale) {
4053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n",
4054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCalibration.pressureScale);
4055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Orientation
4058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mCalibration.orientationCalibration) {
4059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::ORIENTATION_CALIBRATION_NONE:
4060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.orientation.calibration: none\n");
4061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
4063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.orientation.calibration: interpolated\n");
4064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::ORIENTATION_CALIBRATION_VECTOR:
4066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.orientation.calibration: vector\n");
4067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
4069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(false);
4070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Distance
4073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mCalibration.distanceCalibration) {
4074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::DISTANCE_CALIBRATION_NONE:
4075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.distance.calibration: none\n");
4076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::DISTANCE_CALIBRATION_SCALED:
4078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.distance.calibration: scaled\n");
4079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
4081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(false);
4082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCalibration.haveDistanceScale) {
4085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "touch.distance.scale: %0.3f\n",
4086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCalibration.distanceScale);
4087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mCalibration.coverageCalibration) {
4090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::COVERAGE_CALIBRATION_NONE:
4091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.coverage.calibration: none\n");
4092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::COVERAGE_CALIBRATION_BOX:
4094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.coverage.calibration: box\n");
4095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
4097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(false);
4098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4101af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gereckevoid TouchInputMapper::dumpAffineTransformation(String8& dump) {
4102af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dump.append(INDENT3 "Affine Transformation:\n");
4103af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke
4104af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dump.appendFormat(INDENT4 "X scale: %0.3f\n", mAffineTransform.x_scale);
4105af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dump.appendFormat(INDENT4 "X ymix: %0.3f\n", mAffineTransform.x_ymix);
4106af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dump.appendFormat(INDENT4 "X offset: %0.3f\n", mAffineTransform.x_offset);
4107af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dump.appendFormat(INDENT4 "Y xmix: %0.3f\n", mAffineTransform.y_xmix);
4108af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dump.appendFormat(INDENT4 "Y scale: %0.3f\n", mAffineTransform.y_scale);
4109af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dump.appendFormat(INDENT4 "Y offset: %0.3f\n", mAffineTransform.y_offset);
4110af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke}
4111af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke
411212d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gereckevoid TouchInputMapper::updateAffineTransformation() {
411371b16e81f9cbf2e288611f32c43ea7fb4a331fcfJason Gerecke    mAffineTransform = getPolicy()->getTouchAffineTransformation(mDevice->getDescriptor(),
411471b16e81f9cbf2e288611f32c43ea7fb4a331fcfJason Gerecke            mSurfaceOrientation);
411512d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke}
411612d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke
4117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::reset(nsecs_t when) {
4118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorButtonAccumulator.reset(getDevice());
4119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorScrollAccumulator.reset(getDevice());
4120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mTouchButtonAccumulator.reset(getDevice());
4121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerVelocityControl.reset();
4123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mWheelXVelocityControl.reset();
4124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mWheelYVelocityControl.reset();
4125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4126842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mRawStatesPending.clear();
4127842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mCurrentRawState.clear();
4128842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mCurrentCookedState.clear();
4129842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mLastRawState.clear();
4130842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mLastCookedState.clear();
4131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerUsage = POINTER_USAGE_NONE;
4132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mSentHoverEnter = false;
4133842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mHavePointerIds = false;
41348e812826015786e07cb83664f22f69b2f2c72586Michael Wright    mCurrentMotionAborted = false;
4135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mDownTime = 0;
4136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentVirtualKey.down = false;
4138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerGesture.reset();
4140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerSimple.reset();
4141842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    resetExternalStylus();
4142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerController != NULL) {
4144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
4145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->clearSpots();
4146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::reset(when);
4149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4151842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid TouchInputMapper::resetExternalStylus() {
4152842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mExternalStylusState.clear();
4153842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mExternalStylusId = -1;
415443fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright    mExternalStylusFusionTimeout = LLONG_MAX;
415543fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright    mExternalStylusDataPending = false;
415643fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright}
415743fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright
415843fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wrightvoid TouchInputMapper::clearStylusDataPendingFlags() {
4159842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mExternalStylusDataPending = false;
416043fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright    mExternalStylusFusionTimeout = LLONG_MAX;
4161842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
4162842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::process(const RawEvent* rawEvent) {
4164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorButtonAccumulator.process(rawEvent);
4165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorScrollAccumulator.process(rawEvent);
4166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mTouchButtonAccumulator.process(rawEvent);
4167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
4169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        sync(rawEvent->when);
4170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::sync(nsecs_t when) {
4174842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    const RawState* last = mRawStatesPending.isEmpty() ?
4175842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            &mCurrentRawState : &mRawStatesPending.top();
4176842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4177842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Push a new state.
4178842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mRawStatesPending.push();
4179842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    RawState* next = &mRawStatesPending.editTop();
4180842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    next->clear();
4181842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    next->when = when;
4182842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Sync button state.
4184842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    next->buttonState = mTouchButtonAccumulator.getButtonState()
4185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            | mCursorButtonAccumulator.getButtonState();
4186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4187842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Sync scroll
4188842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    next->rawVScroll = mCursorScrollAccumulator.getRelativeVWheel();
4189842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    next->rawHScroll = mCursorScrollAccumulator.getRelativeHWheel();
4190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorScrollAccumulator.finishSync();
4191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4192842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Sync touch
4193842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    syncTouch(when, next);
4194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4195842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Assign pointer ids.
4196842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (!mHavePointerIds) {
4197842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        assignPointerIds(last, next);
4198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4199842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4200842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright#if DEBUG_RAW_EVENTS
4201842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    ALOGD("syncTouch: pointerCount %d -> %d, touching ids 0x%08x -> 0x%08x, "
4202842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            "hovering ids 0x%08x -> 0x%08x",
4203842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            last->rawPointerData.pointerCount,
4204842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            next->rawPointerData.pointerCount,
4205842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            last->rawPointerData.touchingIdBits.value,
4206842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            next->rawPointerData.touchingIdBits.value,
4207842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            last->rawPointerData.hoveringIdBits.value,
4208842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            next->rawPointerData.hoveringIdBits.value);
4209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4211842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    processRawTouches(false /*timeout*/);
4212842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
4213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4214842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid TouchInputMapper::processRawTouches(bool timeout) {
4215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mDeviceMode == DEVICE_MODE_DISABLED) {
4216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Drop all input if the device is disabled.
4217842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mCurrentRawState.clear();
4218842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mRawStatesPending.clear();
4219842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        return;
4220842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
4221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4222842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Drain any pending touch states. The invariant here is that the mCurrentRawState is always
4223842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // valid and must go through the full cook and dispatch cycle. This ensures that anything
4224842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // touching the current state will only observe the events that have been dispatched to the
4225842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // rest of the pipeline.
4226842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    const size_t N = mRawStatesPending.size();
4227842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    size_t count;
4228842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    for(count = 0; count < N; count++) {
4229842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        const RawState& next = mRawStatesPending[count];
4230842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4231842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        // A failure to assign the stylus id means that we're waiting on stylus data
4232842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        // and so should defer the rest of the pipeline.
4233842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (assignExternalStylusId(next, timeout)) {
4234842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            break;
4235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4237842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        // All ready to go.
423843fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright        clearStylusDataPendingFlags();
4239842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mCurrentRawState.copyFrom(next);
424043fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright        if (mCurrentRawState.when < mLastRawState.when) {
424143fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright            mCurrentRawState.when = mLastRawState.when;
424243fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright        }
4243842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        cookAndDispatch(mCurrentRawState.when);
4244842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
4245842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (count != 0) {
4246842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mRawStatesPending.removeItemsAt(0, count);
4247842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
4248842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4249842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (mExternalStylusDataPending) {
425043fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright        if (timeout) {
425143fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright            nsecs_t when = mExternalStylusFusionTimeout - STYLUS_DATA_LATENCY;
425243fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright            clearStylusDataPendingFlags();
425343fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright            mCurrentRawState.copyFrom(mLastRawState);
425443fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright#if DEBUG_STYLUS_FUSION
425543fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright            ALOGD("Timeout expired, synthesizing event with new stylus data");
425643fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright#endif
425743fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright            cookAndDispatch(when);
425843fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright        } else if (mExternalStylusFusionTimeout == LLONG_MAX) {
425943fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright            mExternalStylusFusionTimeout = mExternalStylusState.when + TOUCH_DATA_TIMEOUT;
426043fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright            getContext()->requestTimeoutAtTime(mExternalStylusFusionTimeout);
426143fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright        }
4262842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
4263842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
4264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4265842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid TouchInputMapper::cookAndDispatch(nsecs_t when) {
4266842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Always start with a clean state.
4267842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mCurrentCookedState.clear();
4268842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4269842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Apply stylus buttons to current raw state.
4270842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    applyExternalStylusButtonState(when);
4271842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4272842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Handle policy on initial down or hover events.
4273842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    bool initialDown = mLastRawState.rawPointerData.pointerCount == 0
4274842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            && mCurrentRawState.rawPointerData.pointerCount != 0;
4275842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4276842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    uint32_t policyFlags = 0;
4277842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    bool buttonsPressed = mCurrentRawState.buttonState & ~mLastRawState.buttonState;
4278842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (initialDown || buttonsPressed) {
4279842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        // If this is a touch screen, hide the pointer on an initial down.
4280842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (mDeviceMode == DEVICE_MODE_DIRECT) {
4281842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            getContext()->fadePointer();
4282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4284842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (mParameters.wake) {
4285842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            policyFlags |= POLICY_FLAG_WAKE;
4286842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        }
4287842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
4288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4289842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Consume raw off-screen touches before cooking pointer data.
4290842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // If touches are consumed, subsequent code will not receive any pointer data.
4291842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (consumeRawTouches(when, policyFlags)) {
4292842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mCurrentRawState.rawPointerData.clear();
4293842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
4294842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4295842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Cook pointer data.  This call populates the mCurrentCookedState.cookedPointerData structure
4296842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // with cooked pointer data that has the same ids and indices as the raw data.
4297842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // The following code can use either the raw or cooked data, as needed.
4298842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    cookPointerData();
4299842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4300842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Apply stylus pressure to current cooked state.
4301842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    applyExternalStylusTouchState(when);
4302842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4303842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Synthesize key down from raw buttons if needed.
4304842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
43057b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright            policyFlags, mLastCookedState.buttonState, mCurrentCookedState.buttonState);
4306842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4307842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Dispatch the touches either directly or by translation through a pointer on screen.
4308842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (mDeviceMode == DEVICE_MODE_POINTER) {
4309842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        for (BitSet32 idBits(mCurrentRawState.rawPointerData.touchingIdBits);
4310842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                !idBits.isEmpty(); ) {
4311842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            uint32_t id = idBits.clearFirstMarkedBit();
4312842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            const RawPointerData::Pointer& pointer =
4313842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentRawState.rawPointerData.pointerForId(id);
4314842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
4315842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
4316842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.stylusIdBits.markBit(id);
4317842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
4318842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
4319842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.fingerIdBits.markBit(id);
4320842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_MOUSE) {
4321842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.mouseIdBits.markBit(id);
4322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4323842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        }
4324842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        for (BitSet32 idBits(mCurrentRawState.rawPointerData.hoveringIdBits);
4325842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                !idBits.isEmpty(); ) {
4326842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            uint32_t id = idBits.clearFirstMarkedBit();
4327842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            const RawPointerData::Pointer& pointer =
4328842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentRawState.rawPointerData.pointerForId(id);
4329842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
4330842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
4331842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.stylusIdBits.markBit(id);
4332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4333842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        }
4334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4335842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        // Stylus takes precedence over all tools, then mouse, then finger.
4336842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        PointerUsage pointerUsage = mPointerUsage;
4337842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (!mCurrentCookedState.stylusIdBits.isEmpty()) {
4338842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            mCurrentCookedState.mouseIdBits.clear();
4339842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            mCurrentCookedState.fingerIdBits.clear();
4340842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            pointerUsage = POINTER_USAGE_STYLUS;
4341842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        } else if (!mCurrentCookedState.mouseIdBits.isEmpty()) {
4342842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            mCurrentCookedState.fingerIdBits.clear();
4343842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            pointerUsage = POINTER_USAGE_MOUSE;
4344842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        } else if (!mCurrentCookedState.fingerIdBits.isEmpty() ||
4345842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                isPointerDown(mCurrentRawState.buttonState)) {
4346842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            pointerUsage = POINTER_USAGE_GESTURES;
4347842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        }
4348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4349842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        dispatchPointerUsage(when, policyFlags, pointerUsage);
4350842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    } else {
4351842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (mDeviceMode == DEVICE_MODE_DIRECT
4352842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                && mConfig.showTouches && mPointerController != NULL) {
4353842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
4354842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
4355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4356842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            mPointerController->setButtonState(mCurrentRawState.buttonState);
4357842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords,
4358842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.idToIndex,
4359842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.touchingIdBits);
4360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
43628e812826015786e07cb83664f22f69b2f2c72586Michael Wright        if (!mCurrentMotionAborted) {
43638e812826015786e07cb83664f22f69b2f2c72586Michael Wright            dispatchButtonRelease(when, policyFlags);
43648e812826015786e07cb83664f22f69b2f2c72586Michael Wright            dispatchHoverExit(when, policyFlags);
43658e812826015786e07cb83664f22f69b2f2c72586Michael Wright            dispatchTouches(when, policyFlags);
43668e812826015786e07cb83664f22f69b2f2c72586Michael Wright            dispatchHoverEnterAndMove(when, policyFlags);
43678e812826015786e07cb83664f22f69b2f2c72586Michael Wright            dispatchButtonPress(when, policyFlags);
43688e812826015786e07cb83664f22f69b2f2c72586Michael Wright        }
43698e812826015786e07cb83664f22f69b2f2c72586Michael Wright
43708e812826015786e07cb83664f22f69b2f2c72586Michael Wright        if (mCurrentCookedState.cookedPointerData.pointerCount == 0) {
43718e812826015786e07cb83664f22f69b2f2c72586Michael Wright            mCurrentMotionAborted = false;
43728e812826015786e07cb83664f22f69b2f2c72586Michael Wright        }
4373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4375842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Synthesize key up from raw buttons if needed.
4376842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
43777b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright            policyFlags, mLastCookedState.buttonState, mCurrentCookedState.buttonState);
4378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Clear some transient state.
4380842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mCurrentRawState.rawVScroll = 0;
4381842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mCurrentRawState.rawHScroll = 0;
4382842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4383842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Copy current touch to last touch in preparation for the next cycle.
4384842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mLastRawState.copyFrom(mCurrentRawState);
4385842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mLastCookedState.copyFrom(mCurrentCookedState);
4386842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
4387842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4388842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid TouchInputMapper::applyExternalStylusButtonState(nsecs_t when) {
43897b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    if (mDeviceMode == DEVICE_MODE_DIRECT && hasExternalStylus() && mExternalStylusId != -1) {
4390842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mCurrentRawState.buttonState |= mExternalStylusState.buttons;
4391842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
4392842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
4393842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4394842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid TouchInputMapper::applyExternalStylusTouchState(nsecs_t when) {
439553dca3aadda499824d3d0b2bbc25a72fc1a37877Michael Wright    CookedPointerData& currentPointerData = mCurrentCookedState.cookedPointerData;
439653dca3aadda499824d3d0b2bbc25a72fc1a37877Michael Wright    const CookedPointerData& lastPointerData = mLastCookedState.cookedPointerData;
439753dca3aadda499824d3d0b2bbc25a72fc1a37877Michael Wright
439853dca3aadda499824d3d0b2bbc25a72fc1a37877Michael Wright    if (mExternalStylusId != -1 && currentPointerData.isTouching(mExternalStylusId)) {
439953dca3aadda499824d3d0b2bbc25a72fc1a37877Michael Wright        float pressure = mExternalStylusState.pressure;
440053dca3aadda499824d3d0b2bbc25a72fc1a37877Michael Wright        if (pressure == 0.0f && lastPointerData.isTouching(mExternalStylusId)) {
440153dca3aadda499824d3d0b2bbc25a72fc1a37877Michael Wright            const PointerCoords& coords = lastPointerData.pointerCoordsForId(mExternalStylusId);
440253dca3aadda499824d3d0b2bbc25a72fc1a37877Michael Wright            pressure = coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE);
4403842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        }
440453dca3aadda499824d3d0b2bbc25a72fc1a37877Michael Wright        PointerCoords& coords = currentPointerData.editPointerCoordsWithId(mExternalStylusId);
440553dca3aadda499824d3d0b2bbc25a72fc1a37877Michael Wright        coords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
4406842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
440753dca3aadda499824d3d0b2bbc25a72fc1a37877Michael Wright        PointerProperties& properties =
440853dca3aadda499824d3d0b2bbc25a72fc1a37877Michael Wright                currentPointerData.editPointerPropertiesWithId(mExternalStylusId);
4409842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (mExternalStylusState.toolType != AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
4410842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            properties.toolType = mExternalStylusState.toolType;
4411842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        }
4412842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
4413842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
4414842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4415842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightbool TouchInputMapper::assignExternalStylusId(const RawState& state, bool timeout) {
4416842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (mDeviceMode != DEVICE_MODE_DIRECT || !hasExternalStylus()) {
4417842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        return false;
4418842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
4419842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4420842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    const bool initialDown = mLastRawState.rawPointerData.pointerCount == 0
4421842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            && state.rawPointerData.pointerCount != 0;
4422842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (initialDown) {
4423842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (mExternalStylusState.pressure != 0.0f) {
4424842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright#if DEBUG_STYLUS_FUSION
4425842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            ALOGD("Have both stylus and touch data, beginning fusion");
4426842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright#endif
4427842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            mExternalStylusId = state.rawPointerData.touchingIdBits.firstMarkedBit();
4428842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        } else if (timeout) {
4429842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright#if DEBUG_STYLUS_FUSION
4430842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            ALOGD("Timeout expired, assuming touch is not a stylus.");
4431842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright#endif
4432842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            resetExternalStylus();
4433842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        } else {
443443fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright            if (mExternalStylusFusionTimeout == LLONG_MAX) {
443543fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright                mExternalStylusFusionTimeout = state.when + EXTERNAL_STYLUS_DATA_TIMEOUT;
4436842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            }
4437842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright#if DEBUG_STYLUS_FUSION
4438842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            ALOGD("No stylus data but stylus is connected, requesting timeout "
443943fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright                    "(%" PRId64 "ms)", mExternalStylusFusionTimeout);
4440842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright#endif
444143fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright            getContext()->requestTimeoutAtTime(mExternalStylusFusionTimeout);
4442842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            return true;
4443842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        }
4444842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
4445842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4446842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    // Check if the stylus pointer has gone up.
4447842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (mExternalStylusId != -1 &&
4448842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            !state.rawPointerData.touchingIdBits.hasBit(mExternalStylusId)) {
4449842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright#if DEBUG_STYLUS_FUSION
4450842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            ALOGD("Stylus pointer is going up");
4451842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright#endif
4452842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mExternalStylusId = -1;
4453842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
4454842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4455842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    return false;
4456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::timeoutExpired(nsecs_t when) {
4459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mDeviceMode == DEVICE_MODE_POINTER) {
4460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerUsage == POINTER_USAGE_GESTURES) {
4461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchPointerGestures(when, 0 /*policyFlags*/, true /*isTimeout*/);
4462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4463842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    } else if (mDeviceMode == DEVICE_MODE_DIRECT) {
446443fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright        if (mExternalStylusFusionTimeout < when) {
4465842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            processRawTouches(true /*timeout*/);
446643fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright        } else if (mExternalStylusFusionTimeout != LLONG_MAX) {
446743fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright            getContext()->requestTimeoutAtTime(mExternalStylusFusionTimeout);
4468842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        }
4469842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
4470842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
4471842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
4472842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid TouchInputMapper::updateExternalStylusState(const StylusState& state) {
44734af18b90c149deba620270670c8c630a3fe56165Michael Wright    mExternalStylusState.copyFrom(state);
447443fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright    if (mExternalStylusId != -1 || mExternalStylusFusionTimeout != LLONG_MAX) {
4475842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        // We're either in the middle of a fused stream of data or we're waiting on data before
4476842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        // dispatching the initial down, so go ahead and dispatch now that we have fresh stylus
4477842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        // data.
4478842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mExternalStylusDataPending = true;
4479842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        processRawTouches(false /*timeout*/);
4480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
4484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Check for release of a virtual key.
4485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCurrentVirtualKey.down) {
4486842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (mCurrentRawState.rawPointerData.touchingIdBits.isEmpty()) {
4487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Pointer went up while virtual key was down.
4488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentVirtualKey.down = false;
4489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (!mCurrentVirtualKey.ignored) {
4490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIRTUAL_KEYS
4491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
4492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
4493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                dispatchVirtualKey(when, policyFlags,
4495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        AKEY_EVENT_ACTION_UP,
4496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
4497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return true;
4499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4501842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (mCurrentRawState.rawPointerData.touchingIdBits.count() == 1) {
4502842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            uint32_t id = mCurrentRawState.rawPointerData.touchingIdBits.firstMarkedBit();
4503842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            const RawPointerData::Pointer& pointer =
4504842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentRawState.rawPointerData.pointerForId(id);
4505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
4506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
4507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Pointer is still within the space of the virtual key.
4508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return true;
4509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Pointer left virtual key area or another pointer also went down.
4513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send key cancellation but do not consume the touch yet.
4514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // This is useful when the user swipes through from the virtual key area
4515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // into the main display surface.
4516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentVirtualKey.down = false;
4517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!mCurrentVirtualKey.ignored) {
4518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIRTUAL_KEYS
4519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
4520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
4521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchVirtualKey(when, policyFlags,
4523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AKEY_EVENT_ACTION_UP,
4524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
4525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            | AKEY_EVENT_FLAG_CANCELED);
4526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4529842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (mLastRawState.rawPointerData.touchingIdBits.isEmpty()
4530842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            && !mCurrentRawState.rawPointerData.touchingIdBits.isEmpty()) {
4531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Pointer just went down.  Check for virtual key press or off-screen touches.
4532842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        uint32_t id = mCurrentRawState.rawPointerData.touchingIdBits.firstMarkedBit();
4533842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        const RawPointerData::Pointer& pointer = mCurrentRawState.rawPointerData.pointerForId(id);
4534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!isPointInsideSurface(pointer.x, pointer.y)) {
4535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // If exactly one pointer went down, check for virtual key hit.
4536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Otherwise we will drop the entire stroke.
4537842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            if (mCurrentRawState.rawPointerData.touchingIdBits.count() == 1) {
4538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
4539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (virtualKey) {
4540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentVirtualKey.down = true;
4541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentVirtualKey.downTime = when;
4542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentVirtualKey.keyCode = virtualKey->keyCode;
4543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentVirtualKey.scanCode = virtualKey->scanCode;
4544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentVirtualKey.ignored = mContext->shouldDropVirtualKey(
4545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            when, getDevice(), virtualKey->keyCode, virtualKey->scanCode);
4546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (!mCurrentVirtualKey.ignored) {
4548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIRTUAL_KEYS
4549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ALOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
4550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                mCurrentVirtualKey.keyCode,
4551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                mCurrentVirtualKey.scanCode);
4552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        dispatchVirtualKey(when, policyFlags,
4554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                AKEY_EVENT_ACTION_DOWN,
4555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
4556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
4557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
4558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return true;
4560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Disable all virtual key touches that happen within a short time interval of the
4564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // most recent touch within the screen area.  The idea is to filter out stray
4565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // virtual key presses when interacting with the touch screen.
4566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //
4567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Problems we're trying to solve:
4568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //
4569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // 1. While scrolling a list or dragging the window shade, the user swipes down into a
4570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //    virtual key area that is implemented by a separate touch panel and accidentally
4571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //    triggers a virtual key.
4572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //
4573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
4574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //    area and accidentally triggers a virtual key.  This often happens when virtual keys
4575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //    are layed out below the screen near to where the on screen keyboard's space bar
4576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //    is displayed.
4577842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (mConfig.virtualKeyQuietTime > 0 &&
4578842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            !mCurrentRawState.rawPointerData.touchingIdBits.isEmpty()) {
4579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
4580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return false;
4582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
4585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t keyEventAction, int32_t keyEventFlags) {
4586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t keyCode = mCurrentVirtualKey.keyCode;
4587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t scanCode = mCurrentVirtualKey.scanCode;
4588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    nsecs_t downTime = mCurrentVirtualKey.downTime;
4589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t metaState = mContext->getGlobalMetaState();
4590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    policyFlags |= POLICY_FLAG_VIRTUAL;
4591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
4593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
4594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getListener()->notifyKey(&args);
4595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
45978e812826015786e07cb83664f22f69b2f2c72586Michael Wrightvoid TouchInputMapper::abortTouches(nsecs_t when, uint32_t policyFlags) {
45988e812826015786e07cb83664f22f69b2f2c72586Michael Wright    BitSet32 currentIdBits = mCurrentCookedState.cookedPointerData.touchingIdBits;
45998e812826015786e07cb83664f22f69b2f2c72586Michael Wright    if (!currentIdBits.isEmpty()) {
46008e812826015786e07cb83664f22f69b2f2c72586Michael Wright        int32_t metaState = getContext()->getGlobalMetaState();
46018e812826015786e07cb83664f22f69b2f2c72586Michael Wright        int32_t buttonState = mCurrentCookedState.buttonState;
46028e812826015786e07cb83664f22f69b2f2c72586Michael Wright        dispatchMotion(when, policyFlags, mSource, AMOTION_EVENT_ACTION_CANCEL, 0, 0,
46038e812826015786e07cb83664f22f69b2f2c72586Michael Wright                metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
46048e812826015786e07cb83664f22f69b2f2c72586Michael Wright                mCurrentCookedState.cookedPointerData.pointerProperties,
46058e812826015786e07cb83664f22f69b2f2c72586Michael Wright                mCurrentCookedState.cookedPointerData.pointerCoords,
46068e812826015786e07cb83664f22f69b2f2c72586Michael Wright                mCurrentCookedState.cookedPointerData.idToIndex,
46078e812826015786e07cb83664f22f69b2f2c72586Michael Wright                currentIdBits, -1,
46088e812826015786e07cb83664f22f69b2f2c72586Michael Wright                mOrientedXPrecision, mOrientedYPrecision, mDownTime);
46098e812826015786e07cb83664f22f69b2f2c72586Michael Wright        mCurrentMotionAborted = true;
46108e812826015786e07cb83664f22f69b2f2c72586Michael Wright    }
46118e812826015786e07cb83664f22f69b2f2c72586Michael Wright}
46128e812826015786e07cb83664f22f69b2f2c72586Michael Wright
4613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
4614842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    BitSet32 currentIdBits = mCurrentCookedState.cookedPointerData.touchingIdBits;
4615842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    BitSet32 lastIdBits = mLastCookedState.cookedPointerData.touchingIdBits;
4616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t metaState = getContext()->getGlobalMetaState();
46177b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    int32_t buttonState = mCurrentCookedState.buttonState;
4618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (currentIdBits == lastIdBits) {
4620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!currentIdBits.isEmpty()) {
4621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // No pointer id changes so this is a move event.
4622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // The listener takes care of batching moves so we don't have to deal with that here.
4623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchMotion(when, policyFlags, mSource,
46247b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState,
4625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_EDGE_FLAG_NONE,
4626842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.pointerProperties,
4627842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.pointerCoords,
4628842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.idToIndex,
4629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    currentIdBits, -1,
4630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
4633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // There may be pointers going up and pointers going down and pointers moving
4634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // all at the same time.
4635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value);
4636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
4637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
4638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 dispatchedIdBits(lastIdBits.value);
4639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Update last coordinates of pointers that have moved so that we observe the new
4641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // pointer positions at the same time as other pointers that have just gone up.
4642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool moveNeeded = updateMovedPointers(
4643842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.cookedPointerData.pointerProperties,
4644842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.cookedPointerData.pointerCoords,
4645842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.cookedPointerData.idToIndex,
4646842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mLastCookedState.cookedPointerData.pointerProperties,
4647842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mLastCookedState.cookedPointerData.pointerCoords,
4648842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mLastCookedState.cookedPointerData.idToIndex,
4649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                moveIdBits);
46507b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        if (buttonState != mLastCookedState.buttonState) {
4651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            moveNeeded = true;
4652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Dispatch pointer up events.
4655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        while (!upIdBits.isEmpty()) {
4656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t upId = upIdBits.clearFirstMarkedBit();
4657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchMotion(when, policyFlags, mSource,
46597b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    AMOTION_EVENT_ACTION_POINTER_UP, 0, 0, metaState, buttonState, 0,
4660842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mLastCookedState.cookedPointerData.pointerProperties,
4661842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mLastCookedState.cookedPointerData.pointerCoords,
4662842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mLastCookedState.cookedPointerData.idToIndex,
46637b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    dispatchedIdBits, upId, mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchedIdBits.clearBit(upId);
4665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Dispatch move events if any of the remaining pointers moved from their old locations.
4668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Although applications receive new locations as part of individual pointer up
4669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // events, they do not generally handle them except when presented in a move event.
467043fd19fd1a22d95ed985a0680fd8806d918f3ba7Michael Wright        if (moveNeeded && !moveIdBits.isEmpty()) {
4671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
4672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchMotion(when, policyFlags, mSource,
46737b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState, 0,
4674842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.pointerProperties,
4675842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.pointerCoords,
4676842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.idToIndex,
46777b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    dispatchedIdBits, -1, mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Dispatch pointer down events using the new pointer locations.
4681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        while (!downIdBits.isEmpty()) {
4682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t downId = downIdBits.clearFirstMarkedBit();
4683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchedIdBits.markBit(downId);
4684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (dispatchedIdBits.count() == 1) {
4686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // First pointer is going down.  Set down time.
4687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mDownTime = when;
4688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchMotion(when, policyFlags, mSource,
46917b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    AMOTION_EVENT_ACTION_POINTER_DOWN, 0, 0, metaState, buttonState, 0,
4692842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.pointerProperties,
4693842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.pointerCoords,
4694842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.idToIndex,
46957b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    dispatchedIdBits, downId, mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchHoverExit(nsecs_t when, uint32_t policyFlags) {
4701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mSentHoverEnter &&
4702842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            (mCurrentCookedState.cookedPointerData.hoveringIdBits.isEmpty()
4703842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    || !mCurrentCookedState.cookedPointerData.touchingIdBits.isEmpty())) {
4704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t metaState = getContext()->getGlobalMetaState();
4705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchMotion(when, policyFlags, mSource,
47067b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                AMOTION_EVENT_ACTION_HOVER_EXIT, 0, 0, metaState, mLastCookedState.buttonState, 0,
4707842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mLastCookedState.cookedPointerData.pointerProperties,
4708842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mLastCookedState.cookedPointerData.pointerCoords,
4709842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mLastCookedState.cookedPointerData.idToIndex,
4710842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mLastCookedState.cookedPointerData.hoveringIdBits, -1,
4711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSentHoverEnter = false;
4713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags) {
4717842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (mCurrentCookedState.cookedPointerData.touchingIdBits.isEmpty()
4718842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            && !mCurrentCookedState.cookedPointerData.hoveringIdBits.isEmpty()) {
4719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t metaState = getContext()->getGlobalMetaState();
4720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!mSentHoverEnter) {
4721842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            dispatchMotion(when, policyFlags, mSource, AMOTION_EVENT_ACTION_HOVER_ENTER,
47227b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    0, 0, metaState, mCurrentRawState.buttonState, 0,
4723842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.pointerProperties,
4724842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.pointerCoords,
4725842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.idToIndex,
4726842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.cookedPointerData.hoveringIdBits, -1,
4727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSentHoverEnter = true;
4729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchMotion(when, policyFlags, mSource,
47327b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
4733842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentRawState.buttonState, 0,
4734842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.cookedPointerData.pointerProperties,
4735842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.cookedPointerData.pointerCoords,
4736842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.cookedPointerData.idToIndex,
4737842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.cookedPointerData.hoveringIdBits, -1,
4738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
47427b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wrightvoid TouchInputMapper::dispatchButtonRelease(nsecs_t when, uint32_t policyFlags) {
47437b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    BitSet32 releasedButtons(mLastCookedState.buttonState & ~mCurrentCookedState.buttonState);
47447b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    const BitSet32& idBits = findActiveIdBits(mLastCookedState.cookedPointerData);
47457b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    const int32_t metaState = getContext()->getGlobalMetaState();
47467b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    int32_t buttonState = mLastCookedState.buttonState;
47477b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    while (!releasedButtons.isEmpty()) {
47487b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        int32_t actionButton = BitSet32::valueForBit(releasedButtons.clearFirstMarkedBit());
47497b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        buttonState &= ~actionButton;
47507b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        dispatchMotion(when, policyFlags, mSource,
47517b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    AMOTION_EVENT_ACTION_BUTTON_RELEASE, actionButton,
47527b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    0, metaState, buttonState, 0,
47537b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    mCurrentCookedState.cookedPointerData.pointerProperties,
47547b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    mCurrentCookedState.cookedPointerData.pointerCoords,
47557b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    mCurrentCookedState.cookedPointerData.idToIndex, idBits, -1,
47567b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
47577b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    }
47587b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright}
47597b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright
47607b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wrightvoid TouchInputMapper::dispatchButtonPress(nsecs_t when, uint32_t policyFlags) {
47617b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    BitSet32 pressedButtons(mCurrentCookedState.buttonState & ~mLastCookedState.buttonState);
47627b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    const BitSet32& idBits = findActiveIdBits(mCurrentCookedState.cookedPointerData);
47637b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    const int32_t metaState = getContext()->getGlobalMetaState();
47647b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    int32_t buttonState = mLastCookedState.buttonState;
47657b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    while (!pressedButtons.isEmpty()) {
47667b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        int32_t actionButton = BitSet32::valueForBit(pressedButtons.clearFirstMarkedBit());
47677b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        buttonState |= actionButton;
47687b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        dispatchMotion(when, policyFlags, mSource, AMOTION_EVENT_ACTION_BUTTON_PRESS, actionButton,
47697b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    0, metaState, buttonState, 0,
47707b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    mCurrentCookedState.cookedPointerData.pointerProperties,
47717b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    mCurrentCookedState.cookedPointerData.pointerCoords,
47727b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    mCurrentCookedState.cookedPointerData.idToIndex, idBits, -1,
47737b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
47747b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    }
47757b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright}
47767b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright
47777b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wrightconst BitSet32& TouchInputMapper::findActiveIdBits(const CookedPointerData& cookedPointerData) {
47787b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    if (!cookedPointerData.touchingIdBits.isEmpty()) {
47797b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        return cookedPointerData.touchingIdBits;
47807b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    }
47817b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    return cookedPointerData.hoveringIdBits;
47827b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright}
47837b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright
4784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::cookPointerData() {
4785842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    uint32_t currentPointerCount = mCurrentRawState.rawPointerData.pointerCount;
4786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4787842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mCurrentCookedState.cookedPointerData.clear();
4788842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mCurrentCookedState.cookedPointerData.pointerCount = currentPointerCount;
4789842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mCurrentCookedState.cookedPointerData.hoveringIdBits =
4790842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            mCurrentRawState.rawPointerData.hoveringIdBits;
4791842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mCurrentCookedState.cookedPointerData.touchingIdBits =
4792842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            mCurrentRawState.rawPointerData.touchingIdBits;
4793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
47947b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    if (mCurrentCookedState.cookedPointerData.pointerCount == 0) {
47957b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        mCurrentCookedState.buttonState = 0;
47967b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    } else {
47977b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        mCurrentCookedState.buttonState = mCurrentRawState.buttonState;
47987b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    }
47997b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright
4800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Walk through the the active pointers and map device coordinates onto
4801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // surface coordinates and adjust for display orientation.
4802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t i = 0; i < currentPointerCount; i++) {
4803842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        const RawPointerData::Pointer& in = mCurrentRawState.rawPointerData.pointers[i];
4804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Size
4806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float touchMajor, touchMinor, toolMajor, toolMinor, size;
4807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mCalibration.sizeCalibration) {
4808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::SIZE_CALIBRATION_GEOMETRIC:
4809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::SIZE_CALIBRATION_DIAMETER:
4810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::SIZE_CALIBRATION_BOX:
4811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::SIZE_CALIBRATION_AREA:
4812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.toolMajor.valid) {
4813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMajor = in.touchMajor;
4814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMinor = mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
4815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMajor = in.toolMajor;
4816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMinor = mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
4817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                size = mRawPointerAxes.touchMinor.valid
4818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
4819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (mRawPointerAxes.touchMajor.valid) {
4820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMajor = touchMajor = in.touchMajor;
4821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMinor = touchMinor = mRawPointerAxes.touchMinor.valid
4822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ? in.touchMinor : in.touchMajor;
4823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                size = mRawPointerAxes.touchMinor.valid
4824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
4825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (mRawPointerAxes.toolMajor.valid) {
4826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMajor = toolMajor = in.toolMajor;
4827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMinor = toolMinor = mRawPointerAxes.toolMinor.valid
4828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ? in.toolMinor : in.toolMajor;
4829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                size = mRawPointerAxes.toolMinor.valid
4830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ? avg(in.toolMajor, in.toolMinor) : in.toolMajor;
4831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
4832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOG_ASSERT(false, "No touch or tool axes.  "
4833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        "Size calibration should have been resolved to NONE.");
4834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMajor = 0;
4835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMinor = 0;
4836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMajor = 0;
4837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMinor = 0;
4838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                size = 0;
4839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) {
4842842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                uint32_t touchingCount =
4843842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                        mCurrentRawState.rawPointerData.touchingIdBits.count();
4844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (touchingCount > 1) {
4845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    touchMajor /= touchingCount;
4846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    touchMinor /= touchingCount;
4847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    toolMajor /= touchingCount;
4848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    toolMinor /= touchingCount;
4849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    size /= touchingCount;
4850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
4851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_GEOMETRIC) {
4854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMajor *= mGeometricScale;
4855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMinor *= mGeometricScale;
4856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMajor *= mGeometricScale;
4857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMinor *= mGeometricScale;
4858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_AREA) {
4859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMajor = touchMajor > 0 ? sqrtf(touchMajor) : 0;
4860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMinor = touchMajor;
4861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMajor = toolMajor > 0 ? sqrtf(toolMajor) : 0;
4862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMinor = toolMajor;
4863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DIAMETER) {
4864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMinor = touchMajor;
4865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMinor = toolMajor;
4866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.applySizeScaleAndBias(&touchMajor);
4869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.applySizeScaleAndBias(&touchMinor);
4870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.applySizeScaleAndBias(&toolMajor);
4871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.applySizeScaleAndBias(&toolMinor);
4872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            size *= mSizeScale;
4873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        default:
4875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            touchMajor = 0;
4876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            touchMinor = 0;
4877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toolMajor = 0;
4878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toolMinor = 0;
4879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            size = 0;
4880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Pressure
4884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float pressure;
4885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mCalibration.pressureCalibration) {
4886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
4887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
4888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            pressure = in.pressure * mPressureScale;
4889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        default:
4891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            pressure = in.isHovering ? 0 : 1;
4892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Tilt and Orientation
4896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float tilt;
4897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float orientation;
4898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mHaveTilt) {
4899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float tiltXAngle = (in.tiltX - mTiltXCenter) * mTiltXScale;
4900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float tiltYAngle = (in.tiltY - mTiltYCenter) * mTiltYScale;
4901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
4902d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
4903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
4904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            tilt = 0;
4905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            switch (mCalibration.orientationCalibration) {
4907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
4908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                orientation = in.orientation * mOrientationScale;
4909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
4910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case Calibration::ORIENTATION_CALIBRATION_VECTOR: {
4911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
4912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                int32_t c2 = signExtendNybble(in.orientation & 0x0f);
4913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (c1 != 0 || c2 != 0) {
4914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    orientation = atan2f(c1, c2) * 0.5f;
4915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float confidence = hypotf(c1, c2);
4916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float scale = 1.0f + confidence / 16.0f;
4917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    touchMajor *= scale;
4918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    touchMinor /= scale;
4919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    toolMajor *= scale;
4920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    toolMinor /= scale;
4921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
4922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    orientation = 0;
4923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
4924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
4925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            default:
4927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                orientation = 0;
4928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Distance
4932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float distance;
4933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mCalibration.distanceCalibration) {
4934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::DISTANCE_CALIBRATION_SCALED:
4935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            distance = in.distance * mDistanceScale;
4936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        default:
4938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            distance = 0;
4939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Coverage
4942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t rawLeft, rawTop, rawRight, rawBottom;
4943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mCalibration.coverageCalibration) {
4944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::COVERAGE_CALIBRATION_BOX:
4945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rawLeft = (in.toolMinor & 0xffff0000) >> 16;
4946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rawRight = in.toolMinor & 0x0000ffff;
4947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rawBottom = in.toolMajor & 0x0000ffff;
4948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rawTop = (in.toolMajor & 0xffff0000) >> 16;
4949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        default:
4951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rawLeft = rawTop = rawRight = rawBottom = 0;
4952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4955af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke        // Adjust X,Y coords for device calibration
4956af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke        // TODO: Adjust coverage coords?
4957af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke        float xTransformed = in.x, yTransformed = in.y;
4958af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke        mAffineTransform.applyTo(xTransformed, yTransformed);
4959af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke
4960af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke        // Adjust X, Y, and coverage coords for surface orientation.
4961af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke        float x, y;
4962af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke        float left, top, right, bottom;
4963af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke
4964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mSurfaceOrientation) {
4965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case DISPLAY_ORIENTATION_90:
4966af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            x = float(yTransformed - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
4967af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            y = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale + mXTranslate;
4968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
4969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            right = float(rawBottom- mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
4970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
4971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            top = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
4972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            orientation -= M_PI_2;
497318a81488f928a94bdeede9b884f9b56c8da0c5fcbaik.han            if (mOrientedRanges.haveOrientation && orientation < mOrientedRanges.orientation.min) {
4974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
4975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case DISPLAY_ORIENTATION_180:
4978af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            x = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale + mXTranslate;
4979af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            y = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
4980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
4981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
4982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
4983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
4984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            orientation -= M_PI;
498518a81488f928a94bdeede9b884f9b56c8da0c5fcbaik.han            if (mOrientedRanges.haveOrientation && orientation < mOrientedRanges.orientation.min) {
4986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
4987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case DISPLAY_ORIENTATION_270:
4990af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            x = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
4991af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            y = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
4992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
4993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
4994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
4995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
4996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            orientation += M_PI_2;
499718a81488f928a94bdeede9b884f9b56c8da0c5fcbaik.han            if (mOrientedRanges.haveOrientation && orientation > mOrientedRanges.orientation.max) {
4998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                orientation -= (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
4999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
5001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        default:
5002af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            x = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
5003af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            y = float(yTransformed - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
5004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
5005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
5006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
5007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            top = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
5008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
5009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Write output coords.
5012842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        PointerCoords& out = mCurrentCookedState.cookedPointerData.pointerCoords[i];
5013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.clear();
5014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
5015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
5016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
5017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
5018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
5019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
5020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
5021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);
5022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
5023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_BOX) {
5024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_1, left);
5025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_2, top);
5026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_3, right);
5027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_4, bottom);
5028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
5029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
5030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
5031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Write output properties.
5034842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        PointerProperties& properties =
5035842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.cookedPointerData.pointerProperties[i];
5036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = in.id;
5037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        properties.clear();
5038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        properties.id = id;
5039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        properties.toolType = in.toolType;
5040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Write id index.
5042842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mCurrentCookedState.cookedPointerData.idToIndex[id] = i;
5043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchPointerUsage(nsecs_t when, uint32_t policyFlags,
5047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerUsage pointerUsage) {
5048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (pointerUsage != mPointerUsage) {
5049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        abortPointerUsage(when, policyFlags);
5050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerUsage = pointerUsage;
5051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mPointerUsage) {
5054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case POINTER_USAGE_GESTURES:
5055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
5056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
5057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case POINTER_USAGE_STYLUS:
5058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchPointerStylus(when, policyFlags);
5059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
5060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case POINTER_USAGE_MOUSE:
5061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchPointerMouse(when, policyFlags);
5062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
5063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
5064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
5065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::abortPointerUsage(nsecs_t when, uint32_t policyFlags) {
5069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mPointerUsage) {
5070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case POINTER_USAGE_GESTURES:
5071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        abortPointerGestures(when, policyFlags);
5072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
5073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case POINTER_USAGE_STYLUS:
5074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        abortPointerStylus(when, policyFlags);
5075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
5076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case POINTER_USAGE_MOUSE:
5077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        abortPointerMouse(when, policyFlags);
5078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
5079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
5080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
5081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerUsage = POINTER_USAGE_NONE;
5084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags,
5087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool isTimeout) {
5088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Update current gesture coordinates.
5089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool cancelPreviousGesture, finishPreviousGesture;
5090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool sendEvents = preparePointerGestures(when,
5091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            &cancelPreviousGesture, &finishPreviousGesture, isTimeout);
5092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!sendEvents) {
5093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
5094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (finishPreviousGesture) {
5096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        cancelPreviousGesture = false;
5097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Update the pointer presentation and spots.
51003dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour    if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH) {
51013dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour        mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
5102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (finishPreviousGesture || cancelPreviousGesture) {
5103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->clearSpots();
5104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
51053dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour
51063dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour        if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
51073dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour            mPointerController->setSpots(mPointerGesture.currentGestureCoords,
51083dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour                     mPointerGesture.currentGestureIdToIndex,
51093dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour                     mPointerGesture.currentGestureIdBits);
51103dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour        }
5111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
5112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
5113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Show or hide the pointer if needed.
5116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mPointerGesture.currentGestureMode) {
5117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::NEUTRAL:
5118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::QUIET:
51193dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour        if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH
51203dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour                && mPointerGesture.lastGestureMode == PointerGesture::FREEFORM) {
5121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Remind the user of where the pointer is after finishing a gesture with spots.
5122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL);
5123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
5125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::TAP:
5126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::TAP_DRAG:
5127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::BUTTON_CLICK_OR_DRAG:
5128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::HOVER:
5129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::PRESS:
51303dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour    case PointerGesture::SWIPE:
5131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Unfade the pointer when the current gesture manipulates the
5132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // area directly under the pointer.
5133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
5134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
5135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::FREEFORM:
5136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Fade the pointer when the current gesture manipulates a different
5137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // area and there are spots to guide the user experience.
51383dd617bbad0fe73739ea592d735773c0730b0601Amirhossein Simjour        if (mParameters.gestureMode == Parameters::GESTURE_MODE_MULTI_TOUCH) {
5139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
5140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
5141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
5142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
5144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Send events!
5147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t metaState = getContext()->getGlobalMetaState();
51487b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    int32_t buttonState = mCurrentCookedState.buttonState;
5149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Update last coordinates of pointers that have moved so that we observe the new
5151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // pointer positions at the same time as other pointers that have just gone up.
5152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool down = mPointerGesture.currentGestureMode == PointerGesture::TAP
5153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG
5154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mPointerGesture.currentGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
5155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mPointerGesture.currentGestureMode == PointerGesture::PRESS
5156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mPointerGesture.currentGestureMode == PointerGesture::SWIPE
5157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mPointerGesture.currentGestureMode == PointerGesture::FREEFORM;
5158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool moveNeeded = false;
5159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (down && !cancelPreviousGesture && !finishPreviousGesture
5160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && !mPointerGesture.lastGestureIdBits.isEmpty()
5161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && !mPointerGesture.currentGestureIdBits.isEmpty()) {
5162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 movedGestureIdBits(mPointerGesture.currentGestureIdBits.value
5163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                & mPointerGesture.lastGestureIdBits.value);
5164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        moveNeeded = updateMovedPointers(mPointerGesture.currentGestureProperties,
5165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
5166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.lastGestureProperties,
5167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
5168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                movedGestureIdBits);
51697b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        if (buttonState != mLastCookedState.buttonState) {
5170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            moveNeeded = true;
5171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Send motion events for all pointers that went up or were canceled.
5175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    BitSet32 dispatchedGestureIdBits(mPointerGesture.lastGestureIdBits);
5176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!dispatchedGestureIdBits.isEmpty()) {
5177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (cancelPreviousGesture) {
5178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchMotion(when, policyFlags, mSource,
51797b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    AMOTION_EVENT_ACTION_CANCEL, 0, 0, metaState, buttonState,
5180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_EDGE_FLAG_NONE,
5181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.lastGestureProperties,
5182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
51837b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    dispatchedGestureIdBits, -1, 0,
51847b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    0, mPointerGesture.downTime);
5185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchedGestureIdBits.clear();
5187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
5188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            BitSet32 upGestureIdBits;
5189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (finishPreviousGesture) {
5190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                upGestureIdBits = dispatchedGestureIdBits;
5191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
5192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                upGestureIdBits.value = dispatchedGestureIdBits.value
5193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        & ~mPointerGesture.currentGestureIdBits.value;
5194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            while (!upGestureIdBits.isEmpty()) {
5196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t id = upGestureIdBits.clearFirstMarkedBit();
5197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                dispatchMotion(when, policyFlags, mSource,
51997b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                        AMOTION_EVENT_ACTION_POINTER_UP, 0, 0,
5200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
5201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mPointerGesture.lastGestureProperties,
5202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
5203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        dispatchedGestureIdBits, id,
5204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        0, 0, mPointerGesture.downTime);
5205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                dispatchedGestureIdBits.clearBit(id);
5207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Send motion events for all pointers that moved.
5212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (moveNeeded) {
5213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchMotion(when, policyFlags, mSource,
52147b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState,
52157b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                AMOTION_EVENT_EDGE_FLAG_NONE,
5216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureProperties,
5217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
5218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                dispatchedGestureIdBits, -1,
5219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                0, 0, mPointerGesture.downTime);
5220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Send motion events for all pointers that went down.
5223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (down) {
5224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 downGestureIdBits(mPointerGesture.currentGestureIdBits.value
5225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                & ~dispatchedGestureIdBits.value);
5226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        while (!downGestureIdBits.isEmpty()) {
5227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = downGestureIdBits.clearFirstMarkedBit();
5228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchedGestureIdBits.markBit(id);
5229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (dispatchedGestureIdBits.count() == 1) {
5231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.downTime = when;
5232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchMotion(when, policyFlags, mSource,
52357b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    AMOTION_EVENT_ACTION_POINTER_DOWN, 0, 0, metaState, buttonState, 0,
5236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureProperties,
5237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
5238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    dispatchedGestureIdBits, id,
5239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    0, 0, mPointerGesture.downTime);
5240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Send motion events for hover.
5244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerGesture.currentGestureMode == PointerGesture::HOVER) {
5245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchMotion(when, policyFlags, mSource,
52467b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
5247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
5248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureProperties,
5249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
5250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureIdBits, -1,
5251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                0, 0, mPointerGesture.downTime);
5252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (dispatchedGestureIdBits.isEmpty()
5253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && !mPointerGesture.lastGestureIdBits.isEmpty()) {
5254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Synthesize a hover move event after all pointers go up to indicate that
5255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // the pointer is hovering again even if the user is not currently touching
5256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // the touch pad.  This ensures that a view will receive a fresh hover enter
5257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // event after a tap.
5258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float x, y;
5259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->getPosition(&x, &y);
5260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerProperties pointerProperties;
5262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerProperties.clear();
5263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerProperties.id = 0;
5264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
5265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerCoords pointerCoords;
5267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.clear();
5268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
5269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
5270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
52727b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0,
5273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
5274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mViewport.displayId, 1, &pointerProperties, &pointerCoords,
5275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                0, 0, mPointerGesture.downTime);
5276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifyMotion(&args);
5277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Update state.
5280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerGesture.lastGestureMode = mPointerGesture.currentGestureMode;
5281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!down) {
5282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.lastGestureIdBits.clear();
5283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
5284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.lastGestureIdBits = mPointerGesture.currentGestureIdBits;
5285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) {
5286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = idBits.clearFirstMarkedBit();
5287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
5288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.lastGestureProperties[index].copyFrom(
5289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureProperties[index]);
5290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.lastGestureCoords[index].copyFrom(
5291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureCoords[index]);
5292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.lastGestureIdToIndex[id] = index;
5293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::abortPointerGestures(nsecs_t when, uint32_t policyFlags) {
5298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Cancel previously dispatches pointers.
5299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!mPointerGesture.lastGestureIdBits.isEmpty()) {
5300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t metaState = getContext()->getGlobalMetaState();
5301842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        int32_t buttonState = mCurrentRawState.buttonState;
5302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchMotion(when, policyFlags, mSource,
53037b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                AMOTION_EVENT_ACTION_CANCEL, 0, 0, metaState, buttonState,
5304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AMOTION_EVENT_EDGE_FLAG_NONE,
5305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.lastGestureProperties,
5306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
5307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.lastGestureIdBits, -1,
5308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                0, 0, mPointerGesture.downTime);
5309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Reset the current pointer gesture.
5312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerGesture.reset();
5313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerVelocityControl.reset();
5314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Remove any current spots.
5316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerController != NULL) {
5317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
5318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->clearSpots();
5319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchInputMapper::preparePointerGestures(nsecs_t when,
5323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout) {
5324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    *outCancelPreviousGesture = false;
5325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    *outFinishPreviousGesture = false;
5326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Handle TAP timeout.
5328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (isTimeout) {
5329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("Gestures: Processing timeout");
5331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
5334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
5335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // The tap/drag timeout has not yet expired.
5336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                getContext()->requestTimeoutAtTime(mPointerGesture.tapUpTime
5337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        + mConfig.pointerGestureTapDragInterval);
5338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
5339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // The tap is finished.
5340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Gestures: TAP finished");
5342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                *outFinishPreviousGesture = true;
5344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.activeGestureId = -1;
5346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
5347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureIdBits.clear();
5348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerVelocityControl.reset();
5350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return true;
5351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // We did not handle this timeout.
5355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return false;
5356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5358842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    const uint32_t currentFingerCount = mCurrentCookedState.fingerIdBits.count();
5359842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    const uint32_t lastFingerCount = mLastCookedState.fingerIdBits.count();
5360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Update the velocity tracker.
5362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    {
5363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        VelocityTracker::Position positions[MAX_POINTERS];
5364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t count = 0;
5365842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        for (BitSet32 idBits(mCurrentCookedState.fingerIdBits); !idBits.isEmpty(); count++) {
5366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = idBits.clearFirstMarkedBit();
5367842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            const RawPointerData::Pointer& pointer =
5368842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentRawState.rawPointerData.pointerForId(id);
5369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            positions[count].x = pointer.x * mPointerXMovementScale;
5370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            positions[count].y = pointer.y * mPointerYMovementScale;
5371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.velocityTracker.addMovement(when,
5373842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.fingerIdBits, positions);
5374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // If the gesture ever enters a mode other than TAP, HOVER or TAP_DRAG, without first returning
5377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // to NEUTRAL, then we should not generate tap event.
5378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerGesture.lastGestureMode != PointerGesture::HOVER
5379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && mPointerGesture.lastGestureMode != PointerGesture::TAP
5380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && mPointerGesture.lastGestureMode != PointerGesture::TAP_DRAG) {
5381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.resetTap();
5382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Pick a new active touch id if needed.
5385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Choose an arbitrary pointer that just went down, if there is one.
5386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Otherwise choose an arbitrary remaining pointer.
5387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // This guarantees we always have an active touch id when there is at least one pointer.
5388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // We keep the same active touch id for as long as possible.
5389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool activeTouchChanged = false;
5390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t lastActiveTouchId = mPointerGesture.activeTouchId;
5391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t activeTouchId = lastActiveTouchId;
5392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (activeTouchId < 0) {
5393842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (!mCurrentCookedState.fingerIdBits.isEmpty()) {
5394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            activeTouchChanged = true;
5395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            activeTouchId = mPointerGesture.activeTouchId =
5396842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.fingerIdBits.firstMarkedBit();
5397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.firstTouchTime = when;
5398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5399842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    } else if (!mCurrentCookedState.fingerIdBits.hasBit(activeTouchId)) {
5400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        activeTouchChanged = true;
5401842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (!mCurrentCookedState.fingerIdBits.isEmpty()) {
5402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            activeTouchId = mPointerGesture.activeTouchId =
5403842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentCookedState.fingerIdBits.firstMarkedBit();
5404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
5405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            activeTouchId = mPointerGesture.activeTouchId = -1;
5406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Determine whether we are in quiet time.
5410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool isQuietTime = false;
5411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (activeTouchId < 0) {
5412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.resetQuietTime();
5413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
5414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        isQuietTime = when < mPointerGesture.quietTime + mConfig.pointerGestureQuietInterval;
5415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!isQuietTime) {
5416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS
5417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    || mPointerGesture.lastGestureMode == PointerGesture::SWIPE
5418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)
5419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && currentFingerCount < 2) {
5420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Enter quiet time when exiting swipe or freeform state.
5421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // This is to prevent accidentally entering the hover state and flinging the
5422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // pointer when finishing a swipe and there is still one pointer left onscreen.
5423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                isQuietTime = true;
5424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (mPointerGesture.lastGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
5425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && currentFingerCount >= 2
5426842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    && !isPointerDown(mCurrentRawState.buttonState)) {
5427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Enter quiet time when releasing the button and there are still two or more
5428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // fingers down.  This may indicate that one finger was used to press the button
5429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // but it has not gone up yet.
5430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                isQuietTime = true;
5431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (isQuietTime) {
5433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.quietTime = when;
5434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Switch states based on button and pointer state.
5439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (isQuietTime) {
5440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Case 1: Quiet time. (QUIET)
5441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime
5443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                + mConfig.pointerGestureQuietInterval - when) * 0.000001f);
5444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) {
5446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outFinishPreviousGesture = true;
5447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.activeGestureId = -1;
5450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureMode = PointerGesture::QUIET;
5451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureIdBits.clear();
5452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerVelocityControl.reset();
5454842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    } else if (isPointerDown(mCurrentRawState.buttonState)) {
5455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG)
5456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The pointer follows the active touch point.
5457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Emit DOWN, MOVE, UP events at the pointer location.
5458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        //
5459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Only the active touch matters; other fingers are ignored.  This policy helps
5460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // to handle the case where the user places a second finger on the touch pad
5461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // to apply the necessary force to depress an integrated button below the surface.
5462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // We don't want the second finger to be delivered to applications.
5463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        //
5464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // For this to work well, we need to make sure to track the pointer that is really
5465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // active.  If the user first puts one finger down to click then adds another
5466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // finger to drag then the active pointer should switch to the finger that is
5467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // being dragged.
5468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("Gestures: BUTTON_CLICK_OR_DRAG activeTouchId=%d, "
5470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "currentFingerCount=%d", activeTouchId, currentFingerCount);
5471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Reset state when just starting.
5473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.lastGestureMode != PointerGesture::BUTTON_CLICK_OR_DRAG) {
5474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outFinishPreviousGesture = true;
5475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.activeGestureId = 0;
5476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Switch pointers if needed.
5479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Find the fastest pointer and follow it.
5480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (activeTouchId >= 0 && currentFingerCount > 1) {
5481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t bestId = -1;
5482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed;
5483842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            for (BitSet32 idBits(mCurrentCookedState.fingerIdBits); !idBits.isEmpty(); ) {
5484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t id = idBits.clearFirstMarkedBit();
5485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                float vx, vy;
5486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
5487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float speed = hypotf(vx, vy);
5488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (speed > bestSpeed) {
5489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        bestId = id;
5490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        bestSpeed = speed;
5491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
5492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (bestId >= 0 && bestId != activeTouchId) {
5495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.activeTouchId = activeTouchId = bestId;
5496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                activeTouchChanged = true;
5497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Gestures: BUTTON_CLICK_OR_DRAG switched pointers, "
5499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        "bestId=%d, bestSpeed=%0.3f", bestId, bestSpeed);
5500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5504fa1706afaf12b48fe0ab6d4b061b614bf901b173Jun Mukai        float deltaX = 0, deltaY = 0;
5505842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (activeTouchId >= 0 && mLastCookedState.fingerIdBits.hasBit(activeTouchId)) {
5506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& currentPointer =
5507842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentRawState.rawPointerData.pointerForId(activeTouchId);
5508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& lastPointer =
5509842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mLastRawState.rawPointerData.pointerForId(activeTouchId);
5510fa1706afaf12b48fe0ab6d4b061b614bf901b173Jun Mukai            deltaX = (currentPointer.x - lastPointer.x) * mPointerXMovementScale;
5511fa1706afaf12b48fe0ab6d4b061b614bf901b173Jun Mukai            deltaY = (currentPointer.y - lastPointer.y) * mPointerYMovementScale;
5512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
5514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.move(when, &deltaX, &deltaY);
5515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Move the pointer using a relative motion.
5517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // When using spots, the click will occur at the position of the anchor
5518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // spot and all other spots will move there.
5519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->move(deltaX, deltaY);
5520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
5521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.reset();
5522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float x, y;
5525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->getPosition(&x, &y);
5526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureMode = PointerGesture::BUTTON_CLICK_OR_DRAG;
5528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureIdBits.clear();
5529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
5530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
5531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureProperties[0].clear();
5532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
5533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
5534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].clear();
5535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
5536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
5537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
5538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (currentFingerCount == 0) {
5539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Case 3. No fingers down and button is not pressed. (NEUTRAL)
5540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) {
5541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outFinishPreviousGesture = true;
5542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Watch for taps coming out of HOVER or TAP_DRAG mode.
5545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Checking for taps after TAP_DRAG allows us to detect double-taps.
5546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool tapped = false;
5547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER
5548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                || mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG)
5549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && lastFingerCount == 1) {
5550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) {
5551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                float x, y;
5552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerController->getPosition(&x, &y);
5553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
5554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
5555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: TAP");
5557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.tapUpTime = when;
5560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    getContext()->requestTimeoutAtTime(when
5561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            + mConfig.pointerGestureTapDragInterval);
5562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.activeGestureId = 0;
5564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureMode = PointerGesture::TAP;
5565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureIdBits.clear();
5566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureIdBits.markBit(
5567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            mPointerGesture.activeGestureId);
5568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureIdToIndex[
5569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            mPointerGesture.activeGestureId] = 0;
5570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureProperties[0].clear();
5571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureProperties[0].id =
5572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            mPointerGesture.activeGestureId;
5573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureProperties[0].toolType =
5574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            AMOTION_EVENT_TOOL_TYPE_FINGER;
5575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureCoords[0].clear();
5576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureCoords[0].setAxisValue(
5577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            AMOTION_EVENT_AXIS_X, mPointerGesture.tapX);
5578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureCoords[0].setAxisValue(
5579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            AMOTION_EVENT_AXIS_Y, mPointerGesture.tapY);
5580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureCoords[0].setAxisValue(
5581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
5582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    tapped = true;
5584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
5585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: Not a TAP, deltaX=%f, deltaY=%f",
5587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            x - mPointerGesture.tapX,
5588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            y - mPointerGesture.tapY);
5589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
5592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (mPointerGesture.tapDownTime != LLONG_MIN) {
5594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: Not a TAP, %0.3fms since down",
5595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            (when - mPointerGesture.tapDownTime) * 0.000001f);
5596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
5597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: Not a TAP, incompatible mode transitions");
5598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerVelocityControl.reset();
5604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!tapped) {
5606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: NEUTRAL");
5608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.activeGestureId = -1;
5610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
5611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureIdBits.clear();
5612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (currentFingerCount == 1) {
5614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
5615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The pointer follows the active touch point.
5616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // When in HOVER, emit HOVER_MOVE events at the pointer location.
5617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // When in TAP_DRAG, emit MOVE events at the pointer location.
5618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(activeTouchId >= 0);
5619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureMode = PointerGesture::HOVER;
5621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
5622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
5623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                float x, y;
5624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerController->getPosition(&x, &y);
5625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
5626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
5627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
5628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
5629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: Not a TAP_DRAG, deltaX=%f, deltaY=%f",
5631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            x - mPointerGesture.tapX,
5632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            y - mPointerGesture.tapY);
5633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
5636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Gestures: Not a TAP_DRAG, %0.3fms time since up",
5638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        (when - mPointerGesture.tapUpTime) * 0.000001f);
5639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG) {
5642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
5643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5645fa1706afaf12b48fe0ab6d4b061b614bf901b173Jun Mukai        float deltaX = 0, deltaY = 0;
5646842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (mLastCookedState.fingerIdBits.hasBit(activeTouchId)) {
5647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& currentPointer =
5648842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentRawState.rawPointerData.pointerForId(activeTouchId);
5649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& lastPointer =
5650842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mLastRawState.rawPointerData.pointerForId(activeTouchId);
5651fa1706afaf12b48fe0ab6d4b061b614bf901b173Jun Mukai            deltaX = (currentPointer.x - lastPointer.x) * mPointerXMovementScale;
5652fa1706afaf12b48fe0ab6d4b061b614bf901b173Jun Mukai            deltaY = (currentPointer.y - lastPointer.y) * mPointerYMovementScale;
5653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
5655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.move(when, &deltaX, &deltaY);
5656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Move the pointer using a relative motion.
5658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // When using spots, the hover or drag will occur at the position of the anchor spot.
5659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->move(deltaX, deltaY);
5660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
5661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.reset();
5662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool down;
5665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG) {
5666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: TAP_DRAG");
5668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            down = true;
5670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
5671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: HOVER");
5673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mPointerGesture.lastGestureMode != PointerGesture::HOVER) {
5675d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                *outFinishPreviousGesture = true;
5676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.activeGestureId = 0;
5678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            down = false;
5679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float x, y;
5682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->getPosition(&x, &y);
5683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureIdBits.clear();
5685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
5686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
5687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureProperties[0].clear();
5688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
5689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureProperties[0].toolType =
5690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AMOTION_EVENT_TOOL_TYPE_FINGER;
5691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].clear();
5692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
5693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
5694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
5695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                down ? 1.0f : 0.0f);
5696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (lastFingerCount == 0 && currentFingerCount != 0) {
5698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.resetTap();
5699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.tapDownTime = when;
5700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.tapX = x;
5701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.tapY = y;
5702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
5704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Case 5. At least two fingers down, button is not pressed. (PRESS, SWIPE or FREEFORM)
5705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // We need to provide feedback for each finger that goes down so we cannot wait
5706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // for the fingers to move before deciding what to do.
5707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        //
5708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The ambiguous case is deciding what to do when there are two fingers down but they
5709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // have not moved enough to determine whether they are part of a drag or part of a
5710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // freeform gesture, or just a press or long-press at the pointer location.
5711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        //
5712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // When there are two fingers we start with the PRESS hypothesis and we generate a
5713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // down at the pointer location.
5714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        //
5715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // When the two fingers move enough or when additional fingers are added, we make
5716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // a decision to transition into SWIPE or FREEFORM mode accordingly.
5717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(activeTouchId >= 0);
5718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool settled = when >= mPointerGesture.firstTouchTime
5720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                + mConfig.pointerGestureMultitouchSettleInterval;
5721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.lastGestureMode != PointerGesture::PRESS
5722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && mPointerGesture.lastGestureMode != PointerGesture::SWIPE
5723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
5724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outFinishPreviousGesture = true;
5725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (!settled && currentFingerCount > lastFingerCount) {
5726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Additional pointers have gone down but not yet settled.
5727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Reset the gesture.
5728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, "
5730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
5731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            + mConfig.pointerGestureMultitouchSettleInterval - when)
5732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            * 0.000001f);
5733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outCancelPreviousGesture = true;
5735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
5736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Continue previous gesture.
5737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureMode = mPointerGesture.lastGestureMode;
5738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (*outFinishPreviousGesture || *outCancelPreviousGesture) {
5741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureMode = PointerGesture::PRESS;
5742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.activeGestureId = 0;
5743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.referenceIdBits.clear();
5744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.reset();
5745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Use the centroid and pointer location as the reference points for the gesture.
5747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: Using centroid as reference for MULTITOUCH, "
5749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
5750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            + mConfig.pointerGestureMultitouchSettleInterval - when)
5751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            * 0.000001f);
5752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5753842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            mCurrentRawState.rawPointerData.getCentroidOfTouchingPointers(
5754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    &mPointerGesture.referenceTouchX,
5755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    &mPointerGesture.referenceTouchY);
5756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->getPosition(&mPointerGesture.referenceGestureX,
5757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    &mPointerGesture.referenceGestureY);
5758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Clear the reference deltas for fingers not yet included in the reference calculation.
5761842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        for (BitSet32 idBits(mCurrentCookedState.fingerIdBits.value
5762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                & ~mPointerGesture.referenceIdBits.value); !idBits.isEmpty(); ) {
5763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = idBits.clearFirstMarkedBit();
5764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.referenceDeltas[id].dx = 0;
5765d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.referenceDeltas[id].dy = 0;
5766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5767842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mPointerGesture.referenceIdBits = mCurrentCookedState.fingerIdBits;
5768d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5769d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Add delta for all fingers and calculate a common movement delta.
5770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float commonDeltaX = 0, commonDeltaY = 0;
5771842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        BitSet32 commonIdBits(mLastCookedState.fingerIdBits.value
5772842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                & mCurrentCookedState.fingerIdBits.value);
5773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
5774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            bool first = (idBits == commonIdBits);
5775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = idBits.clearFirstMarkedBit();
5776842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            const RawPointerData::Pointer& cpd = mCurrentRawState.rawPointerData.pointerForId(id);
5777842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            const RawPointerData::Pointer& lpd = mLastRawState.rawPointerData.pointerForId(id);
5778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
5779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            delta.dx += cpd.x - lpd.x;
5780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            delta.dy += cpd.y - lpd.y;
5781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (first) {
5783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                commonDeltaX = delta.dx;
5784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                commonDeltaY = delta.dy;
5785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
5786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx);
5787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy);
5788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Consider transitions from PRESS to SWIPE or MULTITOUCH.
5792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) {
5793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float dist[MAX_POINTER_ID + 1];
5794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t distOverThreshold = 0;
5795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
5796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t id = idBits.clearFirstMarkedBit();
5797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
5798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                dist[id] = hypotf(delta.dx * mPointerXZoomScale,
5799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        delta.dy * mPointerYZoomScale);
5800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) {
5801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    distOverThreshold += 1;
5802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Only transition when at least two pointers have moved further than
5806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // the minimum distance threshold.
5807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (distOverThreshold >= 2) {
5808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (currentFingerCount > 2) {
5809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    // There are more than two pointers, switch to FREEFORM.
5810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2",
5812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            currentFingerCount);
5813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    *outCancelPreviousGesture = true;
5815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
5816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
5817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    // There are exactly two pointers.
5818842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    BitSet32 idBits(mCurrentCookedState.fingerIdBits);
5819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    uint32_t id1 = idBits.clearFirstMarkedBit();
5820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    uint32_t id2 = idBits.firstMarkedBit();
5821842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    const RawPointerData::Pointer& p1 =
5822842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                            mCurrentRawState.rawPointerData.pointerForId(id1);
5823842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    const RawPointerData::Pointer& p2 =
5824842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                            mCurrentRawState.rawPointerData.pointerForId(id2);
5825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float mutualDistance = distance(p1.x, p1.y, p2.x, p2.y);
5826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (mutualDistance > mPointerGestureMaxSwipeWidth) {
5827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        // There are two pointers but they are too far apart for a SWIPE,
5828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        // switch to FREEFORM.
5829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ALOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
5831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                mutualDistance, mPointerGestureMaxSwipeWidth);
5832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        *outCancelPreviousGesture = true;
5834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
5835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    } else {
5836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        // There are two pointers.  Wait for both pointers to start moving
5837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        // before deciding whether this is a SWIPE or FREEFORM gesture.
5838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        float dist1 = dist[id1];
5839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        float dist2 = dist[id2];
5840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        if (dist1 >= mConfig.pointerGestureMultitouchMinDistance
5841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                && dist2 >= mConfig.pointerGestureMultitouchMinDistance) {
5842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            // Calculate the dot product of the displacement vectors.
5843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            // When the vectors are oriented in approximately the same direction,
5844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            // the angle betweeen them is near zero and the cosine of the angle
5845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            // approches 1.0.  Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
5846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
5847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
5848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            float dx1 = delta1.dx * mPointerXZoomScale;
5849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            float dy1 = delta1.dy * mPointerYZoomScale;
5850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            float dx2 = delta2.dx * mPointerXZoomScale;
5851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            float dy2 = delta2.dy * mPointerYZoomScale;
5852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            float dot = dx1 * dx2 + dy1 * dy2;
5853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            float cosine = dot / (dist1 * dist2); // denominator always > 0
5854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
5855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                // Pointers are moving in the same direction.  Switch to SWIPE.
5856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                ALOGD("Gestures: PRESS transitioned to SWIPE, "
5858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
5859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        "cosine %0.3f >= %0.3f",
5860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        dist1, mConfig.pointerGestureMultitouchMinDistance,
5861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        dist2, mConfig.pointerGestureMultitouchMinDistance,
5862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
5863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
5865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            } else {
5866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                // Pointers are moving in different directions.  Switch to FREEFORM.
5867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                ALOGD("Gestures: PRESS transitioned to FREEFORM, "
5869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
5870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        "cosine %0.3f < %0.3f",
5871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        dist1, mConfig.pointerGestureMultitouchMinDistance,
5872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        dist2, mConfig.pointerGestureMultitouchMinDistance,
5873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
5874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                *outCancelPreviousGesture = true;
5876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
5877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            }
5878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        }
5879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
5880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
5883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Switch from SWIPE to FREEFORM if additional pointers go down.
5884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Cancel previous gesture.
5885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (currentFingerCount > 2) {
5886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Gestures: SWIPE transitioned to FREEFORM, number of pointers %d > 2",
5888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        currentFingerCount);
5889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                *outCancelPreviousGesture = true;
5891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
5892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Move the reference points based on the overall group motion of the fingers
5896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // except in PRESS mode while waiting for a transition to occur.
5897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.currentGestureMode != PointerGesture::PRESS
5898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && (commonDeltaX || commonDeltaY)) {
5899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
5900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t id = idBits.clearFirstMarkedBit();
5901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
5902d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                delta.dx = 0;
5903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                delta.dy = 0;
5904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.referenceTouchX += commonDeltaX;
5907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.referenceTouchY += commonDeltaY;
5908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            commonDeltaX *= mPointerXMovementScale;
5910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            commonDeltaY *= mPointerYMovementScale;
5911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rotateDelta(mSurfaceOrientation, &commonDeltaX, &commonDeltaY);
5913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
5914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.referenceGestureX += commonDeltaX;
5916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.referenceGestureY += commonDeltaY;
5917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Report gestures.
5920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.currentGestureMode == PointerGesture::PRESS
5921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                || mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
5922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // PRESS or SWIPE mode.
5923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: PRESS or SWIPE activeTouchId=%d,"
5925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "activeGestureId=%d, currentTouchPointerCount=%d",
5926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
5927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
5929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureIdBits.clear();
5931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
5932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
5933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureProperties[0].clear();
5934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
5935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureProperties[0].toolType =
5936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_TOOL_TYPE_FINGER;
5937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureCoords[0].clear();
5938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
5939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.referenceGestureX);
5940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y,
5941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.referenceGestureY);
5942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
5943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
5944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // FREEFORM mode.
5945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: FREEFORM activeTouchId=%d,"
5947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "activeGestureId=%d, currentTouchPointerCount=%d",
5948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
5949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
5951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureIdBits.clear();
5953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            BitSet32 mappedTouchIdBits;
5955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            BitSet32 usedGestureIdBits;
5956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
5957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Initially, assign the active gesture id to the active touch point
5958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // if there is one.  No other touch id bits are mapped yet.
5959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (!*outCancelPreviousGesture) {
5960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mappedTouchIdBits.markBit(activeTouchId);
5961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    usedGestureIdBits.markBit(mPointerGesture.activeGestureId);
5962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.freeformTouchToGestureIdMap[activeTouchId] =
5963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            mPointerGesture.activeGestureId;
5964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
5965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.activeGestureId = -1;
5966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
5968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Otherwise, assume we mapped all touches from the previous frame.
5969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Reuse all mappings that are still applicable.
5970842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mappedTouchIdBits.value = mLastCookedState.fingerIdBits.value
5971842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                        & mCurrentCookedState.fingerIdBits.value;
5972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                usedGestureIdBits = mPointerGesture.lastGestureIdBits;
5973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Check whether we need to choose a new active gesture id because the
5975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // current went went up.
5976842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                for (BitSet32 upTouchIdBits(mLastCookedState.fingerIdBits.value
5977842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                        & ~mCurrentCookedState.fingerIdBits.value);
5978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        !upTouchIdBits.isEmpty(); ) {
5979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    uint32_t upTouchId = upTouchIdBits.clearFirstMarkedBit();
5980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    uint32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[upTouchId];
5981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (upGestureId == uint32_t(mPointerGesture.activeGestureId)) {
5982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mPointerGesture.activeGestureId = -1;
5983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        break;
5984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
5985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: FREEFORM follow up "
5990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "mappedTouchIdBits=0x%08x, usedGestureIdBits=0x%08x, "
5991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "activeGestureId=%d",
5992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mappedTouchIdBits.value, usedGestureIdBits.value,
5993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.activeGestureId);
5994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5996842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            BitSet32 idBits(mCurrentCookedState.fingerIdBits);
5997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            for (uint32_t i = 0; i < currentFingerCount; i++) {
5998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t touchId = idBits.clearFirstMarkedBit();
5999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t gestureId;
6000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (!mappedTouchIdBits.hasBit(touchId)) {
6001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    gestureId = usedGestureIdBits.markFirstUnmarkedBit();
6002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.freeformTouchToGestureIdMap[touchId] = gestureId;
6003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
6004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: FREEFORM "
6005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            "new mapping for touch id %d -> gesture id %d",
6006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            touchId, gestureId);
6007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
6008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
6009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    gestureId = mPointerGesture.freeformTouchToGestureIdMap[touchId];
6010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
6011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: FREEFORM "
6012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            "existing mapping for touch id %d -> gesture id %d",
6013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            touchId, gestureId);
6014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
6015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
6016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureIdBits.markBit(gestureId);
6017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureIdToIndex[gestureId] = i;
6018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                const RawPointerData::Pointer& pointer =
6020842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                        mCurrentRawState.rawPointerData.pointerForId(touchId);
6021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                float deltaX = (pointer.x - mPointerGesture.referenceTouchX)
6022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        * mPointerXZoomScale;
6023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                float deltaY = (pointer.y - mPointerGesture.referenceTouchY)
6024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        * mPointerYZoomScale;
6025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
6026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureProperties[i].clear();
6028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureProperties[i].id = gestureId;
6029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureProperties[i].toolType =
6030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        AMOTION_EVENT_TOOL_TYPE_FINGER;
6031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureCoords[i].clear();
6032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureCoords[i].setAxisValue(
6033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        AMOTION_EVENT_AXIS_X, mPointerGesture.referenceGestureX + deltaX);
6034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureCoords[i].setAxisValue(
6035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY + deltaY);
6036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureCoords[i].setAxisValue(
6037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
6038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mPointerGesture.activeGestureId < 0) {
6041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.activeGestureId =
6042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mPointerGesture.currentGestureIdBits.firstMarkedBit();
6043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
6044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Gestures: FREEFORM new "
6045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        "activeGestureId=%d", mPointerGesture.activeGestureId);
6046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
6047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6051842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mPointerController->setButtonState(mCurrentRawState.buttonState);
6052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
6054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ALOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
6055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            "currentGestureMode=%d, currentGestureIdBits=0x%08x, "
6056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            "lastGestureMode=%d, lastGestureIdBits=0x%08x",
6057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(*outFinishPreviousGesture), toString(*outCancelPreviousGesture),
6058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIdBits.value,
6059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.lastGestureMode, mPointerGesture.lastGestureIdBits.value);
6060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (BitSet32 idBits = mPointerGesture.currentGestureIdBits; !idBits.isEmpty(); ) {
6061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = idBits.clearFirstMarkedBit();
6062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
6063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
6064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
6065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("  currentGesture[%d]: index=%d, toolType=%d, "
6066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "x=%0.3f, y=%0.3f, pressure=%0.3f",
6067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                id, index, properties.toolType,
6068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                coords.getAxisValue(AMOTION_EVENT_AXIS_X),
6069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
6070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
6071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (BitSet32 idBits = mPointerGesture.lastGestureIdBits; !idBits.isEmpty(); ) {
6073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = idBits.clearFirstMarkedBit();
6074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t index = mPointerGesture.lastGestureIdToIndex[id];
6075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
6076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
6077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("  lastGesture[%d]: index=%d, toolType=%d, "
6078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "x=%0.3f, y=%0.3f, pressure=%0.3f",
6079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                id, index, properties.toolType,
6080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                coords.getAxisValue(AMOTION_EVENT_AXIS_X),
6081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
6082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
6083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
6085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return true;
6086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchPointerStylus(nsecs_t when, uint32_t policyFlags) {
6089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerSimple.currentCoords.clear();
6090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerSimple.currentProperties.clear();
6091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool down, hovering;
6093842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (!mCurrentCookedState.stylusIdBits.isEmpty()) {
6094842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        uint32_t id = mCurrentCookedState.stylusIdBits.firstMarkedBit();
6095842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        uint32_t index = mCurrentCookedState.cookedPointerData.idToIndex[id];
6096842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        float x = mCurrentCookedState.cookedPointerData.pointerCoords[index].getX();
6097842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        float y = mCurrentCookedState.cookedPointerData.pointerCoords[index].getY();
6098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->setPosition(x, y);
6099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6100842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        hovering = mCurrentCookedState.cookedPointerData.hoveringIdBits.hasBit(id);
6101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        down = !hovering;
6102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->getPosition(&x, &y);
6104842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mPointerSimple.currentCoords.copyFrom(
6105842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.cookedPointerData.pointerCoords[index]);
6106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
6107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
6108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentProperties.id = 0;
6109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentProperties.toolType =
6110842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.cookedPointerData.pointerProperties[index].toolType;
6111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
6112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        down = false;
6113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        hovering = false;
6114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dispatchPointerSimple(when, policyFlags, down, hovering);
6117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::abortPointerStylus(nsecs_t when, uint32_t policyFlags) {
6120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    abortPointerSimple(when, policyFlags);
6121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchPointerMouse(nsecs_t when, uint32_t policyFlags) {
6124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerSimple.currentCoords.clear();
6125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerSimple.currentProperties.clear();
6126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool down, hovering;
6128842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (!mCurrentCookedState.mouseIdBits.isEmpty()) {
6129842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        uint32_t id = mCurrentCookedState.mouseIdBits.firstMarkedBit();
6130842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        uint32_t currentIndex = mCurrentRawState.rawPointerData.idToIndex[id];
6131fa1706afaf12b48fe0ab6d4b061b614bf901b173Jun Mukai        float deltaX = 0, deltaY = 0;
6132842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        if (mLastCookedState.mouseIdBits.hasBit(id)) {
6133842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            uint32_t lastIndex = mCurrentRawState.rawPointerData.idToIndex[id];
6134fa1706afaf12b48fe0ab6d4b061b614bf901b173Jun Mukai            deltaX = (mCurrentRawState.rawPointerData.pointers[currentIndex].x
6135842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    - mLastRawState.rawPointerData.pointers[lastIndex].x)
6136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    * mPointerXMovementScale;
6137fa1706afaf12b48fe0ab6d4b061b614bf901b173Jun Mukai            deltaY = (mCurrentRawState.rawPointerData.pointers[currentIndex].y
6138842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    - mLastRawState.rawPointerData.pointers[lastIndex].y)
6139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    * mPointerYMovementScale;
6140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
6142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.move(when, &deltaX, &deltaY);
6143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->move(deltaX, deltaY);
6145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
6146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.reset();
6147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6149842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        down = isPointerDown(mCurrentRawState.buttonState);
6150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        hovering = !down;
6151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float x, y;
6153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->getPosition(&x, &y);
6154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentCoords.copyFrom(
6155842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.cookedPointerData.pointerCoords[currentIndex]);
6156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
6157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
6158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
6159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                hovering ? 0.0f : 1.0f);
6160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentProperties.id = 0;
6161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentProperties.toolType =
6162842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentCookedState.cookedPointerData.pointerProperties[currentIndex].toolType;
6163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
6164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerVelocityControl.reset();
6165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        down = false;
6167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        hovering = false;
6168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dispatchPointerSimple(when, policyFlags, down, hovering);
6171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::abortPointerMouse(nsecs_t when, uint32_t policyFlags) {
6174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    abortPointerSimple(when, policyFlags);
6175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerVelocityControl.reset();
6177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
6180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool down, bool hovering) {
6181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t metaState = getContext()->getGlobalMetaState();
6182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerController != NULL) {
6184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (down || hovering) {
6185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
6186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->clearSpots();
6187842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            mPointerController->setButtonState(mCurrentRawState.buttonState);
6188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
6189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
6190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
6191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerSimple.down && !down) {
6195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.down = false;
6196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send up.
6198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
61997b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                 AMOTION_EVENT_ACTION_UP, 0, 0, metaState, mLastRawState.buttonState, 0,
6200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                 mViewport.displayId,
6201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
6202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                 mOrientedXPrecision, mOrientedYPrecision,
6203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                 mPointerSimple.downTime);
6204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifyMotion(&args);
6205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerSimple.hovering && !hovering) {
6208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.hovering = false;
6209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send hover exit.
6211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
62127b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                AMOTION_EVENT_ACTION_HOVER_EXIT, 0, 0, metaState, mLastRawState.buttonState, 0,
6213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mViewport.displayId,
6214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
6215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientedXPrecision, mOrientedYPrecision,
6216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerSimple.downTime);
6217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifyMotion(&args);
6218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (down) {
6221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!mPointerSimple.down) {
6222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerSimple.down = true;
6223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerSimple.downTime = when;
6224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Send down.
6226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
62277b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    AMOTION_EVENT_ACTION_DOWN, 0, 0, metaState, mCurrentRawState.buttonState, 0,
6228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mViewport.displayId,
6229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
6230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mOrientedXPrecision, mOrientedYPrecision,
6231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerSimple.downTime);
6232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getListener()->notifyMotion(&args);
6233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send move.
6236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
62377b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, mCurrentRawState.buttonState, 0,
6238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mViewport.displayId,
6239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
6240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientedXPrecision, mOrientedYPrecision,
6241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerSimple.downTime);
6242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifyMotion(&args);
6243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (hovering) {
6246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!mPointerSimple.hovering) {
6247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerSimple.hovering = true;
6248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Send hover enter.
6250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
62517b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                    AMOTION_EVENT_ACTION_HOVER_ENTER, 0, 0, metaState,
6252842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    mCurrentRawState.buttonState, 0,
6253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mViewport.displayId,
6254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
6255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mOrientedXPrecision, mOrientedYPrecision,
6256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerSimple.downTime);
6257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getListener()->notifyMotion(&args);
6258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send hover move.
6261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
62627b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 0, metaState,
6263842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                mCurrentRawState.buttonState, 0,
6264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mViewport.displayId,
6265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
6266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientedXPrecision, mOrientedYPrecision,
6267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerSimple.downTime);
6268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifyMotion(&args);
6269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6271842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (mCurrentRawState.rawVScroll || mCurrentRawState.rawHScroll) {
6272842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        float vscroll = mCurrentRawState.rawVScroll;
6273842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        float hscroll = mCurrentRawState.rawHScroll;
6274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mWheelYVelocityControl.move(when, NULL, &vscroll);
6275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mWheelXVelocityControl.move(when, &hscroll, NULL);
6276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send scroll.
6278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerCoords pointerCoords;
6279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.copyFrom(mPointerSimple.currentCoords);
6280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
6281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
6282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
62847b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright                AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, mCurrentRawState.buttonState, 0,
6285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mViewport.displayId,
6286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                1, &mPointerSimple.currentProperties, &pointerCoords,
6287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientedXPrecision, mOrientedYPrecision,
6288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerSimple.downTime);
6289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifyMotion(&args);
6290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Save state.
6293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (down || hovering) {
6294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.lastCoords.copyFrom(mPointerSimple.currentCoords);
6295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.lastProperties.copyFrom(mPointerSimple.currentProperties);
6296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
6297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.reset();
6298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::abortPointerSimple(nsecs_t when, uint32_t policyFlags) {
6302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerSimple.currentCoords.clear();
6303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerSimple.currentProperties.clear();
6304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dispatchPointerSimple(when, policyFlags, false, false);
6306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
63097b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        int32_t action, int32_t actionButton, int32_t flags,
63107b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        int32_t metaState, int32_t buttonState, int32_t edgeFlags,
6311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerProperties* properties, const PointerCoords* coords,
63127b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        const uint32_t* idToIndex, BitSet32 idBits, int32_t changedId,
63137b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        float xPrecision, float yPrecision, nsecs_t downTime) {
6314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    PointerCoords pointerCoords[MAX_POINTERS];
6315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    PointerProperties pointerProperties[MAX_POINTERS];
6316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t pointerCount = 0;
6317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    while (!idBits.isEmpty()) {
6318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = idBits.clearFirstMarkedBit();
6319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t index = idToIndex[id];
6320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerProperties[pointerCount].copyFrom(properties[index]);
6321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords[pointerCount].copyFrom(coords[index]);
6322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (changedId >= 0 && id == uint32_t(changedId)) {
6324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
6325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCount += 1;
6328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ALOG_ASSERT(pointerCount != 0);
6331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (changedId >= 0 && pointerCount == 1) {
6333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Replace initial down and final up action.
6334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // We can compare the action without masking off the changed pointer index
6335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // because we know the index is 0.
6336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
6337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            action = AMOTION_EVENT_ACTION_DOWN;
6338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
6339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            action = AMOTION_EVENT_ACTION_UP;
6340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
6341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Can't happen.
6342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOG_ASSERT(false);
6343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
63477b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright            action, actionButton, flags, metaState, buttonState, edgeFlags,
6348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mViewport.displayId, pointerCount, pointerProperties, pointerCoords,
6349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            xPrecision, yPrecision, downTime);
6350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getListener()->notifyMotion(&args);
6351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties,
6354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerCoords* inCoords, const uint32_t* inIdToIndex,
6355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerProperties* outProperties, PointerCoords* outCoords, const uint32_t* outIdToIndex,
6356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 idBits) const {
6357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool changed = false;
6358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    while (!idBits.isEmpty()) {
6359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = idBits.clearFirstMarkedBit();
6360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t inIndex = inIdToIndex[id];
6361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t outIndex = outIdToIndex[id];
6362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerProperties& curInProperties = inProperties[inIndex];
6364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerCoords& curInCoords = inCoords[inIndex];
6365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerProperties& curOutProperties = outProperties[outIndex];
6366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerCoords& curOutCoords = outCoords[outIndex];
6367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (curInProperties != curOutProperties) {
6369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            curOutProperties.copyFrom(curInProperties);
6370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            changed = true;
6371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (curInCoords != curOutCoords) {
6374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            curOutCoords.copyFrom(curInCoords);
6375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            changed = true;
6376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return changed;
6379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::fadePointer() {
6382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerController != NULL) {
6383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
6384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6387c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brownvoid TouchInputMapper::cancelTouch(nsecs_t when) {
6388c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown    abortPointerUsage(when, 0 /*policyFlags*/);
63898e812826015786e07cb83664f22f69b2f2c72586Michael Wright    abortTouches(when, 0 /* policyFlags*/);
6390c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown}
6391c9aa628d065eb08d6fa30f0ac21c6eca4cfbab75Jeff Brown
6392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
6393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
6394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
6395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightconst TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
6398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t x, int32_t y) {
6399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numVirtualKeys = mVirtualKeys.size();
6400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numVirtualKeys; i++) {
6401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const VirtualKey& virtualKey = mVirtualKeys[i];
6402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIRTUAL_KEYS
6404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
6405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "left=%d, top=%d, right=%d, bottom=%d",
6406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                x, y,
6407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                virtualKey.keyCode, virtualKey.scanCode,
6408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                virtualKey.hitLeft, virtualKey.hitTop,
6409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                virtualKey.hitRight, virtualKey.hitBottom);
6410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
6411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (virtualKey.isHit(x, y)) {
6413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return & virtualKey;
6414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return NULL;
6418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6420842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid TouchInputMapper::assignPointerIds(const RawState* last, RawState* current) {
6421842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    uint32_t currentPointerCount = current->rawPointerData.pointerCount;
6422842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    uint32_t lastPointerCount = last->rawPointerData.pointerCount;
6423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6424842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    current->rawPointerData.clearIdBits();
6425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (currentPointerCount == 0) {
6427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // No pointers to assign.
6428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
6429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (lastPointerCount == 0) {
6432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // All pointers are new.
6433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (uint32_t i = 0; i < currentPointerCount; i++) {
6434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = i;
6435842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            current->rawPointerData.pointers[i].id = id;
6436842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            current->rawPointerData.idToIndex[id] = i;
6437842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            current->rawPointerData.markIdBit(id, current->rawPointerData.isHovering(i));
6438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
6440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (currentPointerCount == 1 && lastPointerCount == 1
6443842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            && current->rawPointerData.pointers[0].toolType
6444842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    == last->rawPointerData.pointers[0].toolType) {
6445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Only one pointer and no change in count so it must have the same id as before.
6446842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        uint32_t id = last->rawPointerData.pointers[0].id;
6447842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        current->rawPointerData.pointers[0].id = id;
6448842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        current->rawPointerData.idToIndex[id] = 0;
6449842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        current->rawPointerData.markIdBit(id, current->rawPointerData.isHovering(0));
6450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
6451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // General case.
6454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // We build a heap of squared euclidean distances between current and last pointers
6455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // associated with the current and last pointer indices.  Then, we find the best
6456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // match (by distance) for each current pointer.
6457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // The pointers must have the same tool type but it is possible for them to
6458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // transition from hovering to touching or vice-versa while retaining the same id.
6459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
6460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t heapSize = 0;
6462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
6463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            currentPointerIndex++) {
6464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
6465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                lastPointerIndex++) {
6466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& currentPointer =
6467842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    current->rawPointerData.pointers[currentPointerIndex];
6468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& lastPointer =
6469842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    last->rawPointerData.pointers[lastPointerIndex];
6470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (currentPointer.toolType == lastPointer.toolType) {
6471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                int64_t deltaX = currentPointer.x - lastPointer.x;
6472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                int64_t deltaY = currentPointer.y - lastPointer.y;
6473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
6475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Insert new element into the heap (sift up).
6477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                heap[heapSize].currentPointerIndex = currentPointerIndex;
6478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                heap[heapSize].lastPointerIndex = lastPointerIndex;
6479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                heap[heapSize].distance = distance;
6480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                heapSize += 1;
6481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Heapify
6486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
6487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        startIndex -= 1;
6488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (uint32_t parentIndex = startIndex; ;) {
6489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t childIndex = parentIndex * 2 + 1;
6490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (childIndex >= heapSize) {
6491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
6492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (childIndex + 1 < heapSize
6495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && heap[childIndex + 1].distance < heap[childIndex].distance) {
6496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                childIndex += 1;
6497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (heap[parentIndex].distance <= heap[childIndex].distance) {
6500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
6501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            swap(heap[parentIndex], heap[childIndex]);
6504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            parentIndex = childIndex;
6505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_POINTER_ASSIGNMENT
6509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ALOGD("assignPointerIds - initial distance min-heap: size=%d", heapSize);
6510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < heapSize; i++) {
6511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
6512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
6513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                heap[i].distance);
6514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
6516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Pull matches out by increasing order of distance.
6518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // To avoid reassigning pointers that have already been matched, the loop keeps track
6519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // of which last and current pointers have been matched using the matchedXXXBits variables.
6520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // It also tracks the used pointer id bits.
6521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    BitSet32 matchedLastBits(0);
6522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    BitSet32 matchedCurrentBits(0);
6523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    BitSet32 usedIdBits(0);
6524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool first = true;
6525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t i = min(currentPointerCount, lastPointerCount); heapSize > 0 && i > 0; i--) {
6526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        while (heapSize > 0) {
6527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (first) {
6528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // The first time through the loop, we just consume the root element of
6529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // the heap (the one with smallest distance).
6530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                first = false;
6531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
6532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Previous iterations consumed the root element of the heap.
6533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Pop root element off of the heap (sift down).
6534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                heap[0] = heap[heapSize];
6535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                for (uint32_t parentIndex = 0; ;) {
6536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    uint32_t childIndex = parentIndex * 2 + 1;
6537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (childIndex >= heapSize) {
6538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        break;
6539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
6540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (childIndex + 1 < heapSize
6542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            && heap[childIndex + 1].distance < heap[childIndex].distance) {
6543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        childIndex += 1;
6544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
6545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (heap[parentIndex].distance <= heap[childIndex].distance) {
6547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        break;
6548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
6549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    swap(heap[parentIndex], heap[childIndex]);
6551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    parentIndex = childIndex;
6552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
6553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_POINTER_ASSIGNMENT
6555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("assignPointerIds - reduced distance min-heap: size=%d", heapSize);
6556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                for (size_t i = 0; i < heapSize; i++) {
6557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
6558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
6559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            heap[i].distance);
6560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
6561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
6562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            heapSize -= 1;
6565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t currentPointerIndex = heap[0].currentPointerIndex;
6567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
6568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t lastPointerIndex = heap[0].lastPointerIndex;
6570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
6571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            matchedCurrentBits.markBit(currentPointerIndex);
6573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            matchedLastBits.markBit(lastPointerIndex);
6574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6575842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            uint32_t id = last->rawPointerData.pointers[lastPointerIndex].id;
6576842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            current->rawPointerData.pointers[currentPointerIndex].id = id;
6577842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            current->rawPointerData.idToIndex[id] = currentPointerIndex;
6578842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            current->rawPointerData.markIdBit(id,
6579842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                    current->rawPointerData.isHovering(currentPointerIndex));
6580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            usedIdBits.markBit(id);
6581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_POINTER_ASSIGNMENT
6583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("assignPointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
6584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    lastPointerIndex, currentPointerIndex, id, heap[0].distance);
6585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
6586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
6587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Assign fresh ids to pointers that were not matched in the process.
6591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t i = currentPointerCount - matchedCurrentBits.count(); i != 0; i--) {
6592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t currentPointerIndex = matchedCurrentBits.markFirstUnmarkedBit();
6593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = usedIdBits.markFirstUnmarkedBit();
6594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6595842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        current->rawPointerData.pointers[currentPointerIndex].id = id;
6596842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        current->rawPointerData.idToIndex[id] = currentPointerIndex;
6597842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        current->rawPointerData.markIdBit(id,
6598842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright                current->rawPointerData.isHovering(currentPointerIndex));
6599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_POINTER_ASSIGNMENT
6601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("assignPointerIds - assigned: cur=%d, id=%d",
6602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                currentPointerIndex, id);
6603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
6604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
6608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
6609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AKEY_STATE_VIRTUAL;
6610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numVirtualKeys = mVirtualKeys.size();
6613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numVirtualKeys; i++) {
6614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const VirtualKey& virtualKey = mVirtualKeys[i];
6615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (virtualKey.keyCode == keyCode) {
6616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return AKEY_STATE_UP;
6617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AKEY_STATE_UNKNOWN;
6621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
6624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
6625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AKEY_STATE_VIRTUAL;
6626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numVirtualKeys = mVirtualKeys.size();
6629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numVirtualKeys; i++) {
6630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const VirtualKey& virtualKey = mVirtualKeys[i];
6631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (virtualKey.scanCode == scanCode) {
6632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return AKEY_STATE_UP;
6633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AKEY_STATE_UNKNOWN;
6637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
6640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const int32_t* keyCodes, uint8_t* outFlags) {
6641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numVirtualKeys = mVirtualKeys.size();
6642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numVirtualKeys; i++) {
6643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const VirtualKey& virtualKey = mVirtualKeys[i];
6644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < numCodes; i++) {
6646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (virtualKey.keyCode == keyCodes[i]) {
6647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                outFlags[i] = 1;
6648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return true;
6653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- SingleTouchInputMapper ---
6657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightSingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) :
6659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        TouchInputMapper(device) {
6660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightSingleTouchInputMapper::~SingleTouchInputMapper() {
6663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SingleTouchInputMapper::reset(nsecs_t when) {
6666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mSingleTouchMotionAccumulator.reset(getDevice());
6667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    TouchInputMapper::reset(when);
6669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SingleTouchInputMapper::process(const RawEvent* rawEvent) {
6672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    TouchInputMapper::process(rawEvent);
6673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mSingleTouchMotionAccumulator.process(rawEvent);
6675d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6677842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid SingleTouchInputMapper::syncTouch(nsecs_t when, RawState* outState) {
6678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mTouchButtonAccumulator.isToolActive()) {
6679842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        outState->rawPointerData.pointerCount = 1;
6680842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        outState->rawPointerData.idToIndex[0] = 0;
6681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
6683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && (mTouchButtonAccumulator.isHovering()
6684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        || (mRawPointerAxes.pressure.valid
6685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                && mSingleTouchMotionAccumulator.getAbsolutePressure() <= 0));
6686842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        outState->rawPointerData.markIdBit(0, isHovering);
6687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6688842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        RawPointerData::Pointer& outPointer = outState->rawPointerData.pointers[0];
6689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.id = 0;
6690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.x = mSingleTouchMotionAccumulator.getAbsoluteX();
6691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.y = mSingleTouchMotionAccumulator.getAbsoluteY();
6692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.pressure = mSingleTouchMotionAccumulator.getAbsolutePressure();
6693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.touchMajor = 0;
6694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.touchMinor = 0;
6695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.toolMajor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
6696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.toolMinor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
6697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.orientation = 0;
6698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.distance = mSingleTouchMotionAccumulator.getAbsoluteDistance();
6699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.tiltX = mSingleTouchMotionAccumulator.getAbsoluteTiltX();
6700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.tiltY = mSingleTouchMotionAccumulator.getAbsoluteTiltY();
6701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.toolType = mTouchButtonAccumulator.getToolType();
6702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
6703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
6704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.isHovering = isHovering;
6706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SingleTouchInputMapper::configureRawPointerAxes() {
6710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    TouchInputMapper::configureRawPointerAxes();
6711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_X, &mRawPointerAxes.x);
6713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_Y, &mRawPointerAxes.y);
6714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPointerAxes.pressure);
6715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_TOOL_WIDTH, &mRawPointerAxes.toolMajor);
6716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_DISTANCE, &mRawPointerAxes.distance);
6717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_TILT_X, &mRawPointerAxes.tiltX);
6718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_TILT_Y, &mRawPointerAxes.tiltY);
6719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool SingleTouchInputMapper::hasStylus() const {
6722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mTouchButtonAccumulator.hasStylus();
6723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- MultiTouchInputMapper ---
6727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightMultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) :
6729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        TouchInputMapper(device) {
6730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightMultiTouchInputMapper::~MultiTouchInputMapper() {
6733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchInputMapper::reset(nsecs_t when) {
6736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mMultiTouchMotionAccumulator.reset(getDevice());
6737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerIdBits.clear();
6739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    TouchInputMapper::reset(when);
6741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchInputMapper::process(const RawEvent* rawEvent) {
6744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    TouchInputMapper::process(rawEvent);
6745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mMultiTouchMotionAccumulator.process(rawEvent);
6747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6749842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid MultiTouchInputMapper::syncTouch(nsecs_t when, RawState* outState) {
6750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
6751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t outCount = 0;
6752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    BitSet32 newPointerIdBits;
67531a632def894f8fec6961d126fcc568c6a7c19441gaoshang    mHavePointerIds = true;
6754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
6756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const MultiTouchMotionAccumulator::Slot* inSlot =
6757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mMultiTouchMotionAccumulator.getSlot(inIndex);
6758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!inSlot->isInUse()) {
6759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            continue;
6760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (outCount >= MAX_POINTERS) {
6763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_POINTERS
6764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("MultiTouch device %s emitted more than maximum of %d pointers; "
6765d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "ignoring the rest.",
6766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    getDeviceName().string(), MAX_POINTERS);
6767d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
6768d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break; // too many fingers!
6769d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6771842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        RawPointerData::Pointer& outPointer = outState->rawPointerData.pointers[outCount];
6772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.x = inSlot->getX();
6773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.y = inSlot->getY();
6774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.pressure = inSlot->getPressure();
6775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.touchMajor = inSlot->getTouchMajor();
6776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.touchMinor = inSlot->getTouchMinor();
6777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.toolMajor = inSlot->getToolMajor();
6778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.toolMinor = inSlot->getToolMinor();
6779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.orientation = inSlot->getOrientation();
6780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.distance = inSlot->getDistance();
6781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.tiltX = 0;
6782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.tiltY = 0;
6783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.toolType = inSlot->getToolType();
6785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
6786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            outPointer.toolType = mTouchButtonAccumulator.getToolType();
6787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
6788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
6789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
6793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && (mTouchButtonAccumulator.isHovering()
6794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        || (mRawPointerAxes.pressure.valid && inSlot->getPressure() <= 0));
6795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.isHovering = isHovering;
6796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Assign pointer id using tracking id if available.
67981a632def894f8fec6961d126fcc568c6a7c19441gaoshang        if (mHavePointerIds) {
67991a632def894f8fec6961d126fcc568c6a7c19441gaoshang            int32_t trackingId = inSlot->getTrackingId();
68001a632def894f8fec6961d126fcc568c6a7c19441gaoshang            int32_t id = -1;
68011a632def894f8fec6961d126fcc568c6a7c19441gaoshang            if (trackingId >= 0) {
68021a632def894f8fec6961d126fcc568c6a7c19441gaoshang                for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
68031a632def894f8fec6961d126fcc568c6a7c19441gaoshang                    uint32_t n = idBits.clearFirstMarkedBit();
68041a632def894f8fec6961d126fcc568c6a7c19441gaoshang                    if (mPointerTrackingIdMap[n] == trackingId) {
68051a632def894f8fec6961d126fcc568c6a7c19441gaoshang                        id = n;
68061a632def894f8fec6961d126fcc568c6a7c19441gaoshang                    }
6807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
6808842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
68091a632def894f8fec6961d126fcc568c6a7c19441gaoshang                if (id < 0 && !mPointerIdBits.isFull()) {
68101a632def894f8fec6961d126fcc568c6a7c19441gaoshang                    id = mPointerIdBits.markFirstUnmarkedBit();
68111a632def894f8fec6961d126fcc568c6a7c19441gaoshang                    mPointerTrackingIdMap[id] = trackingId;
68121a632def894f8fec6961d126fcc568c6a7c19441gaoshang                }
68131a632def894f8fec6961d126fcc568c6a7c19441gaoshang            }
68141a632def894f8fec6961d126fcc568c6a7c19441gaoshang            if (id < 0) {
68151a632def894f8fec6961d126fcc568c6a7c19441gaoshang                mHavePointerIds = false;
68161a632def894f8fec6961d126fcc568c6a7c19441gaoshang                outState->rawPointerData.clearIdBits();
68171a632def894f8fec6961d126fcc568c6a7c19441gaoshang                newPointerIdBits.clear();
68181a632def894f8fec6961d126fcc568c6a7c19441gaoshang            } else {
68191a632def894f8fec6961d126fcc568c6a7c19441gaoshang                outPointer.id = id;
68201a632def894f8fec6961d126fcc568c6a7c19441gaoshang                outState->rawPointerData.idToIndex[id] = outCount;
68211a632def894f8fec6961d126fcc568c6a7c19441gaoshang                outState->rawPointerData.markIdBit(id, isHovering);
68221a632def894f8fec6961d126fcc568c6a7c19441gaoshang                newPointerIdBits.markBit(id);
6823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outCount += 1;
6826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6828842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    outState->rawPointerData.pointerCount = outCount;
6829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerIdBits = newPointerIdBits;
6830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mMultiTouchMotionAccumulator.finishSync();
6832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchInputMapper::configureRawPointerAxes() {
6835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    TouchInputMapper::configureRawPointerAxes();
6836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
6838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
6839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.touchMajor);
6840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_TOUCH_MINOR, &mRawPointerAxes.touchMinor);
6841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &mRawPointerAxes.toolMajor);
6842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_WIDTH_MINOR, &mRawPointerAxes.toolMinor);
6843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &mRawPointerAxes.orientation);
6844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_PRESSURE, &mRawPointerAxes.pressure);
6845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_DISTANCE, &mRawPointerAxes.distance);
6846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_TRACKING_ID, &mRawPointerAxes.trackingId);
6847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_SLOT, &mRawPointerAxes.slot);
6848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mRawPointerAxes.trackingId.valid
6850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && mRawPointerAxes.slot.valid
6851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && mRawPointerAxes.slot.minValue == 0 && mRawPointerAxes.slot.maxValue > 0) {
6852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t slotCount = mRawPointerAxes.slot.maxValue + 1;
6853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (slotCount > MAX_SLOTS) {
685437764c71a0ac79142f90bb112b6cabffb940b955Narayan Kamath            ALOGW("MultiTouch Device %s reported %zu slots but the framework "
685537764c71a0ac79142f90bb112b6cabffb940b955Narayan Kamath                    "only supports a maximum of %zu slots at this time.",
6856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    getDeviceName().string(), slotCount, MAX_SLOTS);
6857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            slotCount = MAX_SLOTS;
6858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mMultiTouchMotionAccumulator.configure(getDevice(),
6860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slotCount, true /*usingSlotsProtocol*/);
6861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
6862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mMultiTouchMotionAccumulator.configure(getDevice(),
6863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                MAX_POINTERS, false /*usingSlotsProtocol*/);
6864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool MultiTouchInputMapper::hasStylus() const {
6868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mMultiTouchMotionAccumulator.hasStylus()
6869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mTouchButtonAccumulator.hasStylus();
6870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6872842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright// --- ExternalStylusInputMapper
6873842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
6874842500e146cdc0036b2a1a3e2acc7626d005128bMichael WrightExternalStylusInputMapper::ExternalStylusInputMapper(InputDevice* device) :
6875842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    InputMapper(device) {
6876842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
6877842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
6878842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
6879842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightuint32_t ExternalStylusInputMapper::getSources() {
6880842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    return AINPUT_SOURCE_STYLUS;
6881842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
6882842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
6883842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid ExternalStylusInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
6884842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    InputMapper::populateDeviceInfo(info);
6885842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, AINPUT_SOURCE_STYLUS,
6886842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright            0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
6887842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
6888842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
6889842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid ExternalStylusInputMapper::dump(String8& dump) {
6890842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dump.append(INDENT2 "External Stylus Input Mapper:\n");
6891842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dump.append(INDENT3 "Raw Stylus Axes:\n");
6892842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPressureAxis, "Pressure");
6893842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dump.append(INDENT3 "Stylus State:\n");
6894842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    dumpStylusState(dump, mStylusState);
6895842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
6896842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
6897842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid ExternalStylusInputMapper::configure(nsecs_t when,
6898842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        const InputReaderConfiguration* config, uint32_t changes) {
6899842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPressureAxis);
6900842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mTouchButtonAccumulator.configure(getDevice());
6901842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
6902842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
6903842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid ExternalStylusInputMapper::reset(nsecs_t when) {
6904842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    InputDevice* device = getDevice();
6905842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mSingleTouchMotionAccumulator.reset(device);
6906842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mTouchButtonAccumulator.reset(device);
6907842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    InputMapper::reset(when);
6908842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
6909842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
6910842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid ExternalStylusInputMapper::process(const RawEvent* rawEvent) {
6911842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mSingleTouchMotionAccumulator.process(rawEvent);
6912842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mTouchButtonAccumulator.process(rawEvent);
6913842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
6914842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
6915842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        sync(rawEvent->when);
6916842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
6917842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
6918842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
6919842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wrightvoid ExternalStylusInputMapper::sync(nsecs_t when) {
6920842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mStylusState.clear();
6921842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
6922842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mStylusState.when = when;
6923842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
692445ccacf937d0d5a957348327ad9947ae96c5d472Michael Wright    mStylusState.toolType = mTouchButtonAccumulator.getToolType();
692545ccacf937d0d5a957348327ad9947ae96c5d472Michael Wright    if (mStylusState.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
692645ccacf937d0d5a957348327ad9947ae96c5d472Michael Wright        mStylusState.toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
692745ccacf937d0d5a957348327ad9947ae96c5d472Michael Wright    }
692845ccacf937d0d5a957348327ad9947ae96c5d472Michael Wright
6929842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    int32_t pressure = mSingleTouchMotionAccumulator.getAbsolutePressure();
6930842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    if (mRawPressureAxis.valid) {
6931842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mStylusState.pressure = float(pressure) / mRawPressureAxis.maxValue;
6932842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    } else if (mTouchButtonAccumulator.isToolActive()) {
6933842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mStylusState.pressure = 1.0f;
6934842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    } else {
6935842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright        mStylusState.pressure = 0.0f;
6936842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    }
6937842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
6938842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mStylusState.buttons = mTouchButtonAccumulator.getButtonState();
6939842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
6940842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright    mContext->dispatchExternalStylusState(mStylusState);
6941842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright}
6942842500e146cdc0036b2a1a3e2acc7626d005128bMichael Wright
6943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- JoystickInputMapper ---
6945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightJoystickInputMapper::JoystickInputMapper(InputDevice* device) :
6947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper(device) {
6948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightJoystickInputMapper::~JoystickInputMapper() {
6951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t JoystickInputMapper::getSources() {
6954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AINPUT_SOURCE_JOYSTICK;
6955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
6958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::populateDeviceInfo(info);
6959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < mAxes.size(); i++) {
6961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const Axis& axis = mAxes.valueAt(i);
6962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        addMotionRange(axis.axisInfo.axis, axis, info);
6963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
6965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            addMotionRange(axis.axisInfo.highAxis, axis, info);
6966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::addMotionRange(int32_t axisId, const Axis& axis,
6972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDeviceInfo* info) {
6973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    info->addMotionRange(axisId, AINPUT_SOURCE_JOYSTICK,
6974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
6975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    /* In order to ease the transition for developers from using the old axes
6976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright     * to the newer, more semantically correct axes, we'll continue to register
6977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright     * the old axes as duplicates of their corresponding new ones.  */
6978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t compatAxis = getCompatAxis(axisId);
6979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (compatAxis >= 0) {
6980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(compatAxis, AINPUT_SOURCE_JOYSTICK,
6981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
6982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright/* A mapping from axes the joystick actually has to the axes that should be
6986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * artificially created for compatibility purposes.
6987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * Returns -1 if no compatibility axis is needed. */
6988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t JoystickInputMapper::getCompatAxis(int32_t axis) {
6989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch(axis) {
6990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_LTRIGGER:
6991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AMOTION_EVENT_AXIS_BRAKE;
6992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_RTRIGGER:
6993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AMOTION_EVENT_AXIS_GAS;
6994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return -1;
6996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::dump(String8& dump) {
6999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT2 "Joystick Input Mapper:\n");
7000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT3 "Axes:\n");
7002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numAxes = mAxes.size();
7003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numAxes; i++) {
7004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const Axis& axis = mAxes.valueAt(i);
7005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const char* label = getAxisLabel(axis.axisInfo.axis);
7006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (label) {
7007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dump.appendFormat(INDENT4 "%s", label);
7008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
7009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dump.appendFormat(INDENT4 "%d", axis.axisInfo.axis);
7010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
7011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
7012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            label = getAxisLabel(axis.axisInfo.highAxis);
7013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (label) {
7014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                dump.appendFormat(" / %s (split at %d)", label, axis.axisInfo.splitValue);
7015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
7016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                dump.appendFormat(" / %d (split at %d)", axis.axisInfo.highAxis,
7017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        axis.axisInfo.splitValue);
7018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
7019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (axis.axisInfo.mode == AxisInfo::MODE_INVERT) {
7020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dump.append(" (invert)");
7021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
7022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f, resolution=%0.5f\n",
7024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
7025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "  scale=%0.5f, offset=%0.5f, "
7026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "highScale=%0.5f, highOffset=%0.5f\n",
7027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                axis.scale, axis.offset, axis.highScale, axis.highOffset);
7028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "  rawAxis=%d, rawMin=%d, rawMax=%d, "
7029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "rawFlat=%d, rawFuzz=%d, rawResolution=%d\n",
7030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
7031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz, axis.rawAxisInfo.resolution);
7032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
7033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
7034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::configure(nsecs_t when,
7036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const InputReaderConfiguration* config, uint32_t changes) {
7037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::configure(when, config, changes);
7038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes) { // first time only
7040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Collect all axes.
7041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
7042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (!(getAbsAxisUsage(abs, getDevice()->getClasses())
7043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    & INPUT_DEVICE_CLASS_JOYSTICK)) {
7044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                continue; // axis must be claimed by a different device
7045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
7046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            RawAbsoluteAxisInfo rawAxisInfo;
7048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getAbsoluteAxisInfo(abs, &rawAxisInfo);
7049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (rawAxisInfo.valid) {
7050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Map axis.
7051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AxisInfo axisInfo;
7052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
7053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (!explicitlyMapped) {
7054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    // Axis is not explicitly mapped, will choose a generic axis later.
7055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axisInfo.mode = AxisInfo::MODE_NORMAL;
7056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axisInfo.axis = -1;
7057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
7058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Apply flat override.
7060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                int32_t rawFlat = axisInfo.flatOverride < 0
7061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ? rawAxisInfo.flat : axisInfo.flatOverride;
7062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Calculate scaling factors and limits.
7064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                Axis axis;
7065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (axisInfo.mode == AxisInfo::MODE_SPLIT) {
7066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue);
7067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
7068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
7069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            scale, 0.0f, highScale, 0.0f,
7070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
7071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            rawAxisInfo.resolution * scale);
7072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else if (isCenteredAxis(axisInfo.axis)) {
7073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
7074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
7075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
7076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            scale, offset, scale, offset,
7077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
7078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            rawAxisInfo.resolution * scale);
7079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
7080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
7081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
7082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            scale, 0.0f, scale, 0.0f,
7083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
7084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            rawAxisInfo.resolution * scale);
7085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
7086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // To eliminate noise while the joystick is at rest, filter out small variations
7088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // in axis values up front.
7089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                axis.filter = axis.fuzz ? axis.fuzz : axis.flat * 0.25f;
7090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mAxes.add(abs, axis);
7092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
7093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
7094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // If there are too many axes, start dropping them.
7096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Prefer to keep explicitly mapped axes.
7097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mAxes.size() > PointerCoords::MAX_AXES) {
709837764c71a0ac79142f90bb112b6cabffb940b955Narayan Kamath            ALOGI("Joystick '%s' has %zu axes but the framework only supports a maximum of %d.",
7099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
7100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            pruneAxes(true);
7101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            pruneAxes(false);
7102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
7103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Assign generic axis ids to remaining axes.
7105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1;
7106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t numAxes = mAxes.size();
7107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < numAxes; i++) {
7108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            Axis& axis = mAxes.editValueAt(i);
7109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (axis.axisInfo.axis < 0) {
7110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
7111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        && haveAxis(nextGenericAxisId)) {
7112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    nextGenericAxisId += 1;
7113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
7114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
7116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axis.axisInfo.axis = nextGenericAxisId;
7117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    nextGenericAxisId += 1;
7118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
7119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
7120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            "have already been assigned to other axes.",
7121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            getDeviceName().string(), mAxes.keyAt(i));
7122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mAxes.removeItemsAt(i--);
7123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    numAxes -= 1;
7124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
7125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
7126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
7127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
7128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
7129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool JoystickInputMapper::haveAxis(int32_t axisId) {
7131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numAxes = mAxes.size();
7132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numAxes; i++) {
7133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const Axis& axis = mAxes.valueAt(i);
7134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (axis.axisInfo.axis == axisId
7135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                || (axis.axisInfo.mode == AxisInfo::MODE_SPLIT
7136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        && axis.axisInfo.highAxis == axisId)) {
7137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return true;
7138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
7139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
7140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return false;
7141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
7142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) {
7144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t i = mAxes.size();
7145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) {
7146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) {
7147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            continue;
7148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
7149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Discarding joystick '%s' axis %d because there are too many axes.",
7150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                getDeviceName().string(), mAxes.keyAt(i));
7151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mAxes.removeItemsAt(i);
7152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
7153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
7154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool JoystickInputMapper::isCenteredAxis(int32_t axis) {
7156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (axis) {
7157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_X:
7158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_Y:
7159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_Z:
7160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_RX:
7161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_RY:
7162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_RZ:
7163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_HAT_X:
7164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_HAT_Y:
7165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_ORIENTATION:
7166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_RUDDER:
7167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_WHEEL:
7168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return true;
7169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
7170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return false;
7171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
7172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
7173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::reset(nsecs_t when) {
7175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Recenter all axes.
7176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numAxes = mAxes.size();
7177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numAxes; i++) {
7178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Axis& axis = mAxes.editValueAt(i);
7179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        axis.resetValue();
7180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
7181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::reset(when);
7183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
7184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::process(const RawEvent* rawEvent) {
7186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (rawEvent->type) {
7187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case EV_ABS: {
7188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ssize_t index = mAxes.indexOfKey(rawEvent->code);
7189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (index >= 0) {
7190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            Axis& axis = mAxes.editValueAt(index);
7191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float newValue, highNewValue;
7192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            switch (axis.axisInfo.mode) {
7193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case AxisInfo::MODE_INVERT:
7194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)
7195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        * axis.scale + axis.offset;
7196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                highNewValue = 0.0f;
7197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
7198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case AxisInfo::MODE_SPLIT:
7199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (rawEvent->value < axis.axisInfo.splitValue) {
7200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    newValue = (axis.axisInfo.splitValue - rawEvent->value)
7201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            * axis.scale + axis.offset;
7202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    highNewValue = 0.0f;
7203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else if (rawEvent->value > axis.axisInfo.splitValue) {
7204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    newValue = 0.0f;
7205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    highNewValue = (rawEvent->value - axis.axisInfo.splitValue)
7206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            * axis.highScale + axis.highOffset;
7207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
7208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    newValue = 0.0f;
7209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    highNewValue = 0.0f;
7210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
7211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
7212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            default:
7213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                newValue = rawEvent->value * axis.scale + axis.offset;
7214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                highNewValue = 0.0f;
7215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
7216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
7217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            axis.newValue = newValue;
7218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            axis.highNewValue = highNewValue;
7219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
7220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
7221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
7222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case EV_SYN:
7224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (rawEvent->code) {
7225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case SYN_REPORT:
7226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            sync(rawEvent->when, false /*force*/);
7227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
7228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
7229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
7230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
7231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
7232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::sync(nsecs_t when, bool force) {
7234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!filterAxes(force)) {
7235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
7236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
7237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t metaState = mContext->getGlobalMetaState();
7239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t buttonState = 0;
7240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    PointerProperties pointerProperties;
7242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerProperties.clear();
7243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerProperties.id = 0;
7244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
7245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    PointerCoords pointerCoords;
7247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCoords.clear();
7248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numAxes = mAxes.size();
7250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numAxes; i++) {
7251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const Axis& axis = mAxes.valueAt(i);
7252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        setPointerCoordsAxisValue(&pointerCoords, axis.axisInfo.axis, axis.currentValue);
7253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
7254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            setPointerCoordsAxisValue(&pointerCoords, axis.axisInfo.highAxis,
7255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axis.highCurrentValue);
7256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
7257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
7258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Moving a joystick axis should not wake the device because joysticks can
7260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // be fairly noisy even when not in use.  On the other hand, pushing a gamepad
7261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // button will likely wake the device.
7262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // TODO: Use the input device configuration to control this behavior more finely.
7263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t policyFlags = 0;
7264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
72667b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright            AMOTION_EVENT_ACTION_MOVE, 0, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
7267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ADISPLAY_ID_NONE, 1, &pointerProperties, &pointerCoords, 0, 0, 0);
7268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getListener()->notifyMotion(&args);
7269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
7270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::setPointerCoordsAxisValue(PointerCoords* pointerCoords,
7272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t axis, float value) {
7273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCoords->setAxisValue(axis, value);
7274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    /* In order to ease the transition for developers from using the old axes
7275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright     * to the newer, more semantically correct axes, we'll continue to produce
7276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright     * values for the old axes as mirrors of the value of their corresponding
7277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright     * new axes. */
7278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t compatAxis = getCompatAxis(axis);
7279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (compatAxis >= 0) {
7280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords->setAxisValue(compatAxis, value);
7281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
7282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
7283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool JoystickInputMapper::filterAxes(bool force) {
7285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool atLeastOneSignificantChange = force;
7286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numAxes = mAxes.size();
7287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numAxes; i++) {
7288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Axis& axis = mAxes.editValueAt(i);
7289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (force || hasValueChangedSignificantly(axis.filter,
7290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                axis.newValue, axis.currentValue, axis.min, axis.max)) {
7291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            axis.currentValue = axis.newValue;
7292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            atLeastOneSignificantChange = true;
7293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
7294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
7295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (force || hasValueChangedSignificantly(axis.filter,
7296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axis.highNewValue, axis.highCurrentValue, axis.min, axis.max)) {
7297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                axis.highCurrentValue = axis.highNewValue;
7298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                atLeastOneSignificantChange = true;
7299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
7300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
7301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
7302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return atLeastOneSignificantChange;
7303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
7304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool JoystickInputMapper::hasValueChangedSignificantly(
7306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float filter, float newValue, float currentValue, float min, float max) {
7307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (newValue != currentValue) {
7308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Filter out small changes in value unless the value is converging on the axis
7309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // bounds or center point.  This is intended to reduce the amount of information
7310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // sent to applications by particularly noisy joysticks (such as PS3).
7311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (fabs(newValue - currentValue) > filter
7312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, min)
7313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, max)
7314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, 0)) {
7315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return true;
7316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
7317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
7318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return false;
7319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
7320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool JoystickInputMapper::hasMovedNearerToValueWithinFilteredRange(
7322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float filter, float newValue, float currentValue, float thresholdValue) {
7323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float newDistance = fabs(newValue - thresholdValue);
7324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (newDistance < filter) {
7325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float oldDistance = fabs(currentValue - thresholdValue);
7326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (newDistance < oldDistance) {
7327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return true;
7328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
7329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
7330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return false;
7331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
7332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
7333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} // namespace android
7334