InputReader.cpp revision 41d2f80739700a56fd6a670923a2966add8dae61
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
42d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include "InputReader.h"
43d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
44d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <cutils/log.h>
45d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <input/Keyboard.h>
46d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <input/VirtualKeyMap.h>
47d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
48d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <stddef.h>
49d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <stdlib.h>
50d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <unistd.h>
51d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <errno.h>
52d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <limits.h>
53d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <math.h>
54d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
55d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define INDENT "  "
56d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define INDENT2 "    "
57d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define INDENT3 "      "
58d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define INDENT4 "        "
59d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#define INDENT5 "          "
60d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
61d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightnamespace android {
62d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
63d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- Constants ---
64d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
65d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Maximum number of slots supported when using the slot-based Multitouch Protocol B.
66d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic const size_t MAX_SLOTS = 32;
67d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
68d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- Static Functions ---
69d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
70d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrighttemplate<typename T>
71d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightinline static T abs(const T& value) {
72d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return value < 0 ? - value : value;
73d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
74d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
75d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrighttemplate<typename T>
76d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightinline static T min(const T& a, const T& b) {
77d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return a < b ? a : b;
78d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
79d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
80d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrighttemplate<typename T>
81d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightinline static void swap(T& a, T& b) {
82d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    T temp = a;
83d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    a = b;
84d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    b = temp;
85d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
86d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
87d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightinline static float avg(float x, float y) {
88d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return (x + y) / 2;
89d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
90d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
91d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightinline static float distance(float x1, float y1, float x2, float y2) {
92d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return hypotf(x1 - x2, y1 - y2);
93d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
94d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
95d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightinline static int32_t signExtendNybble(int32_t value) {
96d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return value >= 8 ? value - 16 : value;
97d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
98d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
99d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic inline const char* toString(bool value) {
100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return value ? "true" : "false";
101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation,
104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const int32_t map[][4], size_t mapSize) {
105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (orientation != DISPLAY_ORIENTATION_0) {
106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < mapSize; i++) {
107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (value == map[i][0]) {
108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return map[i][orientation];
109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return value;
113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic const int32_t keyCodeRotationMap[][4] = {
116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // key codes enumerated counter-clockwise with the original (unrotated) key first
117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // no rotation,        90 degree rotation,  180 degree rotation, 270 degree rotation
118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        { AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT },
119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        { AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN },
120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        { AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT },
121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        { AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP },
122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright};
123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic const size_t keyCodeRotationMapSize =
124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return rotateValueUsingRotationMap(keyCode, orientation,
128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            keyCodeRotationMap, keyCodeRotationMapSize);
129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic void rotateDelta(int32_t orientation, float* deltaX, float* deltaY) {
132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float temp;
133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (orientation) {
134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case DISPLAY_ORIENTATION_90:
135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        temp = *deltaX;
136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *deltaX = *deltaY;
137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *deltaY = -temp;
138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case DISPLAY_ORIENTATION_180:
141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *deltaX = -*deltaX;
142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *deltaY = -*deltaY;
143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case DISPLAY_ORIENTATION_270:
146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        temp = *deltaX;
147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *deltaX = -*deltaY;
148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *deltaY = temp;
149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Returns true if the pointer should be reported as being down given the specified
158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// button states.  This determines whether the event is reported as a touch event.
159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic bool isPointerDown(int32_t buttonState) {
160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return buttonState &
161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            (AMOTION_EVENT_BUTTON_PRIMARY | AMOTION_EVENT_BUTTON_SECONDARY
162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    | AMOTION_EVENT_BUTTON_TERTIARY);
163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic float calculateCommonVector(float a, float b) {
166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (a > 0 && b > 0) {
167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return a < b ? a : b;
168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (a < 0 && b < 0) {
169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return a > b ? a : b;
170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return 0;
172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic void synthesizeButtonKey(InputReaderContext* context, int32_t action,
176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        nsecs_t when, int32_t deviceId, uint32_t source,
177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState,
178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t buttonState, int32_t keyCode) {
179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (
180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            (action == AKEY_EVENT_ACTION_DOWN
181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && !(lastButtonState & buttonState)
182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && (currentButtonState & buttonState))
183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || (action == AKEY_EVENT_ACTION_UP
184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && (lastButtonState & buttonState)
185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && !(currentButtonState & buttonState))) {
186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyKeyArgs args(when, deviceId, source, policyFlags,
187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                action, 0, keyCode, 0, context->getGlobalMetaState(), when);
188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        context->getListener()->notifyKey(&args);
189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic void synthesizeButtonKeys(InputReaderContext* context, int32_t action,
193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        nsecs_t when, int32_t deviceId, uint32_t source,
194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState) {
195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            lastButtonState, currentButtonState,
197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            AMOTION_EVENT_BUTTON_BACK, AKEYCODE_BACK);
198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            lastButtonState, currentButtonState,
200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            AMOTION_EVENT_BUTTON_FORWARD, AKEYCODE_FORWARD);
201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- InputReaderConfiguration ---
205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputReaderConfiguration::getDisplayInfo(bool external, DisplayViewport* outViewport) const {
207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    const DisplayViewport& viewport = external ? mExternalDisplay : mInternalDisplay;
208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (viewport.displayId >= 0) {
209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *outViewport = viewport;
210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return true;
211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return false;
213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReaderConfiguration::setDisplayInfo(bool external, const DisplayViewport& viewport) {
216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    DisplayViewport& v = external ? mExternalDisplay : mInternalDisplay;
217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    v = viewport;
218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
221af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke// -- TouchAffineTransformation --
222af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gereckevoid TouchAffineTransformation::applyTo(float& x, float& y) const {
223af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    float newX, newY;
224af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    newX = x * x_scale + y * x_ymix + x_offset;
225af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    newY = x * y_xmix + y * y_scale + y_offset;
226af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke
227af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    x = newX;
228af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    y = newY;
229af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke}
230af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke
231af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke
232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- InputReader ---
233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputReader::InputReader(const sp<EventHubInterface>& eventHub,
235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const sp<InputReaderPolicyInterface>& policy,
236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const sp<InputListenerInterface>& listener) :
237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mContext(this), mEventHub(eventHub), mPolicy(policy),
238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mGlobalMetaState(0), mGeneration(1),
239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mConfigurationChangesToRefresh(0) {
241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mQueuedListener = new QueuedInputListener(listener);
242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    { // acquire lock
244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        AutoMutex _l(mLock);
245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        refreshConfigurationLocked(0);
247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        updateGlobalMetaStateLocked();
248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } // release lock
249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputReader::~InputReader() {
252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < mDevices.size(); i++) {
253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        delete mDevices.valueAt(i);
254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::loopOnce() {
258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t oldGeneration;
259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t timeoutMillis;
260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool inputDevicesChanged = false;
261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    Vector<InputDeviceInfo> inputDevices;
262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    { // acquire lock
263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        AutoMutex _l(mLock);
264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        oldGeneration = mGeneration;
266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        timeoutMillis = -1;
267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t changes = mConfigurationChangesToRefresh;
269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (changes) {
270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfigurationChangesToRefresh = 0;
271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            timeoutMillis = 0;
272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            refreshConfigurationLocked(changes);
273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (mNextTimeout != LLONG_MAX) {
274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } // release lock
278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    { // acquire lock
282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        AutoMutex _l(mLock);
283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mReaderIsAliveCondition.broadcast();
284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (count) {
286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            processEventsLocked(mEventBuffer, count);
287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mNextTimeout != LLONG_MAX) {
290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (now >= mNextTimeout) {
292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_RAW_EVENTS
293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mNextTimeout = LLONG_MAX;
296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                timeoutExpiredLocked(now);
297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (oldGeneration != mGeneration) {
301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            inputDevicesChanged = true;
302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getInputDevicesLocked(inputDevices);
303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } // release lock
305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Send out a message that the describes the changed input devices.
307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (inputDevicesChanged) {
308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPolicy->notifyInputDevicesChanged(inputDevices);
309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Flush queued events out to the listener.
312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // This must happen outside of the lock because the listener could potentially call
313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // back into the InputReader's methods, such as getScanCodeState, or become blocked
314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // on another thread similarly waiting to acquire the InputReader lock thereby
315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // resulting in a deadlock.  This situation is actually quite plausible because the
316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // listener is actually the input dispatcher, which calls into the window manager,
317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // which occasionally calls into the input reader.
318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mQueuedListener->flush();
319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (const RawEvent* rawEvent = rawEvents; count;) {
323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t type = rawEvent->type;
324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t batchSize = 1;
325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t deviceId = rawEvent->deviceId;
327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            while (batchSize < count) {
328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT
329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        || rawEvent[batchSize].deviceId != deviceId) {
330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    break;
331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                batchSize += 1;
333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_RAW_EVENTS
335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("BatchSize: %d Count: %d", batchSize, count);
336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            switch (rawEvent->type) {
340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case EventHubInterface::DEVICE_ADDED:
341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                addDeviceLocked(rawEvent->when, rawEvent->deviceId);
342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case EventHubInterface::DEVICE_REMOVED:
344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case EventHubInterface::FINISHED_DEVICE_SCAN:
347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                handleConfigurationChangedLocked(rawEvent->when);
348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            default:
350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOG_ASSERT(false); // can't happen
351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        count -= batchSize;
355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        rawEvent += batchSize;
356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceIndex >= 0) {
362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t classes = mEventHub->getDeviceClasses(deviceId);
368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    device->configure(when, &mConfig, 0);
372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    device->reset(when);
373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (device->isIgnored()) {
375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                identifier.name.string());
377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId,
379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                identifier.name.string(), device->getSources());
380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mDevices.add(deviceId, device);
383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bumpGenerationLocked();
384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputDevice* device = NULL;
388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceIndex < 0) {
390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    device = mDevices.valueAt(deviceIndex);
395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mDevices.removeItemsAt(deviceIndex, 1);
396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bumpGenerationLocked();
397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (device->isIgnored()) {
399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)",
400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                device->getId(), device->getName().string());
401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Device removed: id=%d, name='%s', sources=0x%08x",
403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                device->getId(), device->getName().string(), device->getSources());
404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    device->reset(when);
407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    delete device;
408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const InputDeviceIdentifier& identifier, uint32_t classes) {
412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            controllerNumber, identifier, classes);
414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // External devices.
416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->setExternal(true);
418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Switch-like devices.
421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_SWITCH) {
422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->addMapper(new SwitchInputMapper(device));
423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Vibrator-like devices.
426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->addMapper(new VibratorInputMapper(device));
428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Keyboard-like devices.
431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t keyboardSource = 0;
432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        keyboardSource |= AINPUT_SOURCE_KEYBOARD;
435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_DPAD) {
440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        keyboardSource |= AINPUT_SOURCE_DPAD;
441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        keyboardSource |= AINPUT_SOURCE_GAMEPAD;
444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (keyboardSource != 0) {
447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Cursor-like devices.
451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_CURSOR) {
452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->addMapper(new CursorInputMapper(device));
453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Touchscreens and touchpad devices.
456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->addMapper(new MultiTouchInputMapper(device));
458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->addMapper(new SingleTouchInputMapper(device));
460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Joystick-like devices.
463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->addMapper(new JoystickInputMapper(device));
465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return device;
468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::processEventsForDeviceLocked(int32_t deviceId,
471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const RawEvent* rawEvents, size_t count) {
472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceIndex < 0) {
474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGW("Discarding event for unknown deviceId %d.", deviceId);
475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputDevice* device = mDevices.valueAt(deviceIndex);
479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (device->isIgnored()) {
480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        //ALOGD("Discarding event for ignored deviceId %d.", deviceId);
481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    device->process(rawEvents, count);
485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::timeoutExpiredLocked(nsecs_t when) {
488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < mDevices.size(); i++) {
489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device = mDevices.valueAt(i);
490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!device->isIgnored()) {
491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            device->timeoutExpired(when);
492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::handleConfigurationChangedLocked(nsecs_t when) {
497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Reset global meta state because it depends on the list of all configured devices.
498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    updateGlobalMetaStateLocked();
499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Enqueue configuration changed.
501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    NotifyConfigurationChangedArgs args(when);
502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mQueuedListener->notifyConfigurationChanged(&args);
503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::refreshConfigurationLocked(uint32_t changes) {
506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPolicy->getReaderConfiguration(&mConfig);
507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (changes) {
510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Reconfiguring input devices.  changes=0x%08x", changes);
511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mEventHub->requestReopenDevices();
515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            for (size_t i = 0; i < mDevices.size(); i++) {
517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                InputDevice* device = mDevices.valueAt(i);
518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                device->configure(now, &mConfig, changes);
519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::updateGlobalMetaStateLocked() {
525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mGlobalMetaState = 0;
526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < mDevices.size(); i++) {
528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device = mDevices.valueAt(i);
529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mGlobalMetaState |= device->getMetaState();
530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::getGlobalMetaStateLocked() {
534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mGlobalMetaState;
535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mDisableVirtualKeysTimeout = time;
539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputReader::shouldDropVirtualKeyLocked(nsecs_t now,
542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device, int32_t keyCode, int32_t scanCode) {
543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (now < mDisableVirtualKeysTimeout) {
544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Dropping virtual key from device %s because virtual keys are "
545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "temporarily disabled for the next %0.3fms.  keyCode=%d, scanCode=%d",
546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                device->getName().string(),
547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                (mDisableVirtualKeysTimeout - now) * 0.000001,
548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                keyCode, scanCode);
549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return true;
550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return false;
552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::fadePointerLocked() {
556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < mDevices.size(); i++) {
557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device = mDevices.valueAt(i);
558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->fadePointer();
559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (when < mNextTimeout) {
564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mNextTimeout = when;
565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mEventHub->wake();
566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::bumpGenerationLocked() {
570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return ++mGeneration;
571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::getInputDevices(Vector<InputDeviceInfo>& outInputDevices) {
574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getInputDevicesLocked(outInputDevices);
576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices) {
579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    outInputDevices.clear();
580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numDevices = mDevices.size();
582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numDevices; i++) {
583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device = mDevices.valueAt(i);
584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!device->isIgnored()) {
585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            outInputDevices.push();
586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            device->getDeviceInfo(&outInputDevices.editTop());
587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t keyCode) {
593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t scanCode) {
600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        GetStateFunc getStateFunc) {
613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t result = AKEY_STATE_UNKNOWN;
614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceId >= 0) {
615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (deviceIndex >= 0) {
617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            InputDevice* device = mDevices.valueAt(deviceIndex);
618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                result = (device->*getStateFunc)(sourceMask, code);
620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t numDevices = mDevices.size();
624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < numDevices; i++) {
625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            InputDevice* device = mDevices.valueAt(i);
626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // value.  Otherwise, return AKEY_STATE_UP as long as one device reports it.
629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                int32_t currentResult = (device->*getStateFunc)(sourceMask, code);
630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (currentResult >= AKEY_STATE_DOWN) {
631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    return currentResult;
632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else if (currentResult == AKEY_STATE_UP) {
633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    result = currentResult;
634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return result;
639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    memset(outFlags, 0, numCodes);
646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool result = false;
652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceId >= 0) {
653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (deviceIndex >= 0) {
655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            InputDevice* device = mDevices.valueAt(deviceIndex);
656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                result = device->markSupportedKeyCodes(sourceMask,
658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        numCodes, keyCodes, outFlags);
659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t numDevices = mDevices.size();
663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < numDevices; i++) {
664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            InputDevice* device = mDevices.valueAt(i);
665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                result |= device->markSupportedKeyCodes(sourceMask,
667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        numCodes, keyCodes, outFlags);
668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return result;
672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::requestRefreshConfiguration(uint32_t changes) {
675d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (changes) {
678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool needWake = !mConfigurationChangesToRefresh;
679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mConfigurationChangesToRefresh |= changes;
680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (needWake) {
682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mEventHub->wake();
683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ssize_t repeat, int32_t token) {
689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceIndex >= 0) {
693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device = mDevices.valueAt(deviceIndex);
694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->vibrate(pattern, patternSize, repeat, token);
695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceIndex >= 0) {
703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device = mDevices.valueAt(deviceIndex);
704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->cancelVibrate(token);
705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::dump(String8& dump) {
709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    AutoMutex _l(mLock);
710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mEventHub->dump(dump);
712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append("\n");
713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append("Input Reader State:\n");
715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < mDevices.size(); i++) {
717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDevices.valueAt(i)->dump(dump);
718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT "Configuration:\n");
721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT2 "ExcludedDeviceNames: [");
722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (i != 0) {
724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dump.append(", ");
725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(mConfig.excludedDeviceNames.itemAt(i).string());
727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append("]\n");
729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.virtualKeyQuietTime * 0.000001f);
731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "PointerVelocityControlParameters: "
733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerVelocityControlParameters.scale,
735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerVelocityControlParameters.lowThreshold,
736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerVelocityControlParameters.highThreshold,
737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerVelocityControlParameters.acceleration);
738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "WheelVelocityControlParameters: "
740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.wheelVelocityControlParameters.scale,
742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.wheelVelocityControlParameters.lowThreshold,
743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.wheelVelocityControlParameters.highThreshold,
744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.wheelVelocityControlParameters.acceleration);
745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "PointerGesture:\n");
747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Enabled: %s\n",
748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mConfig.pointerGesturesEnabled));
749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "QuietInterval: %0.1fms\n",
750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureQuietInterval * 0.000001f);
751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureDragMinSwitchSpeed);
753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "TapInterval: %0.1fms\n",
754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureTapInterval * 0.000001f);
755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "TapDragInterval: %0.1fms\n",
756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureTapDragInterval * 0.000001f);
757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "TapSlop: %0.1fpx\n",
758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureTapSlop);
759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureMultitouchMinDistance);
763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureSwipeTransitionAngleCosine);
765d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureSwipeMaxWidthRatio);
767d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "MovementSpeedRatio: %0.1f\n",
768d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureMovementSpeedRatio);
769d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "ZoomSpeedRatio: %0.1f\n",
770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mConfig.pointerGestureZoomSpeedRatio);
771d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::monitor() {
774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Acquire and release the lock to ensure that the reader has not deadlocked.
775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLock.lock();
776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mEventHub->wake();
777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mReaderIsAliveCondition.wait(mLock);
778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLock.unlock();
779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Check the EventHub
781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mEventHub->monitor();
782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- InputReader::ContextImpl ---
786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputReader::ContextImpl::ContextImpl(InputReader* reader) :
788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mReader(reader) {
789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::ContextImpl::updateGlobalMetaState() {
792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // lock is already held by the input loop
793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mReader->updateGlobalMetaStateLocked();
794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::ContextImpl::getGlobalMetaState() {
797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // lock is already held by the input loop
798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mReader->getGlobalMetaStateLocked();
799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // lock is already held by the input loop
803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mReader->disableVirtualKeysUntilLocked(time);
804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now,
807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDevice* device, int32_t keyCode, int32_t scanCode) {
808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // lock is already held by the input loop
809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::ContextImpl::fadePointer() {
813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // lock is already held by the input loop
814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mReader->fadePointerLocked();
815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // lock is already held by the input loop
819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mReader->requestTimeoutAtTimeLocked(when);
820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputReader::ContextImpl::bumpGeneration() {
823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // lock is already held by the input loop
824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mReader->bumpGenerationLocked();
825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mReader->mPolicy.get();
829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputListenerInterface* InputReader::ContextImpl::getListener() {
832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mReader->mQueuedListener.get();
833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightEventHubInterface* InputReader::ContextImpl::getEventHub() {
836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mReader->mEventHub.get();
837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- InputReaderThread ---
841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Thread(/*canCallJava*/ true), mReader(reader) {
844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputReaderThread::~InputReaderThread() {
847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputReaderThread::threadLoop() {
850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mReader->loopOnce();
851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return true;
852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- InputDevice ---
856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t controllerNumber, const InputDeviceIdentifier& identifier, uint32_t classes) :
859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mContext(context), mId(id), mGeneration(generation), mControllerNumber(controllerNumber),
860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mIdentifier(identifier), mClasses(classes),
861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSources(0), mIsExternal(false), mDropUntilNextSync(false) {
862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputDevice::~InputDevice() {
865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        delete mMappers[i];
868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mMappers.clear();
870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::dump(String8& dump) {
873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputDeviceInfo deviceInfo;
874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getDeviceInfo(& deviceInfo);
875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(),
877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            deviceInfo.getDisplayName().string());
878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "Generation: %d\n", mGeneration);
879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!ranges.isEmpty()) {
885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT2 "Motion Ranges:\n");
886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < ranges.size(); i++) {
887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const char* label = getAxisLabel(range.axis);
889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            char name[32];
890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (label) {
891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                strncpy(name, label, sizeof(name));
892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                name[sizeof(name) - 1] = '\0';
893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                snprintf(name, sizeof(name), "%d", range.axis);
895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dump.appendFormat(INDENT3 "%s: source=0x%08x, "
897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, resolution=%0.3f\n",
898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    name, range.source, range.min, range.max, range.flat, range.fuzz,
899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    range.resolution);
900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
902d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mapper->dump(dump);
907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::addMapper(InputMapper* mapper) {
911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mMappers.add(mapper);
912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) {
915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mSources = 0;
916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!isIgnored()) {
918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!changes) { // first time only
919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                sp<KeyCharacterMap> keyboardLayout =
925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier);
926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (mContext->getEventHub()->setKeyboardLayoutOverlay(mId, keyboardLayout)) {
927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    bumpGeneration();
928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                String8 alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (mAlias != alias) {
936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mAlias = alias;
937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    bumpGeneration();
938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t numMappers = mMappers.size();
943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < numMappers; i++) {
944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            InputMapper* mapper = mMappers[i];
945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mapper->configure(when, config, changes);
946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSources |= mapper->getSources();
947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::reset(nsecs_t when) {
952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mapper->reset(when);
956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mContext->updateGlobalMetaState();
959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    notifyReset(when);
961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::process(const RawEvent* rawEvents, size_t count) {
964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Process all of the events in order for each mapper.
965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // We cannot simply ask each mapper to process them in bulk because mappers may
966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // have side-effects that must be interleaved.  For example, joystick movement events and
967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // gamepad button presses are handled by different mappers but they should be dispatched
968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // in the order received.
969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_RAW_EVENTS
972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%lld",
973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,
974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                rawEvent->when);
975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mDropUntilNextSync) {
978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mDropUntilNextSync = false;
980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_RAW_EVENTS
981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Recovered from input event buffer overrun.");
982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_RAW_EVENTS
985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Dropped input event while waiting for next input sync.");
986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGI("Detected input event buffer overrun for device %s.", getName().string());
990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mDropUntilNextSync = true;
991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            reset(rawEvent->when);
992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            for (size_t i = 0; i < numMappers; i++) {
994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                InputMapper* mapper = mMappers[i];
995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mapper->process(rawEvent);
996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::timeoutExpired(nsecs_t when) {
1002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mapper->timeoutExpired(when);
1006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
1010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias,
1011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mIsExternal);
1012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mapper->populateDeviceInfo(outDeviceInfo);
1017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
1021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState);
1022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
1025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getState(sourceMask, scanCode, & InputMapper::getScanCodeState);
1026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
1029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getState(sourceMask, switchCode, & InputMapper::getSwitchState);
1030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
1033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t result = AKEY_STATE_UNKNOWN;
1034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
1038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
1039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // value.  Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
1040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t currentResult = (mapper->*getStateFunc)(sourceMask, code);
1041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (currentResult >= AKEY_STATE_DOWN) {
1042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return currentResult;
1043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (currentResult == AKEY_STATE_UP) {
1044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                result = currentResult;
1045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
1046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return result;
1049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
1052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const int32_t* keyCodes, uint8_t* outFlags) {
1053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool result = false;
1054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
1058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
1059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return result;
1062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
1065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t token) {
1066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mapper->vibrate(pattern, patternSize, repeat, token);
1070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::cancelVibrate(int32_t token) {
1074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mapper->cancelVibrate(token);
1078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputDevice::getMetaState() {
1082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t result = 0;
1083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        result |= mapper->getMetaState();
1087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return result;
1089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::fadePointer() {
1092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numMappers = mMappers.size();
1093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numMappers; i++) {
1094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper* mapper = mMappers[i];
1095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mapper->fadePointer();
1096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::bumpGeneration() {
1100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mGeneration = mContext->bumpGeneration();
1101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputDevice::notifyReset(nsecs_t when) {
1104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    NotifyDeviceResetArgs args(when, mId);
1105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mContext->getListener()->notifyDeviceReset(&args);
1106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- CursorButtonAccumulator ---
1110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightCursorButtonAccumulator::CursorButtonAccumulator() {
1112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearButtons();
1113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorButtonAccumulator::reset(InputDevice* device) {
1116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnLeft = device->isKeyPressed(BTN_LEFT);
1117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnRight = device->isKeyPressed(BTN_RIGHT);
1118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnMiddle = device->isKeyPressed(BTN_MIDDLE);
1119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnBack = device->isKeyPressed(BTN_BACK);
1120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnSide = device->isKeyPressed(BTN_SIDE);
1121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnForward = device->isKeyPressed(BTN_FORWARD);
1122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnExtra = device->isKeyPressed(BTN_EXTRA);
1123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnTask = device->isKeyPressed(BTN_TASK);
1124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorButtonAccumulator::clearButtons() {
1127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnLeft = 0;
1128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnRight = 0;
1129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnMiddle = 0;
1130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnBack = 0;
1131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnSide = 0;
1132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnForward = 0;
1133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnExtra = 0;
1134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnTask = 0;
1135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorButtonAccumulator::process(const RawEvent* rawEvent) {
1138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_KEY) {
1139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (rawEvent->code) {
1140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_LEFT:
1141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnLeft = rawEvent->value;
1142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_RIGHT:
1144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnRight = rawEvent->value;
1145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_MIDDLE:
1147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnMiddle = rawEvent->value;
1148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_BACK:
1150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnBack = rawEvent->value;
1151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_SIDE:
1153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnSide = rawEvent->value;
1154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_FORWARD:
1156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnForward = rawEvent->value;
1157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_EXTRA:
1159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnExtra = rawEvent->value;
1160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TASK:
1162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnTask = rawEvent->value;
1163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t CursorButtonAccumulator::getButtonState() const {
1169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t result = 0;
1170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnLeft) {
1171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        result |= AMOTION_EVENT_BUTTON_PRIMARY;
1172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnRight) {
1174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        result |= AMOTION_EVENT_BUTTON_SECONDARY;
1175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnMiddle) {
1177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        result |= AMOTION_EVENT_BUTTON_TERTIARY;
1178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnBack || mBtnSide) {
1180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        result |= AMOTION_EVENT_BUTTON_BACK;
1181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnForward || mBtnExtra) {
1183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        result |= AMOTION_EVENT_BUTTON_FORWARD;
1184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return result;
1186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- CursorMotionAccumulator ---
1190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightCursorMotionAccumulator::CursorMotionAccumulator() {
1192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearRelativeAxes();
1193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorMotionAccumulator::reset(InputDevice* device) {
1196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearRelativeAxes();
1197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorMotionAccumulator::clearRelativeAxes() {
1200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mRelX = 0;
1201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mRelY = 0;
1202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorMotionAccumulator::process(const RawEvent* rawEvent) {
1205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_REL) {
1206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (rawEvent->code) {
1207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case REL_X:
1208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mRelX = rawEvent->value;
1209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case REL_Y:
1211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mRelY = rawEvent->value;
1212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorMotionAccumulator::finishSync() {
1218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearRelativeAxes();
1219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- CursorScrollAccumulator ---
1223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightCursorScrollAccumulator::CursorScrollAccumulator() :
1225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mHaveRelWheel(false), mHaveRelHWheel(false) {
1226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearRelativeAxes();
1227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorScrollAccumulator::configure(InputDevice* device) {
1230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveRelWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_WHEEL);
1231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveRelHWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_HWHEEL);
1232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorScrollAccumulator::reset(InputDevice* device) {
1235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearRelativeAxes();
1236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorScrollAccumulator::clearRelativeAxes() {
1239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mRelWheel = 0;
1240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mRelHWheel = 0;
1241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorScrollAccumulator::process(const RawEvent* rawEvent) {
1244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_REL) {
1245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (rawEvent->code) {
1246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case REL_WHEEL:
1247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mRelWheel = rawEvent->value;
1248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case REL_HWHEEL:
1250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mRelHWheel = rawEvent->value;
1251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorScrollAccumulator::finishSync() {
1257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearRelativeAxes();
1258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- TouchButtonAccumulator ---
1262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightTouchButtonAccumulator::TouchButtonAccumulator() :
1264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mHaveBtnTouch(false), mHaveStylus(false) {
1265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearButtons();
1266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchButtonAccumulator::configure(InputDevice* device) {
1269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveBtnTouch = device->hasKey(BTN_TOUCH);
1270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveStylus = device->hasKey(BTN_TOOL_PEN)
1271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || device->hasKey(BTN_TOOL_RUBBER)
1272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || device->hasKey(BTN_TOOL_BRUSH)
1273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || device->hasKey(BTN_TOOL_PENCIL)
1274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || device->hasKey(BTN_TOOL_AIRBRUSH);
1275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchButtonAccumulator::reset(InputDevice* device) {
1278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnTouch = device->isKeyPressed(BTN_TOUCH);
1279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnStylus = device->isKeyPressed(BTN_STYLUS);
1280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnStylus2 = device->isKeyPressed(BTN_STYLUS);
1281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolFinger = device->isKeyPressed(BTN_TOOL_FINGER);
1282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolPen = device->isKeyPressed(BTN_TOOL_PEN);
1283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolRubber = device->isKeyPressed(BTN_TOOL_RUBBER);
1284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolBrush = device->isKeyPressed(BTN_TOOL_BRUSH);
1285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolPencil = device->isKeyPressed(BTN_TOOL_PENCIL);
1286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolAirbrush = device->isKeyPressed(BTN_TOOL_AIRBRUSH);
1287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolMouse = device->isKeyPressed(BTN_TOOL_MOUSE);
1288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolLens = device->isKeyPressed(BTN_TOOL_LENS);
1289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolDoubleTap = device->isKeyPressed(BTN_TOOL_DOUBLETAP);
1290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolTripleTap = device->isKeyPressed(BTN_TOOL_TRIPLETAP);
1291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolQuadTap = device->isKeyPressed(BTN_TOOL_QUADTAP);
1292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchButtonAccumulator::clearButtons() {
1295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnTouch = 0;
1296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnStylus = 0;
1297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnStylus2 = 0;
1298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolFinger = 0;
1299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolPen = 0;
1300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolRubber = 0;
1301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolBrush = 0;
1302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolPencil = 0;
1303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolAirbrush = 0;
1304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolMouse = 0;
1305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolLens = 0;
1306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolDoubleTap = 0;
1307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolTripleTap = 0;
1308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mBtnToolQuadTap = 0;
1309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchButtonAccumulator::process(const RawEvent* rawEvent) {
1312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_KEY) {
1313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (rawEvent->code) {
1314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOUCH:
1315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnTouch = rawEvent->value;
1316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_STYLUS:
1318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnStylus = rawEvent->value;
1319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_STYLUS2:
1321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnStylus2 = rawEvent->value;
1322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_FINGER:
1324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolFinger = rawEvent->value;
1325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_PEN:
1327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolPen = rawEvent->value;
1328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_RUBBER:
1330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolRubber = rawEvent->value;
1331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_BRUSH:
1333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolBrush = rawEvent->value;
1334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_PENCIL:
1336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolPencil = rawEvent->value;
1337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_AIRBRUSH:
1339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolAirbrush = rawEvent->value;
1340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_MOUSE:
1342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolMouse = rawEvent->value;
1343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_LENS:
1345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolLens = rawEvent->value;
1346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_DOUBLETAP:
1348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolDoubleTap = rawEvent->value;
1349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_TRIPLETAP:
1351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolTripleTap = rawEvent->value;
1352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case BTN_TOOL_QUADTAP:
1354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mBtnToolQuadTap = rawEvent->value;
1355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t TouchButtonAccumulator::getButtonState() const {
1361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t result = 0;
1362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnStylus) {
1363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        result |= AMOTION_EVENT_BUTTON_SECONDARY;
1364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnStylus2) {
1366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        result |= AMOTION_EVENT_BUTTON_TERTIARY;
1367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return result;
1369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t TouchButtonAccumulator::getToolType() const {
1372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnToolMouse || mBtnToolLens) {
1373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AMOTION_EVENT_TOOL_TYPE_MOUSE;
1374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnToolRubber) {
1376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AMOTION_EVENT_TOOL_TYPE_ERASER;
1377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnToolPen || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush) {
1379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AMOTION_EVENT_TOOL_TYPE_STYLUS;
1380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mBtnToolFinger || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap) {
1382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AMOTION_EVENT_TOOL_TYPE_FINGER;
1383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
1385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchButtonAccumulator::isToolActive() const {
1388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mBtnTouch || mBtnToolFinger || mBtnToolPen || mBtnToolRubber
1389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush
1390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mBtnToolMouse || mBtnToolLens
1391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap;
1392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchButtonAccumulator::isHovering() const {
1395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mHaveBtnTouch && !mBtnTouch;
1396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchButtonAccumulator::hasStylus() const {
1399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mHaveStylus;
1400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- RawPointerAxes ---
1404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightRawPointerAxes::RawPointerAxes() {
1406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clear();
1407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid RawPointerAxes::clear() {
1410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    x.clear();
1411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    y.clear();
1412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pressure.clear();
1413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    touchMajor.clear();
1414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    touchMinor.clear();
1415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    toolMajor.clear();
1416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    toolMinor.clear();
1417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    orientation.clear();
1418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    distance.clear();
1419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    tiltX.clear();
1420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    tiltY.clear();
1421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    trackingId.clear();
1422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    slot.clear();
1423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- RawPointerData ---
1427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightRawPointerData::RawPointerData() {
1429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clear();
1430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid RawPointerData::clear() {
1433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCount = 0;
1434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearIdBits();
1435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid RawPointerData::copyFrom(const RawPointerData& other) {
1438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCount = other.pointerCount;
1439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    hoveringIdBits = other.hoveringIdBits;
1440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    touchingIdBits = other.touchingIdBits;
1441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t i = 0; i < pointerCount; i++) {
1443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointers[i] = other.pointers[i];
1444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int id = pointers[i].id;
1446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        idToIndex[id] = other.idToIndex[id];
1447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const {
1451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float x = 0, y = 0;
1452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t count = touchingIdBits.count();
1453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (count) {
1454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (BitSet32 idBits(touchingIdBits); !idBits.isEmpty(); ) {
1455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = idBits.clearFirstMarkedBit();
1456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const Pointer& pointer = pointerForId(id);
1457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            x += pointer.x;
1458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            y += pointer.y;
1459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        x /= count;
1461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        y /= count;
1462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    *outX = x;
1464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    *outY = y;
1465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- CookedPointerData ---
1469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightCookedPointerData::CookedPointerData() {
1471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clear();
1472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CookedPointerData::clear() {
1475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCount = 0;
1476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    hoveringIdBits.clear();
1477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    touchingIdBits.clear();
1478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CookedPointerData::copyFrom(const CookedPointerData& other) {
1481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCount = other.pointerCount;
1482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    hoveringIdBits = other.hoveringIdBits;
1483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    touchingIdBits = other.touchingIdBits;
1484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t i = 0; i < pointerCount; i++) {
1486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerProperties[i].copyFrom(other.pointerProperties[i]);
1487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords[i].copyFrom(other.pointerCoords[i]);
1488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int id = pointerProperties[i].id;
1490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        idToIndex[id] = other.idToIndex[id];
1491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- SingleTouchMotionAccumulator ---
1496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightSingleTouchMotionAccumulator::SingleTouchMotionAccumulator() {
1498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clearAbsoluteAxes();
1499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SingleTouchMotionAccumulator::reset(InputDevice* device) {
1502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsX = device->getAbsoluteAxisValue(ABS_X);
1503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsY = device->getAbsoluteAxisValue(ABS_Y);
1504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsPressure = device->getAbsoluteAxisValue(ABS_PRESSURE);
1505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsToolWidth = device->getAbsoluteAxisValue(ABS_TOOL_WIDTH);
1506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsDistance = device->getAbsoluteAxisValue(ABS_DISTANCE);
1507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsTiltX = device->getAbsoluteAxisValue(ABS_TILT_X);
1508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsTiltY = device->getAbsoluteAxisValue(ABS_TILT_Y);
1509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SingleTouchMotionAccumulator::clearAbsoluteAxes() {
1512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsX = 0;
1513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsY = 0;
1514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsPressure = 0;
1515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsToolWidth = 0;
1516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsDistance = 0;
1517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsTiltX = 0;
1518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsTiltY = 0;
1519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SingleTouchMotionAccumulator::process(const RawEvent* rawEvent) {
1522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_ABS) {
1523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (rawEvent->code) {
1524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case ABS_X:
1525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mAbsX = rawEvent->value;
1526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case ABS_Y:
1528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mAbsY = rawEvent->value;
1529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case ABS_PRESSURE:
1531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mAbsPressure = rawEvent->value;
1532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case ABS_TOOL_WIDTH:
1534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mAbsToolWidth = rawEvent->value;
1535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case ABS_DISTANCE:
1537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mAbsDistance = rawEvent->value;
1538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case ABS_TILT_X:
1540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mAbsTiltX = rawEvent->value;
1541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case ABS_TILT_Y:
1543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mAbsTiltY = rawEvent->value;
1544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
1545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- MultiTouchMotionAccumulator ---
1551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightMultiTouchMotionAccumulator::MultiTouchMotionAccumulator() :
1553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentSlot(-1), mSlots(NULL), mSlotCount(0), mUsingSlotsProtocol(false),
1554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mHaveStylus(false) {
1555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightMultiTouchMotionAccumulator::~MultiTouchMotionAccumulator() {
1558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    delete[] mSlots;
1559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchMotionAccumulator::configure(InputDevice* device,
1562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t slotCount, bool usingSlotsProtocol) {
1563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mSlotCount = slotCount;
1564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mUsingSlotsProtocol = usingSlotsProtocol;
1565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveStylus = device->hasAbsoluteAxis(ABS_MT_TOOL_TYPE);
1566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    delete[] mSlots;
1568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mSlots = new Slot[slotCount];
1569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchMotionAccumulator::reset(InputDevice* device) {
1572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Unfortunately there is no way to read the initial contents of the slots.
1573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // So when we reset the accumulator, we must assume they are all zeroes.
1574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mUsingSlotsProtocol) {
1575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Query the driver for the current slot index and use it as the initial slot
1576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // before we start reading events from the device.  It is possible that the
1577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // current slot index will not be the same as it was when the first event was
1578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // written into the evdev buffer, which means the input mapper could start
1579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // out of sync with the initial state of the events in the evdev buffer.
1580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // In the extremely unlikely case that this happens, the data from
1581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // two slots will be confused until the next ABS_MT_SLOT event is received.
1582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // This can cause the touch point to "jump", but at least there will be
1583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // no stuck touches.
1584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t initialSlot;
1585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        status_t status = device->getEventHub()->getAbsoluteAxisValue(device->getId(),
1586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ABS_MT_SLOT, &initialSlot);
1587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (status) {
1588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Could not retrieve current multitouch slot index.  status=%d", status);
1589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            initialSlot = -1;
1590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        clearSlots(initialSlot);
1592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
1593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        clearSlots(-1);
1594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchMotionAccumulator::clearSlots(int32_t initialSlot) {
1598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mSlots) {
1599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < mSlotCount; i++) {
1600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSlots[i].clear();
1601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentSlot = initialSlot;
1604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
1607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_ABS) {
1608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool newSlot = false;
1609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mUsingSlotsProtocol) {
1610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (rawEvent->code == ABS_MT_SLOT) {
1611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentSlot = rawEvent->value;
1612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                newSlot = true;
1613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
1614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (mCurrentSlot < 0) {
1615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentSlot = 0;
1616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) {
1619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_POINTERS
1620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (newSlot) {
1621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGW("MultiTouch device emitted invalid slot index %d but it "
1622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        "should be between 0 and %d; ignoring this slot.",
1623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mCurrentSlot, mSlotCount - 1);
1624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
1625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
1626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
1627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            Slot* slot = &mSlots[mCurrentSlot];
1628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            switch (rawEvent->code) {
1630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_POSITION_X:
1631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTPositionX = rawEvent->value;
1633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_POSITION_Y:
1635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTPositionY = rawEvent->value;
1637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_TOUCH_MAJOR:
1639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTTouchMajor = rawEvent->value;
1641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_TOUCH_MINOR:
1643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTTouchMinor = rawEvent->value;
1645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mHaveAbsMTTouchMinor = true;
1646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_WIDTH_MAJOR:
1648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTWidthMajor = rawEvent->value;
1650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_WIDTH_MINOR:
1652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTWidthMinor = rawEvent->value;
1654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mHaveAbsMTWidthMinor = true;
1655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_ORIENTATION:
1657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTOrientation = rawEvent->value;
1659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_TRACKING_ID:
1661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (mUsingSlotsProtocol && rawEvent->value < 0) {
1662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    // The slot is no longer in use but it retains its previous contents,
1663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    // which may be reused for subsequent touches.
1664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    slot->mInUse = false;
1665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
1666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    slot->mInUse = true;
1667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    slot->mAbsMTTrackingId = rawEvent->value;
1668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
1669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_PRESSURE:
1671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTPressure = rawEvent->value;
1673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_DISTANCE:
1675d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTDistance = rawEvent->value;
1677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case ABS_MT_TOOL_TYPE:
1679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mInUse = true;
1680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mAbsMTToolType = rawEvent->value;
1681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slot->mHaveAbsMTToolType = true;
1682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
1683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
1684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
1686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
1687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentSlot += 1;
1688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchMotionAccumulator::finishSync() {
1692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!mUsingSlotsProtocol) {
1693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        clearSlots(-1);
1694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool MultiTouchMotionAccumulator::hasStylus() const {
1698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mHaveStylus;
1699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- MultiTouchMotionAccumulator::Slot ---
1703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightMultiTouchMotionAccumulator::Slot::Slot() {
1705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    clear();
1706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchMotionAccumulator::Slot::clear() {
1709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mInUse = false;
1710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveAbsMTTouchMinor = false;
1711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveAbsMTWidthMinor = false;
1712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mHaveAbsMTToolType = false;
1713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTPositionX = 0;
1714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTPositionY = 0;
1715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTTouchMajor = 0;
1716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTTouchMinor = 0;
1717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTWidthMajor = 0;
1718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTWidthMinor = 0;
1719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTOrientation = 0;
1720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTTrackingId = -1;
1721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTPressure = 0;
1722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTDistance = 0;
1723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mAbsMTToolType = 0;
1724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t MultiTouchMotionAccumulator::Slot::getToolType() const {
1727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mHaveAbsMTToolType) {
1728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mAbsMTToolType) {
1729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case MT_TOOL_FINGER:
1730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return AMOTION_EVENT_TOOL_TYPE_FINGER;
1731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case MT_TOOL_PEN:
1732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return AMOTION_EVENT_TOOL_TYPE_STYLUS;
1733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
1736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- InputMapper ---
1740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputMapper::InputMapper(InputDevice* device) :
1742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDevice(device), mContext(device->getContext()) {
1743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightInputMapper::~InputMapper() {
1746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
1749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    info->addSource(getSources());
1750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::dump(String8& dump) {
1753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::configure(nsecs_t when,
1756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const InputReaderConfiguration* config, uint32_t changes) {
1757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::reset(nsecs_t when) {
1760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::timeoutExpired(nsecs_t when) {
1763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1765d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
1766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AKEY_STATE_UNKNOWN;
1767d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1768d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1769d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
1770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AKEY_STATE_UNKNOWN;
1771d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
1774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AKEY_STATE_UNKNOWN;
1775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
1778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const int32_t* keyCodes, uint8_t* outFlags) {
1779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return false;
1780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
1783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t token) {
1784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::cancelVibrate(int32_t token) {
1787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t InputMapper::getMetaState() {
1790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return 0;
1791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::fadePointer() {
1794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatus_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo) {
1797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
1798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::bumpGeneration() {
1801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mDevice->bumpGeneration();
1802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid InputMapper::dumpRawAbsoluteAxisInfo(String8& dump,
1805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const RawAbsoluteAxisInfo& axis, const char* name) {
1806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (axis.valid) {
1807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d, resolution=%d\n",
1808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz, axis.resolution);
1809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
1810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "%s: unknown range\n", name);
1811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- SwitchInputMapper ---
1816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightSwitchInputMapper::SwitchInputMapper(InputDevice* device) :
1818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper(device), mUpdatedSwitchValues(0), mUpdatedSwitchMask(0) {
1819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightSwitchInputMapper::~SwitchInputMapper() {
1822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t SwitchInputMapper::getSources() {
1825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AINPUT_SOURCE_SWITCH;
1826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SwitchInputMapper::process(const RawEvent* rawEvent) {
1829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (rawEvent->type) {
1830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case EV_SW:
1831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        processSwitch(rawEvent->code, rawEvent->value);
1832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
1833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case EV_SYN:
1835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (rawEvent->code == SYN_REPORT) {
1836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            sync(rawEvent->when);
1837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SwitchInputMapper::processSwitch(int32_t switchCode, int32_t switchValue) {
1842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (switchCode >= 0 && switchCode < 32) {
1843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (switchValue) {
1844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mUpdatedSwitchValues |= 1 << switchCode;
1845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mUpdatedSwitchMask |= 1 << switchCode;
1847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SwitchInputMapper::sync(nsecs_t when) {
1851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mUpdatedSwitchMask) {
1852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifySwitchArgs args(when, 0, mUpdatedSwitchValues, mUpdatedSwitchMask);
1853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifySwitch(&args);
1854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mUpdatedSwitchValues = 0;
1856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mUpdatedSwitchMask = 0;
1857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
1861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getEventHub()->getSwitchState(getDeviceId(), switchCode);
1862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- VibratorInputMapper ---
1866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightVibratorInputMapper::VibratorInputMapper(InputDevice* device) :
1868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper(device), mVibrating(false) {
1869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightVibratorInputMapper::~VibratorInputMapper() {
1872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t VibratorInputMapper::getSources() {
1875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return 0;
1876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
1879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::populateDeviceInfo(info);
1880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    info->setVibrator(true);
1882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::process(const RawEvent* rawEvent) {
1885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // TODO: Handle FF_STATUS, although it does not seem to be widely supported.
1886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
1889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t token) {
1890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIBRATOR
1891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 patternStr;
1892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < patternSize; i++) {
1893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (i != 0) {
1894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            patternStr.append(", ");
1895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        patternStr.appendFormat("%lld", pattern[i]);
1897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ALOGD("vibrate: deviceId=%d, pattern=[%s], repeat=%ld, token=%d",
1899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getDeviceId(), patternStr.string(), repeat, token);
1900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
1901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1902d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mVibrating = true;
1903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    memcpy(mPattern, pattern, patternSize * sizeof(nsecs_t));
1904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPatternSize = patternSize;
1905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mRepeat = repeat;
1906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mToken = token;
1907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mIndex = -1;
1908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    nextStep();
1910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::cancelVibrate(int32_t token) {
1913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIBRATOR
1914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ALOGD("cancelVibrate: deviceId=%d, token=%d", getDeviceId(), token);
1915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
1916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mVibrating && mToken == token) {
1918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        stopVibrating();
1919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::timeoutExpired(nsecs_t when) {
1923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mVibrating) {
1924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (when >= mNextStepTime) {
1925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            nextStep();
1926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
1927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getContext()->requestTimeoutAtTime(mNextStepTime);
1928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::nextStep() {
1933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mIndex += 1;
1934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (size_t(mIndex) >= mPatternSize) {
1935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mRepeat < 0) {
1936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // We are done.
1937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            stopVibrating();
1938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return;
1939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
1940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mIndex = mRepeat;
1941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool vibratorOn = mIndex & 1;
1944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    nsecs_t duration = mPattern[mIndex];
1945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (vibratorOn) {
1946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIBRATOR
1947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("nextStep: sending vibrate deviceId=%d, duration=%lld",
1948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                getDeviceId(), duration);
1949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
1950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getEventHub()->vibrate(getDeviceId(), duration);
1951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
1952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIBRATOR
1953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("nextStep: sending cancel vibrate deviceId=%d", getDeviceId());
1954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
1955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getEventHub()->cancelVibrate(getDeviceId());
1956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
1957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
1958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mNextStepTime = now + duration;
1959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getContext()->requestTimeoutAtTime(mNextStepTime);
1960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIBRATOR
1961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ALOGD("nextStep: scheduled timeout in %0.3fms", duration * 0.000001f);
1962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
1963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::stopVibrating() {
1966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mVibrating = false;
1967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIBRATOR
1968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
1969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
1970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getEventHub()->cancelVibrate(getDeviceId());
1971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid VibratorInputMapper::dump(String8& dump) {
1974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT2 "Vibrator Input Mapper:\n");
1975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Vibrating: %s\n", toString(mVibrating));
1976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- KeyboardInputMapper ---
1980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightKeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
1982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t source, int32_t keyboardType) :
1983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper(device), mSource(source),
1984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mKeyboardType(keyboardType) {
1985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightKeyboardInputMapper::~KeyboardInputMapper() {
1988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t KeyboardInputMapper::getSources() {
1991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mSource;
1992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
1993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
1995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::populateDeviceInfo(info);
1996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
1997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    info->setKeyboardType(mKeyboardType);
1998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    info->setKeyCharacterMap(getEventHub()->getKeyCharacterMap(getDeviceId()));
1999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::dump(String8& dump) {
2002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT2 "Keyboard Input Mapper:\n");
2003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpParameters(dump);
2004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
2005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
200641d2f80739700a56fd6a670923a2966add8dae61Mark Salyzyn    dump.appendFormat(INDENT3 "KeyDowns: %zu keys currently down\n", mKeyDowns.size());
2007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mMetaState);
200841d2f80739700a56fd6a670923a2966add8dae61Mark Salyzyn    dump.appendFormat(INDENT3 "DownTime: %lld\n", (long long)mDownTime);
2009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::configure(nsecs_t when,
2013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const InputReaderConfiguration* config, uint32_t changes) {
2014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::configure(when, config, changes);
2015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes) { // first time only
2017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure basic parameters.
2018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        configureParameters();
2019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
2022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
2023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            DisplayViewport v;
2024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (config->getDisplayInfo(false /*external*/, &v)) {
2025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientation = v.orientation;
2026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
2027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientation = DISPLAY_ORIENTATION_0;
2028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
2029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
2030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientation = DISPLAY_ORIENTATION_0;
2031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::configureParameters() {
2036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.orientationAware = false;
2037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"),
2038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.orientationAware);
2039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.hasAssociatedDisplay = false;
2041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.orientationAware) {
2042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.hasAssociatedDisplay = true;
2043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2044dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright
2045dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright    mParameters.handlesKeyRepeat = false;
2046dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright    getDevice()->getConfiguration().tryGetProperty(String8("keyboard.handlesKeyRepeat"),
2047dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright            mParameters.handlesKeyRepeat);
2048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::dumpParameters(String8& dump) {
2051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT3 "Parameters:\n");
2052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
2053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mParameters.hasAssociatedDisplay));
2054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
2055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mParameters.orientationAware));
2056dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright    dump.appendFormat(INDENT4 "HandlesKeyRepeat: %s\n",
2057dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright            toString(mParameters.handlesKeyRepeat));
2058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::reset(nsecs_t when) {
2061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mMetaState = AMETA_NONE;
2062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mDownTime = 0;
2063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mKeyDowns.clear();
2064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentHidUsage = 0;
2065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    resetLedState();
2067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::reset(when);
2069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::process(const RawEvent* rawEvent) {
2072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (rawEvent->type) {
2073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case EV_KEY: {
2074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t scanCode = rawEvent->code;
2075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t usageCode = mCurrentHidUsage;
2076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentHidUsage = 0;
2077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (isKeyboardOrGamepadKey(scanCode)) {
2079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t keyCode;
2080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t flags;
2081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, &keyCode, &flags)) {
2082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                keyCode = AKEYCODE_UNKNOWN;
2083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                flags = 0;
2084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
2085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags);
2086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
2088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case EV_MSC: {
2090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (rawEvent->code == MSC_SCAN) {
2091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentHidUsage = rawEvent->value;
2092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
2094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case EV_SYN: {
2096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (rawEvent->code == SYN_REPORT) {
2097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentHidUsage = 0;
2098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
2104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return scanCode < BTN_MOUSE
2105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        || scanCode >= KEY_OK
2106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        || (scanCode >= BTN_MISC && scanCode < BTN_MOUSE)
2107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI);
2108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
2111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t scanCode, uint32_t policyFlags) {
2112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (down) {
2114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Rotate key codes according to orientation if needed.
2115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
2116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            keyCode = rotateKeyCode(keyCode, mOrientation);
2117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Add key down.
2120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ssize_t keyDownIndex = findKeyDown(scanCode);
2121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (keyDownIndex >= 0) {
2122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // key repeat, be sure to use same keycode as before in case of rotation
2123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
2124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
2125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // key down
2126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if ((policyFlags & POLICY_FLAG_VIRTUAL)
2127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && mContext->shouldDropVirtualKey(when,
2128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            getDevice(), keyCode, scanCode)) {
2129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return;
2130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
2131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mKeyDowns.push();
2133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            KeyDown& keyDown = mKeyDowns.editTop();
2134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            keyDown.keyCode = keyCode;
2135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            keyDown.scanCode = scanCode;
2136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDownTime = when;
2139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
2140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Remove key down.
2141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ssize_t keyDownIndex = findKeyDown(scanCode);
2142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (keyDownIndex >= 0) {
2143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // key up, be sure to use same keycode as before in case of rotation
2144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
2145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mKeyDowns.removeAt(size_t(keyDownIndex));
2146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
2147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // key was not actually down
2148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGI("Dropping key up from device %s because the key was not down.  "
2149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "keyCode=%d, scanCode=%d",
2150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    getDeviceName().string(), keyCode, scanCode);
2151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return;
2152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t oldMetaState = mMetaState;
2156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
2157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool metaStateChanged = oldMetaState != newMetaState;
2158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (metaStateChanged) {
2159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mMetaState = newMetaState;
2160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        updateLedState(false);
2161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    nsecs_t downTime = mDownTime;
2164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Key down on external an keyboard should wake the device.
2166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // We don't do this for internal keyboards to prevent them from waking up in your pocket.
2167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // For internal keyboards, the key layout file should specify the policy flags for
2168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // each wake key individually.
2169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // TODO: Use the input device configuration to control this behavior more finely.
2170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (down && getDevice()->isExternal()
2171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && !(policyFlags & (POLICY_FLAG_WAKE | POLICY_FLAG_WAKE_DROPPED))) {
2172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        policyFlags |= POLICY_FLAG_WAKE_DROPPED;
2173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2175dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright    if (mParameters.handlesKeyRepeat) {
2176dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright        policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
2177dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright    }
2178dcfcf5d0ae73b79af60da5e72c070c481ffb1189Michael Wright
2179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (metaStateChanged) {
2180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getContext()->updateGlobalMetaState();
2181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (down && !isMetaKey(keyCode)) {
2184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getContext()->fadePointer();
2185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
2188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
2189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
2190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getListener()->notifyKey(&args);
2191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
2194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t n = mKeyDowns.size();
2195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < n; i++) {
2196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mKeyDowns[i].scanCode == scanCode) {
2197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return i;
2198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return -1;
2201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
2204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
2205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
2208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
2209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
2212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const int32_t* keyCodes, uint8_t* outFlags) {
2213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
2214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t KeyboardInputMapper::getMetaState() {
2217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mMetaState;
2218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::resetLedState() {
2221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    initializeLedState(mCapsLockLedState, ALED_CAPS_LOCK);
2222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    initializeLedState(mNumLockLedState, ALED_NUM_LOCK);
2223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    initializeLedState(mScrollLockLedState, ALED_SCROLL_LOCK);
2224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    updateLedState(true);
2226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
2229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
2230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ledState.on = false;
2231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::updateLedState(bool reset) {
2234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    updateLedStateForModifier(mCapsLockLedState, ALED_CAPS_LOCK,
2235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            AMETA_CAPS_LOCK_ON, reset);
2236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    updateLedStateForModifier(mNumLockLedState, ALED_NUM_LOCK,
2237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            AMETA_NUM_LOCK_ON, reset);
2238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    updateLedStateForModifier(mScrollLockLedState, ALED_SCROLL_LOCK,
2239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            AMETA_SCROLL_LOCK_ON, reset);
2240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid KeyboardInputMapper::updateLedStateForModifier(LedState& ledState,
2243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t led, int32_t modifier, bool reset) {
2244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (ledState.avail) {
2245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool desiredState = (mMetaState & modifier) != 0;
2246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (reset || ledState.on != desiredState) {
2247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getEventHub()->setLedState(getDeviceId(), led, desiredState);
2248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ledState.on = desiredState;
2249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- CursorInputMapper ---
2255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightCursorInputMapper::CursorInputMapper(InputDevice* device) :
2257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper(device) {
2258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightCursorInputMapper::~CursorInputMapper() {
2261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t CursorInputMapper::getSources() {
2264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mSource;
2265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
2268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::populateDeviceInfo(info);
2269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.mode == Parameters::MODE_POINTER) {
2271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float minX, minY, maxX, maxY;
2272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
2273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f, 0.0f);
2274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f, 0.0f);
2275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
2277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale, 0.0f);
2278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale, 0.0f);
2279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
2281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCursorScrollAccumulator.haveRelativeVWheel()) {
2283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
2284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCursorScrollAccumulator.haveRelativeHWheel()) {
2286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
2287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::dump(String8& dump) {
2291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT2 "Cursor Input Mapper:\n");
2292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpParameters(dump);
2293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
2294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
2295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
2296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
2297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
2298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mCursorScrollAccumulator.haveRelativeVWheel()));
2299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
2300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mCursorScrollAccumulator.haveRelativeHWheel()));
2301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
2302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
2303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
2304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
2305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
230641d2f80739700a56fd6a670923a2966add8dae61Mark Salyzyn    dump.appendFormat(INDENT3 "DownTime: %lld\n", (long long)mDownTime);
2307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::configure(nsecs_t when,
2310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const InputReaderConfiguration* config, uint32_t changes) {
2311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::configure(when, config, changes);
2312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes) { // first time only
2314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCursorScrollAccumulator.configure(getDevice());
2315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure basic parameters.
2317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        configureParameters();
2318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure device mode.
2320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mParameters.mode) {
2321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Parameters::MODE_POINTER:
2322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSource = AINPUT_SOURCE_MOUSE;
2323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mXPrecision = 1.0f;
2324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mYPrecision = 1.0f;
2325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mXScale = 1.0f;
2326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mYScale = 1.0f;
2327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController = getPolicy()->obtainPointerController(getDeviceId());
2328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
2329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Parameters::MODE_NAVIGATION:
2330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSource = AINPUT_SOURCE_TRACKBALL;
2331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
2332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
2333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
2334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
2335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
2336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mVWheelScale = 1.0f;
2339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mHWheelScale = 1.0f;
2340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
2343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
2344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
2345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
2346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
2349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
2350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            DisplayViewport v;
2351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (config->getDisplayInfo(false /*external*/, &v)) {
2352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientation = v.orientation;
2353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
2354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientation = DISPLAY_ORIENTATION_0;
2355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
2356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
2357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientation = DISPLAY_ORIENTATION_0;
2358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bumpGeneration();
2360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::configureParameters() {
2364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.mode = Parameters::MODE_POINTER;
2365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 cursorModeString;
2366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (getDevice()->getConfiguration().tryGetProperty(String8("cursor.mode"), cursorModeString)) {
2367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (cursorModeString == "navigation") {
2368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.mode = Parameters::MODE_NAVIGATION;
2369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (cursorModeString != "pointer" && cursorModeString != "default") {
2370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
2371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.orientationAware = false;
2375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
2376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.orientationAware);
2377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.hasAssociatedDisplay = false;
2379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
2380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.hasAssociatedDisplay = true;
2381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::dumpParameters(String8& dump) {
2385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT3 "Parameters:\n");
2386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
2387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mParameters.hasAssociatedDisplay));
2388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mParameters.mode) {
2390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Parameters::MODE_POINTER:
2391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "Mode: pointer\n");
2392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
2393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Parameters::MODE_NAVIGATION:
2394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "Mode: navigation\n");
2395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
2396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
2397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(false);
2398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
2401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mParameters.orientationAware));
2402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::reset(nsecs_t when) {
2405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mButtonState = 0;
2406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mDownTime = 0;
2407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerVelocityControl.reset();
2409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mWheelXVelocityControl.reset();
2410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mWheelYVelocityControl.reset();
2411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorButtonAccumulator.reset(getDevice());
2413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorMotionAccumulator.reset(getDevice());
2414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorScrollAccumulator.reset(getDevice());
2415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::reset(when);
2417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::process(const RawEvent* rawEvent) {
2420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorButtonAccumulator.process(rawEvent);
2421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorMotionAccumulator.process(rawEvent);
2422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorScrollAccumulator.process(rawEvent);
2423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
2425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        sync(rawEvent->when);
2426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::sync(nsecs_t when) {
2430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t lastButtonState = mButtonState;
2431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
2432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mButtonState = currentButtonState;
2433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool wasDown = isPointerDown(lastButtonState);
2435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool down = isPointerDown(currentButtonState);
2436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool downChanged;
2437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!wasDown && down) {
2438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDownTime = when;
2439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        downChanged = true;
2440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (wasDown && !down) {
2441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        downChanged = true;
2442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
2443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        downChanged = false;
2444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    nsecs_t downTime = mDownTime;
2446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool buttonsChanged = currentButtonState != lastButtonState;
2447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool buttonsPressed = currentButtonState & ~lastButtonState;
2448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
2450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
2451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool moved = deltaX != 0 || deltaY != 0;
2452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Rotate delta according to orientation if needed.
2454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.orientationAware && mParameters.hasAssociatedDisplay
2455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && (deltaX != 0.0f || deltaY != 0.0f)) {
2456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        rotateDelta(mOrientation, &deltaX, &deltaY);
2457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Move the pointer.
2460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    PointerProperties pointerProperties;
2461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerProperties.clear();
2462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerProperties.id = 0;
2463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
2464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    PointerCoords pointerCoords;
2466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCoords.clear();
2467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float vscroll = mCursorScrollAccumulator.getRelativeVWheel();
2469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float hscroll = mCursorScrollAccumulator.getRelativeHWheel();
2470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool scrolled = vscroll != 0 || hscroll != 0;
2471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mWheelYVelocityControl.move(when, NULL, &vscroll);
2473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mWheelXVelocityControl.move(when, &hscroll, NULL);
2474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerVelocityControl.move(when, &deltaX, &deltaY);
2476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t displayId;
2478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerController != NULL) {
2479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (moved || scrolled || buttonsChanged) {
2480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->setPresentation(
2481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    PointerControllerInterface::PRESENTATION_POINTER);
2482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (moved) {
2484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerController->move(deltaX, deltaY);
2485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
2486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (buttonsChanged) {
2488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerController->setButtonState(currentButtonState);
2489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
2490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
2492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float x, y;
2495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->getPosition(&x, &y);
2496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
2497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
2498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        displayId = ADISPLAY_ID_DEFAULT;
2499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
2500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
2501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
2502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        displayId = ADISPLAY_ID_NONE;
2503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
2506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Moving an external trackball or mouse should wake the device.
2508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // We don't do this for internal cursor devices to prevent them from waking up
2509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // the device in your pocket.
2510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // TODO: Use the input device configuration to control this behavior more finely.
2511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t policyFlags = 0;
2512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if ((buttonsPressed || moved || scrolled) && getDevice()->isExternal()) {
2513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        policyFlags |= POLICY_FLAG_WAKE_DROPPED;
2514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Synthesize key down from buttons if needed.
2517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
2518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            policyFlags, lastButtonState, currentButtonState);
2519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Send motion event.
2521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (downChanged || moved || scrolled || buttonsChanged) {
2522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t metaState = mContext->getGlobalMetaState();
2523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t motionEventAction;
2524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (downChanged) {
2525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
2526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (down || mPointerController == NULL) {
2527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            motionEventAction = AMOTION_EVENT_ACTION_MOVE;
2528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
2529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
2530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
2533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                motionEventAction, 0, metaState, currentButtonState, 0,
2534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                displayId, 1, &pointerProperties, &pointerCoords,
2535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mXPrecision, mYPrecision, downTime);
2536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifyMotion(&args);
2537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send hover move after UP to tell the application that the mouse is hovering now.
2539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (motionEventAction == AMOTION_EVENT_ACTION_UP
2540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && mPointerController != NULL) {
2541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
2542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
2543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
2544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    displayId, 1, &pointerProperties, &pointerCoords,
2545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mXPrecision, mYPrecision, downTime);
2546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getListener()->notifyMotion(&hoverArgs);
2547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send scroll events.
2550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (scrolled) {
2551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
2552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
2553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
2555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
2556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_EDGE_FLAG_NONE,
2557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    displayId, 1, &pointerProperties, &pointerCoords,
2558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mXPrecision, mYPrecision, downTime);
2559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getListener()->notifyMotion(&scrollArgs);
2560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Synthesize key up from buttons if needed.
2564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
2565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            policyFlags, lastButtonState, currentButtonState);
2566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorMotionAccumulator.finishSync();
2568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorScrollAccumulator.finishSync();
2569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
2572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
2573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
2574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
2575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AKEY_STATE_UNKNOWN;
2576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid CursorInputMapper::fadePointer() {
2580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerController != NULL) {
2581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
2582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- TouchInputMapper ---
2587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightTouchInputMapper::TouchInputMapper(InputDevice* device) :
2589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper(device),
2590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
2591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSurfaceWidth(-1), mSurfaceHeight(-1), mSurfaceLeft(0), mSurfaceTop(0),
2592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSurfaceOrientation(DISPLAY_ORIENTATION_0) {
2593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightTouchInputMapper::~TouchInputMapper() {
2596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t TouchInputMapper::getSources() {
2599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mSource;
2600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
2603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::populateDeviceInfo(info);
2604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mDeviceMode != DEVICE_MODE_DISABLED) {
2606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(mOrientedRanges.x);
2607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(mOrientedRanges.y);
2608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(mOrientedRanges.pressure);
2609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mOrientedRanges.haveSize) {
2611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.size);
2612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mOrientedRanges.haveTouchSize) {
2615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.touchMajor);
2616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.touchMinor);
2617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mOrientedRanges.haveToolSize) {
2620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.toolMajor);
2621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.toolMinor);
2622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mOrientedRanges.haveOrientation) {
2625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.orientation);
2626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mOrientedRanges.haveDistance) {
2629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.distance);
2630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mOrientedRanges.haveTilt) {
2633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(mOrientedRanges.tilt);
2634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCursorScrollAccumulator.haveRelativeVWheel()) {
2637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
2638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    0.0f);
2639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCursorScrollAccumulator.haveRelativeHWheel()) {
2641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
2642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    0.0f);
2643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_BOX) {
2645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const InputDeviceInfo::MotionRange& x = mOrientedRanges.x;
2646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const InputDeviceInfo::MotionRange& y = mOrientedRanges.y;
2647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_1, mSource, x.min, x.max, x.flat,
2648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    x.fuzz, x.resolution);
2649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_2, mSource, y.min, y.max, y.flat,
2650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    y.fuzz, y.resolution);
2651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_3, mSource, x.min, x.max, x.flat,
2652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    x.fuzz, x.resolution);
2653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_4, mSource, y.min, y.max, y.flat,
2654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    y.fuzz, y.resolution);
2655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->setButtonUnderPad(mParameters.hasButtonUnderPad);
2657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dump(String8& dump) {
2661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT2 "Touch Input Mapper:\n");
2662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpParameters(dump);
2663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpVirtualKeys(dump);
2664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawPointerAxes(dump);
2665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpCalibration(dump);
2666af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dumpAffineTransformation(dump);
2667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpSurface(dump);
2668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
2670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "XTranslate: %0.3f\n", mXTranslate);
2671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "YTranslate: %0.3f\n", mYTranslate);
2672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "XScale: %0.3f\n", mXScale);
2673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "YScale: %0.3f\n", mYScale);
2674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision);
2675d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mYPrecision);
2676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mGeometricScale);
2677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mPressureScale);
2678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mSizeScale);
2679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mOrientationScale);
2680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mDistanceScale);
2681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "HaveTilt: %s\n", toString(mHaveTilt));
2682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "TiltXCenter: %0.3f\n", mTiltXCenter);
2683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "TiltXScale: %0.3f\n", mTiltXScale);
2684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "TiltYCenter: %0.3f\n", mTiltYCenter);
2685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "TiltYScale: %0.3f\n", mTiltYScale);
2686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Last Button State: 0x%08x\n", mLastButtonState);
2688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Last Raw Touch: pointerCount=%d\n",
2690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mLastRawPointerData.pointerCount);
2691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t i = 0; i < mLastRawPointerData.pointerCount; i++) {
2692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const RawPointerData::Pointer& pointer = mLastRawPointerData.pointers[i];
2693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
2694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
2695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "orientation=%d, tiltX=%d, tiltY=%d, distance=%d, "
2696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "toolType=%d, isHovering=%s\n", i,
2697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointer.id, pointer.x, pointer.y, pointer.pressure,
2698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointer.touchMajor, pointer.touchMinor,
2699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointer.toolMajor, pointer.toolMinor,
2700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointer.orientation, pointer.tiltX, pointer.tiltY, pointer.distance,
2701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointer.toolType, toString(pointer.isHovering));
2702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Last Cooked Touch: pointerCount=%d\n",
2705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mLastCookedPointerData.pointerCount);
2706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t i = 0; i < mLastCookedPointerData.pointerCount; i++) {
2707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerProperties& pointerProperties = mLastCookedPointerData.pointerProperties[i];
2708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerCoords& pointerCoords = mLastCookedPointerData.pointerCoords[i];
2709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "[%d]: id=%d, x=%0.3f, y=%0.3f, pressure=%0.3f, "
2710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "touchMajor=%0.3f, touchMinor=%0.3f, toolMajor=%0.3f, toolMinor=%0.3f, "
2711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "orientation=%0.3f, tilt=%0.3f, distance=%0.3f, "
2712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "toolType=%d, isHovering=%s\n", i,
2713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerProperties.id,
2714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getX(),
2715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getY(),
2716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
2722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TILT),
2723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE),
2724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerProperties.toolType,
2725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toString(mLastCookedPointerData.isHovering(i)));
2726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mDeviceMode == DEVICE_MODE_POINTER) {
2729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
2730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
2731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerXMovementScale);
2732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
2733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerYMovementScale);
2734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
2735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerXZoomScale);
2736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
2737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerYZoomScale);
2738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
2739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGestureMaxSwipeWidth);
2740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::configure(nsecs_t when,
2744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const InputReaderConfiguration* config, uint32_t changes) {
2745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::configure(when, config, changes);
2746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mConfig = *config;
2748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes) { // first time only
2750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure basic parameters.
2751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        configureParameters();
2752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure common accumulators.
2754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCursorScrollAccumulator.configure(getDevice());
2755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mTouchButtonAccumulator.configure(getDevice());
2756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure absolute axis information.
2758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        configureRawPointerAxes();
2759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Prepare input device calibration.
2761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        parseCalibration();
2762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        resolveCalibration();
2763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
276512d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke    if (!changes || (changes & InputReaderConfiguration::TOUCH_AFFINE_TRANSFORMATION)) {
276612d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke        // Update location calibration to reflect current settings
276712d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke        updateAffineTransformation();
276812d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke    }
276912d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke
2770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
2771d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Update pointer speed.
2772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerVelocityControl.setParameters(mConfig.pointerVelocityControlParameters);
2773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mWheelXVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
2774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mWheelYVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
2775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool resetNeeded = false;
2778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes || (changes & (InputReaderConfiguration::CHANGE_DISPLAY_INFO
2779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            | InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT
2780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            | InputReaderConfiguration::CHANGE_SHOW_TOUCHES))) {
2781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure device sources, surface dimensions, orientation and
2782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // scaling factors.
2783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        configureSurface(when, &resetNeeded);
2784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (changes && resetNeeded) {
2787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send reset, unless this is the first time the device has been configured,
2788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // in which case the reader will call reset itself after all mappers are ready.
2789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getDevice()->notifyReset(when);
2790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::configureParameters() {
2794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Use the pointer presentation mode for devices that do not support distinct
2795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // multitouch.  The spot-based presentation relies on being able to accurately
2796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // locate two or more fingers on the touch pad.
2797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.gestureMode = getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_SEMI_MT)
2798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ? Parameters::GESTURE_MODE_POINTER : Parameters::GESTURE_MODE_SPOTS;
2799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 gestureModeString;
2801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"),
2802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            gestureModeString)) {
2803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (gestureModeString == "pointer") {
2804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.gestureMode = Parameters::GESTURE_MODE_POINTER;
2805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (gestureModeString == "spots") {
2806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.gestureMode = Parameters::GESTURE_MODE_SPOTS;
2807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (gestureModeString != "default") {
2808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.string());
2809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) {
2813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The device is a touch screen.
2814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
2815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_POINTER)) {
2816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The device is a pointing device like a track pad.
2817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
2818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (getEventHub()->hasRelativeAxis(getDeviceId(), REL_X)
2819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || getEventHub()->hasRelativeAxis(getDeviceId(), REL_Y)) {
2820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The device is a cursor device with a touch pad attached.
2821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // By default don't use the touch pad to move the pointer.
2822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
2823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
2824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The device is a touch pad of unknown purpose.
2825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
2826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.hasButtonUnderPad=
2829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_BUTTONPAD);
2830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 deviceTypeString;
2832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
2833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            deviceTypeString)) {
2834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (deviceTypeString == "touchScreen") {
2835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
2836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (deviceTypeString == "touchPad") {
2837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
2838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (deviceTypeString == "touchNavigation") {
2839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_NAVIGATION;
2840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (deviceTypeString == "pointer") {
2841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
2842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (deviceTypeString != "default") {
2843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
2844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
2848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
2849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mParameters.orientationAware);
2850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.hasAssociatedDisplay = false;
2852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mParameters.associatedDisplayIsExternal = false;
2853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.orientationAware
2854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
2855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
2856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.hasAssociatedDisplay = true;
2857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mParameters.associatedDisplayIsExternal =
2858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
2859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        && getDevice()->isExternal();
2860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2861c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown
2862c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown    // Initial downs on external touch devices should wake the device.
2863c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown    // Normally we don't do this for internal touch screens to prevent them from waking
2864c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown    // up in your pocket but you can enable it using the input device configuration.
2865c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown    mParameters.wake = getDevice()->isExternal();
2866c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown    getDevice()->getConfiguration().tryGetProperty(String8("touch.wake"),
2867c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown            mParameters.wake);
2868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dumpParameters(String8& dump) {
2871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT3 "Parameters:\n");
2872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mParameters.gestureMode) {
2874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Parameters::GESTURE_MODE_POINTER:
2875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "GestureMode: pointer\n");
2876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
2877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Parameters::GESTURE_MODE_SPOTS:
2878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "GestureMode: spots\n");
2879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
2880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
2881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        assert(false);
2882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mParameters.deviceType) {
2885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
2886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "DeviceType: touchScreen\n");
2887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
2888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Parameters::DEVICE_TYPE_TOUCH_PAD:
2889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "DeviceType: touchPad\n");
2890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
2891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Parameters::DEVICE_TYPE_TOUCH_NAVIGATION:
2892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "DeviceType: touchNavigation\n");
2893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
2894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Parameters::DEVICE_TYPE_POINTER:
2895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "DeviceType: pointer\n");
2896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
2897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
2898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(false);
2899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s\n",
2902d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mParameters.hasAssociatedDisplay),
2903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mParameters.associatedDisplayIsExternal));
2904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
2905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(mParameters.orientationAware));
2906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::configureRawPointerAxes() {
2909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mRawPointerAxes.clear();
2910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dumpRawPointerAxes(String8& dump) {
2913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT3 "Raw Touch Axes:\n");
2914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.x, "X");
2915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.y, "Y");
2916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.pressure, "Pressure");
2917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMajor, "TouchMajor");
2918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMinor, "TouchMinor");
2919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMajor, "ToolMajor");
2920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMinor, "ToolMinor");
2921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.orientation, "Orientation");
2922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.distance, "Distance");
2923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltX, "TiltX");
2924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltY, "TiltY");
2925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.trackingId, "TrackingId");
2926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.slot, "Slot");
2927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
2928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
2930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t oldDeviceMode = mDeviceMode;
2931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Determine device mode.
2933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER
2934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && mConfig.pointerGesturesEnabled) {
2935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSource = AINPUT_SOURCE_MOUSE;
2936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDeviceMode = DEVICE_MODE_POINTER;
2937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (hasStylus()) {
2938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSource |= AINPUT_SOURCE_STYLUS;
2939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
2941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && mParameters.hasAssociatedDisplay) {
2942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSource = AINPUT_SOURCE_TOUCHSCREEN;
2943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDeviceMode = DEVICE_MODE_DIRECT;
2944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (hasStylus()) {
2945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSource |= AINPUT_SOURCE_STYLUS;
2946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_NAVIGATION) {
2948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSource = AINPUT_SOURCE_TOUCH_NAVIGATION;
2949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDeviceMode = DEVICE_MODE_NAVIGATION;
2950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
2951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSource = AINPUT_SOURCE_TOUCHPAD;
2952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDeviceMode = DEVICE_MODE_UNSCALED;
2953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Ensure we have valid X and Y axes.
2956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) {
2957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGW(INDENT "Touch device '%s' did not report support for X or Y axis!  "
2958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "The device will be inoperable.", getDeviceName().string());
2959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDeviceMode = DEVICE_MODE_DISABLED;
2960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
2961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Raw width and height in the natural orientation.
2964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
2965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
2966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Get associated display dimensions.
2968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    DisplayViewport newViewport;
2969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.hasAssociatedDisplay) {
2970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!mConfig.getDisplayInfo(mParameters.associatedDisplayIsExternal, &newViewport)) {
2971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGI(INDENT "Touch device '%s' could not query the properties of its associated "
2972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "display.  The device will be inoperable until the display size "
2973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "becomes available.",
2974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    getDeviceName().string());
2975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mDeviceMode = DEVICE_MODE_DISABLED;
2976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return;
2977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
2978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
2979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        newViewport.setNonDisplayViewport(rawWidth, rawHeight);
2980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
2981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool viewportChanged = mViewport != newViewport;
2982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (viewportChanged) {
2983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mViewport = newViewport;
2984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
2985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mDeviceMode == DEVICE_MODE_DIRECT || mDeviceMode == DEVICE_MODE_POINTER) {
2986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Convert rotated viewport to natural surface coordinates.
2987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t naturalLogicalWidth, naturalLogicalHeight;
2988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t naturalPhysicalWidth, naturalPhysicalHeight;
2989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t naturalPhysicalLeft, naturalPhysicalTop;
2990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t naturalDeviceWidth, naturalDeviceHeight;
2991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            switch (mViewport.orientation) {
2992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case DISPLAY_ORIENTATION_90:
2993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
2994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
2995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
2996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
2997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom;
2998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalTop = mViewport.physicalLeft;
2999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceWidth = mViewport.deviceHeight;
3000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceHeight = mViewport.deviceWidth;
3001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
3002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case DISPLAY_ORIENTATION_180:
3003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
3004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
3005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
3006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
3007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight;
3008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom;
3009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceWidth = mViewport.deviceWidth;
3010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceHeight = mViewport.deviceHeight;
3011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
3012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case DISPLAY_ORIENTATION_270:
3013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
3014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
3015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
3016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
3017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalLeft = mViewport.physicalTop;
3018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight;
3019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceWidth = mViewport.deviceHeight;
3020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceHeight = mViewport.deviceWidth;
3021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
3022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case DISPLAY_ORIENTATION_0:
3023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            default:
3024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
3025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
3026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
3027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
3028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalLeft = mViewport.physicalLeft;
3029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalPhysicalTop = mViewport.physicalTop;
3030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceWidth = mViewport.deviceWidth;
3031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                naturalDeviceHeight = mViewport.deviceHeight;
3032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
3033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
3036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
3037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
3038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceTop = naturalPhysicalTop * naturalLogicalHeight / naturalPhysicalHeight;
3039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceOrientation = mParameters.orientationAware ?
3041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mViewport.orientation : DISPLAY_ORIENTATION_0;
3042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
3043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceWidth = rawWidth;
3044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceHeight = rawHeight;
3045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceLeft = 0;
3046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceTop = 0;
3047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSurfaceOrientation = DISPLAY_ORIENTATION_0;
3048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // If moving between pointer modes, need to reset some state.
3052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool deviceModeChanged = mDeviceMode != oldDeviceMode;
3053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (deviceModeChanged) {
3054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.clear();
3055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Create pointer controller if needed.
3058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mDeviceMode == DEVICE_MODE_POINTER ||
3059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            (mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches)) {
3060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerController == NULL) {
3061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController = getPolicy()->obtainPointerController(getDeviceId());
3062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController.clear();
3065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (viewportChanged || deviceModeChanged) {
3068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
3069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "display id %d",
3070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                getDeviceId(), getDeviceName().string(), mSurfaceWidth, mSurfaceHeight,
3071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mSurfaceOrientation, mDeviceMode, mViewport.displayId);
3072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Configure X and Y factors.
3074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mXScale = float(mSurfaceWidth) / rawWidth;
3075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mYScale = float(mSurfaceHeight) / rawHeight;
3076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mXTranslate = -mSurfaceLeft;
3077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mYTranslate = -mSurfaceTop;
3078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mXPrecision = 1.0f / mXScale;
3079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mYPrecision = 1.0f / mYScale;
3080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
3082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.x.source = mSource;
3083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
3084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.y.source = mSource;
3085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        configureVirtualKeys();
3087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Scale factor for terms that are not oriented in a particular axis.
3089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // If the pixels are square then xScale == yScale otherwise we fake it
3090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // by choosing an average.
3091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mGeometricScale = avg(mXScale, mYScale);
3092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Size of diagonal axis.
3094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float diagonalSize = hypotf(mSurfaceWidth, mSurfaceHeight);
3095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Size factors.
3097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
3098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mRawPointerAxes.touchMajor.valid
3099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && mRawPointerAxes.touchMajor.maxValue != 0) {
3100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mSizeScale = 1.0f / mRawPointerAxes.touchMajor.maxValue;
3101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (mRawPointerAxes.toolMajor.valid
3102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && mRawPointerAxes.toolMajor.maxValue != 0) {
3103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mSizeScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
3104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
3105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mSizeScale = 0.0f;
3106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.haveTouchSize = true;
3109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.haveToolSize = true;
3110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.haveSize = true;
3111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
3113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMajor.source = mSource;
3114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMajor.min = 0;
3115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMajor.max = diagonalSize;
3116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMajor.flat = 0;
3117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMajor.fuzz = 0;
3118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMajor.resolution = 0;
3119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
3121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
3122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
3124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMajor.source = mSource;
3125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMajor.min = 0;
3126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMajor.max = diagonalSize;
3127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMajor.flat = 0;
3128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMajor.fuzz = 0;
3129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMajor.resolution = 0;
3130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMinor = mOrientedRanges.toolMajor;
3132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
3133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
3135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.size.source = mSource;
3136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.size.min = 0;
3137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.size.max = 1.0;
3138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.size.flat = 0;
3139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.size.fuzz = 0;
3140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.size.resolution = 0;
3141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
3142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSizeScale = 0.0f;
3143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Pressure factors.
3146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPressureScale = 0;
3147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
3148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                || mCalibration.pressureCalibration
3149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
3150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mCalibration.havePressureScale) {
3151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPressureScale = mCalibration.pressureScale;
3152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (mRawPointerAxes.pressure.valid
3153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && mRawPointerAxes.pressure.maxValue != 0) {
3154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPressureScale = 1.0f / mRawPointerAxes.pressure.maxValue;
3155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
3159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.pressure.source = mSource;
3160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.pressure.min = 0;
3161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.pressure.max = 1.0;
3162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.pressure.flat = 0;
3163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.pressure.fuzz = 0;
3164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientedRanges.pressure.resolution = 0;
3165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Tilt
3167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mTiltXCenter = 0;
3168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mTiltXScale = 0;
3169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mTiltYCenter = 0;
3170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mTiltYScale = 0;
3171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mHaveTilt = mRawPointerAxes.tiltX.valid && mRawPointerAxes.tiltY.valid;
3172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mHaveTilt) {
3173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mTiltXCenter = avg(mRawPointerAxes.tiltX.minValue,
3174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mRawPointerAxes.tiltX.maxValue);
3175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mTiltYCenter = avg(mRawPointerAxes.tiltY.minValue,
3176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mRawPointerAxes.tiltY.maxValue);
3177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mTiltXScale = M_PI / 180;
3178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mTiltYScale = M_PI / 180;
3179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.haveTilt = true;
3181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.tilt.axis = AMOTION_EVENT_AXIS_TILT;
3183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.tilt.source = mSource;
3184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.tilt.min = 0;
3185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.tilt.max = M_PI_2;
3186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.tilt.flat = 0;
3187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.tilt.fuzz = 0;
3188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.tilt.resolution = 0;
3189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Orientation
3192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mOrientationScale = 0;
3193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mHaveTilt) {
3194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.haveOrientation = true;
3195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
3197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.source = mSource;
3198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.min = -M_PI;
3199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.max = M_PI;
3200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.flat = 0;
3201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.fuzz = 0;
3202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.resolution = 0;
3203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (mCalibration.orientationCalibration !=
3204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                Calibration::ORIENTATION_CALIBRATION_NONE) {
3205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mCalibration.orientationCalibration
3206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
3207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (mRawPointerAxes.orientation.valid) {
3208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (mRawPointerAxes.orientation.maxValue > 0) {
3209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mOrientationScale = M_PI_2 / mRawPointerAxes.orientation.maxValue;
3210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    } else if (mRawPointerAxes.orientation.minValue < 0) {
3211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mOrientationScale = -M_PI_2 / mRawPointerAxes.orientation.minValue;
3212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    } else {
3213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mOrientationScale = 0;
3214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
3215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
3216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.haveOrientation = true;
3219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
3221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.source = mSource;
3222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.min = -M_PI_2;
3223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.max = M_PI_2;
3224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.flat = 0;
3225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.fuzz = 0;
3226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.orientation.resolution = 0;
3227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Distance
3230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDistanceScale = 0;
3231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.distanceCalibration != Calibration::DISTANCE_CALIBRATION_NONE) {
3232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mCalibration.distanceCalibration
3233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    == Calibration::DISTANCE_CALIBRATION_SCALED) {
3234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (mCalibration.haveDistanceScale) {
3235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mDistanceScale = mCalibration.distanceScale;
3236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
3237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mDistanceScale = 1.0f;
3238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
3239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.haveDistance = true;
3242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
3244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.distance.source = mSource;
3245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.distance.min =
3246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mRawPointerAxes.distance.minValue * mDistanceScale;
3247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.distance.max =
3248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mRawPointerAxes.distance.maxValue * mDistanceScale;
3249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.distance.flat = 0;
3250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.distance.fuzz =
3251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mRawPointerAxes.distance.fuzz * mDistanceScale;
3252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.distance.resolution = 0;
3253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Compute oriented precision, scales and ranges.
3256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Note that the maximum value reported is an inclusive maximum value so it is one
3257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // unit less than the total width or height of surface.
3258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mSurfaceOrientation) {
3259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case DISPLAY_ORIENTATION_90:
3260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case DISPLAY_ORIENTATION_270:
3261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedXPrecision = mYPrecision;
3262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedYPrecision = mXPrecision;
3263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.min = mYTranslate;
3265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.max = mSurfaceHeight + mYTranslate - 1;
3266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.flat = 0;
3267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.fuzz = 0;
3268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.resolution = mRawPointerAxes.y.resolution * mYScale;
3269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.min = mXTranslate;
3271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.max = mSurfaceWidth + mXTranslate - 1;
3272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.flat = 0;
3273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.fuzz = 0;
3274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.resolution = mRawPointerAxes.x.resolution * mXScale;
3275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
3276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        default:
3278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedXPrecision = mXPrecision;
3279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedYPrecision = mYPrecision;
3280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.min = mXTranslate;
3282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.max = mSurfaceWidth + mXTranslate - 1;
3283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.flat = 0;
3284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.fuzz = 0;
3285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.x.resolution = mRawPointerAxes.x.resolution * mXScale;
3286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.min = mYTranslate;
3288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.max = mSurfaceHeight + mYTranslate - 1;
3289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.flat = 0;
3290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.fuzz = 0;
3291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mOrientedRanges.y.resolution = mRawPointerAxes.y.resolution * mYScale;
3292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
3293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
329571b16e81f9cbf2e288611f32c43ea7fb4a331fcfJason Gerecke        // Location
329671b16e81f9cbf2e288611f32c43ea7fb4a331fcfJason Gerecke        updateAffineTransformation();
329771b16e81f9cbf2e288611f32c43ea7fb4a331fcfJason Gerecke
3298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mDeviceMode == DEVICE_MODE_POINTER) {
3299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Compute pointer gesture detection parameters.
3300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float rawDiagonal = hypotf(rawWidth, rawHeight);
3301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);
3302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Scale movements such that one whole swipe of the touch pad covers a
3304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // given area relative to the diagonal size of the display when no acceleration
3305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // is applied.
3306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Assume that the touch pad has a square aspect ratio such that movements in
3307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // X and Y of the same number of raw units cover the same physical distance.
3308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerXMovementScale = mConfig.pointerGestureMovementSpeedRatio
3309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    * displayDiagonal / rawDiagonal;
3310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerYMovementScale = mPointerXMovementScale;
3311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Scale zooms to cover a smaller range of the display than movements do.
3313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // This value determines the area around the pointer that is affected by freeform
3314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // pointer gestures.
3315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerXZoomScale = mConfig.pointerGestureZoomSpeedRatio
3316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    * displayDiagonal / rawDiagonal;
3317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerYZoomScale = mPointerXZoomScale;
3318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Max width between pointers to detect a swipe gesture is more than some fraction
3320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // of the diagonal axis of the touch pad.  Touches that are wider than this are
3321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // translated into freeform gestures.
3322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGestureMaxSwipeWidth =
3323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
3324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Abort current pointer usages because the state has changed.
3326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            abortPointerUsage(when, 0 /*policyFlags*/);
3327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Inform the dispatcher about the changes.
3330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *outResetNeeded = true;
3331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bumpGeneration();
3332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dumpSurface(String8& dump) {
3336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "Viewport: displayId=%d, orientation=%d, "
3337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            "logicalFrame=[%d, %d, %d, %d], "
3338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            "physicalFrame=[%d, %d, %d, %d], "
3339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            "deviceSize=[%d, %d]\n",
3340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mViewport.displayId, mViewport.orientation,
3341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mViewport.logicalLeft, mViewport.logicalTop,
3342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mViewport.logicalRight, mViewport.logicalBottom,
3343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mViewport.physicalLeft, mViewport.physicalTop,
3344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mViewport.physicalRight, mViewport.physicalBottom,
3345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mViewport.deviceWidth, mViewport.deviceHeight);
3346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
3348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
3349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
3350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
3351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
3352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::configureVirtualKeys() {
3355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    Vector<VirtualKeyDefinition> virtualKeyDefinitions;
3356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
3357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mVirtualKeys.clear();
3359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (virtualKeyDefinitions.size() == 0) {
3361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
3362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
3365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t touchScreenLeft = mRawPointerAxes.x.minValue;
3367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t touchScreenTop = mRawPointerAxes.y.minValue;
3368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t touchScreenWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
3369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t touchScreenHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
3370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
3372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const VirtualKeyDefinition& virtualKeyDefinition =
3373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                virtualKeyDefinitions[i];
3374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mVirtualKeys.add();
3376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        VirtualKey& virtualKey = mVirtualKeys.editTop();
3377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        virtualKey.scanCode = virtualKeyDefinition.scanCode;
3379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t keyCode;
3380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t flags;
3381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, &keyCode, &flags)) {
3382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
3383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    virtualKey.scanCode);
3384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mVirtualKeys.pop(); // drop the key
3385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            continue;
3386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        virtualKey.keyCode = keyCode;
3389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        virtualKey.flags = flags;
3390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // convert the key definition's display coordinates into touch coordinates for a hit box
3392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t halfWidth = virtualKeyDefinition.width / 2;
3393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t halfHeight = virtualKeyDefinition.height / 2;
3394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
3396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
3397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
3398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
3399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
3400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                * touchScreenHeight / mSurfaceHeight + touchScreenTop;
3401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
3402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                * touchScreenHeight / mSurfaceHeight + touchScreenTop;
3403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dumpVirtualKeys(String8& dump) {
3407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!mVirtualKeys.isEmpty()) {
3408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT3 "Virtual Keys:\n");
3409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < mVirtualKeys.size(); i++) {
3411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const VirtualKey& virtualKey = mVirtualKeys.itemAt(i);
341241d2f80739700a56fd6a670923a2966add8dae61Mark Salyzyn            dump.appendFormat(INDENT4 "%zu: scanCode=%d, keyCode=%d, "
3413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
3414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    i, virtualKey.scanCode, virtualKey.keyCode,
3415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    virtualKey.hitLeft, virtualKey.hitRight,
3416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    virtualKey.hitTop, virtualKey.hitBottom);
3417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::parseCalibration() {
3422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    const PropertyMap& in = getDevice()->getConfiguration();
3423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    Calibration& out = mCalibration;
3424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Size
3426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
3427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 sizeCalibrationString;
3428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) {
3429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (sizeCalibrationString == "none") {
3430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
3431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (sizeCalibrationString == "geometric") {
3432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
3433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (sizeCalibrationString == "diameter") {
3434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeCalibration = Calibration::SIZE_CALIBRATION_DIAMETER;
3435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (sizeCalibrationString == "box") {
3436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeCalibration = Calibration::SIZE_CALIBRATION_BOX;
3437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (sizeCalibrationString == "area") {
3438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeCalibration = Calibration::SIZE_CALIBRATION_AREA;
3439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (sizeCalibrationString != "default") {
3440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for touch.size.calibration: '%s'",
3441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    sizeCalibrationString.string());
3442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.haveSizeScale = in.tryGetProperty(String8("touch.size.scale"),
3446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeScale);
3447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.haveSizeBias = in.tryGetProperty(String8("touch.size.bias"),
3448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeBias);
3449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.haveSizeIsSummed = in.tryGetProperty(String8("touch.size.isSummed"),
3450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.sizeIsSummed);
3451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Pressure
3453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
3454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 pressureCalibrationString;
3455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) {
3456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (pressureCalibrationString == "none") {
3457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
3458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (pressureCalibrationString == "physical") {
3459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
3460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (pressureCalibrationString == "amplitude") {
3461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
3462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (pressureCalibrationString != "default") {
3463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for touch.pressure.calibration: '%s'",
3464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    pressureCalibrationString.string());
3465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
3469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.pressureScale);
3470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Orientation
3472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
3473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 orientationCalibrationString;
3474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) {
3475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (orientationCalibrationString == "none") {
3476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
3477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (orientationCalibrationString == "interpolated") {
3478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
3479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (orientationCalibrationString == "vector") {
3480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR;
3481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (orientationCalibrationString != "default") {
3482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for touch.orientation.calibration: '%s'",
3483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    orientationCalibrationString.string());
3484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Distance
3488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_DEFAULT;
3489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 distanceCalibrationString;
3490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (in.tryGetProperty(String8("touch.distance.calibration"), distanceCalibrationString)) {
3491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (distanceCalibrationString == "none") {
3492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
3493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (distanceCalibrationString == "scaled") {
3494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
3495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (distanceCalibrationString != "default") {
3496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for touch.distance.calibration: '%s'",
3497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    distanceCalibrationString.string());
3498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.haveDistanceScale = in.tryGetProperty(String8("touch.distance.scale"),
3502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.distanceScale);
3503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_DEFAULT;
3505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    String8 coverageCalibrationString;
3506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (in.tryGetProperty(String8("touch.coverage.calibration"), coverageCalibrationString)) {
3507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (coverageCalibrationString == "none") {
3508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_NONE;
3509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (coverageCalibrationString == "box") {
3510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_BOX;
3511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (coverageCalibrationString != "default") {
3512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("Invalid value for touch.coverage.calibration: '%s'",
3513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    coverageCalibrationString.string());
3514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::resolveCalibration() {
3519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Size
3520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mRawPointerAxes.touchMajor.valid || mRawPointerAxes.toolMajor.valid) {
3521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DEFAULT) {
3522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
3523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
3526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Pressure
3529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mRawPointerAxes.pressure.valid) {
3530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_DEFAULT) {
3531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
3532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
3535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Orientation
3538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mRawPointerAxes.orientation.valid) {
3539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.orientationCalibration == Calibration::ORIENTATION_CALIBRATION_DEFAULT) {
3540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
3541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
3544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Distance
3547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mRawPointerAxes.distance.valid) {
3548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.distanceCalibration == Calibration::DISTANCE_CALIBRATION_DEFAULT) {
3549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
3550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
3553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Coverage
3556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_DEFAULT) {
3557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCalibration.coverageCalibration = Calibration::COVERAGE_CALIBRATION_NONE;
3558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dumpCalibration(String8& dump) {
3562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT3 "Calibration:\n");
3563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Size
3565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mCalibration.sizeCalibration) {
3566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::SIZE_CALIBRATION_NONE:
3567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.size.calibration: none\n");
3568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::SIZE_CALIBRATION_GEOMETRIC:
3570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.size.calibration: geometric\n");
3571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::SIZE_CALIBRATION_DIAMETER:
3573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.size.calibration: diameter\n");
3574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::SIZE_CALIBRATION_BOX:
3576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.size.calibration: box\n");
3577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::SIZE_CALIBRATION_AREA:
3579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.size.calibration: area\n");
3580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
3582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(false);
3583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCalibration.haveSizeScale) {
3586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "touch.size.scale: %0.3f\n",
3587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCalibration.sizeScale);
3588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCalibration.haveSizeBias) {
3591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "touch.size.bias: %0.3f\n",
3592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCalibration.sizeBias);
3593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCalibration.haveSizeIsSummed) {
3596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "touch.size.isSummed: %s\n",
3597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toString(mCalibration.sizeIsSummed));
3598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Pressure
3601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mCalibration.pressureCalibration) {
3602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::PRESSURE_CALIBRATION_NONE:
3603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.pressure.calibration: none\n");
3604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
3606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.pressure.calibration: physical\n");
3607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
3609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.pressure.calibration: amplitude\n");
3610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
3612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(false);
3613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCalibration.havePressureScale) {
3616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n",
3617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCalibration.pressureScale);
3618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Orientation
3621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mCalibration.orientationCalibration) {
3622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::ORIENTATION_CALIBRATION_NONE:
3623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.orientation.calibration: none\n");
3624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
3626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.orientation.calibration: interpolated\n");
3627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::ORIENTATION_CALIBRATION_VECTOR:
3629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.orientation.calibration: vector\n");
3630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
3632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(false);
3633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Distance
3636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mCalibration.distanceCalibration) {
3637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::DISTANCE_CALIBRATION_NONE:
3638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.distance.calibration: none\n");
3639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::DISTANCE_CALIBRATION_SCALED:
3641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.distance.calibration: scaled\n");
3642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
3644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(false);
3645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCalibration.haveDistanceScale) {
3648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "touch.distance.scale: %0.3f\n",
3649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCalibration.distanceScale);
3650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mCalibration.coverageCalibration) {
3653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::COVERAGE_CALIBRATION_NONE:
3654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.coverage.calibration: none\n");
3655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case Calibration::COVERAGE_CALIBRATION_BOX:
3657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.append(INDENT4 "touch.coverage.calibration: box\n");
3658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
3659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
3660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(false);
3661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3664af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gereckevoid TouchInputMapper::dumpAffineTransformation(String8& dump) {
3665af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dump.append(INDENT3 "Affine Transformation:\n");
3666af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke
3667af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dump.appendFormat(INDENT4 "X scale: %0.3f\n", mAffineTransform.x_scale);
3668af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dump.appendFormat(INDENT4 "X ymix: %0.3f\n", mAffineTransform.x_ymix);
3669af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dump.appendFormat(INDENT4 "X offset: %0.3f\n", mAffineTransform.x_offset);
3670af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dump.appendFormat(INDENT4 "Y xmix: %0.3f\n", mAffineTransform.y_xmix);
3671af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dump.appendFormat(INDENT4 "Y scale: %0.3f\n", mAffineTransform.y_scale);
3672af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke    dump.appendFormat(INDENT4 "Y offset: %0.3f\n", mAffineTransform.y_offset);
3673af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke}
3674af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke
367512d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gereckevoid TouchInputMapper::updateAffineTransformation() {
367671b16e81f9cbf2e288611f32c43ea7fb4a331fcfJason Gerecke    mAffineTransform = getPolicy()->getTouchAffineTransformation(mDevice->getDescriptor(),
367771b16e81f9cbf2e288611f32c43ea7fb4a331fcfJason Gerecke            mSurfaceOrientation);
367812d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke}
367912d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke
3680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::reset(nsecs_t when) {
3681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorButtonAccumulator.reset(getDevice());
3682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorScrollAccumulator.reset(getDevice());
3683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mTouchButtonAccumulator.reset(getDevice());
3684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerVelocityControl.reset();
3686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mWheelXVelocityControl.reset();
3687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mWheelYVelocityControl.reset();
3688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentRawPointerData.clear();
3690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLastRawPointerData.clear();
3691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentCookedPointerData.clear();
3692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLastCookedPointerData.clear();
3693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentButtonState = 0;
3694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLastButtonState = 0;
3695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentRawVScroll = 0;
3696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentRawHScroll = 0;
3697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentFingerIdBits.clear();
3698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLastFingerIdBits.clear();
3699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentStylusIdBits.clear();
3700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLastStylusIdBits.clear();
3701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentMouseIdBits.clear();
3702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLastMouseIdBits.clear();
3703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerUsage = POINTER_USAGE_NONE;
3704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mSentHoverEnter = false;
3705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mDownTime = 0;
3706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentVirtualKey.down = false;
3708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerGesture.reset();
3710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerSimple.reset();
3711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerController != NULL) {
3713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
3714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->clearSpots();
3715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::reset(when);
3718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::process(const RawEvent* rawEvent) {
3721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorButtonAccumulator.process(rawEvent);
3722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorScrollAccumulator.process(rawEvent);
3723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mTouchButtonAccumulator.process(rawEvent);
3724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
3726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        sync(rawEvent->when);
3727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::sync(nsecs_t when) {
3731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Sync button state.
3732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
3733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            | mCursorButtonAccumulator.getButtonState();
3734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Sync scroll state.
3736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentRawVScroll = mCursorScrollAccumulator.getRelativeVWheel();
3737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentRawHScroll = mCursorScrollAccumulator.getRelativeHWheel();
3738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCursorScrollAccumulator.finishSync();
3739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Sync touch state.
3741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool havePointerIds = true;
3742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentRawPointerData.clear();
3743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    syncTouch(when, &havePointerIds);
3744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_RAW_EVENTS
3746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!havePointerIds) {
3747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("syncTouch: pointerCount %d -> %d, no pointer ids",
3748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mLastRawPointerData.pointerCount,
3749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentRawPointerData.pointerCount);
3750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("syncTouch: pointerCount %d -> %d, touching ids 0x%08x -> 0x%08x, "
3752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "hovering ids 0x%08x -> 0x%08x",
3753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mLastRawPointerData.pointerCount,
3754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentRawPointerData.pointerCount,
3755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mLastRawPointerData.touchingIdBits.value,
3756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentRawPointerData.touchingIdBits.value,
3757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mLastRawPointerData.hoveringIdBits.value,
3758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentRawPointerData.hoveringIdBits.value);
3759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
3761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Reset state that we will compute below.
3763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentFingerIdBits.clear();
3764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentStylusIdBits.clear();
3765d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentMouseIdBits.clear();
3766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentCookedPointerData.clear();
3767d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3768d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mDeviceMode == DEVICE_MODE_DISABLED) {
3769d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Drop all input if the device is disabled.
3770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentRawPointerData.clear();
3771d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentButtonState = 0;
3772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
3773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Preprocess pointer data.
3774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!havePointerIds) {
3775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            assignPointerIds();
3776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Handle policy on initial down or hover events.
3779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t policyFlags = 0;
3780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool initialDown = mLastRawPointerData.pointerCount == 0
3781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && mCurrentRawPointerData.pointerCount != 0;
3782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool buttonsPressed = mCurrentButtonState & ~mLastButtonState;
3783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (initialDown || buttonsPressed) {
3784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // If this is a touch screen, hide the pointer on an initial down.
3785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mDeviceMode == DEVICE_MODE_DIRECT) {
3786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                getContext()->fadePointer();
3787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3789c5e2442e59c427a921139722a7431e412f359dd8Jeff Brown            if (mParameters.wake) {
3790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                policyFlags |= POLICY_FLAG_WAKE_DROPPED;
3791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Synthesize key down from raw buttons if needed.
3795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
3796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                policyFlags, mLastButtonState, mCurrentButtonState);
3797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Consume raw off-screen touches before cooking pointer data.
3799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // If touches are consumed, subsequent code will not receive any pointer data.
3800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (consumeRawTouches(when, policyFlags)) {
3801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentRawPointerData.clear();
3802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Cook pointer data.  This call populates the mCurrentCookedPointerData structure
3805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // with cooked pointer data that has the same ids and indices as the raw data.
3806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The following code can use either the raw or cooked data, as needed.
3807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        cookPointerData();
3808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Dispatch the touches either directly or by translation through a pointer on screen.
3810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mDeviceMode == DEVICE_MODE_POINTER) {
3811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); ) {
3812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t id = idBits.clearFirstMarkedBit();
3813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
3814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
3815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
3816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentStylusIdBits.markBit(id);
3817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
3818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
3819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentFingerIdBits.markBit(id);
3820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_MOUSE) {
3821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentMouseIdBits.markBit(id);
3822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
3823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            for (BitSet32 idBits(mCurrentRawPointerData.hoveringIdBits); !idBits.isEmpty(); ) {
3825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t id = idBits.clearFirstMarkedBit();
3826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
3827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
3828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
3829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentStylusIdBits.markBit(id);
3830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
3831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Stylus takes precedence over all tools, then mouse, then finger.
3834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            PointerUsage pointerUsage = mPointerUsage;
3835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (!mCurrentStylusIdBits.isEmpty()) {
3836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentMouseIdBits.clear();
3837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentFingerIdBits.clear();
3838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerUsage = POINTER_USAGE_STYLUS;
3839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (!mCurrentMouseIdBits.isEmpty()) {
3840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentFingerIdBits.clear();
3841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerUsage = POINTER_USAGE_MOUSE;
3842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (!mCurrentFingerIdBits.isEmpty() || isPointerDown(mCurrentButtonState)) {
3843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                pointerUsage = POINTER_USAGE_GESTURES;
3844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchPointerUsage(when, policyFlags, pointerUsage);
3847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
3848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mDeviceMode == DEVICE_MODE_DIRECT
3849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && mConfig.showTouches && mPointerController != NULL) {
3850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
3851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
3852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerController->setButtonState(mCurrentButtonState);
3854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerController->setSpots(mCurrentCookedPointerData.pointerCoords,
3855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mCurrentCookedPointerData.idToIndex,
3856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mCurrentCookedPointerData.touchingIdBits);
3857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchHoverExit(when, policyFlags);
3860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchTouches(when, policyFlags);
3861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchHoverEnterAndMove(when, policyFlags);
3862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Synthesize key up from raw buttons if needed.
3865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
3866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                policyFlags, mLastButtonState, mCurrentButtonState);
3867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Copy current touch to last touch in preparation for the next cycle.
3870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLastRawPointerData.copyFrom(mCurrentRawPointerData);
3871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLastCookedPointerData.copyFrom(mCurrentCookedPointerData);
3872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLastButtonState = mCurrentButtonState;
3873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLastFingerIdBits = mCurrentFingerIdBits;
3874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLastStylusIdBits = mCurrentStylusIdBits;
3875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mLastMouseIdBits = mCurrentMouseIdBits;
3876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Clear some transient state.
3878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentRawVScroll = 0;
3879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentRawHScroll = 0;
3880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::timeoutExpired(nsecs_t when) {
3883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mDeviceMode == DEVICE_MODE_POINTER) {
3884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerUsage == POINTER_USAGE_GESTURES) {
3885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchPointerGestures(when, 0 /*policyFlags*/, true /*isTimeout*/);
3886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
3891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Check for release of a virtual key.
3892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCurrentVirtualKey.down) {
3893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCurrentRawPointerData.touchingIdBits.isEmpty()) {
3894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Pointer went up while virtual key was down.
3895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentVirtualKey.down = false;
3896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (!mCurrentVirtualKey.ignored) {
3897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIRTUAL_KEYS
3898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
3899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
3900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
3901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                dispatchVirtualKey(when, policyFlags,
3902d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        AKEY_EVENT_ACTION_UP,
3903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
3904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return true;
3906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
3909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
3910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
3911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
3912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
3913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Pointer is still within the space of the virtual key.
3914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return true;
3915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Pointer left virtual key area or another pointer also went down.
3919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send key cancellation but do not consume the touch yet.
3920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // This is useful when the user swipes through from the virtual key area
3921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // into the main display surface.
3922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentVirtualKey.down = false;
3923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!mCurrentVirtualKey.ignored) {
3924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIRTUAL_KEYS
3925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
3926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
3927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
3928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchVirtualKey(when, policyFlags,
3929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AKEY_EVENT_ACTION_UP,
3930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
3931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            | AKEY_EVENT_FLAG_CANCELED);
3932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mLastRawPointerData.touchingIdBits.isEmpty()
3936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
3937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Pointer just went down.  Check for virtual key press or off-screen touches.
3938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
3939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
3940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!isPointInsideSurface(pointer.x, pointer.y)) {
3941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // If exactly one pointer went down, check for virtual key hit.
3942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Otherwise we will drop the entire stroke.
3943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
3944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
3945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (virtualKey) {
3946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentVirtualKey.down = true;
3947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentVirtualKey.downTime = when;
3948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentVirtualKey.keyCode = virtualKey->keyCode;
3949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentVirtualKey.scanCode = virtualKey->scanCode;
3950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentVirtualKey.ignored = mContext->shouldDropVirtualKey(
3951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            when, getDevice(), virtualKey->keyCode, virtualKey->scanCode);
3952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (!mCurrentVirtualKey.ignored) {
3954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIRTUAL_KEYS
3955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ALOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
3956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                mCurrentVirtualKey.keyCode,
3957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                mCurrentVirtualKey.scanCode);
3958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
3959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        dispatchVirtualKey(when, policyFlags,
3960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                AKEY_EVENT_ACTION_DOWN,
3961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
3962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
3963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
3964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
3965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return true;
3966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
3967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Disable all virtual key touches that happen within a short time interval of the
3970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // most recent touch within the screen area.  The idea is to filter out stray
3971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // virtual key presses when interacting with the touch screen.
3972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //
3973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Problems we're trying to solve:
3974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //
3975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // 1. While scrolling a list or dragging the window shade, the user swipes down into a
3976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //    virtual key area that is implemented by a separate touch panel and accidentally
3977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //    triggers a virtual key.
3978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //
3979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
3980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //    area and accidentally triggers a virtual key.  This often happens when virtual keys
3981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //    are layed out below the screen near to where the on screen keyboard's space bar
3982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    //    is displayed.
3983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mConfig.virtualKeyQuietTime > 0 && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
3984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
3985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
3986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return false;
3987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
3988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
3990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t keyEventAction, int32_t keyEventFlags) {
3991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t keyCode = mCurrentVirtualKey.keyCode;
3992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t scanCode = mCurrentVirtualKey.scanCode;
3993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    nsecs_t downTime = mCurrentVirtualKey.downTime;
3994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t metaState = mContext->getGlobalMetaState();
3995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    policyFlags |= POLICY_FLAG_VIRTUAL;
3996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
3998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
3999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getListener()->notifyKey(&args);
4000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
4003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    BitSet32 currentIdBits = mCurrentCookedPointerData.touchingIdBits;
4004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    BitSet32 lastIdBits = mLastCookedPointerData.touchingIdBits;
4005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t metaState = getContext()->getGlobalMetaState();
4006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t buttonState = mCurrentButtonState;
4007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (currentIdBits == lastIdBits) {
4009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!currentIdBits.isEmpty()) {
4010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // No pointer id changes so this is a move event.
4011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // The listener takes care of batching moves so we don't have to deal with that here.
4012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchMotion(when, policyFlags, mSource,
4013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState,
4014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_EDGE_FLAG_NONE,
4015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentCookedPointerData.pointerProperties,
4016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentCookedPointerData.pointerCoords,
4017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentCookedPointerData.idToIndex,
4018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    currentIdBits, -1,
4019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
4022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // There may be pointers going up and pointers going down and pointers moving
4023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // all at the same time.
4024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value);
4025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
4026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
4027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 dispatchedIdBits(lastIdBits.value);
4028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Update last coordinates of pointers that have moved so that we observe the new
4030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // pointer positions at the same time as other pointers that have just gone up.
4031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool moveNeeded = updateMovedPointers(
4032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentCookedPointerData.pointerProperties,
4033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentCookedPointerData.pointerCoords,
4034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentCookedPointerData.idToIndex,
4035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mLastCookedPointerData.pointerProperties,
4036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mLastCookedPointerData.pointerCoords,
4037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mLastCookedPointerData.idToIndex,
4038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                moveIdBits);
4039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (buttonState != mLastButtonState) {
4040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            moveNeeded = true;
4041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Dispatch pointer up events.
4044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        while (!upIdBits.isEmpty()) {
4045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t upId = upIdBits.clearFirstMarkedBit();
4046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchMotion(when, policyFlags, mSource,
4048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_ACTION_POINTER_UP, 0, metaState, buttonState, 0,
4049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mLastCookedPointerData.pointerProperties,
4050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mLastCookedPointerData.pointerCoords,
4051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mLastCookedPointerData.idToIndex,
4052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    dispatchedIdBits, upId,
4053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchedIdBits.clearBit(upId);
4055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Dispatch move events if any of the remaining pointers moved from their old locations.
4058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Although applications receive new locations as part of individual pointer up
4059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // events, they do not generally handle them except when presented in a move event.
4060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (moveNeeded) {
4061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
4062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchMotion(when, policyFlags, mSource,
4063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0,
4064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentCookedPointerData.pointerProperties,
4065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentCookedPointerData.pointerCoords,
4066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentCookedPointerData.idToIndex,
4067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    dispatchedIdBits, -1,
4068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Dispatch pointer down events using the new pointer locations.
4072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        while (!downIdBits.isEmpty()) {
4073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t downId = downIdBits.clearFirstMarkedBit();
4074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchedIdBits.markBit(downId);
4075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (dispatchedIdBits.count() == 1) {
4077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // First pointer is going down.  Set down time.
4078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mDownTime = when;
4079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchMotion(when, policyFlags, mSource,
4082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
4083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentCookedPointerData.pointerProperties,
4084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentCookedPointerData.pointerCoords,
4085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentCookedPointerData.idToIndex,
4086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    dispatchedIdBits, downId,
4087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchHoverExit(nsecs_t when, uint32_t policyFlags) {
4093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mSentHoverEnter &&
4094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            (mCurrentCookedPointerData.hoveringIdBits.isEmpty()
4095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    || !mCurrentCookedPointerData.touchingIdBits.isEmpty())) {
4096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t metaState = getContext()->getGlobalMetaState();
4097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchMotion(when, policyFlags, mSource,
4098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
4099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mLastCookedPointerData.pointerProperties,
4100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mLastCookedPointerData.pointerCoords,
4101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mLastCookedPointerData.idToIndex,
4102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mLastCookedPointerData.hoveringIdBits, -1,
4103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mSentHoverEnter = false;
4105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags) {
4109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCurrentCookedPointerData.touchingIdBits.isEmpty()
4110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && !mCurrentCookedPointerData.hoveringIdBits.isEmpty()) {
4111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t metaState = getContext()->getGlobalMetaState();
4112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!mSentHoverEnter) {
4113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchMotion(when, policyFlags, mSource,
4114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
4115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentCookedPointerData.pointerProperties,
4116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentCookedPointerData.pointerCoords,
4117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentCookedPointerData.idToIndex,
4118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentCookedPointerData.hoveringIdBits, -1,
4119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mSentHoverEnter = true;
4121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchMotion(when, policyFlags, mSource,
4124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
4125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentCookedPointerData.pointerProperties,
4126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentCookedPointerData.pointerCoords,
4127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentCookedPointerData.idToIndex,
4128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentCookedPointerData.hoveringIdBits, -1,
4129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientedXPrecision, mOrientedYPrecision, mDownTime);
4130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::cookPointerData() {
4134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
4135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentCookedPointerData.clear();
4137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentCookedPointerData.pointerCount = currentPointerCount;
4138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentCookedPointerData.hoveringIdBits = mCurrentRawPointerData.hoveringIdBits;
4139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentCookedPointerData.touchingIdBits = mCurrentRawPointerData.touchingIdBits;
4140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Walk through the the active pointers and map device coordinates onto
4142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // surface coordinates and adjust for display orientation.
4143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t i = 0; i < currentPointerCount; i++) {
4144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const RawPointerData::Pointer& in = mCurrentRawPointerData.pointers[i];
4145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Size
4147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float touchMajor, touchMinor, toolMajor, toolMinor, size;
4148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mCalibration.sizeCalibration) {
4149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::SIZE_CALIBRATION_GEOMETRIC:
4150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::SIZE_CALIBRATION_DIAMETER:
4151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::SIZE_CALIBRATION_BOX:
4152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::SIZE_CALIBRATION_AREA:
4153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.toolMajor.valid) {
4154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMajor = in.touchMajor;
4155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMinor = mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
4156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMajor = in.toolMajor;
4157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMinor = mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
4158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                size = mRawPointerAxes.touchMinor.valid
4159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
4160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (mRawPointerAxes.touchMajor.valid) {
4161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMajor = touchMajor = in.touchMajor;
4162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMinor = touchMinor = mRawPointerAxes.touchMinor.valid
4163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ? in.touchMinor : in.touchMajor;
4164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                size = mRawPointerAxes.touchMinor.valid
4165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
4166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (mRawPointerAxes.toolMajor.valid) {
4167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMajor = toolMajor = in.toolMajor;
4168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMinor = toolMinor = mRawPointerAxes.toolMinor.valid
4169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ? in.toolMinor : in.toolMajor;
4170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                size = mRawPointerAxes.toolMinor.valid
4171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ? avg(in.toolMajor, in.toolMinor) : in.toolMajor;
4172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
4173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOG_ASSERT(false, "No touch or tool axes.  "
4174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        "Size calibration should have been resolved to NONE.");
4175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMajor = 0;
4176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMinor = 0;
4177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMajor = 0;
4178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMinor = 0;
4179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                size = 0;
4180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) {
4183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count();
4184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (touchingCount > 1) {
4185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    touchMajor /= touchingCount;
4186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    touchMinor /= touchingCount;
4187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    toolMajor /= touchingCount;
4188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    toolMinor /= touchingCount;
4189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    size /= touchingCount;
4190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
4191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_GEOMETRIC) {
4194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMajor *= mGeometricScale;
4195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMinor *= mGeometricScale;
4196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMajor *= mGeometricScale;
4197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMinor *= mGeometricScale;
4198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_AREA) {
4199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMajor = touchMajor > 0 ? sqrtf(touchMajor) : 0;
4200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMinor = touchMajor;
4201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMajor = toolMajor > 0 ? sqrtf(toolMajor) : 0;
4202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMinor = toolMajor;
4203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DIAMETER) {
4204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                touchMinor = touchMajor;
4205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                toolMinor = toolMajor;
4206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.applySizeScaleAndBias(&touchMajor);
4209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.applySizeScaleAndBias(&touchMinor);
4210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.applySizeScaleAndBias(&toolMajor);
4211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCalibration.applySizeScaleAndBias(&toolMinor);
4212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            size *= mSizeScale;
4213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        default:
4215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            touchMajor = 0;
4216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            touchMinor = 0;
4217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toolMajor = 0;
4218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toolMinor = 0;
4219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            size = 0;
4220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Pressure
4224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float pressure;
4225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mCalibration.pressureCalibration) {
4226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
4227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
4228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            pressure = in.pressure * mPressureScale;
4229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        default:
4231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            pressure = in.isHovering ? 0 : 1;
4232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Tilt and Orientation
4236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float tilt;
4237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float orientation;
4238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mHaveTilt) {
4239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float tiltXAngle = (in.tiltX - mTiltXCenter) * mTiltXScale;
4240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float tiltYAngle = (in.tiltY - mTiltYCenter) * mTiltYScale;
4241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
4242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
4243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
4244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            tilt = 0;
4245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            switch (mCalibration.orientationCalibration) {
4247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
4248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                orientation = in.orientation * mOrientationScale;
4249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
4250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case Calibration::ORIENTATION_CALIBRATION_VECTOR: {
4251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
4252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                int32_t c2 = signExtendNybble(in.orientation & 0x0f);
4253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (c1 != 0 || c2 != 0) {
4254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    orientation = atan2f(c1, c2) * 0.5f;
4255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float confidence = hypotf(c1, c2);
4256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float scale = 1.0f + confidence / 16.0f;
4257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    touchMajor *= scale;
4258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    touchMinor /= scale;
4259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    toolMajor *= scale;
4260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    toolMinor /= scale;
4261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
4262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    orientation = 0;
4263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
4264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
4265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            default:
4267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                orientation = 0;
4268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Distance
4272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float distance;
4273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mCalibration.distanceCalibration) {
4274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::DISTANCE_CALIBRATION_SCALED:
4275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            distance = in.distance * mDistanceScale;
4276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        default:
4278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            distance = 0;
4279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Coverage
4282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t rawLeft, rawTop, rawRight, rawBottom;
4283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mCalibration.coverageCalibration) {
4284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case Calibration::COVERAGE_CALIBRATION_BOX:
4285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rawLeft = (in.toolMinor & 0xffff0000) >> 16;
4286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rawRight = in.toolMinor & 0x0000ffff;
4287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rawBottom = in.toolMajor & 0x0000ffff;
4288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rawTop = (in.toolMajor & 0xffff0000) >> 16;
4289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        default:
4291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rawLeft = rawTop = rawRight = rawBottom = 0;
4292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4295af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke        // Adjust X,Y coords for device calibration
4296af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke        // TODO: Adjust coverage coords?
4297af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke        float xTransformed = in.x, yTransformed = in.y;
4298af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke        mAffineTransform.applyTo(xTransformed, yTransformed);
4299af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke
4300af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke        // Adjust X, Y, and coverage coords for surface orientation.
4301af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke        float x, y;
4302af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke        float left, top, right, bottom;
4303af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke
4304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (mSurfaceOrientation) {
4305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case DISPLAY_ORIENTATION_90:
4306af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            x = float(yTransformed - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
4307af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            y = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale + mXTranslate;
4308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
4309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            right = float(rawBottom- mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
4310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
4311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            top = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
4312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            orientation -= M_PI_2;
4313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (orientation < mOrientedRanges.orientation.min) {
4314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
4315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case DISPLAY_ORIENTATION_180:
4318af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            x = float(mRawPointerAxes.x.maxValue - xTransformed) * mXScale + mXTranslate;
4319af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            y = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
4320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
4321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
4322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
4323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
4324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            orientation -= M_PI;
4325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (orientation < mOrientedRanges.orientation.min) {
4326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
4327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case DISPLAY_ORIENTATION_270:
4330af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            x = float(mRawPointerAxes.y.maxValue - yTransformed) * mYScale + mYTranslate;
4331af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            y = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
4332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
4333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
4334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
4335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
4336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            orientation += M_PI_2;
4337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (orientation > mOrientedRanges.orientation.max) {
4338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                orientation -= (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
4339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        default:
4342af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            x = float(xTransformed - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
4343af126fb538c39d5488d62695b1bfb2990a3ef7dbJason Gerecke            y = float(yTransformed - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
4344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
4345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
4346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
4347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            top = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
4348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
4349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Write output coords.
4352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerCoords& out = mCurrentCookedPointerData.pointerCoords[i];
4353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.clear();
4354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
4355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
4356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
4357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
4358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
4359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
4360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
4361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);
4362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
4363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_BOX) {
4364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_1, left);
4365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_2, top);
4366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_3, right);
4367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_4, bottom);
4368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
4369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
4370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
4371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Write output properties.
4374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerProperties& properties = mCurrentCookedPointerData.pointerProperties[i];
4375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = in.id;
4376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        properties.clear();
4377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        properties.id = id;
4378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        properties.toolType = in.toolType;
4379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Write id index.
4381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentCookedPointerData.idToIndex[id] = i;
4382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchPointerUsage(nsecs_t when, uint32_t policyFlags,
4386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerUsage pointerUsage) {
4387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (pointerUsage != mPointerUsage) {
4388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        abortPointerUsage(when, policyFlags);
4389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerUsage = pointerUsage;
4390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mPointerUsage) {
4393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case POINTER_USAGE_GESTURES:
4394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
4395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case POINTER_USAGE_STYLUS:
4397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchPointerStylus(when, policyFlags);
4398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case POINTER_USAGE_MOUSE:
4400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchPointerMouse(when, policyFlags);
4401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
4403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::abortPointerUsage(nsecs_t when, uint32_t policyFlags) {
4408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mPointerUsage) {
4409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case POINTER_USAGE_GESTURES:
4410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        abortPointerGestures(when, policyFlags);
4411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case POINTER_USAGE_STYLUS:
4413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        abortPointerStylus(when, policyFlags);
4414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case POINTER_USAGE_MOUSE:
4416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        abortPointerMouse(when, policyFlags);
4417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
4419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerUsage = POINTER_USAGE_NONE;
4423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags,
4426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool isTimeout) {
4427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Update current gesture coordinates.
4428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool cancelPreviousGesture, finishPreviousGesture;
4429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool sendEvents = preparePointerGestures(when,
4430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            &cancelPreviousGesture, &finishPreviousGesture, isTimeout);
4431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!sendEvents) {
4432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
4433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (finishPreviousGesture) {
4435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        cancelPreviousGesture = false;
4436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Update the pointer presentation and spots.
4439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
4440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
4441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (finishPreviousGesture || cancelPreviousGesture) {
4442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->clearSpots();
4443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->setSpots(mPointerGesture.currentGestureCoords,
4445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureIdToIndex,
4446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureIdBits);
4447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
4448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
4449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Show or hide the pointer if needed.
4452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (mPointerGesture.currentGestureMode) {
4453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::NEUTRAL:
4454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::QUIET:
4455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS
4456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && (mPointerGesture.lastGestureMode == PointerGesture::SWIPE
4457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)) {
4458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Remind the user of where the pointer is after finishing a gesture with spots.
4459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL);
4460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::TAP:
4463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::TAP_DRAG:
4464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::BUTTON_CLICK_OR_DRAG:
4465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::HOVER:
4466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::PRESS:
4467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Unfade the pointer when the current gesture manipulates the
4468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // area directly under the pointer.
4469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
4470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::SWIPE:
4472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case PointerGesture::FREEFORM:
4473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Fade the pointer when the current gesture manipulates a different
4474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // area and there are spots to guide the user experience.
4475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
4476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
4477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
4478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
4479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
4481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Send events!
4484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t metaState = getContext()->getGlobalMetaState();
4485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t buttonState = mCurrentButtonState;
4486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Update last coordinates of pointers that have moved so that we observe the new
4488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // pointer positions at the same time as other pointers that have just gone up.
4489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool down = mPointerGesture.currentGestureMode == PointerGesture::TAP
4490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG
4491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mPointerGesture.currentGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
4492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mPointerGesture.currentGestureMode == PointerGesture::PRESS
4493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mPointerGesture.currentGestureMode == PointerGesture::SWIPE
4494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mPointerGesture.currentGestureMode == PointerGesture::FREEFORM;
4495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool moveNeeded = false;
4496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (down && !cancelPreviousGesture && !finishPreviousGesture
4497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && !mPointerGesture.lastGestureIdBits.isEmpty()
4498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && !mPointerGesture.currentGestureIdBits.isEmpty()) {
4499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 movedGestureIdBits(mPointerGesture.currentGestureIdBits.value
4500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                & mPointerGesture.lastGestureIdBits.value);
4501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        moveNeeded = updateMovedPointers(mPointerGesture.currentGestureProperties,
4502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
4503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.lastGestureProperties,
4504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
4505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                movedGestureIdBits);
4506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (buttonState != mLastButtonState) {
4507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            moveNeeded = true;
4508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Send motion events for all pointers that went up or were canceled.
4512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    BitSet32 dispatchedGestureIdBits(mPointerGesture.lastGestureIdBits);
4513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!dispatchedGestureIdBits.isEmpty()) {
4514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (cancelPreviousGesture) {
4515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchMotion(when, policyFlags, mSource,
4516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
4517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_EDGE_FLAG_NONE,
4518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.lastGestureProperties,
4519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
4520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    dispatchedGestureIdBits, -1,
4521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    0, 0, mPointerGesture.downTime);
4522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchedGestureIdBits.clear();
4524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
4525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            BitSet32 upGestureIdBits;
4526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (finishPreviousGesture) {
4527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                upGestureIdBits = dispatchedGestureIdBits;
4528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
4529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                upGestureIdBits.value = dispatchedGestureIdBits.value
4530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        & ~mPointerGesture.currentGestureIdBits.value;
4531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            while (!upGestureIdBits.isEmpty()) {
4533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t id = upGestureIdBits.clearFirstMarkedBit();
4534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                dispatchMotion(when, policyFlags, mSource,
4536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        AMOTION_EVENT_ACTION_POINTER_UP, 0,
4537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
4538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mPointerGesture.lastGestureProperties,
4539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
4540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        dispatchedGestureIdBits, id,
4541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        0, 0, mPointerGesture.downTime);
4542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                dispatchedGestureIdBits.clearBit(id);
4544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Send motion events for all pointers that moved.
4549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (moveNeeded) {
4550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchMotion(when, policyFlags, mSource,
4551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
4552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureProperties,
4553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
4554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                dispatchedGestureIdBits, -1,
4555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                0, 0, mPointerGesture.downTime);
4556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Send motion events for all pointers that went down.
4559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (down) {
4560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 downGestureIdBits(mPointerGesture.currentGestureIdBits.value
4561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                & ~dispatchedGestureIdBits.value);
4562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        while (!downGestureIdBits.isEmpty()) {
4563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = downGestureIdBits.clearFirstMarkedBit();
4564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchedGestureIdBits.markBit(id);
4565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (dispatchedGestureIdBits.count() == 1) {
4567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.downTime = when;
4568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dispatchMotion(when, policyFlags, mSource,
4571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
4572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureProperties,
4573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
4574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    dispatchedGestureIdBits, id,
4575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    0, 0, mPointerGesture.downTime);
4576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Send motion events for hover.
4580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerGesture.currentGestureMode == PointerGesture::HOVER) {
4581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchMotion(when, policyFlags, mSource,
4582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
4583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
4584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureProperties,
4585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
4586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureIdBits, -1,
4587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                0, 0, mPointerGesture.downTime);
4588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (dispatchedGestureIdBits.isEmpty()
4589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && !mPointerGesture.lastGestureIdBits.isEmpty()) {
4590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Synthesize a hover move event after all pointers go up to indicate that
4591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // the pointer is hovering again even if the user is not currently touching
4592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // the touch pad.  This ensures that a view will receive a fresh hover enter
4593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // event after a tap.
4594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float x, y;
4595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->getPosition(&x, &y);
4596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerProperties pointerProperties;
4598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerProperties.clear();
4599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerProperties.id = 0;
4600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
4601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerCoords pointerCoords;
4603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.clear();
4604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
4605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
4606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
4608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
4609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
4610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mViewport.displayId, 1, &pointerProperties, &pointerCoords,
4611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                0, 0, mPointerGesture.downTime);
4612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifyMotion(&args);
4613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Update state.
4616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerGesture.lastGestureMode = mPointerGesture.currentGestureMode;
4617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!down) {
4618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.lastGestureIdBits.clear();
4619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
4620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.lastGestureIdBits = mPointerGesture.currentGestureIdBits;
4621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) {
4622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = idBits.clearFirstMarkedBit();
4623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
4624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.lastGestureProperties[index].copyFrom(
4625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureProperties[index]);
4626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.lastGestureCoords[index].copyFrom(
4627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureCoords[index]);
4628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.lastGestureIdToIndex[id] = index;
4629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::abortPointerGestures(nsecs_t when, uint32_t policyFlags) {
4634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Cancel previously dispatches pointers.
4635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!mPointerGesture.lastGestureIdBits.isEmpty()) {
4636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t metaState = getContext()->getGlobalMetaState();
4637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t buttonState = mCurrentButtonState;
4638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dispatchMotion(when, policyFlags, mSource,
4639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
4640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AMOTION_EVENT_EDGE_FLAG_NONE,
4641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.lastGestureProperties,
4642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
4643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.lastGestureIdBits, -1,
4644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                0, 0, mPointerGesture.downTime);
4645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Reset the current pointer gesture.
4648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerGesture.reset();
4649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerVelocityControl.reset();
4650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Remove any current spots.
4652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerController != NULL) {
4653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
4654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->clearSpots();
4655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
4657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchInputMapper::preparePointerGestures(nsecs_t when,
4659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout) {
4660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    *outCancelPreviousGesture = false;
4661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    *outFinishPreviousGesture = false;
4662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Handle TAP timeout.
4664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (isTimeout) {
4665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
4666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("Gestures: Processing timeout");
4667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
4670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
4671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // The tap/drag timeout has not yet expired.
4672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                getContext()->requestTimeoutAtTime(mPointerGesture.tapUpTime
4673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        + mConfig.pointerGestureTapDragInterval);
4674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
4675d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // The tap is finished.
4676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
4677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Gestures: TAP finished");
4678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                *outFinishPreviousGesture = true;
4680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.activeGestureId = -1;
4682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
4683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureIdBits.clear();
4684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerVelocityControl.reset();
4686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return true;
4687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // We did not handle this timeout.
4691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return false;
4692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    const uint32_t currentFingerCount = mCurrentFingerIdBits.count();
4695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    const uint32_t lastFingerCount = mLastFingerIdBits.count();
4696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Update the velocity tracker.
4698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    {
4699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        VelocityTracker::Position positions[MAX_POINTERS];
4700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t count = 0;
4701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); count++) {
4702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = idBits.clearFirstMarkedBit();
4703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
4704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            positions[count].x = pointer.x * mPointerXMovementScale;
4705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            positions[count].y = pointer.y * mPointerYMovementScale;
4706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.velocityTracker.addMovement(when,
4708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentFingerIdBits, positions);
4709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // If the gesture ever enters a mode other than TAP, HOVER or TAP_DRAG, without first returning
4712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // to NEUTRAL, then we should not generate tap event.
4713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerGesture.lastGestureMode != PointerGesture::HOVER
4714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && mPointerGesture.lastGestureMode != PointerGesture::TAP
4715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && mPointerGesture.lastGestureMode != PointerGesture::TAP_DRAG) {
4716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.resetTap();
4717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Pick a new active touch id if needed.
4720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Choose an arbitrary pointer that just went down, if there is one.
4721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Otherwise choose an arbitrary remaining pointer.
4722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // This guarantees we always have an active touch id when there is at least one pointer.
4723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // We keep the same active touch id for as long as possible.
4724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool activeTouchChanged = false;
4725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t lastActiveTouchId = mPointerGesture.activeTouchId;
4726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t activeTouchId = lastActiveTouchId;
4727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (activeTouchId < 0) {
4728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!mCurrentFingerIdBits.isEmpty()) {
4729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            activeTouchChanged = true;
4730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            activeTouchId = mPointerGesture.activeTouchId =
4731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentFingerIdBits.firstMarkedBit();
4732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.firstTouchTime = when;
4733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (!mCurrentFingerIdBits.hasBit(activeTouchId)) {
4735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        activeTouchChanged = true;
4736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!mCurrentFingerIdBits.isEmpty()) {
4737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            activeTouchId = mPointerGesture.activeTouchId =
4738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentFingerIdBits.firstMarkedBit();
4739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
4740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            activeTouchId = mPointerGesture.activeTouchId = -1;
4741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Determine whether we are in quiet time.
4745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool isQuietTime = false;
4746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (activeTouchId < 0) {
4747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.resetQuietTime();
4748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
4749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        isQuietTime = when < mPointerGesture.quietTime + mConfig.pointerGestureQuietInterval;
4750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!isQuietTime) {
4751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS
4752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    || mPointerGesture.lastGestureMode == PointerGesture::SWIPE
4753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)
4754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && currentFingerCount < 2) {
4755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Enter quiet time when exiting swipe or freeform state.
4756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // This is to prevent accidentally entering the hover state and flinging the
4757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // pointer when finishing a swipe and there is still one pointer left onscreen.
4758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                isQuietTime = true;
4759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else if (mPointerGesture.lastGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
4760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && currentFingerCount >= 2
4761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && !isPointerDown(mCurrentButtonState)) {
4762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Enter quiet time when releasing the button and there are still two or more
4763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // fingers down.  This may indicate that one finger was used to press the button
4764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // but it has not gone up yet.
4765d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                isQuietTime = true;
4766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4767d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (isQuietTime) {
4768d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.quietTime = when;
4769d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4771d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
4772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Switch states based on button and pointer state.
4774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (isQuietTime) {
4775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Case 1: Quiet time. (QUIET)
4776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
4777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime
4778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                + mConfig.pointerGestureQuietInterval - when) * 0.000001f);
4779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) {
4781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outFinishPreviousGesture = true;
4782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.activeGestureId = -1;
4785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureMode = PointerGesture::QUIET;
4786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureIdBits.clear();
4787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerVelocityControl.reset();
4789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (isPointerDown(mCurrentButtonState)) {
4790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG)
4791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The pointer follows the active touch point.
4792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Emit DOWN, MOVE, UP events at the pointer location.
4793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        //
4794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Only the active touch matters; other fingers are ignored.  This policy helps
4795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // to handle the case where the user places a second finger on the touch pad
4796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // to apply the necessary force to depress an integrated button below the surface.
4797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // We don't want the second finger to be delivered to applications.
4798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        //
4799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // For this to work well, we need to make sure to track the pointer that is really
4800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // active.  If the user first puts one finger down to click then adds another
4801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // finger to drag then the active pointer should switch to the finger that is
4802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // being dragged.
4803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
4804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("Gestures: BUTTON_CLICK_OR_DRAG activeTouchId=%d, "
4805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "currentFingerCount=%d", activeTouchId, currentFingerCount);
4806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Reset state when just starting.
4808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.lastGestureMode != PointerGesture::BUTTON_CLICK_OR_DRAG) {
4809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outFinishPreviousGesture = true;
4810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.activeGestureId = 0;
4811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Switch pointers if needed.
4814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Find the fastest pointer and follow it.
4815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (activeTouchId >= 0 && currentFingerCount > 1) {
4816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t bestId = -1;
4817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed;
4818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); ) {
4819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t id = idBits.clearFirstMarkedBit();
4820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                float vx, vy;
4821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
4822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float speed = hypotf(vx, vy);
4823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (speed > bestSpeed) {
4824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        bestId = id;
4825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        bestSpeed = speed;
4826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
4827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
4828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (bestId >= 0 && bestId != activeTouchId) {
4830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.activeTouchId = activeTouchId = bestId;
4831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                activeTouchChanged = true;
4832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
4833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Gestures: BUTTON_CLICK_OR_DRAG switched pointers, "
4834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        "bestId=%d, bestSpeed=%0.3f", bestId, bestSpeed);
4835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (activeTouchId >= 0 && mLastFingerIdBits.hasBit(activeTouchId)) {
4840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& currentPointer =
4841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentRawPointerData.pointerForId(activeTouchId);
4842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& lastPointer =
4843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mLastRawPointerData.pointerForId(activeTouchId);
4844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float deltaX = (currentPointer.x - lastPointer.x) * mPointerXMovementScale;
4845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float deltaY = (currentPointer.y - lastPointer.y) * mPointerYMovementScale;
4846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
4848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.move(when, &deltaX, &deltaY);
4849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Move the pointer using a relative motion.
4851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // When using spots, the click will occur at the position of the anchor
4852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // spot and all other spots will move there.
4853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->move(deltaX, deltaY);
4854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
4855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.reset();
4856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float x, y;
4859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->getPosition(&x, &y);
4860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureMode = PointerGesture::BUTTON_CLICK_OR_DRAG;
4862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureIdBits.clear();
4863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
4864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
4865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureProperties[0].clear();
4866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
4867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
4868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].clear();
4869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
4870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
4871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
4872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (currentFingerCount == 0) {
4873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Case 3. No fingers down and button is not pressed. (NEUTRAL)
4874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) {
4875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outFinishPreviousGesture = true;
4876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Watch for taps coming out of HOVER or TAP_DRAG mode.
4879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Checking for taps after TAP_DRAG allows us to detect double-taps.
4880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool tapped = false;
4881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER
4882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                || mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG)
4883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && lastFingerCount == 1) {
4884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) {
4885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                float x, y;
4886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerController->getPosition(&x, &y);
4887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
4888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
4889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
4890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: TAP");
4891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.tapUpTime = when;
4894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    getContext()->requestTimeoutAtTime(when
4895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            + mConfig.pointerGestureTapDragInterval);
4896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.activeGestureId = 0;
4898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureMode = PointerGesture::TAP;
4899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureIdBits.clear();
4900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureIdBits.markBit(
4901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            mPointerGesture.activeGestureId);
4902d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureIdToIndex[
4903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            mPointerGesture.activeGestureId] = 0;
4904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureProperties[0].clear();
4905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureProperties[0].id =
4906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            mPointerGesture.activeGestureId;
4907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureProperties[0].toolType =
4908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            AMOTION_EVENT_TOOL_TYPE_FINGER;
4909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureCoords[0].clear();
4910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureCoords[0].setAxisValue(
4911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            AMOTION_EVENT_AXIS_X, mPointerGesture.tapX);
4912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureCoords[0].setAxisValue(
4913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            AMOTION_EVENT_AXIS_Y, mPointerGesture.tapY);
4914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureCoords[0].setAxisValue(
4915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
4916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    tapped = true;
4918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
4919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
4920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: Not a TAP, deltaX=%f, deltaY=%f",
4921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            x - mPointerGesture.tapX,
4922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            y - mPointerGesture.tapY);
4923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
4925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
4926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
4927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (mPointerGesture.tapDownTime != LLONG_MIN) {
4928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: Not a TAP, %0.3fms since down",
4929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            (when - mPointerGesture.tapDownTime) * 0.000001f);
4930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
4931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: Not a TAP, incompatible mode transitions");
4932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
4933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerVelocityControl.reset();
4938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!tapped) {
4940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
4941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: NEUTRAL");
4942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.activeGestureId = -1;
4944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
4945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureIdBits.clear();
4946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else if (currentFingerCount == 1) {
4948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
4949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The pointer follows the active touch point.
4950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // When in HOVER, emit HOVER_MOVE events at the pointer location.
4951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // When in TAP_DRAG, emit MOVE events at the pointer location.
4952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(activeTouchId >= 0);
4953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureMode = PointerGesture::HOVER;
4955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
4956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
4957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                float x, y;
4958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerController->getPosition(&x, &y);
4959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
4960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
4961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
4962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
4963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
4964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: Not a TAP_DRAG, deltaX=%f, deltaY=%f",
4965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            x - mPointerGesture.tapX,
4966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            y - mPointerGesture.tapY);
4967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
4969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
4970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
4971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Gestures: Not a TAP_DRAG, %0.3fms time since up",
4972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        (when - mPointerGesture.tapUpTime) * 0.000001f);
4973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
4974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
4975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG) {
4976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
4977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mLastFingerIdBits.hasBit(activeTouchId)) {
4980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& currentPointer =
4981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentRawPointerData.pointerForId(activeTouchId);
4982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& lastPointer =
4983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mLastRawPointerData.pointerForId(activeTouchId);
4984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float deltaX = (currentPointer.x - lastPointer.x)
4985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    * mPointerXMovementScale;
4986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float deltaY = (currentPointer.y - lastPointer.y)
4987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    * mPointerYMovementScale;
4988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
4990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.move(when, &deltaX, &deltaY);
4991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Move the pointer using a relative motion.
4993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // When using spots, the hover or drag will occur at the position of the anchor spot.
4994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->move(deltaX, deltaY);
4995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
4996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.reset();
4997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
4998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
4999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool down;
5000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG) {
5001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: TAP_DRAG");
5003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            down = true;
5005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
5006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: HOVER");
5008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mPointerGesture.lastGestureMode != PointerGesture::HOVER) {
5010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                *outFinishPreviousGesture = true;
5011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.activeGestureId = 0;
5013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            down = false;
5014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float x, y;
5017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->getPosition(&x, &y);
5018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureIdBits.clear();
5020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
5021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
5022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureProperties[0].clear();
5023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
5024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureProperties[0].toolType =
5025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AMOTION_EVENT_TOOL_TYPE_FINGER;
5026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].clear();
5027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
5028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
5029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
5030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                down ? 1.0f : 0.0f);
5031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (lastFingerCount == 0 && currentFingerCount != 0) {
5033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.resetTap();
5034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.tapDownTime = when;
5035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.tapX = x;
5036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.tapY = y;
5037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
5039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Case 5. At least two fingers down, button is not pressed. (PRESS, SWIPE or FREEFORM)
5040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // We need to provide feedback for each finger that goes down so we cannot wait
5041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // for the fingers to move before deciding what to do.
5042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        //
5043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // The ambiguous case is deciding what to do when there are two fingers down but they
5044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // have not moved enough to determine whether they are part of a drag or part of a
5045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // freeform gesture, or just a press or long-press at the pointer location.
5046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        //
5047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // When there are two fingers we start with the PRESS hypothesis and we generate a
5048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // down at the pointer location.
5049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        //
5050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // When the two fingers move enough or when additional fingers are added, we make
5051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // a decision to transition into SWIPE or FREEFORM mode accordingly.
5052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOG_ASSERT(activeTouchId >= 0);
5053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool settled = when >= mPointerGesture.firstTouchTime
5055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                + mConfig.pointerGestureMultitouchSettleInterval;
5056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.lastGestureMode != PointerGesture::PRESS
5057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && mPointerGesture.lastGestureMode != PointerGesture::SWIPE
5058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
5059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outFinishPreviousGesture = true;
5060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (!settled && currentFingerCount > lastFingerCount) {
5061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Additional pointers have gone down but not yet settled.
5062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Reset the gesture.
5063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, "
5065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
5066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            + mConfig.pointerGestureMultitouchSettleInterval - when)
5067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            * 0.000001f);
5068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outCancelPreviousGesture = true;
5070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
5071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Continue previous gesture.
5072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureMode = mPointerGesture.lastGestureMode;
5073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (*outFinishPreviousGesture || *outCancelPreviousGesture) {
5076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureMode = PointerGesture::PRESS;
5077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.activeGestureId = 0;
5078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.referenceIdBits.clear();
5079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.reset();
5080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Use the centroid and pointer location as the reference points for the gesture.
5082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: Using centroid as reference for MULTITOUCH, "
5084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
5085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            + mConfig.pointerGestureMultitouchSettleInterval - when)
5086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            * 0.000001f);
5087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentRawPointerData.getCentroidOfTouchingPointers(
5089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    &mPointerGesture.referenceTouchX,
5090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    &mPointerGesture.referenceTouchY);
5091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->getPosition(&mPointerGesture.referenceGestureX,
5092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    &mPointerGesture.referenceGestureY);
5093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Clear the reference deltas for fingers not yet included in the reference calculation.
5096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (BitSet32 idBits(mCurrentFingerIdBits.value
5097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                & ~mPointerGesture.referenceIdBits.value); !idBits.isEmpty(); ) {
5098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = idBits.clearFirstMarkedBit();
5099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.referenceDeltas[id].dx = 0;
5100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.referenceDeltas[id].dy = 0;
5101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerGesture.referenceIdBits = mCurrentFingerIdBits;
5103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Add delta for all fingers and calculate a common movement delta.
5105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float commonDeltaX = 0, commonDeltaY = 0;
5106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 commonIdBits(mLastFingerIdBits.value
5107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                & mCurrentFingerIdBits.value);
5108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
5109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            bool first = (idBits == commonIdBits);
5110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = idBits.clearFirstMarkedBit();
5111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& cpd = mCurrentRawPointerData.pointerForId(id);
5112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& lpd = mLastRawPointerData.pointerForId(id);
5113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
5114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            delta.dx += cpd.x - lpd.x;
5115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            delta.dy += cpd.y - lpd.y;
5116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (first) {
5118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                commonDeltaX = delta.dx;
5119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                commonDeltaY = delta.dy;
5120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
5121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx);
5122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy);
5123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Consider transitions from PRESS to SWIPE or MULTITOUCH.
5127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) {
5128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float dist[MAX_POINTER_ID + 1];
5129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t distOverThreshold = 0;
5130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
5131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t id = idBits.clearFirstMarkedBit();
5132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
5133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                dist[id] = hypotf(delta.dx * mPointerXZoomScale,
5134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        delta.dy * mPointerYZoomScale);
5135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) {
5136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    distOverThreshold += 1;
5137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Only transition when at least two pointers have moved further than
5141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // the minimum distance threshold.
5142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (distOverThreshold >= 2) {
5143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (currentFingerCount > 2) {
5144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    // There are more than two pointers, switch to FREEFORM.
5145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2",
5147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            currentFingerCount);
5148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    *outCancelPreviousGesture = true;
5150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
5151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
5152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    // There are exactly two pointers.
5153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    BitSet32 idBits(mCurrentFingerIdBits);
5154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    uint32_t id1 = idBits.clearFirstMarkedBit();
5155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    uint32_t id2 = idBits.firstMarkedBit();
5156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    const RawPointerData::Pointer& p1 = mCurrentRawPointerData.pointerForId(id1);
5157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    const RawPointerData::Pointer& p2 = mCurrentRawPointerData.pointerForId(id2);
5158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float mutualDistance = distance(p1.x, p1.y, p2.x, p2.y);
5159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (mutualDistance > mPointerGestureMaxSwipeWidth) {
5160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        // There are two pointers but they are too far apart for a SWIPE,
5161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        // switch to FREEFORM.
5162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ALOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
5164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                mutualDistance, mPointerGestureMaxSwipeWidth);
5165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        *outCancelPreviousGesture = true;
5167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
5168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    } else {
5169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        // There are two pointers.  Wait for both pointers to start moving
5170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        // before deciding whether this is a SWIPE or FREEFORM gesture.
5171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        float dist1 = dist[id1];
5172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        float dist2 = dist[id2];
5173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        if (dist1 >= mConfig.pointerGestureMultitouchMinDistance
5174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                && dist2 >= mConfig.pointerGestureMultitouchMinDistance) {
5175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            // Calculate the dot product of the displacement vectors.
5176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            // When the vectors are oriented in approximately the same direction,
5177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            // the angle betweeen them is near zero and the cosine of the angle
5178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            // approches 1.0.  Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
5179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
5180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
5181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            float dx1 = delta1.dx * mPointerXZoomScale;
5182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            float dy1 = delta1.dy * mPointerYZoomScale;
5183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            float dx2 = delta2.dx * mPointerXZoomScale;
5184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            float dy2 = delta2.dy * mPointerYZoomScale;
5185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            float dot = dx1 * dx2 + dy1 * dy2;
5186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            float cosine = dot / (dist1 * dist2); // denominator always > 0
5187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
5188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                // Pointers are moving in the same direction.  Switch to SWIPE.
5189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                ALOGD("Gestures: PRESS transitioned to SWIPE, "
5191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
5192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        "cosine %0.3f >= %0.3f",
5193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        dist1, mConfig.pointerGestureMultitouchMinDistance,
5194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        dist2, mConfig.pointerGestureMultitouchMinDistance,
5195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
5196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
5198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            } else {
5199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                // Pointers are moving in different directions.  Switch to FREEFORM.
5200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                ALOGD("Gestures: PRESS transitioned to FREEFORM, "
5202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
5203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        "cosine %0.3f < %0.3f",
5204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        dist1, mConfig.pointerGestureMultitouchMinDistance,
5205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        dist2, mConfig.pointerGestureMultitouchMinDistance,
5206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                        cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
5207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                *outCancelPreviousGesture = true;
5209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
5210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            }
5211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        }
5212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
5213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
5216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Switch from SWIPE to FREEFORM if additional pointers go down.
5217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Cancel previous gesture.
5218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (currentFingerCount > 2) {
5219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Gestures: SWIPE transitioned to FREEFORM, number of pointers %d > 2",
5221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        currentFingerCount);
5222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                *outCancelPreviousGesture = true;
5224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
5225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Move the reference points based on the overall group motion of the fingers
5229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // except in PRESS mode while waiting for a transition to occur.
5230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.currentGestureMode != PointerGesture::PRESS
5231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && (commonDeltaX || commonDeltaY)) {
5232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
5233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t id = idBits.clearFirstMarkedBit();
5234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
5235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                delta.dx = 0;
5236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                delta.dy = 0;
5237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.referenceTouchX += commonDeltaX;
5240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.referenceTouchY += commonDeltaY;
5241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            commonDeltaX *= mPointerXMovementScale;
5243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            commonDeltaY *= mPointerYMovementScale;
5244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rotateDelta(mSurfaceOrientation, &commonDeltaX, &commonDeltaY);
5246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
5247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.referenceGestureX += commonDeltaX;
5249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.referenceGestureY += commonDeltaY;
5250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Report gestures.
5253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mPointerGesture.currentGestureMode == PointerGesture::PRESS
5254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                || mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
5255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // PRESS or SWIPE mode.
5256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: PRESS or SWIPE activeTouchId=%d,"
5258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "activeGestureId=%d, currentTouchPointerCount=%d",
5259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
5260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
5262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureIdBits.clear();
5264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
5265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
5266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureProperties[0].clear();
5267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
5268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureProperties[0].toolType =
5269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_TOOL_TYPE_FINGER;
5270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureCoords[0].clear();
5271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
5272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.referenceGestureX);
5273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y,
5274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.referenceGestureY);
5275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
5276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
5277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // FREEFORM mode.
5278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: FREEFORM activeTouchId=%d,"
5280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "activeGestureId=%d, currentTouchPointerCount=%d",
5281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
5282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
5284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureIdBits.clear();
5286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            BitSet32 mappedTouchIdBits;
5288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            BitSet32 usedGestureIdBits;
5289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
5290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Initially, assign the active gesture id to the active touch point
5291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // if there is one.  No other touch id bits are mapped yet.
5292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (!*outCancelPreviousGesture) {
5293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mappedTouchIdBits.markBit(activeTouchId);
5294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    usedGestureIdBits.markBit(mPointerGesture.activeGestureId);
5295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.freeformTouchToGestureIdMap[activeTouchId] =
5296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            mPointerGesture.activeGestureId;
5297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
5298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.activeGestureId = -1;
5299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
5301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Otherwise, assume we mapped all touches from the previous frame.
5302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Reuse all mappings that are still applicable.
5303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mappedTouchIdBits.value = mLastFingerIdBits.value
5304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        & mCurrentFingerIdBits.value;
5305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                usedGestureIdBits = mPointerGesture.lastGestureIdBits;
5306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Check whether we need to choose a new active gesture id because the
5308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // current went went up.
5309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                for (BitSet32 upTouchIdBits(mLastFingerIdBits.value
5310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        & ~mCurrentFingerIdBits.value);
5311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        !upTouchIdBits.isEmpty(); ) {
5312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    uint32_t upTouchId = upTouchIdBits.clearFirstMarkedBit();
5313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    uint32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[upTouchId];
5314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (upGestureId == uint32_t(mPointerGesture.activeGestureId)) {
5315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mPointerGesture.activeGestureId = -1;
5316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        break;
5317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
5318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("Gestures: FREEFORM follow up "
5323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "mappedTouchIdBits=0x%08x, usedGestureIdBits=0x%08x, "
5324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "activeGestureId=%d",
5325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mappedTouchIdBits.value, usedGestureIdBits.value,
5326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.activeGestureId);
5327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            BitSet32 idBits(mCurrentFingerIdBits);
5330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            for (uint32_t i = 0; i < currentFingerCount; i++) {
5331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t touchId = idBits.clearFirstMarkedBit();
5332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint32_t gestureId;
5333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (!mappedTouchIdBits.hasBit(touchId)) {
5334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    gestureId = usedGestureIdBits.markFirstUnmarkedBit();
5335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerGesture.freeformTouchToGestureIdMap[touchId] = gestureId;
5336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: FREEFORM "
5338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            "new mapping for touch id %d -> gesture id %d",
5339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            touchId, gestureId);
5340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
5342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    gestureId = mPointerGesture.freeformTouchToGestureIdMap[touchId];
5343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("Gestures: FREEFORM "
5345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            "existing mapping for touch id %d -> gesture id %d",
5346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            touchId, gestureId);
5347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureIdBits.markBit(gestureId);
5350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureIdToIndex[gestureId] = i;
5351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                const RawPointerData::Pointer& pointer =
5353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mCurrentRawPointerData.pointerForId(touchId);
5354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                float deltaX = (pointer.x - mPointerGesture.referenceTouchX)
5355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        * mPointerXZoomScale;
5356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                float deltaY = (pointer.y - mPointerGesture.referenceTouchY)
5357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        * mPointerYZoomScale;
5358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
5359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureProperties[i].clear();
5361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureProperties[i].id = gestureId;
5362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureProperties[i].toolType =
5363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        AMOTION_EVENT_TOOL_TYPE_FINGER;
5364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureCoords[i].clear();
5365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureCoords[i].setAxisValue(
5366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        AMOTION_EVENT_AXIS_X, mPointerGesture.referenceGestureX + deltaX);
5367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureCoords[i].setAxisValue(
5368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY + deltaY);
5369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.currentGestureCoords[i].setAxisValue(
5370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
5371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (mPointerGesture.activeGestureId < 0) {
5374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerGesture.activeGestureId =
5375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        mPointerGesture.currentGestureIdBits.firstMarkedBit();
5376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("Gestures: FREEFORM new "
5378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        "activeGestureId=%d", mPointerGesture.activeGestureId);
5379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerController->setButtonState(mCurrentButtonState);
5385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_GESTURES
5387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ALOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
5388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            "currentGestureMode=%d, currentGestureIdBits=0x%08x, "
5389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            "lastGestureMode=%d, lastGestureIdBits=0x%08x",
5390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            toString(*outFinishPreviousGesture), toString(*outCancelPreviousGesture),
5391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIdBits.value,
5392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerGesture.lastGestureMode, mPointerGesture.lastGestureIdBits.value);
5393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (BitSet32 idBits = mPointerGesture.currentGestureIdBits; !idBits.isEmpty(); ) {
5394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = idBits.clearFirstMarkedBit();
5395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
5396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
5397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
5398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("  currentGesture[%d]: index=%d, toolType=%d, "
5399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "x=%0.3f, y=%0.3f, pressure=%0.3f",
5400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                id, index, properties.toolType,
5401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                coords.getAxisValue(AMOTION_EVENT_AXIS_X),
5402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
5403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
5404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (BitSet32 idBits = mPointerGesture.lastGestureIdBits; !idBits.isEmpty(); ) {
5406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = idBits.clearFirstMarkedBit();
5407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t index = mPointerGesture.lastGestureIdToIndex[id];
5408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
5409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
5410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("  lastGesture[%d]: index=%d, toolType=%d, "
5411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "x=%0.3f, y=%0.3f, pressure=%0.3f",
5412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                id, index, properties.toolType,
5413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                coords.getAxisValue(AMOTION_EVENT_AXIS_X),
5414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
5415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
5416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return true;
5419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchPointerStylus(nsecs_t when, uint32_t policyFlags) {
5422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerSimple.currentCoords.clear();
5423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerSimple.currentProperties.clear();
5424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool down, hovering;
5426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!mCurrentStylusIdBits.isEmpty()) {
5427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = mCurrentStylusIdBits.firstMarkedBit();
5428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t index = mCurrentCookedPointerData.idToIndex[id];
5429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float x = mCurrentCookedPointerData.pointerCoords[index].getX();
5430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float y = mCurrentCookedPointerData.pointerCoords[index].getY();
5431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->setPosition(x, y);
5432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        hovering = mCurrentCookedPointerData.hoveringIdBits.hasBit(id);
5434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        down = !hovering;
5435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->getPosition(&x, &y);
5437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentCoords.copyFrom(mCurrentCookedPointerData.pointerCoords[index]);
5438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
5439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
5440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentProperties.id = 0;
5441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentProperties.toolType =
5442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentCookedPointerData.pointerProperties[index].toolType;
5443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
5444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        down = false;
5445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        hovering = false;
5446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dispatchPointerSimple(when, policyFlags, down, hovering);
5449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::abortPointerStylus(nsecs_t when, uint32_t policyFlags) {
5452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    abortPointerSimple(when, policyFlags);
5453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchPointerMouse(nsecs_t when, uint32_t policyFlags) {
5456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerSimple.currentCoords.clear();
5457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerSimple.currentProperties.clear();
5458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool down, hovering;
5460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!mCurrentMouseIdBits.isEmpty()) {
5461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = mCurrentMouseIdBits.firstMarkedBit();
5462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t currentIndex = mCurrentRawPointerData.idToIndex[id];
5463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mLastMouseIdBits.hasBit(id)) {
5464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t lastIndex = mCurrentRawPointerData.idToIndex[id];
5465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float deltaX = (mCurrentRawPointerData.pointers[currentIndex].x
5466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    - mLastRawPointerData.pointers[lastIndex].x)
5467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    * mPointerXMovementScale;
5468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float deltaY = (mCurrentRawPointerData.pointers[currentIndex].y
5469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    - mLastRawPointerData.pointers[lastIndex].y)
5470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    * mPointerYMovementScale;
5471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
5473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.move(when, &deltaX, &deltaY);
5474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->move(deltaX, deltaY);
5476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
5477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerVelocityControl.reset();
5478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        down = isPointerDown(mCurrentButtonState);
5481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        hovering = !down;
5482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float x, y;
5484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->getPosition(&x, &y);
5485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentCoords.copyFrom(
5486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentCookedPointerData.pointerCoords[currentIndex]);
5487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
5488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
5489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
5490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                hovering ? 0.0f : 1.0f);
5491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentProperties.id = 0;
5492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.currentProperties.toolType =
5493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentCookedPointerData.pointerProperties[currentIndex].toolType;
5494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
5495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerVelocityControl.reset();
5496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        down = false;
5498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        hovering = false;
5499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dispatchPointerSimple(when, policyFlags, down, hovering);
5502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::abortPointerMouse(nsecs_t when, uint32_t policyFlags) {
5505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    abortPointerSimple(when, policyFlags);
5506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerVelocityControl.reset();
5508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
5511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool down, bool hovering) {
5512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t metaState = getContext()->getGlobalMetaState();
5513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerController != NULL) {
5515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (down || hovering) {
5516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
5517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->clearSpots();
5518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->setButtonState(mCurrentButtonState);
5519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
5520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
5521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
5522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerSimple.down && !down) {
5526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.down = false;
5527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send up.
5529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
5530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                 AMOTION_EVENT_ACTION_UP, 0, metaState, mLastButtonState, 0,
5531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                 mViewport.displayId,
5532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
5533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                 mOrientedXPrecision, mOrientedYPrecision,
5534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                 mPointerSimple.downTime);
5535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifyMotion(&args);
5536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerSimple.hovering && !hovering) {
5539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.hovering = false;
5540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send hover exit.
5542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
5543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
5544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mViewport.displayId,
5545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
5546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientedXPrecision, mOrientedYPrecision,
5547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerSimple.downTime);
5548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifyMotion(&args);
5549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (down) {
5552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!mPointerSimple.down) {
5553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerSimple.down = true;
5554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerSimple.downTime = when;
5555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Send down.
5557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
5558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_ACTION_DOWN, 0, metaState, mCurrentButtonState, 0,
5559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mViewport.displayId,
5560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
5561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mOrientedXPrecision, mOrientedYPrecision,
5562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerSimple.downTime);
5563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getListener()->notifyMotion(&args);
5564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send move.
5567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
5568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AMOTION_EVENT_ACTION_MOVE, 0, metaState, mCurrentButtonState, 0,
5569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mViewport.displayId,
5570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
5571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientedXPrecision, mOrientedYPrecision,
5572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerSimple.downTime);
5573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifyMotion(&args);
5574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (hovering) {
5577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!mPointerSimple.hovering) {
5578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mPointerSimple.hovering = true;
5579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Send hover enter.
5581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
5582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
5583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mViewport.displayId,
5584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
5585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mOrientedXPrecision, mOrientedYPrecision,
5586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerSimple.downTime);
5587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getListener()->notifyMotion(&args);
5588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5590d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send hover move.
5591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
5592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
5593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mViewport.displayId,
5594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
5595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientedXPrecision, mOrientedYPrecision,
5596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerSimple.downTime);
5597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifyMotion(&args);
5598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCurrentRawVScroll || mCurrentRawHScroll) {
5601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float vscroll = mCurrentRawVScroll;
5602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float hscroll = mCurrentRawHScroll;
5603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mWheelYVelocityControl.move(when, NULL, &vscroll);
5604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mWheelXVelocityControl.move(when, &hscroll, NULL);
5605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Send scroll.
5607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerCoords pointerCoords;
5608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.copyFrom(mPointerSimple.currentCoords);
5609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
5610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
5611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
5613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AMOTION_EVENT_ACTION_SCROLL, 0, metaState, mCurrentButtonState, 0,
5614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mViewport.displayId,
5615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                1, &mPointerSimple.currentProperties, &pointerCoords,
5616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mOrientedXPrecision, mOrientedYPrecision,
5617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mPointerSimple.downTime);
5618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        getListener()->notifyMotion(&args);
5619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Save state.
5622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (down || hovering) {
5623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.lastCoords.copyFrom(mPointerSimple.currentCoords);
5624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.lastProperties.copyFrom(mPointerSimple.currentProperties);
5625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
5626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerSimple.reset();
5627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::abortPointerSimple(nsecs_t when, uint32_t policyFlags) {
5631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerSimple.currentCoords.clear();
5632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerSimple.currentProperties.clear();
5633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dispatchPointerSimple(when, policyFlags, false, false);
5635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
5638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
5639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerProperties* properties, const PointerCoords* coords,
5640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const uint32_t* idToIndex, BitSet32 idBits,
5641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime) {
5642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    PointerCoords pointerCoords[MAX_POINTERS];
5643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    PointerProperties pointerProperties[MAX_POINTERS];
5644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t pointerCount = 0;
5645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    while (!idBits.isEmpty()) {
5646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = idBits.clearFirstMarkedBit();
5647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t index = idToIndex[id];
5648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerProperties[pointerCount].copyFrom(properties[index]);
5649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords[pointerCount].copyFrom(coords[index]);
5650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (changedId >= 0 && id == uint32_t(changedId)) {
5652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
5653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCount += 1;
5656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ALOG_ASSERT(pointerCount != 0);
5659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (changedId >= 0 && pointerCount == 1) {
5661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Replace initial down and final up action.
5662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // We can compare the action without masking off the changed pointer index
5663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // because we know the index is 0.
5664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
5665d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            action = AMOTION_EVENT_ACTION_DOWN;
5666d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
5667d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            action = AMOTION_EVENT_ACTION_UP;
5668d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
5669d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            // Can't happen.
5670d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOG_ASSERT(false);
5671d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5672d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5673d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5674d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
5675d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            action, flags, metaState, buttonState, edgeFlags,
5676d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mViewport.displayId, pointerCount, pointerProperties, pointerCoords,
5677d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            xPrecision, yPrecision, downTime);
5678d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getListener()->notifyMotion(&args);
5679d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5680d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5681d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties,
5682d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerCoords* inCoords, const uint32_t* inIdToIndex,
5683d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerProperties* outProperties, PointerCoords* outCoords, const uint32_t* outIdToIndex,
5684d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        BitSet32 idBits) const {
5685d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool changed = false;
5686d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    while (!idBits.isEmpty()) {
5687d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = idBits.clearFirstMarkedBit();
5688d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t inIndex = inIdToIndex[id];
5689d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t outIndex = outIdToIndex[id];
5690d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5691d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerProperties& curInProperties = inProperties[inIndex];
5692d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const PointerCoords& curInCoords = inCoords[inIndex];
5693d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerProperties& curOutProperties = outProperties[outIndex];
5694d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PointerCoords& curOutCoords = outCoords[outIndex];
5695d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5696d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (curInProperties != curOutProperties) {
5697d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            curOutProperties.copyFrom(curInProperties);
5698d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            changed = true;
5699d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5700d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5701d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (curInCoords != curOutCoords) {
5702d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            curOutCoords.copyFrom(curInCoords);
5703d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            changed = true;
5704d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5705d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5706d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return changed;
5707d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5708d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5709d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::fadePointer() {
5710d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mPointerController != NULL) {
5711d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
5712d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5713d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5714d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5715d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
5716d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
5717d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
5718d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5719d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5720d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightconst TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
5721d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t x, int32_t y) {
5722d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numVirtualKeys = mVirtualKeys.size();
5723d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numVirtualKeys; i++) {
5724d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const VirtualKey& virtualKey = mVirtualKeys[i];
5725d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5726d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_VIRTUAL_KEYS
5727d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
5728d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "left=%d, top=%d, right=%d, bottom=%d",
5729d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                x, y,
5730d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                virtualKey.keyCode, virtualKey.scanCode,
5731d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                virtualKey.hitLeft, virtualKey.hitTop,
5732d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                virtualKey.hitRight, virtualKey.hitBottom);
5733d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5734d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5735d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (virtualKey.isHit(x, y)) {
5736d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return & virtualKey;
5737d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5738d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5739d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5740d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return NULL;
5741d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5742d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5743d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid TouchInputMapper::assignPointerIds() {
5744d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
5745d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t lastPointerCount = mLastRawPointerData.pointerCount;
5746d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5747d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentRawPointerData.clearIdBits();
5748d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5749d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (currentPointerCount == 0) {
5750d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // No pointers to assign.
5751d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
5752d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5753d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5754d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (lastPointerCount == 0) {
5755d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // All pointers are new.
5756d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (uint32_t i = 0; i < currentPointerCount; i++) {
5757d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = i;
5758d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentRawPointerData.pointers[i].id = id;
5759d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentRawPointerData.idToIndex[id] = i;
5760d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(i));
5761d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5762d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
5763d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5764d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5765d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (currentPointerCount == 1 && lastPointerCount == 1
5766d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && mCurrentRawPointerData.pointers[0].toolType
5767d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    == mLastRawPointerData.pointers[0].toolType) {
5768d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Only one pointer and no change in count so it must have the same id as before.
5769d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = mLastRawPointerData.pointers[0].id;
5770d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentRawPointerData.pointers[0].id = id;
5771d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentRawPointerData.idToIndex[id] = 0;
5772d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(0));
5773d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
5774d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5775d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5776d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // General case.
5777d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // We build a heap of squared euclidean distances between current and last pointers
5778d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // associated with the current and last pointer indices.  Then, we find the best
5779d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // match (by distance) for each current pointer.
5780d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // The pointers must have the same tool type but it is possible for them to
5781d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // transition from hovering to touching or vice-versa while retaining the same id.
5782d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
5783d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5784d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t heapSize = 0;
5785d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
5786d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            currentPointerIndex++) {
5787d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
5788d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                lastPointerIndex++) {
5789d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& currentPointer =
5790d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentRawPointerData.pointers[currentPointerIndex];
5791d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const RawPointerData::Pointer& lastPointer =
5792d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mLastRawPointerData.pointers[lastPointerIndex];
5793d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (currentPointer.toolType == lastPointer.toolType) {
5794d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                int64_t deltaX = currentPointer.x - lastPointer.x;
5795d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                int64_t deltaY = currentPointer.y - lastPointer.y;
5796d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5797d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
5798d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5799d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Insert new element into the heap (sift up).
5800d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                heap[heapSize].currentPointerIndex = currentPointerIndex;
5801d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                heap[heapSize].lastPointerIndex = lastPointerIndex;
5802d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                heap[heapSize].distance = distance;
5803d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                heapSize += 1;
5804d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5805d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5806d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5807d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5808d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Heapify
5809d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
5810d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        startIndex -= 1;
5811d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (uint32_t parentIndex = startIndex; ;) {
5812d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t childIndex = parentIndex * 2 + 1;
5813d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (childIndex >= heapSize) {
5814d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
5815d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5816d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5817d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (childIndex + 1 < heapSize
5818d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    && heap[childIndex + 1].distance < heap[childIndex].distance) {
5819d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                childIndex += 1;
5820d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5821d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5822d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (heap[parentIndex].distance <= heap[childIndex].distance) {
5823d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
5824d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5825d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5826d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            swap(heap[parentIndex], heap[childIndex]);
5827d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            parentIndex = childIndex;
5828d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5829d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5830d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5831d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_POINTER_ASSIGNMENT
5832d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    ALOGD("assignPointerIds - initial distance min-heap: size=%d", heapSize);
5833d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < heapSize; i++) {
5834d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
5835d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
5836d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                heap[i].distance);
5837d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5838d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5839d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5840d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Pull matches out by increasing order of distance.
5841d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // To avoid reassigning pointers that have already been matched, the loop keeps track
5842d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // of which last and current pointers have been matched using the matchedXXXBits variables.
5843d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // It also tracks the used pointer id bits.
5844d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    BitSet32 matchedLastBits(0);
5845d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    BitSet32 matchedCurrentBits(0);
5846d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    BitSet32 usedIdBits(0);
5847d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool first = true;
5848d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t i = min(currentPointerCount, lastPointerCount); heapSize > 0 && i > 0; i--) {
5849d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        while (heapSize > 0) {
5850d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (first) {
5851d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // The first time through the loop, we just consume the root element of
5852d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // the heap (the one with smallest distance).
5853d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                first = false;
5854d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
5855d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Previous iterations consumed the root element of the heap.
5856d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Pop root element off of the heap (sift down).
5857d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                heap[0] = heap[heapSize];
5858d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                for (uint32_t parentIndex = 0; ;) {
5859d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    uint32_t childIndex = parentIndex * 2 + 1;
5860d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (childIndex >= heapSize) {
5861d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        break;
5862d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
5863d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5864d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (childIndex + 1 < heapSize
5865d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            && heap[childIndex + 1].distance < heap[childIndex].distance) {
5866d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        childIndex += 1;
5867d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
5868d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5869d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (heap[parentIndex].distance <= heap[childIndex].distance) {
5870d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        break;
5871d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
5872d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5873d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    swap(heap[parentIndex], heap[childIndex]);
5874d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    parentIndex = childIndex;
5875d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5876d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5877d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_POINTER_ASSIGNMENT
5878d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                ALOGD("assignPointerIds - reduced distance min-heap: size=%d", heapSize);
5879d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                for (size_t i = 0; i < heapSize; i++) {
5880d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
5881d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
5882d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            heap[i].distance);
5883d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5884d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5885d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5886d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5887d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            heapSize -= 1;
5888d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5889d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t currentPointerIndex = heap[0].currentPointerIndex;
5890d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
5891d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5892d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t lastPointerIndex = heap[0].lastPointerIndex;
5893d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
5894d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5895d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            matchedCurrentBits.markBit(currentPointerIndex);
5896d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            matchedLastBits.markBit(lastPointerIndex);
5897d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5898d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint32_t id = mLastRawPointerData.pointers[lastPointerIndex].id;
5899d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
5900d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
5901d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            mCurrentRawPointerData.markIdBit(id,
5902d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mCurrentRawPointerData.isHovering(currentPointerIndex));
5903d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            usedIdBits.markBit(id);
5904d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5905d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_POINTER_ASSIGNMENT
5906d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("assignPointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
5907d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    lastPointerIndex, currentPointerIndex, id, heap[0].distance);
5908d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5909d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
5910d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5911d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5912d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5913d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Assign fresh ids to pointers that were not matched in the process.
5914d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (uint32_t i = currentPointerCount - matchedCurrentBits.count(); i != 0; i--) {
5915d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t currentPointerIndex = matchedCurrentBits.markFirstUnmarkedBit();
5916d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t id = usedIdBits.markFirstUnmarkedBit();
5917d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5918d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
5919d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
5920d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentRawPointerData.markIdBit(id,
5921d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentRawPointerData.isHovering(currentPointerIndex));
5922d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5923d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_POINTER_ASSIGNMENT
5924d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGD("assignPointerIds - assigned: cur=%d, id=%d",
5925d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                currentPointerIndex, id);
5926d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
5927d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5928d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5929d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5930d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
5931d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
5932d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AKEY_STATE_VIRTUAL;
5933d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5934d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5935d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numVirtualKeys = mVirtualKeys.size();
5936d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numVirtualKeys; i++) {
5937d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const VirtualKey& virtualKey = mVirtualKeys[i];
5938d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (virtualKey.keyCode == keyCode) {
5939d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return AKEY_STATE_UP;
5940d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5941d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5942d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5943d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AKEY_STATE_UNKNOWN;
5944d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5945d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5946d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
5947d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
5948d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AKEY_STATE_VIRTUAL;
5949d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5950d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5951d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numVirtualKeys = mVirtualKeys.size();
5952d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numVirtualKeys; i++) {
5953d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const VirtualKey& virtualKey = mVirtualKeys[i];
5954d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (virtualKey.scanCode == scanCode) {
5955d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return AKEY_STATE_UP;
5956d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5957d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5958d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5959d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AKEY_STATE_UNKNOWN;
5960d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5961d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5962d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
5963d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const int32_t* keyCodes, uint8_t* outFlags) {
5964d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numVirtualKeys = mVirtualKeys.size();
5965d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numVirtualKeys; i++) {
5966d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const VirtualKey& virtualKey = mVirtualKeys[i];
5967d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5968d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < numCodes; i++) {
5969d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (virtualKey.keyCode == keyCodes[i]) {
5970d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                outFlags[i] = 1;
5971d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
5972d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
5973d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
5974d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5975d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return true;
5976d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5977d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5978d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5979d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- SingleTouchInputMapper ---
5980d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5981d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightSingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) :
5982d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        TouchInputMapper(device) {
5983d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5984d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5985d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightSingleTouchInputMapper::~SingleTouchInputMapper() {
5986d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5987d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5988d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SingleTouchInputMapper::reset(nsecs_t when) {
5989d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mSingleTouchMotionAccumulator.reset(getDevice());
5990d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5991d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    TouchInputMapper::reset(when);
5992d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5993d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5994d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SingleTouchInputMapper::process(const RawEvent* rawEvent) {
5995d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    TouchInputMapper::process(rawEvent);
5996d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5997d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mSingleTouchMotionAccumulator.process(rawEvent);
5998d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
5999d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6000d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SingleTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
6001d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mTouchButtonAccumulator.isToolActive()) {
6002d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentRawPointerData.pointerCount = 1;
6003d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentRawPointerData.idToIndex[0] = 0;
6004d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6005d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
6006d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && (mTouchButtonAccumulator.isHovering()
6007d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        || (mRawPointerAxes.pressure.valid
6008d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                                && mSingleTouchMotionAccumulator.getAbsolutePressure() <= 0));
6009d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mCurrentRawPointerData.markIdBit(0, isHovering);
6010d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6011d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[0];
6012d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.id = 0;
6013d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.x = mSingleTouchMotionAccumulator.getAbsoluteX();
6014d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.y = mSingleTouchMotionAccumulator.getAbsoluteY();
6015d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.pressure = mSingleTouchMotionAccumulator.getAbsolutePressure();
6016d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.touchMajor = 0;
6017d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.touchMinor = 0;
6018d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.toolMajor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
6019d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.toolMinor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
6020d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.orientation = 0;
6021d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.distance = mSingleTouchMotionAccumulator.getAbsoluteDistance();
6022d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.tiltX = mSingleTouchMotionAccumulator.getAbsoluteTiltX();
6023d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.tiltY = mSingleTouchMotionAccumulator.getAbsoluteTiltY();
6024d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.toolType = mTouchButtonAccumulator.getToolType();
6025d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
6026d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
6027d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6028d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.isHovering = isHovering;
6029d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6030d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6031d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6032d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid SingleTouchInputMapper::configureRawPointerAxes() {
6033d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    TouchInputMapper::configureRawPointerAxes();
6034d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6035d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_X, &mRawPointerAxes.x);
6036d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_Y, &mRawPointerAxes.y);
6037d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPointerAxes.pressure);
6038d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_TOOL_WIDTH, &mRawPointerAxes.toolMajor);
6039d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_DISTANCE, &mRawPointerAxes.distance);
6040d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_TILT_X, &mRawPointerAxes.tiltX);
6041d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_TILT_Y, &mRawPointerAxes.tiltY);
6042d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6043d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6044d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool SingleTouchInputMapper::hasStylus() const {
6045d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mTouchButtonAccumulator.hasStylus();
6046d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6047d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6048d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6049d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- MultiTouchInputMapper ---
6050d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6051d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightMultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) :
6052d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        TouchInputMapper(device) {
6053d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6054d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6055d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightMultiTouchInputMapper::~MultiTouchInputMapper() {
6056d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6057d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6058d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchInputMapper::reset(nsecs_t when) {
6059d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mMultiTouchMotionAccumulator.reset(getDevice());
6060d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6061d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerIdBits.clear();
6062d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6063d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    TouchInputMapper::reset(when);
6064d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6065d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6066d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchInputMapper::process(const RawEvent* rawEvent) {
6067d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    TouchInputMapper::process(rawEvent);
6068d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6069d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mMultiTouchMotionAccumulator.process(rawEvent);
6070d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6071d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6072d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
6073d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
6074d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t outCount = 0;
6075d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    BitSet32 newPointerIdBits;
6076d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6077d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
6078d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const MultiTouchMotionAccumulator::Slot* inSlot =
6079d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mMultiTouchMotionAccumulator.getSlot(inIndex);
6080d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (!inSlot->isInUse()) {
6081d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            continue;
6082d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6083d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6084d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (outCount >= MAX_POINTERS) {
6085d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#if DEBUG_POINTERS
6086d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGD("MultiTouch device %s emitted more than maximum of %d pointers; "
6087d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "ignoring the rest.",
6088d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    getDeviceName().string(), MAX_POINTERS);
6089d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#endif
6090d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break; // too many fingers!
6091d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6092d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6093d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[outCount];
6094d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.x = inSlot->getX();
6095d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.y = inSlot->getY();
6096d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.pressure = inSlot->getPressure();
6097d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.touchMajor = inSlot->getTouchMajor();
6098d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.touchMinor = inSlot->getTouchMinor();
6099d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.toolMajor = inSlot->getToolMajor();
6100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.toolMinor = inSlot->getToolMinor();
6101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.orientation = inSlot->getOrientation();
6102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.distance = inSlot->getDistance();
6103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.tiltX = 0;
6104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.tiltY = 0;
6105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.toolType = inSlot->getToolType();
6107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
6108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            outPointer.toolType = mTouchButtonAccumulator.getToolType();
6109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
6110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
6111d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6114d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
6115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                && (mTouchButtonAccumulator.isHovering()
6116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        || (mRawPointerAxes.pressure.valid && inSlot->getPressure() <= 0));
6117d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outPointer.isHovering = isHovering;
6118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Assign pointer id using tracking id if available.
6120d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (*outHavePointerIds) {
6121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t trackingId = inSlot->getTrackingId();
6122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t id = -1;
6123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (trackingId >= 0) {
6124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
6125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    uint32_t n = idBits.clearFirstMarkedBit();
6126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (mPointerTrackingIdMap[n] == trackingId) {
6127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        id = n;
6128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
6129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
6130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (id < 0 && !mPointerIdBits.isFull()) {
6132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    id = mPointerIdBits.markFirstUnmarkedBit();
6133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mPointerTrackingIdMap[id] = trackingId;
6134d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
6135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (id < 0) {
6137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                *outHavePointerIds = false;
6138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentRawPointerData.clearIdBits();
6139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                newPointerIdBits.clear();
6140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
6141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                outPointer.id = id;
6142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentRawPointerData.idToIndex[id] = outCount;
6143d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mCurrentRawPointerData.markIdBit(id, isHovering);
6144d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                newPointerIdBits.markBit(id);
6145d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6147d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6148d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outCount += 1;
6149d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6150d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6151d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mCurrentRawPointerData.pointerCount = outCount;
6152d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mPointerIdBits = newPointerIdBits;
6153d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6154d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    mMultiTouchMotionAccumulator.finishSync();
6155d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid MultiTouchInputMapper::configureRawPointerAxes() {
6158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    TouchInputMapper::configureRawPointerAxes();
6159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
6161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
6162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.touchMajor);
6163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_TOUCH_MINOR, &mRawPointerAxes.touchMinor);
6164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &mRawPointerAxes.toolMajor);
6165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_WIDTH_MINOR, &mRawPointerAxes.toolMinor);
6166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &mRawPointerAxes.orientation);
6167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_PRESSURE, &mRawPointerAxes.pressure);
6168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_DISTANCE, &mRawPointerAxes.distance);
6169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_TRACKING_ID, &mRawPointerAxes.trackingId);
6170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getAbsoluteAxisInfo(ABS_MT_SLOT, &mRawPointerAxes.slot);
6171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (mRawPointerAxes.trackingId.valid
6173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && mRawPointerAxes.slot.valid
6174d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            && mRawPointerAxes.slot.minValue == 0 && mRawPointerAxes.slot.maxValue > 0) {
6175d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t slotCount = mRawPointerAxes.slot.maxValue + 1;
6176d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (slotCount > MAX_SLOTS) {
6177d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGW("MultiTouch Device %s reported %d slots but the framework "
6178d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    "only supports a maximum of %d slots at this time.",
6179d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    getDeviceName().string(), slotCount, MAX_SLOTS);
6180d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            slotCount = MAX_SLOTS;
6181d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6182d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mMultiTouchMotionAccumulator.configure(getDevice(),
6183d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                slotCount, true /*usingSlotsProtocol*/);
6184d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    } else {
6185d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mMultiTouchMotionAccumulator.configure(getDevice(),
6186d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                MAX_POINTERS, false /*usingSlotsProtocol*/);
6187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6188d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6189d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6190d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool MultiTouchInputMapper::hasStylus() const {
6191d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return mMultiTouchMotionAccumulator.hasStylus()
6192d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            || mTouchButtonAccumulator.hasStylus();
6193d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6194d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6195d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6196d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- JoystickInputMapper ---
6197d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6198d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightJoystickInputMapper::JoystickInputMapper(InputDevice* device) :
6199d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputMapper(device) {
6200d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6201d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6202d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael WrightJoystickInputMapper::~JoystickInputMapper() {
6203d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6204d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6205d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightuint32_t JoystickInputMapper::getSources() {
6206d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return AINPUT_SOURCE_JOYSTICK;
6207d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6208d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
6210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::populateDeviceInfo(info);
6211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < mAxes.size(); i++) {
6213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const Axis& axis = mAxes.valueAt(i);
6214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        addMotionRange(axis.axisInfo.axis, axis, info);
6215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
6217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            addMotionRange(axis.axisInfo.highAxis, axis, info);
6218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6221d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::addMotionRange(int32_t axisId, const Axis& axis,
6224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDeviceInfo* info) {
6225d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    info->addMotionRange(axisId, AINPUT_SOURCE_JOYSTICK,
6226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
6227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    /* In order to ease the transition for developers from using the old axes
6228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright     * to the newer, more semantically correct axes, we'll continue to register
6229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright     * the old axes as duplicates of their corresponding new ones.  */
6230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t compatAxis = getCompatAxis(axisId);
6231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (compatAxis >= 0) {
6232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info->addMotionRange(compatAxis, AINPUT_SOURCE_JOYSTICK,
6233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
6234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright/* A mapping from axes the joystick actually has to the axes that should be
6238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * artificially created for compatibility purposes.
6239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * Returns -1 if no compatibility axis is needed. */
6240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightint32_t JoystickInputMapper::getCompatAxis(int32_t axis) {
6241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch(axis) {
6242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_LTRIGGER:
6243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AMOTION_EVENT_AXIS_BRAKE;
6244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_RTRIGGER:
6245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AMOTION_EVENT_AXIS_GAS;
6246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return -1;
6248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::dump(String8& dump) {
6251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT2 "Joystick Input Mapper:\n");
6252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    dump.append(INDENT3 "Axes:\n");
6254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numAxes = mAxes.size();
6255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numAxes; i++) {
6256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const Axis& axis = mAxes.valueAt(i);
6257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const char* label = getAxisLabel(axis.axisInfo.axis);
6258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (label) {
6259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dump.appendFormat(INDENT4 "%s", label);
6260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else {
6261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dump.appendFormat(INDENT4 "%d", axis.axisInfo.axis);
6262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
6264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            label = getAxisLabel(axis.axisInfo.highAxis);
6265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (label) {
6266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                dump.appendFormat(" / %s (split at %d)", label, axis.axisInfo.splitValue);
6267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            } else {
6268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                dump.appendFormat(" / %d (split at %d)", axis.axisInfo.highAxis,
6269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        axis.axisInfo.splitValue);
6270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        } else if (axis.axisInfo.mode == AxisInfo::MODE_INVERT) {
6272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            dump.append(" (invert)");
6273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f, resolution=%0.5f\n",
6276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
6277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "  scale=%0.5f, offset=%0.5f, "
6278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "highScale=%0.5f, highOffset=%0.5f\n",
6279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                axis.scale, axis.offset, axis.highScale, axis.highOffset);
6280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        dump.appendFormat(INDENT4 "  rawAxis=%d, rawMin=%d, rawMax=%d, "
6281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                "rawFlat=%d, rawFuzz=%d, rawResolution=%d\n",
6282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
6283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz, axis.rawAxisInfo.resolution);
6284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::configure(nsecs_t when,
6288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const InputReaderConfiguration* config, uint32_t changes) {
6289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::configure(when, config, changes);
6290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!changes) { // first time only
6292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Collect all axes.
6293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
6294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (!(getAbsAxisUsage(abs, getDevice()->getClasses())
6295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    & INPUT_DEVICE_CLASS_JOYSTICK)) {
6296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                continue; // axis must be claimed by a different device
6297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            RawAbsoluteAxisInfo rawAxisInfo;
6300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            getAbsoluteAxisInfo(abs, &rawAxisInfo);
6301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (rawAxisInfo.valid) {
6302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Map axis.
6303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                AxisInfo axisInfo;
6304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
6305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (!explicitlyMapped) {
6306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    // Axis is not explicitly mapped, will choose a generic axis later.
6307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axisInfo.mode = AxisInfo::MODE_NORMAL;
6308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axisInfo.axis = -1;
6309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
6310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Apply flat override.
6312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                int32_t rawFlat = axisInfo.flatOverride < 0
6313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        ? rawAxisInfo.flat : axisInfo.flatOverride;
6314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // Calculate scaling factors and limits.
6316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                Axis axis;
6317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (axisInfo.mode == AxisInfo::MODE_SPLIT) {
6318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue);
6319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
6320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
6321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            scale, 0.0f, highScale, 0.0f,
6322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
6323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            rawAxisInfo.resolution * scale);
6324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else if (isCenteredAxis(axisInfo.axis)) {
6325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
6326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
6327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
6328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            scale, offset, scale, offset,
6329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
6330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            rawAxisInfo.resolution * scale);
6331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
6332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
6333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
6334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            scale, 0.0f, scale, 0.0f,
6335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
6336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            rawAxisInfo.resolution * scale);
6337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
6338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // To eliminate noise while the joystick is at rest, filter out small variations
6340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                // in axis values up front.
6341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                axis.filter = axis.fuzz ? axis.fuzz : axis.flat * 0.25f;
6342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                mAxes.add(abs, axis);
6344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // If there are too many axes, start dropping them.
6348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Prefer to keep explicitly mapped axes.
6349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mAxes.size() > PointerCoords::MAX_AXES) {
6350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ALOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.",
6351d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
6352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            pruneAxes(true);
6353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            pruneAxes(false);
6354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Assign generic axis ids to remaining axes.
6357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1;
6358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        size_t numAxes = mAxes.size();
6359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < numAxes; i++) {
6360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            Axis& axis = mAxes.editValueAt(i);
6361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (axis.axisInfo.axis < 0) {
6362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
6363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        && haveAxis(nextGenericAxisId)) {
6364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    nextGenericAxisId += 1;
6365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
6366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
6368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axis.axisInfo.axis = nextGenericAxisId;
6369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    nextGenericAxisId += 1;
6370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
6371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    ALOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
6372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            "have already been assigned to other axes.",
6373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            getDeviceName().string(), mAxes.keyAt(i));
6374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    mAxes.removeItemsAt(i--);
6375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    numAxes -= 1;
6376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
6377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool JoystickInputMapper::haveAxis(int32_t axisId) {
6383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numAxes = mAxes.size();
6384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numAxes; i++) {
6385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const Axis& axis = mAxes.valueAt(i);
6386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (axis.axisInfo.axis == axisId
6387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                || (axis.axisInfo.mode == AxisInfo::MODE_SPLIT
6388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        && axis.axisInfo.highAxis == axisId)) {
6389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return true;
6390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return false;
6393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) {
6396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t i = mAxes.size();
6397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) {
6398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) {
6399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            continue;
6400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ALOGI("Discarding joystick '%s' axis %d because there are too many axes.",
6402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                getDeviceName().string(), mAxes.keyAt(i));
6403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mAxes.removeItemsAt(i);
6404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool JoystickInputMapper::isCenteredAxis(int32_t axis) {
6408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (axis) {
6409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_X:
6410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_Y:
6411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_Z:
6412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_RX:
6413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_RY:
6414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_RZ:
6415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_HAT_X:
6416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_HAT_Y:
6417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_ORIENTATION:
6418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_RUDDER:
6419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case AMOTION_EVENT_AXIS_WHEEL:
6420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return true;
6421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    default:
6422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return false;
6423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::reset(nsecs_t when) {
6427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Recenter all axes.
6428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numAxes = mAxes.size();
6429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numAxes; i++) {
6430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Axis& axis = mAxes.editValueAt(i);
6431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        axis.resetValue();
6432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputMapper::reset(when);
6435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::process(const RawEvent* rawEvent) {
6438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    switch (rawEvent->type) {
6439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case EV_ABS: {
6440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ssize_t index = mAxes.indexOfKey(rawEvent->code);
6441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (index >= 0) {
6442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            Axis& axis = mAxes.editValueAt(index);
6443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            float newValue, highNewValue;
6444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            switch (axis.axisInfo.mode) {
6445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case AxisInfo::MODE_INVERT:
6446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)
6447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        * axis.scale + axis.offset;
6448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                highNewValue = 0.0f;
6449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
6450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            case AxisInfo::MODE_SPLIT:
6451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (rawEvent->value < axis.axisInfo.splitValue) {
6452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    newValue = (axis.axisInfo.splitValue - rawEvent->value)
6453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            * axis.scale + axis.offset;
6454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    highNewValue = 0.0f;
6455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else if (rawEvent->value > axis.axisInfo.splitValue) {
6456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    newValue = 0.0f;
6457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    highNewValue = (rawEvent->value - axis.axisInfo.splitValue)
6458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                            * axis.highScale + axis.highOffset;
6459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                } else {
6460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    newValue = 0.0f;
6461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    highNewValue = 0.0f;
6462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
6463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
6464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            default:
6465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                newValue = rawEvent->value * axis.scale + axis.offset;
6466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                highNewValue = 0.0f;
6467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                break;
6468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            axis.newValue = newValue;
6470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            axis.highNewValue = highNewValue;
6471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
6473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    case EV_SYN:
6476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        switch (rawEvent->code) {
6477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        case SYN_REPORT:
6478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            sync(rawEvent->when, false /*force*/);
6479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            break;
6480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        break;
6482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::sync(nsecs_t when, bool force) {
6486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (!filterAxes(force)) {
6487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return;
6488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t metaState = mContext->getGlobalMetaState();
6491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t buttonState = 0;
6492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    PointerProperties pointerProperties;
6494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerProperties.clear();
6495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerProperties.id = 0;
6496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
6497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    PointerCoords pointerCoords;
6499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCoords.clear();
6500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numAxes = mAxes.size();
6502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numAxes; i++) {
6503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        const Axis& axis = mAxes.valueAt(i);
6504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        setPointerCoordsAxisValue(&pointerCoords, axis.axisInfo.axis, axis.currentValue);
6505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
6506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            setPointerCoordsAxisValue(&pointerCoords, axis.axisInfo.highAxis,
6507d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axis.highCurrentValue);
6508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // Moving a joystick axis should not wake the device because joysticks can
6512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // be fairly noisy even when not in use.  On the other hand, pushing a gamepad
6513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // button will likely wake the device.
6514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    // TODO: Use the input device configuration to control this behavior more finely.
6515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    uint32_t policyFlags = 0;
6516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
6518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
6519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ADISPLAY_ID_NONE, 1, &pointerProperties, &pointerCoords, 0, 0, 0);
6520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    getListener()->notifyMotion(&args);
6521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightvoid JoystickInputMapper::setPointerCoordsAxisValue(PointerCoords* pointerCoords,
6524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t axis, float value) {
6525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    pointerCoords->setAxisValue(axis, value);
6526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    /* In order to ease the transition for developers from using the old axes
6527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright     * to the newer, more semantically correct axes, we'll continue to produce
6528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright     * values for the old axes as mirrors of the value of their corresponding
6529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright     * new axes. */
6530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t compatAxis = getCompatAxis(axis);
6531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (compatAxis >= 0) {
6532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        pointerCoords->setAxisValue(compatAxis, value);
6533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool JoystickInputMapper::filterAxes(bool force) {
6537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool atLeastOneSignificantChange = force;
6538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    size_t numAxes = mAxes.size();
6539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    for (size_t i = 0; i < numAxes; i++) {
6540d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Axis& axis = mAxes.editValueAt(i);
6541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (force || hasValueChangedSignificantly(axis.filter,
6542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                axis.newValue, axis.currentValue, axis.min, axis.max)) {
6543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            axis.currentValue = axis.newValue;
6544d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            atLeastOneSignificantChange = true;
6545d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6546d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
6547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (force || hasValueChangedSignificantly(axis.filter,
6548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    axis.highNewValue, axis.highCurrentValue, axis.min, axis.max)) {
6549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                axis.highCurrentValue = axis.highNewValue;
6550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                atLeastOneSignificantChange = true;
6551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
6552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return atLeastOneSignificantChange;
6555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6557d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool JoystickInputMapper::hasValueChangedSignificantly(
6558d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float filter, float newValue, float currentValue, float min, float max) {
6559d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (newValue != currentValue) {
6560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Filter out small changes in value unless the value is converging on the axis
6561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // bounds or center point.  This is intended to reduce the amount of information
6562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // sent to applications by particularly noisy joysticks (such as PS3).
6563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (fabs(newValue - currentValue) > filter
6564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, min)
6565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, max)
6566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, 0)) {
6567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return true;
6568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return false;
6571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightbool JoystickInputMapper::hasMovedNearerToValueWithinFilteredRange(
6574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float filter, float newValue, float currentValue, float thresholdValue) {
6575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float newDistance = fabs(newValue - thresholdValue);
6576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    if (newDistance < filter) {
6577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        float oldDistance = fabs(currentValue - thresholdValue);
6578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (newDistance < oldDistance) {
6579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return true;
6580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
6581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
6582d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return false;
6583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
6584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
6585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright} // namespace android
6586