InputReader.cpp revision 9e8e40cb5f8aeb0702002eee60d1ce394bf699ee
1b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown/*
2b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * Copyright (C) 2010 The Android Open Source Project
3b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *
4b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
5b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * you may not use this file except in compliance with the License.
6b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * You may obtain a copy of the License at
7b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *
8b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
9b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *
10b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * Unless required by applicable law or agreed to in writing, software
11b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
12b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * See the License for the specific language governing permissions and
14b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * limitations under the License.
15b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown */
16b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
1746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define LOG_TAG "InputReader"
1846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown//#define LOG_NDEBUG 0
2046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Log debug messages for each raw event received from the EventHub.
2246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define DEBUG_RAW_EVENTS 0
2346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Log debug messages about touch screen filtering hacks.
25349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown#define DEBUG_HACKS 0
2646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Log debug messages about virtual key processing.
28349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown#define DEBUG_VIRTUAL_KEYS 0
2946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Log debug messages about pointers.
31349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown#define DEBUG_POINTERS 0
3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
335c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown// Log debug messages about pointer assignment calculations.
345c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown#define DEBUG_POINTER_ASSIGNMENT 0
355c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown
36b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#include "InputReader.h"
37b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
3846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <cutils/log.h>
396b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown#include <ui/Keyboard.h>
409065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown#include <ui/VirtualKeyMap.h>
4146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <stddef.h>
438d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown#include <stdlib.h>
4446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <unistd.h>
4546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <errno.h>
4646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <limits.h>
47c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown#include <math.h>
4846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
498d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown#define INDENT "  "
50ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown#define INDENT2 "    "
51ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown#define INDENT3 "      "
52ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown#define INDENT4 "        "
538d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
5446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android {
5546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// --- Static Functions ---
5746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Browntemplate<typename T>
5946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Browninline static T abs(const T& value) {
6046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return value < 0 ? - value : value;
6146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
6246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
6346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Browntemplate<typename T>
6446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Browninline static T min(const T& a, const T& b) {
6546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return a < b ? a : b;
6646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
6746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
685c225b1680e696ae8bbf505a1997d6f720672f74Jeff Browntemplate<typename T>
695c225b1680e696ae8bbf505a1997d6f720672f74Jeff Browninline static void swap(T& a, T& b) {
705c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    T temp = a;
715c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    a = b;
725c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    b = temp;
735c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown}
745c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown
758d60866e2100db70ecf0502c14768a384514d7e9Jeff Browninline static float avg(float x, float y) {
768d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    return (x + y) / 2;
778d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
788d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
798d60866e2100db70ecf0502c14768a384514d7e9Jeff Browninline static float pythag(float x, float y) {
808d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    return sqrtf(x * x + y * y);
818d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
828d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
83517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Browninline static int32_t signExtendNybble(int32_t value) {
84517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown    return value >= 8 ? value - 16 : value;
85517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown}
86517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown
87ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownstatic inline const char* toString(bool value) {
88ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    return value ? "true" : "false";
89ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
90ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
919626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brownstatic int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation,
929626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        const int32_t map[][4], size_t mapSize) {
939626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    if (orientation != DISPLAY_ORIENTATION_0) {
949626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        for (size_t i = 0; i < mapSize; i++) {
959626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            if (value == map[i][0]) {
969626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                return map[i][orientation];
979626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            }
989626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        }
999626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    }
1009626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    return value;
1019626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown}
1029626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
10346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic const int32_t keyCodeRotationMap[][4] = {
10446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        // key codes enumerated counter-clockwise with the original (unrotated) key first
10546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        // no rotation,        90 degree rotation,  180 degree rotation, 270 degree rotation
106fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        { AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT },
107fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        { AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN },
108fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        { AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT },
109fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown        { AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP },
11046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown};
1119626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brownstatic const size_t keyCodeRotationMapSize =
11246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
11346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
11446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownint32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
1159626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    return rotateValueUsingRotationMap(keyCode, orientation,
1169626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            keyCodeRotationMap, keyCodeRotationMapSize);
1179626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown}
1189626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
1199626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brownstatic const int32_t edgeFlagRotationMap[][4] = {
1209626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        // edge flags enumerated counter-clockwise with the original (unrotated) edge flag first
1219626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        // no rotation,        90 degree rotation,  180 degree rotation, 270 degree rotation
1229626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        { AMOTION_EVENT_EDGE_FLAG_BOTTOM,   AMOTION_EVENT_EDGE_FLAG_RIGHT,
1239626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                AMOTION_EVENT_EDGE_FLAG_TOP,     AMOTION_EVENT_EDGE_FLAG_LEFT },
1249626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        { AMOTION_EVENT_EDGE_FLAG_RIGHT,  AMOTION_EVENT_EDGE_FLAG_TOP,
1259626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                AMOTION_EVENT_EDGE_FLAG_LEFT,   AMOTION_EVENT_EDGE_FLAG_BOTTOM },
1269626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        { AMOTION_EVENT_EDGE_FLAG_TOP,     AMOTION_EVENT_EDGE_FLAG_LEFT,
1279626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                AMOTION_EVENT_EDGE_FLAG_BOTTOM,   AMOTION_EVENT_EDGE_FLAG_RIGHT },
1289626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        { AMOTION_EVENT_EDGE_FLAG_LEFT,   AMOTION_EVENT_EDGE_FLAG_BOTTOM,
1299626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                AMOTION_EVENT_EDGE_FLAG_RIGHT,  AMOTION_EVENT_EDGE_FLAG_TOP },
1309626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown};
1319626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brownstatic const size_t edgeFlagRotationMapSize =
1329626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        sizeof(edgeFlagRotationMap) / sizeof(edgeFlagRotationMap[0]);
1339626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
1349626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brownstatic int32_t rotateEdgeFlag(int32_t edgeFlag, int32_t orientation) {
1359626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    return rotateValueUsingRotationMap(edgeFlag, orientation,
1369626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            edgeFlagRotationMap, edgeFlagRotationMapSize);
13746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
13846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownstatic inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
1406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
1416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
1426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
14346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
14446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// --- InputReader ---
14546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
14646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownInputReader::InputReader(const sp<EventHubInterface>& eventHub,
1479c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        const sp<InputReaderPolicyInterface>& policy,
14846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        const sp<InputDispatcherInterface>& dispatcher) :
1496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
150fe50892af3b365806a767298dfd8e86447682581Jeff Brown        mGlobalMetaState(0), mDisableVirtualKeysTimeout(-1) {
1519c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    configureExcludedDevices();
1526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    updateGlobalMetaState();
1536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    updateInputConfiguration();
15446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
15546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
15646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownInputReader::~InputReader() {
15746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    for (size_t i = 0; i < mDevices.size(); i++) {
15846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        delete mDevices.valueAt(i);
15946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
16046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
16146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
16246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid InputReader::loopOnce() {
16346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    RawEvent rawEvent;
1646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mEventHub->getEvent(& rawEvent);
16546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
16646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_RAW_EVENTS
1679065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    LOGD("Input event: device=%d type=0x%x scancode=%d keycode=%d value=%d",
16846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            rawEvent.deviceId, rawEvent.type, rawEvent.scanCode, rawEvent.keyCode,
16946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            rawEvent.value);
17046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
17146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    process(& rawEvent);
17346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
17446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid InputReader::process(const RawEvent* rawEvent) {
17646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    switch (rawEvent->type) {
17746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    case EventHubInterface::DEVICE_ADDED:
1787342bb9693f480f6c713b4a4f82a9ad9131cd667Jeff Brown        addDevice(rawEvent->deviceId);
17946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        break;
18046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
18146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    case EventHubInterface::DEVICE_REMOVED:
1827342bb9693f480f6c713b4a4f82a9ad9131cd667Jeff Brown        removeDevice(rawEvent->deviceId);
1837342bb9693f480f6c713b4a4f82a9ad9131cd667Jeff Brown        break;
1847342bb9693f480f6c713b4a4f82a9ad9131cd667Jeff Brown
1857342bb9693f480f6c713b4a4f82a9ad9131cd667Jeff Brown    case EventHubInterface::FINISHED_DEVICE_SCAN:
186c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        handleConfigurationChanged(rawEvent->when);
18746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        break;
18846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    default:
1906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        consumeEvent(rawEvent);
19146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        break;
1926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
1936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
19446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1957342bb9693f480f6c713b4a4f82a9ad9131cd667Jeff Brownvoid InputReader::addDevice(int32_t deviceId) {
1966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    String8 name = mEventHub->getDeviceName(deviceId);
1976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    uint32_t classes = mEventHub->getDeviceClasses(deviceId);
19846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputDevice* device = createDevice(deviceId, name, classes);
2006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    device->configure();
20146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2028d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    if (device->isIgnored()) {
2039065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown        LOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId, name.string());
2048d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    } else {
2059065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown        LOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId, name.string(),
206ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                device->getSources());
2078d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
2088d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    bool added = false;
2106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    { // acquire device registry writer lock
2116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        RWLock::AutoWLock _wl(mDeviceRegistryLock);
21246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
2146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (deviceIndex < 0) {
2156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mDevices.add(deviceId, device);
2166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            added = true;
2176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
2186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } // release device registry writer lock
21946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (! added) {
2216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        LOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
2226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        delete device;
22346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return;
22446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
22546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
22646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2277342bb9693f480f6c713b4a4f82a9ad9131cd667Jeff Brownvoid InputReader::removeDevice(int32_t deviceId) {
2286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    bool removed = false;
2296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputDevice* device = NULL;
2306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    { // acquire device registry writer lock
2316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        RWLock::AutoWLock _wl(mDeviceRegistryLock);
2326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
2336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
2346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (deviceIndex >= 0) {
2356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            device = mDevices.valueAt(deviceIndex);
2366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mDevices.removeItemsAt(deviceIndex, 1);
2376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            removed = true;
2386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
2396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } // release device registry writer lock
24046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (! removed) {
2426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        LOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
2436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        return;
2446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
24546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (device->isIgnored()) {
2479065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown        LOGI("Device removed: id=%d, name='%s' (ignored non-input device)",
2486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                device->getId(), device->getName().string());
2496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } else {
2509065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown        LOGI("Device removed: id=%d, name='%s', sources=0x%08x",
2516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                device->getId(), device->getName().string(), device->getSources());
25246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
2536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
2548d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    device->reset();
2558d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    delete device;
25746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
25846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, uint32_t classes) {
2606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputDevice* device = new InputDevice(this, deviceId, name);
26146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
26256194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // External devices.
26356194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
26456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        device->setExternal(true);
26556194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    }
26656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
2676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Switch-like devices.
2686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (classes & INPUT_DEVICE_CLASS_SWITCH) {
2696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        device->addMapper(new SwitchInputMapper(device));
270fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown    }
271fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown
2726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Keyboard-like devices.
2736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    uint32_t keyboardSources = 0;
2746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
2756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
2766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        keyboardSources |= AINPUT_SOURCE_KEYBOARD;
2776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
2786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
2796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
2806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
2816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (classes & INPUT_DEVICE_CLASS_DPAD) {
2826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        keyboardSources |= AINPUT_SOURCE_DPAD;
2836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
284cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
285cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        keyboardSources |= AINPUT_SOURCE_GAMEPAD;
286cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
287fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown
2886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (keyboardSources != 0) {
28947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        device->addMapper(new KeyboardInputMapper(device, keyboardSources, keyboardType));
290fd03582995e0fce963dd0fa0669e3211b74c0dd7Jeff Brown    }
29146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
29283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    // Cursor-like devices.
29383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    if (classes & INPUT_DEVICE_CLASS_CURSOR) {
29483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        device->addMapper(new CursorInputMapper(device));
2956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
29646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
29758a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    // Touchscreens and touchpad devices.
29858a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
29947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        device->addMapper(new MultiTouchInputMapper(device));
30058a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
30147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        device->addMapper(new SingleTouchInputMapper(device));
30246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
3036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
304cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    // Joystick-like devices.
305cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
306cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        device->addMapper(new JoystickInputMapper(device));
307cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
308cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
3096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return device;
31046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
31146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputReader::consumeEvent(const RawEvent* rawEvent) {
3136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    int32_t deviceId = rawEvent->deviceId;
31446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    { // acquire device registry reader lock
3166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        RWLock::AutoRLock _rl(mDeviceRegistryLock);
31746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
3196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (deviceIndex < 0) {
3206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            LOGW("Discarding event for unknown deviceId %d.", deviceId);
3216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return;
32246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
3236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputDevice* device = mDevices.valueAt(deviceIndex);
3256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (device->isIgnored()) {
3266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            //LOGD("Discarding event for ignored deviceId %d.", deviceId);
3276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return;
32846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
3296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        device->process(rawEvent);
3316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } // release device registry reader lock
33246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
33346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
334c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brownvoid InputReader::handleConfigurationChanged(nsecs_t when) {
3356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Reset global meta state because it depends on the list of all configured devices.
3366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    updateGlobalMetaState();
3376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Update input configuration.
3396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    updateInputConfiguration();
34046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Enqueue configuration changed.
3426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mDispatcher->notifyConfigurationChanged(when);
34346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
34446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputReader::configureExcludedDevices() {
3466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    Vector<String8> excludedDeviceNames;
3476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mPolicy->getExcludedDeviceNames(excludedDeviceNames);
34846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < excludedDeviceNames.size(); i++) {
3506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mEventHub->addExcludedDevice(excludedDeviceNames[i]);
35146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
3526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
35346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputReader::updateGlobalMetaState() {
3556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    { // acquire state lock
3566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        AutoMutex _l(mStateLock);
35746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mGlobalMetaState = 0;
35946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        { // acquire device registry reader lock
3616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            RWLock::AutoRLock _rl(mDeviceRegistryLock);
36246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            for (size_t i = 0; i < mDevices.size(); i++) {
3646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                InputDevice* device = mDevices.valueAt(i);
3656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mGlobalMetaState |= device->getMetaState();
3666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
3676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        } // release device registry reader lock
3686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } // release state lock
3696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
37046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputReader::getGlobalMetaState() {
3726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    { // acquire state lock
3736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        AutoMutex _l(mStateLock);
37446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        return mGlobalMetaState;
3766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } // release state lock
3776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
37846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputReader::updateInputConfiguration() {
3806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    { // acquire state lock
3816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        AutoMutex _l(mStateLock);
38246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t touchScreenConfig = InputConfiguration::TOUCHSCREEN_NOTOUCH;
3846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t keyboardConfig = InputConfiguration::KEYBOARD_NOKEYS;
3856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t navigationConfig = InputConfiguration::NAVIGATION_NONAV;
3866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        { // acquire device registry reader lock
3876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            RWLock::AutoRLock _rl(mDeviceRegistryLock);
38846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            InputDeviceInfo deviceInfo;
3906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            for (size_t i = 0; i < mDevices.size(); i++) {
3916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                InputDevice* device = mDevices.valueAt(i);
3926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                device->getDeviceInfo(& deviceInfo);
3936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                uint32_t sources = deviceInfo.getSources();
39446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) {
3966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER;
3976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
3986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) {
3996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL;
4006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) {
4016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    navigationConfig = InputConfiguration::NAVIGATION_DPAD;
4026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
4036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) {
4046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    keyboardConfig = InputConfiguration::KEYBOARD_QWERTY;
4056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
4066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
4076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        } // release device registry reader lock
40846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mInputConfiguration.touchScreen = touchScreenConfig;
4106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mInputConfiguration.keyboard = keyboardConfig;
4116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mInputConfiguration.navigation = navigationConfig;
4126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } // release state lock
41346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
41446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
415fe50892af3b365806a767298dfd8e86447682581Jeff Brownvoid InputReader::disableVirtualKeysUntil(nsecs_t time) {
416fe50892af3b365806a767298dfd8e86447682581Jeff Brown    mDisableVirtualKeysTimeout = time;
417fe50892af3b365806a767298dfd8e86447682581Jeff Brown}
418fe50892af3b365806a767298dfd8e86447682581Jeff Brown
419fe50892af3b365806a767298dfd8e86447682581Jeff Brownbool InputReader::shouldDropVirtualKey(nsecs_t now,
420fe50892af3b365806a767298dfd8e86447682581Jeff Brown        InputDevice* device, int32_t keyCode, int32_t scanCode) {
421fe50892af3b365806a767298dfd8e86447682581Jeff Brown    if (now < mDisableVirtualKeysTimeout) {
422fe50892af3b365806a767298dfd8e86447682581Jeff Brown        LOGI("Dropping virtual key from device %s because virtual keys are "
423fe50892af3b365806a767298dfd8e86447682581Jeff Brown                "temporarily disabled for the next %0.3fms.  keyCode=%d, scanCode=%d",
424fe50892af3b365806a767298dfd8e86447682581Jeff Brown                device->getName().string(),
425fe50892af3b365806a767298dfd8e86447682581Jeff Brown                (mDisableVirtualKeysTimeout - now) * 0.000001,
426fe50892af3b365806a767298dfd8e86447682581Jeff Brown                keyCode, scanCode);
427fe50892af3b365806a767298dfd8e86447682581Jeff Brown        return true;
428fe50892af3b365806a767298dfd8e86447682581Jeff Brown    } else {
429fe50892af3b365806a767298dfd8e86447682581Jeff Brown        return false;
430fe50892af3b365806a767298dfd8e86447682581Jeff Brown    }
431fe50892af3b365806a767298dfd8e86447682581Jeff Brown}
432fe50892af3b365806a767298dfd8e86447682581Jeff Brown
43305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid InputReader::fadePointer() {
43405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    { // acquire device registry reader lock
43505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        RWLock::AutoRLock _rl(mDeviceRegistryLock);
43605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
43705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        for (size_t i = 0; i < mDevices.size(); i++) {
43805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown            InputDevice* device = mDevices.valueAt(i);
43905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown            device->fadePointer();
44005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        }
44105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    } // release device registry reader lock
44205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
44305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
4446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
4456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    { // acquire state lock
4466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        AutoMutex _l(mStateLock);
4479c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
4486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        *outConfiguration = mInputConfiguration;
4496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } // release state lock
45046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
45146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownstatus_t InputReader::getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) {
4536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    { // acquire device registry reader lock
4546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        RWLock::AutoRLock _rl(mDeviceRegistryLock);
45546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
4576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (deviceIndex < 0) {
4586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return NAME_NOT_FOUND;
4596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
46046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputDevice* device = mDevices.valueAt(deviceIndex);
4626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (device->isIgnored()) {
4636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return NAME_NOT_FOUND;
4646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
46546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        device->getDeviceInfo(outDeviceInfo);
4676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        return OK;
4686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } // release device registy reader lock
4696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
47046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputReader::getInputDeviceIds(Vector<int32_t>& outDeviceIds) {
4726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    outDeviceIds.clear();
47346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    { // acquire device registry reader lock
4756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        RWLock::AutoRLock _rl(mDeviceRegistryLock);
47646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        size_t numDevices = mDevices.size();
4786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        for (size_t i = 0; i < numDevices; i++) {
4796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            InputDevice* device = mDevices.valueAt(i);
4806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (! device->isIgnored()) {
4816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                outDeviceIds.add(device->getId());
4826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
48346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
4846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } // release device registy reader lock
4856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
48646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
4886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t keyCode) {
4896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getState(deviceId, sourceMask, keyCode, & InputDevice::getKeyCodeState);
4906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
491c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
4926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
4936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t scanCode) {
4946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getState(deviceId, sourceMask, scanCode, & InputDevice::getScanCodeState);
4956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
496c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
4976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
4986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getState(deviceId, sourceMask, switchCode, & InputDevice::getSwitchState);
4996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
500c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
5016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputReader::getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
5026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        GetStateFunc getStateFunc) {
5036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    { // acquire device registry reader lock
5046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        RWLock::AutoRLock _rl(mDeviceRegistryLock);
5056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
5066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t result = AKEY_STATE_UNKNOWN;
5076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (deviceId >= 0) {
5086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
5096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (deviceIndex >= 0) {
5106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                InputDevice* device = mDevices.valueAt(deviceIndex);
5116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
5126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    result = (device->*getStateFunc)(sourceMask, code);
5136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
5146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
5156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        } else {
5166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            size_t numDevices = mDevices.size();
5176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            for (size_t i = 0; i < numDevices; i++) {
5186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                InputDevice* device = mDevices.valueAt(i);
5196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
5206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    result = (device->*getStateFunc)(sourceMask, code);
5216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    if (result >= AKEY_STATE_DOWN) {
5226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        return result;
5236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    }
5246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
5256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
5266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
5276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        return result;
5286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } // release device registy reader lock
5296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
53046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
5326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
5336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    memset(outFlags, 0, numCodes);
5346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return markSupportedKeyCodes(deviceId, sourceMask, numCodes, keyCodes, outFlags);
5356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
53646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
5386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        const int32_t* keyCodes, uint8_t* outFlags) {
5396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    { // acquire device registry reader lock
5406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        RWLock::AutoRLock _rl(mDeviceRegistryLock);
5416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        bool result = false;
5426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (deviceId >= 0) {
5436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
5446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (deviceIndex >= 0) {
5456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                InputDevice* device = mDevices.valueAt(deviceIndex);
5466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
5476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    result = device->markSupportedKeyCodes(sourceMask,
5486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                            numCodes, keyCodes, outFlags);
54946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                }
5506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
5516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        } else {
5526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            size_t numDevices = mDevices.size();
5536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            for (size_t i = 0; i < numDevices; i++) {
5546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                InputDevice* device = mDevices.valueAt(i);
5556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
5566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    result |= device->markSupportedKeyCodes(sourceMask,
5576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                            numCodes, keyCodes, outFlags);
55846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                }
55946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
56046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
5616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        return result;
5626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } // release device registy reader lock
5636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
56446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
565b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputReader::dump(String8& dump) {
566f2f487183052865d50c004a835360be1728b5a52Jeff Brown    mEventHub->dump(dump);
567f2f487183052865d50c004a835360be1728b5a52Jeff Brown    dump.append("\n");
568f2f487183052865d50c004a835360be1728b5a52Jeff Brown
569f2f487183052865d50c004a835360be1728b5a52Jeff Brown    dump.append("Input Reader State:\n");
570f2f487183052865d50c004a835360be1728b5a52Jeff Brown
571ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    { // acquire device registry reader lock
572ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        RWLock::AutoRLock _rl(mDeviceRegistryLock);
573b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
574ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        for (size_t i = 0; i < mDevices.size(); i++) {
575ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown            mDevices.valueAt(i)->dump(dump);
576b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
577ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    } // release device registy reader lock
578b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
579b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
58046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- InputReaderThread ---
58246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
5846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        Thread(/*canCallJava*/ true), mReader(reader) {
58546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
58646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputReaderThread::~InputReaderThread() {
5886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
58946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool InputReaderThread::threadLoop() {
5916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mReader->loopOnce();
5926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return true;
5936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
59446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
59546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- InputDevice ---
59746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputDevice::InputDevice(InputReaderContext* context, int32_t id, const String8& name) :
59956194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        mContext(context), mId(id), mName(name), mSources(0), mIsExternal(false) {
6006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
60146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
6026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputDevice::~InputDevice() {
6036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
6046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
6056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        delete mMappers[i];
60646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
6076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mMappers.clear();
6086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
60946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
610ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid InputDevice::dump(String8& dump) {
611ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    InputDeviceInfo deviceInfo;
612ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    getDeviceInfo(& deviceInfo);
613ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
6149065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(),
615ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown            deviceInfo.getName().string());
61656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
617ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
618ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
619cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown
620cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown    const KeyedVector<int32_t, InputDeviceInfo::MotionRange> ranges = deviceInfo.getMotionRanges();
621cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown    if (!ranges.isEmpty()) {
622ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT2 "Motion Ranges:\n");
623cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown        for (size_t i = 0; i < ranges.size(); i++) {
624cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            int32_t axis = ranges.keyAt(i);
625cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            const char* label = getAxisLabel(axis);
626cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            char name[32];
627cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            if (label) {
628cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown                strncpy(name, label, sizeof(name));
629cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown                name[sizeof(name) - 1] = '\0';
630cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            } else {
631cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown                snprintf(name, sizeof(name), "%d", axis);
632cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            }
633cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
634cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            dump.appendFormat(INDENT3 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
635cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown                    name, range.min, range.max, range.flat, range.fuzz);
636cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown        }
637ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    }
638ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
639ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    size_t numMappers = mMappers.size();
640ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
641ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        InputMapper* mapper = mMappers[i];
642ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        mapper->dump(dump);
643ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    }
644ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
645ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
6466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputDevice::addMapper(InputMapper* mapper) {
6476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mMappers.add(mapper);
6486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
649349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
6506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputDevice::configure() {
6518d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    if (! isIgnored()) {
65247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
6538d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
6548d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
6556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mSources = 0;
6566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
6576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
6586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
6596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
6606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mapper->configure();
6616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mSources |= mapper->getSources();
662349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown    }
6636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
664349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
6656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputDevice::reset() {
6666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
6676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
6686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
6696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mapper->reset();
670349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown    }
6716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
672349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
6736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputDevice::process(const RawEvent* rawEvent) {
6746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
6756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
6766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
6776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mapper->process(rawEvent);
67846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
6796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
68046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
6816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
6826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    outDeviceInfo->initialize(mId, mName);
68346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
6846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
6856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
6866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
6876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mapper->populateDeviceInfo(outDeviceInfo);
68846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
68946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
69046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
6916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
6926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState);
6936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
69446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
6956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
6966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getState(sourceMask, scanCode, & InputMapper::getScanCodeState);
6976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
69846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
6996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
7006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getState(sourceMask, switchCode, & InputMapper::getSwitchState);
7016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
70246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
7046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    int32_t result = AKEY_STATE_UNKNOWN;
7056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
7066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
7076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
7086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
7096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            result = (mapper->*getStateFunc)(sourceMask, code);
7106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (result >= AKEY_STATE_DOWN) {
7116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                return result;
7126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
71346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
71446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
7156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return result;
7166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
71746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
7196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        const int32_t* keyCodes, uint8_t* outFlags) {
7206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    bool result = false;
7216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
7226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
7236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
7246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
7256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
72646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
72746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
7286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return result;
7296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
73046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputDevice::getMetaState() {
7326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    int32_t result = 0;
7336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    size_t numMappers = mMappers.size();
7346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < numMappers; i++) {
7356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper* mapper = mMappers[i];
7366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        result |= mapper->getMetaState();
73746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
7386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return result;
7396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
74046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
74105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid InputDevice::fadePointer() {
74205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    size_t numMappers = mMappers.size();
74305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    for (size_t i = 0; i < numMappers; i++) {
74405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        InputMapper* mapper = mMappers[i];
74505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        mapper->fadePointer();
74605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
74705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
74805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
74946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- InputMapper ---
75146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputMapper::InputMapper(InputDevice* device) :
7536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mDevice(device), mContext(device->getContext()) {
7546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
75546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownInputMapper::~InputMapper() {
7576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
75846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
7606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    info->addSource(getSources());
76146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
76246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
763ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid InputMapper::dump(String8& dump) {
764ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
765ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
7666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputMapper::configure() {
7676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
76846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid InputMapper::reset() {
7706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
77146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
7736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
7746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
77546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
7776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
7786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
77946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
7816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
78246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
78346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
7846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
7856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        const int32_t* keyCodes, uint8_t* outFlags) {
7866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return false;
7876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
788349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
7896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t InputMapper::getMetaState() {
7906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return 0;
7916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
79246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
79305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid InputMapper::fadePointer() {
79405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
79505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
796cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownvoid InputMapper::dumpRawAbsoluteAxisInfo(String8& dump,
797cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        const RawAbsoluteAxisInfo& axis, const char* name) {
798cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    if (axis.valid) {
799cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d\n",
800cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown                name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz);
801cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    } else {
802cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        dump.appendFormat(INDENT4 "%s: unknown range\n", name);
803cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
804cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
805cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
8066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
8076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- SwitchInputMapper ---
8086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
8096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownSwitchInputMapper::SwitchInputMapper(InputDevice* device) :
8106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        InputMapper(device) {
81146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
81246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownSwitchInputMapper::~SwitchInputMapper() {
8146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
8156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
8166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownuint32_t SwitchInputMapper::getSources() {
81789de57a8d252a25ef2412a11a66089a9ff6ffe29Jeff Brown    return AINPUT_SOURCE_SWITCH;
8186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
8196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
8206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid SwitchInputMapper::process(const RawEvent* rawEvent) {
8216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    switch (rawEvent->type) {
8226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    case EV_SW:
8236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        processSwitch(rawEvent->when, rawEvent->scanCode, rawEvent->value);
8246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        break;
82546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
8266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
82746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid SwitchInputMapper::processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) {
829b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    getDispatcher()->notifySwitch(when, switchCode, switchValue, 0);
8306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
83146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
8336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getEventHub()->getSwitchState(getDeviceId(), switchCode);
8346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
83546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
83646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- KeyboardInputMapper ---
8386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
83947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff BrownKeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
8406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        uint32_t sources, int32_t keyboardType) :
84147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        InputMapper(device), mSources(sources),
8426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mKeyboardType(keyboardType) {
8436328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    initializeLocked();
8446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
8456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
8466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownKeyboardInputMapper::~KeyboardInputMapper() {
8476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
8486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
8496328cdc89e099806a1893b89e4c724d596272d9eJeff Brownvoid KeyboardInputMapper::initializeLocked() {
8506328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    mLocked.metaState = AMETA_NONE;
8516328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    mLocked.downTime = 0;
8526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
8536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
8546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownuint32_t KeyboardInputMapper::getSources() {
8556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return mSources;
8566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
8576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
8586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
8596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputMapper::populateDeviceInfo(info);
8606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
8616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    info->setKeyboardType(mKeyboardType);
8626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
8636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
864ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid KeyboardInputMapper::dump(String8& dump) {
865ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    { // acquire lock
866ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        AutoMutex _l(mLock);
867ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT2 "Keyboard Input Mapper:\n");
86847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        dumpParameters(dump);
869ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
870ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mLocked.keyDowns.size());
871ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mLocked.metaState);
872ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
873ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    } // release lock
874ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
875ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
87647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
87747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brownvoid KeyboardInputMapper::configure() {
87847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    InputMapper::configure();
87947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
88047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    // Configure basic parameters.
88147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    configureParameters();
88249ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
88349ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    // Reset LEDs.
88449ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    {
88549ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        AutoMutex _l(mLock);
88649ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        resetLedStateLocked();
88749ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    }
88847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
88947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
89047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brownvoid KeyboardInputMapper::configureParameters() {
89147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    mParameters.orientationAware = false;
89247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"),
89347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            mParameters.orientationAware);
89447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
89547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    mParameters.associatedDisplayId = mParameters.orientationAware ? 0 : -1;
89647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
89747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
89847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brownvoid KeyboardInputMapper::dumpParameters(String8& dump) {
89947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.append(INDENT3 "Parameters:\n");
90047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n",
90147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            mParameters.associatedDisplayId);
90247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
90347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            toString(mParameters.orientationAware));
90447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
90547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
9066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid KeyboardInputMapper::reset() {
9076328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    for (;;) {
9086328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t keyCode, scanCode;
9096328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        { // acquire lock
9106328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            AutoMutex _l(mLock);
9116328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
9126328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            // Synthesize key up event on reset if keys are currently down.
9136328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            if (mLocked.keyDowns.isEmpty()) {
9146328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                initializeLocked();
91549ed71db425c5054e3ad9526496a7e116c89556bJeff Brown                resetLedStateLocked();
9166328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                break; // done
9176328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
9186328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
9196328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            const KeyDown& keyDown = mLocked.keyDowns.top();
9206328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            keyCode = keyDown.keyCode;
9216328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            scanCode = keyDown.scanCode;
9226328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        } // release lock
9236328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
9246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
9256328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        processKey(when, false, keyCode, scanCode, 0);
9266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
9276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
9286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputMapper::reset();
9296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    getContext()->updateGlobalMetaState();
9306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
9316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
9326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid KeyboardInputMapper::process(const RawEvent* rawEvent) {
9336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    switch (rawEvent->type) {
9346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    case EV_KEY: {
9356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t scanCode = rawEvent->scanCode;
9366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (isKeyboardOrGamepadKey(scanCode)) {
9376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            processKey(rawEvent->when, rawEvent->value != 0, rawEvent->keyCode, scanCode,
9386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    rawEvent->flags);
93946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
9406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        break;
9416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
9426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
9436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
94446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
9456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
9466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return scanCode < BTN_MOUSE
9476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        || scanCode >= KEY_OK
9489e8e40cb5f8aeb0702002eee60d1ce394bf699eeJeff Brown        || (scanCode >= BTN_MISC && scanCode < BTN_MOUSE)
949cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI);
9506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
95146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
9526328cdc89e099806a1893b89e4c724d596272d9eJeff Brownvoid KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
9536328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t scanCode, uint32_t policyFlags) {
9546328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    int32_t newMetaState;
9556328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    nsecs_t downTime;
9566328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    bool metaStateChanged = false;
9576328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
9586328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    { // acquire lock
9596328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        AutoMutex _l(mLock);
9606328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
9616328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        if (down) {
9626328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            // Rotate key codes according to orientation if needed.
9636328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
96447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0) {
9656328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                int32_t orientation;
96647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown                if (!getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
96747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown                        NULL, NULL, & orientation)) {
968b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown                    orientation = DISPLAY_ORIENTATION_0;
9696328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                }
9706328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
9716328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                keyCode = rotateKeyCode(keyCode, orientation);
97246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
97346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
9746328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            // Add key down.
9756328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            ssize_t keyDownIndex = findKeyDownLocked(scanCode);
9766328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            if (keyDownIndex >= 0) {
9776328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                // key repeat, be sure to use same keycode as before in case of rotation
9786b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
9796328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            } else {
9806328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                // key down
981fe50892af3b365806a767298dfd8e86447682581Jeff Brown                if ((policyFlags & POLICY_FLAG_VIRTUAL)
982fe50892af3b365806a767298dfd8e86447682581Jeff Brown                        && mContext->shouldDropVirtualKey(when,
983fe50892af3b365806a767298dfd8e86447682581Jeff Brown                                getDevice(), keyCode, scanCode)) {
984fe50892af3b365806a767298dfd8e86447682581Jeff Brown                    return;
985fe50892af3b365806a767298dfd8e86447682581Jeff Brown                }
986fe50892af3b365806a767298dfd8e86447682581Jeff Brown
9876328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                mLocked.keyDowns.push();
9886328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                KeyDown& keyDown = mLocked.keyDowns.editTop();
9896328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                keyDown.keyCode = keyCode;
9906328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                keyDown.scanCode = scanCode;
9916328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
9926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
9936328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            mLocked.downTime = when;
9946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        } else {
9956328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            // Remove key down.
9966328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            ssize_t keyDownIndex = findKeyDownLocked(scanCode);
9976328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            if (keyDownIndex >= 0) {
9986328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                // key up, be sure to use same keycode as before in case of rotation
9996b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
10006328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                mLocked.keyDowns.removeAt(size_t(keyDownIndex));
10016328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            } else {
10026328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                // key was not actually down
10036328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                LOGI("Dropping key up from device %s because the key was not down.  "
10046328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                        "keyCode=%d, scanCode=%d",
10056328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                        getDeviceName().string(), keyCode, scanCode);
10066328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                return;
10076328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
10086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
10096328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
10106328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t oldMetaState = mLocked.metaState;
10116328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        newMetaState = updateMetaState(keyCode, down, oldMetaState);
10126328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        if (oldMetaState != newMetaState) {
10136328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            mLocked.metaState = newMetaState;
10146328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            metaStateChanged = true;
1015497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown            updateLedStateLocked(false);
101646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
101746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10186328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        downTime = mLocked.downTime;
10196328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    } // release lock
10206328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
102156194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // Key down on external an keyboard should wake the device.
102256194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // We don't do this for internal keyboards to prevent them from waking up in your pocket.
102356194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // For internal keyboards, the key layout file should specify the policy flags for
102456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // each wake key individually.
102556194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // TODO: Use the input device configuration to control this behavior more finely.
102656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    if (down && getDevice()->isExternal()
102756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown            && !(policyFlags & (POLICY_FLAG_WAKE | POLICY_FLAG_WAKE_DROPPED))) {
102856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        policyFlags |= POLICY_FLAG_WAKE_DROPPED;
102956194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    }
103056194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
10316328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    if (metaStateChanged) {
10326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        getContext()->updateGlobalMetaState();
103346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
103446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
103505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    if (down && !isMetaKey(keyCode)) {
103605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        getContext()->fadePointer();
103705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
103805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
103983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    getDispatcher()->notifyKey(when, getDeviceId(), mSources, policyFlags,
1040b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
1041b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
10426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
1043c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
10446328cdc89e099806a1893b89e4c724d596272d9eJeff Brownssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) {
10456328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    size_t n = mLocked.keyDowns.size();
10466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (size_t i = 0; i < n; i++) {
10476328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        if (mLocked.keyDowns[i].scanCode == scanCode) {
10486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return i;
104946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
10506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
10516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return -1;
10526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
105346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
10556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
10566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
1057c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown
10586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
10596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
10606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
106146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
10636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        const int32_t* keyCodes, uint8_t* outFlags) {
10646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
10656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
106646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t KeyboardInputMapper::getMetaState() {
10686328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    { // acquire lock
10696328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        AutoMutex _l(mLock);
10706328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        return mLocked.metaState;
10716328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    } // release lock
10726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
107300ba884436dc8b222ad850c73c936d87bf4e84deJeff Brown
107449ed71db425c5054e3ad9526496a7e116c89556bJeff Brownvoid KeyboardInputMapper::resetLedStateLocked() {
107549ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    initializeLedStateLocked(mLocked.capsLockLedState, LED_CAPSL);
107649ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    initializeLedStateLocked(mLocked.numLockLedState, LED_NUML);
107749ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    initializeLedStateLocked(mLocked.scrollLockLedState, LED_SCROLLL);
107849ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
107949ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    updateLedStateLocked(true);
108049ed71db425c5054e3ad9526496a7e116c89556bJeff Brown}
108149ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
108249ed71db425c5054e3ad9526496a7e116c89556bJeff Brownvoid KeyboardInputMapper::initializeLedStateLocked(LockedState::LedState& ledState, int32_t led) {
108349ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
108449ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    ledState.on = false;
108549ed71db425c5054e3ad9526496a7e116c89556bJeff Brown}
108649ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
1087497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brownvoid KeyboardInputMapper::updateLedStateLocked(bool reset) {
1088497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown    updateLedStateForModifierLocked(mLocked.capsLockLedState, LED_CAPSL,
108951e7fe7545e3509ebb5c31c10440acd31cec89a2Jeff Brown            AMETA_CAPS_LOCK_ON, reset);
1090497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown    updateLedStateForModifierLocked(mLocked.numLockLedState, LED_NUML,
109151e7fe7545e3509ebb5c31c10440acd31cec89a2Jeff Brown            AMETA_NUM_LOCK_ON, reset);
1092497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown    updateLedStateForModifierLocked(mLocked.scrollLockLedState, LED_SCROLLL,
109351e7fe7545e3509ebb5c31c10440acd31cec89a2Jeff Brown            AMETA_SCROLL_LOCK_ON, reset);
1094497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown}
1095497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown
1096497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brownvoid KeyboardInputMapper::updateLedStateForModifierLocked(LockedState::LedState& ledState,
1097497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown        int32_t led, int32_t modifier, bool reset) {
1098497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown    if (ledState.avail) {
1099497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown        bool desiredState = (mLocked.metaState & modifier) != 0;
110049ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        if (reset || ledState.on != desiredState) {
1101497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown            getEventHub()->setLedState(getDeviceId(), led, desiredState);
1102497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown            ledState.on = desiredState;
1103497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown        }
1104497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown    }
1105497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown}
1106497a92cc5ba2176b8a8484b0a7da040eac0e887bJeff Brown
11076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
110883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown// --- CursorInputMapper ---
11096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
111083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff BrownCursorInputMapper::CursorInputMapper(InputDevice* device) :
111147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        InputMapper(device) {
11126328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    initializeLocked();
11136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
11146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
111583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff BrownCursorInputMapper::~CursorInputMapper() {
11166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
11176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
111883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownuint32_t CursorInputMapper::getSources() {
111983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    return mSources;
11206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
11216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
112283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
11236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputMapper::populateDeviceInfo(info);
11246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
112583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    if (mParameters.mode == Parameters::MODE_POINTER) {
112683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        float minX, minY, maxX, maxY;
112783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
11286f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            info->addMotionRange(AMOTION_EVENT_AXIS_X, minX, maxX, 0.0f, 0.0f);
11296f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            info->addMotionRange(AMOTION_EVENT_AXIS_Y, minY, maxY, 0.0f, 0.0f);
113083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        }
113183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    } else {
11326f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        info->addMotionRange(AMOTION_EVENT_AXIS_X, -1.0f, 1.0f, 0.0f, mXScale);
11336f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        info->addMotionRange(AMOTION_EVENT_AXIS_Y, -1.0f, 1.0f, 0.0f, mYScale);
11346f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
11356f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, 0.0f, 1.0f, 0.0f, 0.0f);
11366f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
11376f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    if (mHaveVWheel) {
11386f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, -1.0f, 1.0f, 0.0f, 0.0f);
11396f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
11406f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    if (mHaveHWheel) {
11416f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, -1.0f, 1.0f, 0.0f, 0.0f);
114283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    }
11436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
11446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
114583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::dump(String8& dump) {
1146ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    { // acquire lock
1147ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        AutoMutex _l(mLock);
114883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        dump.append(INDENT2 "Cursor Input Mapper:\n");
114947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        dumpParameters(dump);
11506f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
11516f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
1152ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
1153ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
11546f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        dump.appendFormat(INDENT3 "HaveVWheel: %s\n", toString(mHaveVWheel));
11556f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        dump.appendFormat(INDENT3 "HaveHWheel: %s\n", toString(mHaveHWheel));
11566f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
11576f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
1158ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.appendFormat(INDENT3 "Down: %s\n", toString(mLocked.down));
1159ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
1160ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    } // release lock
1161ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
1162ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
116383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::configure() {
116447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    InputMapper::configure();
116547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
116647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    // Configure basic parameters.
116747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    configureParameters();
116883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
116983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    // Configure device mode.
117083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    switch (mParameters.mode) {
117183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    case Parameters::MODE_POINTER:
117283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        mSources = AINPUT_SOURCE_MOUSE;
117383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        mXPrecision = 1.0f;
117483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        mYPrecision = 1.0f;
117583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        mXScale = 1.0f;
117683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        mYScale = 1.0f;
117783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        mPointerController = getPolicy()->obtainPointerController(getDeviceId());
117883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        break;
117983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    case Parameters::MODE_NAVIGATION:
118083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        mSources = AINPUT_SOURCE_TRACKBALL;
118183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
118283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
118383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
118483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
118583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        break;
118683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    }
11876f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
11886f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    mVWheelScale = 1.0f;
11896f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    mHWheelScale = 1.0f;
1190cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown
1191cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown    mHaveVWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_WHEEL);
1192cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown    mHaveHWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_HWHEEL);
119347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
119447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
119583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::configureParameters() {
119683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    mParameters.mode = Parameters::MODE_POINTER;
119783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    String8 cursorModeString;
119883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    if (getDevice()->getConfiguration().tryGetProperty(String8("cursor.mode"), cursorModeString)) {
119983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        if (cursorModeString == "navigation") {
120083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown            mParameters.mode = Parameters::MODE_NAVIGATION;
120183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        } else if (cursorModeString != "pointer" && cursorModeString != "default") {
120283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown            LOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
120383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        }
120483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    }
120583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
120647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    mParameters.orientationAware = false;
120783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
120847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            mParameters.orientationAware);
120947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
121083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    mParameters.associatedDisplayId = mParameters.mode == Parameters::MODE_POINTER
121183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown            || mParameters.orientationAware ? 0 : -1;
121247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
121347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
121483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::dumpParameters(String8& dump) {
121547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.append(INDENT3 "Parameters:\n");
121647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n",
121747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            mParameters.associatedDisplayId);
121883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
121983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    switch (mParameters.mode) {
122083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    case Parameters::MODE_POINTER:
122183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        dump.append(INDENT4 "Mode: pointer\n");
122283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        break;
122383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    case Parameters::MODE_NAVIGATION:
122483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        dump.append(INDENT4 "Mode: navigation\n");
122583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        break;
122683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    default:
122783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        assert(false);
122883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    }
122983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
123047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
123147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            toString(mParameters.orientationAware));
123247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown}
123347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
123483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::initializeLocked() {
12356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mAccumulator.clear();
12366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
12376328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    mLocked.down = false;
12386328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    mLocked.downTime = 0;
12396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
12406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
124183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::reset() {
12426328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    for (;;) {
12436328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        { // acquire lock
12446328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            AutoMutex _l(mLock);
12456328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
12466328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            if (! mLocked.down) {
12476328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                initializeLocked();
12486328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                break; // done
12496328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
12506328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        } // release lock
12516328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
125283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        // Synthesize button up event on reset.
12536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
12546328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        mAccumulator.fields = Accumulator::FIELD_BTN_MOUSE;
12556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mAccumulator.btnMouse = false;
12566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        sync(when);
125746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
125846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
12596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputMapper::reset();
12606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
12616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
126283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::process(const RawEvent* rawEvent) {
12636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    switch (rawEvent->type) {
12646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    case EV_KEY:
12656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        switch (rawEvent->scanCode) {
126633bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        case BTN_LEFT:
126733bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        case BTN_RIGHT:
126833bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        case BTN_MIDDLE:
126933bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        case BTN_SIDE:
127033bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        case BTN_EXTRA:
127133bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        case BTN_FORWARD:
127233bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        case BTN_BACK:
127333bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        case BTN_TASK:
12746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE;
12756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.btnMouse = rawEvent->value != 0;
12762dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            // Sync now since BTN_MOUSE is not necessarily followed by SYN_REPORT and
12772dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            // we need to ensure that we report the up/down promptly.
12786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            sync(rawEvent->when);
12796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
128046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
12816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        break;
12826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
12836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    case EV_REL:
12846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        switch (rawEvent->scanCode) {
12856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case REL_X:
12866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.fields |= Accumulator::FIELD_REL_X;
12876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.relX = rawEvent->value;
12886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
12896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case REL_Y:
12906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.fields |= Accumulator::FIELD_REL_Y;
12916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.relY = rawEvent->value;
12926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
12936f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        case REL_WHEEL:
12946f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            mAccumulator.fields |= Accumulator::FIELD_REL_WHEEL;
12956f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            mAccumulator.relWheel = rawEvent->value;
12966f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            break;
12976f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        case REL_HWHEEL:
12986f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            mAccumulator.fields |= Accumulator::FIELD_REL_HWHEEL;
12996f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            mAccumulator.relHWheel = rawEvent->value;
13006f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            break;
130146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
13026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        break;
130346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
13046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    case EV_SYN:
13056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        switch (rawEvent->scanCode) {
13066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case SYN_REPORT:
13072dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            sync(rawEvent->when);
13086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
13096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
13106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        break;
13116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
131246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
131346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
131483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownvoid CursorInputMapper::sync(nsecs_t when) {
13152dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown    uint32_t fields = mAccumulator.fields;
13162dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown    if (fields == 0) {
13172dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        return; // no new state changes, so nothing to do
13182dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown    }
13192dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown
13209626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    int32_t motionEventAction;
13219626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    int32_t motionEventEdgeFlags;
13226328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    PointerCoords pointerCoords;
13236328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    nsecs_t downTime;
132433bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown    float vscroll, hscroll;
13256328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    { // acquire lock
13266328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        AutoMutex _l(mLock);
132746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
13286328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE;
132946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
13306328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        if (downChanged) {
13316328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            if (mAccumulator.btnMouse) {
13321c9d06e0470c41e2720c65be076b6080bf8595c0Jeff Brown                if (!mLocked.down) {
13331c9d06e0470c41e2720c65be076b6080bf8595c0Jeff Brown                    mLocked.down = true;
13341c9d06e0470c41e2720c65be076b6080bf8595c0Jeff Brown                    mLocked.downTime = when;
13351c9d06e0470c41e2720c65be076b6080bf8595c0Jeff Brown                } else {
13361c9d06e0470c41e2720c65be076b6080bf8595c0Jeff Brown                    downChanged = false;
13371c9d06e0470c41e2720c65be076b6080bf8595c0Jeff Brown                }
13386328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            } else {
13391c9d06e0470c41e2720c65be076b6080bf8595c0Jeff Brown                if (mLocked.down) {
13401c9d06e0470c41e2720c65be076b6080bf8595c0Jeff Brown                    mLocked.down = false;
13411c9d06e0470c41e2720c65be076b6080bf8595c0Jeff Brown                } else {
13421c9d06e0470c41e2720c65be076b6080bf8595c0Jeff Brown                    downChanged = false;
13431c9d06e0470c41e2720c65be076b6080bf8595c0Jeff Brown                }
13446328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
13456328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        }
134646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
13476328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        downTime = mLocked.downTime;
134883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        float deltaX = fields & Accumulator::FIELD_REL_X ? mAccumulator.relX * mXScale : 0.0f;
134983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        float deltaY = fields & Accumulator::FIELD_REL_Y ? mAccumulator.relY * mYScale : 0.0f;
135046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
13516328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        if (downChanged) {
13526328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
1353cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown        } else if (mLocked.down || mPointerController == NULL) {
13546328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            motionEventAction = AMOTION_EVENT_ACTION_MOVE;
1355cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown        } else {
1356cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
135746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
135846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
135947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0
136083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown                && (deltaX != 0.0f || deltaY != 0.0f)) {
13616328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            // Rotate motion based on display orientation if needed.
13626328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
13636328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            int32_t orientation;
136447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
136547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown                    NULL, NULL, & orientation)) {
1366b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown                orientation = DISPLAY_ORIENTATION_0;
13676328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
13686328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
13696328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            float temp;
13706328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            switch (orientation) {
1371b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            case DISPLAY_ORIENTATION_90:
137283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown                temp = deltaX;
137383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown                deltaX = deltaY;
137483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown                deltaY = -temp;
13756328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                break;
13766328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
1377b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            case DISPLAY_ORIENTATION_180:
137883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown                deltaX = -deltaX;
137983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown                deltaY = -deltaY;
13806328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                break;
13816328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
1382b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            case DISPLAY_ORIENTATION_270:
138383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown                temp = deltaX;
138483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown                deltaX = -deltaY;
138583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown                deltaY = temp;
13866328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                break;
13876328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
13886328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        }
138983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
139091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown        pointerCoords.clear();
139191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
13929626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        motionEventEdgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
13939626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
139483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        if (mPointerController != NULL) {
139583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown            mPointerController->move(deltaX, deltaY);
139683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown            if (downChanged) {
139783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown                mPointerController->setButtonState(mLocked.down ? POINTER_BUTTON_1 : 0);
139883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown            }
139991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            float x, y;
140091c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            mPointerController->getPosition(&x, &y);
1401ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
1402ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
14039626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
14049626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
14059626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                float minX, minY, maxX, maxY;
14069626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
14079626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                    if (x <= minX) {
14089626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                        motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
14099626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                    } else if (x >= maxX) {
14109626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                        motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
14119626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                    }
14129626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                    if (y <= minY) {
14139626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                        motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
14149626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                    } else if (y >= maxY) {
14159626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                        motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
14169626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                    }
14179626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                }
14189626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            }
141983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        } else {
1420ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
1421ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
142283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        }
142383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
1424ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, mLocked.down ? 1.0f : 0.0f);
14256f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
14266f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        if (mHaveVWheel && (fields & Accumulator::FIELD_REL_WHEEL)) {
142733bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown            vscroll = mAccumulator.relWheel;
142833bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        } else {
142933bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown            vscroll = 0;
14306f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
14316f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        if (mHaveHWheel && (fields & Accumulator::FIELD_REL_HWHEEL)) {
143233bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown            hscroll = mAccumulator.relHWheel;
143333bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        } else {
143433bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown            hscroll = 0;
14356f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
143605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        if (hscroll != 0 || vscroll != 0) {
143705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown            mPointerController->unfade();
143805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        }
14396328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    } // release lock
144046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
144156194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // Moving an external trackball or mouse should wake the device.
144256194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // We don't do this for internal cursor devices to prevent them from waking up
144356194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // the device in your pocket.
144456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // TODO: Use the input device configuration to control this behavior more finely.
144556194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    uint32_t policyFlags = 0;
144656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    if (getDevice()->isExternal()) {
144756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        policyFlags |= POLICY_FLAG_WAKE_DROPPED;
144856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    }
144956194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
14506328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    int32_t metaState = mContext->getGlobalMetaState();
145146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    int32_t pointerId = 0;
145256194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    getDispatcher()->notifyMotion(when, getDeviceId(), mSources, policyFlags,
14539626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            motionEventAction, 0, metaState, motionEventEdgeFlags,
1454b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
1455b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
1456b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    mAccumulator.clear();
145733bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown
145833bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown    if (vscroll != 0 || hscroll != 0) {
145933bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
146033bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
146133bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown
146256194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        getDispatcher()->notifyMotion(when, getDeviceId(), mSources, policyFlags,
146333bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown                AMOTION_EVENT_ACTION_SCROLL, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
146433bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown                1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
146533bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown    }
146646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
146746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
146883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brownint32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
1469c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown    if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
1470c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown        return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
1471c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown    } else {
1472c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown        return AKEY_STATE_UNKNOWN;
1473c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown    }
1474c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown}
1475c3fc2d03d58a258c53c9265a70143d4af076b764Jeff Brown
147605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid CursorInputMapper::fadePointer() {
147705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    { // acquire lock
147805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        AutoMutex _l(mLock);
147905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        mPointerController->fade();
148005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    } // release lock
148105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
148205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
148346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
14846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- TouchInputMapper ---
148546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
148647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff BrownTouchInputMapper::TouchInputMapper(InputDevice* device) :
148747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        InputMapper(device) {
14886328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    mLocked.surfaceOrientation = -1;
14896328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    mLocked.surfaceWidth = -1;
14906328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    mLocked.surfaceHeight = -1;
14916328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
14926328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    initializeLocked();
14936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
149446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
14956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownTouchInputMapper::~TouchInputMapper() {
149646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
149746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
14986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownuint32_t TouchInputMapper::getSources() {
149983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    return mSources;
15006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
150146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
15026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
15036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputMapper::populateDeviceInfo(info);
15046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
15056328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    { // acquire lock
15066328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        AutoMutex _l(mLock);
15076328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
15086328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        // Ensure surface information is up to date so that orientation changes are
15096328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        // noticed immediately.
15106328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        configureSurfaceLocked();
15116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
15126f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        info->addMotionRange(AMOTION_EVENT_AXIS_X, mLocked.orientedRanges.x);
15136f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        info->addMotionRange(AMOTION_EVENT_AXIS_Y, mLocked.orientedRanges.y);
15148d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
15158d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (mLocked.orientedRanges.havePressure) {
15166f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE,
15178d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    mLocked.orientedRanges.pressure);
15188d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
15198d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
15208d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (mLocked.orientedRanges.haveSize) {
15216f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            info->addMotionRange(AMOTION_EVENT_AXIS_SIZE,
15228d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    mLocked.orientedRanges.size);
15238d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
15248d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
1525c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        if (mLocked.orientedRanges.haveTouchSize) {
15266f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            info->addMotionRange(AMOTION_EVENT_AXIS_TOUCH_MAJOR,
15278d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    mLocked.orientedRanges.touchMajor);
15286f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            info->addMotionRange(AMOTION_EVENT_AXIS_TOUCH_MINOR,
15298d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    mLocked.orientedRanges.touchMinor);
15308d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
15318d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
1532c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        if (mLocked.orientedRanges.haveToolSize) {
15336f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            info->addMotionRange(AMOTION_EVENT_AXIS_TOOL_MAJOR,
15348d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    mLocked.orientedRanges.toolMajor);
15356f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            info->addMotionRange(AMOTION_EVENT_AXIS_TOOL_MINOR,
15368d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    mLocked.orientedRanges.toolMinor);
15378d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
15388d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
15398d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (mLocked.orientedRanges.haveOrientation) {
15406f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            info->addMotionRange(AMOTION_EVENT_AXIS_ORIENTATION,
15418d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    mLocked.orientedRanges.orientation);
15428d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
15436328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    } // release lock
15446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
15456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
1546ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid TouchInputMapper::dump(String8& dump) {
1547ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    { // acquire lock
1548ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        AutoMutex _l(mLock);
1549ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT2 "Touch Input Mapper:\n");
1550ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dumpParameters(dump);
1551ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dumpVirtualKeysLocked(dump);
1552ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dumpRawAxes(dump);
1553ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dumpCalibration(dump);
1554ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dumpSurfaceLocked(dump);
1555511ee5f89fad45bd0456b1335b745f2b8d87641bJeff Brown        dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
1556c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale);
1557c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale);
1558c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mLocked.xPrecision);
1559c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mLocked.yPrecision);
1560c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mLocked.geometricScale);
1561c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mLocked.toolSizeLinearScale);
1562c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mLocked.toolSizeLinearBias);
1563c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mLocked.toolSizeAreaScale);
1564c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mLocked.toolSizeAreaBias);
1565c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mLocked.pressureScale);
1566c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mLocked.sizeScale);
1567c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "OrientationSCale: %0.3f\n", mLocked.orientationScale);
1568ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    } // release lock
1569ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
1570ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
15716328cdc89e099806a1893b89e4c724d596272d9eJeff Brownvoid TouchInputMapper::initializeLocked() {
15726328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    mCurrentTouch.clear();
15736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mLastTouch.clear();
15746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mDownTime = 0;
157546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
15766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (uint32_t i = 0; i < MAX_POINTERS; i++) {
15776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mAveragingTouchFilter.historyStart[i] = 0;
15786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mAveragingTouchFilter.historyEnd[i] = 0;
157946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
158046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
15816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mJumpyTouchFilter.jumpyPointsDropped = 0;
15826328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
15836328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    mLocked.currentVirtualKey.down = false;
15848d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
15858d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mLocked.orientedRanges.havePressure = false;
15868d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mLocked.orientedRanges.haveSize = false;
1587c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    mLocked.orientedRanges.haveTouchSize = false;
1588c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    mLocked.orientedRanges.haveToolSize = false;
15898d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mLocked.orientedRanges.haveOrientation = false;
15908d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
15918d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
15926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid TouchInputMapper::configure() {
15936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    InputMapper::configure();
159446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
15956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Configure basic parameters.
15968d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    configureParameters();
159746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
159883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    // Configure sources.
159983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    switch (mParameters.deviceType) {
160083c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
160183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        mSources = AINPUT_SOURCE_TOUCHSCREEN;
160283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        break;
160383c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    case Parameters::DEVICE_TYPE_TOUCH_PAD:
160483c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        mSources = AINPUT_SOURCE_TOUCHPAD;
160583c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        break;
160683c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    default:
160783c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown        assert(false);
160883c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    }
160983c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown
16106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Configure absolute axis information.
16118d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    configureRawAxes();
16128d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
16138d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Prepare input device calibration.
16148d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    parseCalibration();
16158d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    resolveCalibration();
161646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
16176328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    { // acquire lock
16186328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        AutoMutex _l(mLock);
161946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
16208d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown         // Configure surface dimensions and orientation.
16216328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        configureSurfaceLocked();
16226328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    } // release lock
16236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
162446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
16258d60866e2100db70ecf0502c14768a384514d7e9Jeff Brownvoid TouchInputMapper::configureParameters() {
16268d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
16278d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
16288d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
1629fe50892af3b365806a767298dfd8e86447682581Jeff Brown    mParameters.virtualKeyQuietTime = getPolicy()->getVirtualKeyQuietTime();
163047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
163147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    String8 deviceTypeString;
163258a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
163347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
163447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            deviceTypeString)) {
163558a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown        if (deviceTypeString == "touchScreen") {
163658a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
163758a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown        } else if (deviceTypeString != "touchPad") {
163847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            LOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
163947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        }
164047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    }
164147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    bool isTouchScreen = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
164247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
164347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    mParameters.orientationAware = isTouchScreen;
164447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
164547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            mParameters.orientationAware);
164647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
164747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    mParameters.associatedDisplayId = mParameters.orientationAware || isTouchScreen ? 0 : -1;
16488d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
16498d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
1650ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid TouchInputMapper::dumpParameters(String8& dump) {
165147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.append(INDENT3 "Parameters:\n");
165247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
165347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    switch (mParameters.deviceType) {
165447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
165547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        dump.append(INDENT4 "DeviceType: touchScreen\n");
165647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        break;
165747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    case Parameters::DEVICE_TYPE_TOUCH_PAD:
165847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        dump.append(INDENT4 "DeviceType: touchPad\n");
165947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        break;
166047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    default:
166147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        assert(false);
166247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    }
166347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
166447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n",
166547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            mParameters.associatedDisplayId);
166647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
166747e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown            toString(mParameters.orientationAware));
166847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
166947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "UseBadTouchFilter: %s\n",
1670ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown            toString(mParameters.useBadTouchFilter));
167147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "UseAveragingTouchFilter: %s\n",
1672ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown            toString(mParameters.useAveragingTouchFilter));
167347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    dump.appendFormat(INDENT4 "UseJumpyTouchFilter: %s\n",
1674ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown            toString(mParameters.useJumpyTouchFilter));
1675b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
1676b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
16778d60866e2100db70ecf0502c14768a384514d7e9Jeff Brownvoid TouchInputMapper::configureRawAxes() {
16788d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mRawAxes.x.clear();
16798d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mRawAxes.y.clear();
16808d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mRawAxes.pressure.clear();
16818d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mRawAxes.touchMajor.clear();
16828d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mRawAxes.touchMinor.clear();
16838d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mRawAxes.toolMajor.clear();
16848d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mRawAxes.toolMinor.clear();
16858d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mRawAxes.orientation.clear();
16868d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
16878d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
1688ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid TouchInputMapper::dumpRawAxes(String8& dump) {
1689ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    dump.append(INDENT3 "Raw Axes:\n");
1690cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawAxes.x, "X");
1691cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawAxes.y, "Y");
1692cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawAxes.pressure, "Pressure");
1693cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawAxes.touchMajor, "TouchMajor");
1694cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawAxes.touchMinor, "TouchMinor");
1695cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawAxes.toolMajor, "ToolMajor");
1696cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawAxes.toolMinor, "ToolMinor");
1697cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    dumpRawAbsoluteAxisInfo(dump, mRawAxes.orientation, "Orientation");
16986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
169946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17006328cdc89e099806a1893b89e4c724d596272d9eJeff Brownbool TouchInputMapper::configureSurfaceLocked() {
17019626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    // Ensure we have valid X and Y axes.
17029626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    if (!mRawAxes.x.valid || !mRawAxes.y.valid) {
17039626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        LOGW(INDENT "Touch device '%s' did not report support for X or Y axis!  "
17049626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                "The device will be inoperable.", getDeviceName().string());
17059626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        return false;
17069626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    }
17079626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
17086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Update orientation and dimensions if needed.
1709b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    int32_t orientation = DISPLAY_ORIENTATION_0;
17109626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    int32_t width = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1;
17119626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    int32_t height = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1;
171247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
171347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    if (mParameters.associatedDisplayId >= 0) {
171447e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        bool wantSize = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
171547e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        bool wantOrientation = mParameters.orientationAware;
171647e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown
17176328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
171847e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
171947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown                wantSize ? &width : NULL, wantSize ? &height : NULL,
172047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown                wantOrientation ? &orientation : NULL)) {
17216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return false;
17226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
172346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
172446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17256328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    bool orientationChanged = mLocked.surfaceOrientation != orientation;
17266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (orientationChanged) {
17276328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        mLocked.surfaceOrientation = orientation;
172846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
172946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17306328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
17316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (sizeChanged) {
17329065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown        LOGI("Device reconfigured: id=%d, name='%s', display size is now %dx%d",
1733ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                getDeviceId(), getDeviceName().string(), width, height);
17348d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
17356328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        mLocked.surfaceWidth = width;
17366328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        mLocked.surfaceHeight = height;
173746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17388d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Configure X and Y factors.
17399626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        mLocked.xScale = float(width) / (mRawAxes.x.maxValue - mRawAxes.x.minValue + 1);
17409626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        mLocked.yScale = float(height) / (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1);
17419626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        mLocked.xPrecision = 1.0f / mLocked.xScale;
17429626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        mLocked.yPrecision = 1.0f / mLocked.yScale;
17439626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
17449626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        configureVirtualKeysLocked();
17450b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
17468d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Scale factor for terms that are not oriented in a particular axis.
17478d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // If the pixels are square then xScale == yScale otherwise we fake it
17488d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // by choosing an average.
17498d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        mLocked.geometricScale = avg(mLocked.xScale, mLocked.yScale);
17508d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
17518d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Size of diagonal axis.
17528d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        float diagonalSize = pythag(width, height);
17538d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
17548d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // TouchMajor and TouchMinor factors.
1755c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        if (mCalibration.touchSizeCalibration != Calibration::TOUCH_SIZE_CALIBRATION_NONE) {
1756c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            mLocked.orientedRanges.haveTouchSize = true;
17578d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.touchMajor.min = 0;
17588d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.touchMajor.max = diagonalSize;
17598d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.touchMajor.flat = 0;
17608d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.touchMajor.fuzz = 0;
17618d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor;
17628d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
17638d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
17648d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // ToolMajor and ToolMinor factors.
1765c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        mLocked.toolSizeLinearScale = 0;
1766c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        mLocked.toolSizeLinearBias = 0;
1767c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        mLocked.toolSizeAreaScale = 0;
1768c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        mLocked.toolSizeAreaBias = 0;
1769c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        if (mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) {
1770c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            if (mCalibration.toolSizeCalibration == Calibration::TOOL_SIZE_CALIBRATION_LINEAR) {
1771c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                if (mCalibration.haveToolSizeLinearScale) {
1772c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale;
17738d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
1774c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    mLocked.toolSizeLinearScale = float(min(width, height))
17758d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                            / mRawAxes.toolMajor.maxValue;
17768d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                }
17778d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
1778c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                if (mCalibration.haveToolSizeLinearBias) {
1779c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias;
1780c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                }
1781c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            } else if (mCalibration.toolSizeCalibration ==
1782c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    Calibration::TOOL_SIZE_CALIBRATION_AREA) {
1783c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                if (mCalibration.haveToolSizeLinearScale) {
1784c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale;
1785c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                } else {
1786c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    mLocked.toolSizeLinearScale = min(width, height);
1787c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                }
1788c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown
1789c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                if (mCalibration.haveToolSizeLinearBias) {
1790c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias;
1791c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                }
1792c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown
1793c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                if (mCalibration.haveToolSizeAreaScale) {
1794c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    mLocked.toolSizeAreaScale = mCalibration.toolSizeAreaScale;
1795c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
1796c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    mLocked.toolSizeAreaScale = 1.0f / mRawAxes.toolMajor.maxValue;
1797c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                }
1798c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown
1799c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                if (mCalibration.haveToolSizeAreaBias) {
1800c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    mLocked.toolSizeAreaBias = mCalibration.toolSizeAreaBias;
18018d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                }
18028d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
18038d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
1804c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            mLocked.orientedRanges.haveToolSize = true;
18058d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.toolMajor.min = 0;
18068d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.toolMajor.max = diagonalSize;
18078d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.toolMajor.flat = 0;
18088d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.toolMajor.fuzz = 0;
18098d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor;
18108d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
18118d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
18128d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Pressure factors.
1813c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        mLocked.pressureScale = 0;
18148d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) {
18158d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            RawAbsoluteAxisInfo rawPressureAxis;
18168d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            switch (mCalibration.pressureSource) {
18178d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            case Calibration::PRESSURE_SOURCE_PRESSURE:
18188d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                rawPressureAxis = mRawAxes.pressure;
18198d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
18208d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            case Calibration::PRESSURE_SOURCE_TOUCH:
18218d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                rawPressureAxis = mRawAxes.touchMajor;
18228d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
18238d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            default:
18248d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                rawPressureAxis.clear();
18258d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
18268d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
18278d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
18288d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    || mCalibration.pressureCalibration
18298d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                            == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
18308d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                if (mCalibration.havePressureScale) {
18318d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    mLocked.pressureScale = mCalibration.pressureScale;
18328d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                } else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) {
18338d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    mLocked.pressureScale = 1.0f / rawPressureAxis.maxValue;
18348d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                }
18358d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
18368d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
18378d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.havePressure = true;
18388d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.pressure.min = 0;
18398d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.pressure.max = 1.0;
18408d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.pressure.flat = 0;
18418d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.pressure.fuzz = 0;
18428d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
18438d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
18448d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Size factors.
1845c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        mLocked.sizeScale = 0;
18468d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
18478d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) {
18488d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
18498d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    mLocked.sizeScale = 1.0f / mRawAxes.toolMajor.maxValue;
18508d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                }
18518d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
18526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
18538d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.haveSize = true;
18548d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.size.min = 0;
18558d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.size.max = 1.0;
18568d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.size.flat = 0;
18578d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.size.fuzz = 0;
18588d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
18596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
18608d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Orientation
1861c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        mLocked.orientationScale = 0;
18628d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) {
18638d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            if (mCalibration.orientationCalibration
18648d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
18658d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                if (mRawAxes.orientation.valid && mRawAxes.orientation.maxValue != 0) {
18668d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    mLocked.orientationScale = float(M_PI_2) / mRawAxes.orientation.maxValue;
18678d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                }
18688d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
18696328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
18708d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.orientation.min = - M_PI_2;
18718d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.orientation.max = M_PI_2;
18728d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.orientation.flat = 0;
18738d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mLocked.orientedRanges.orientation.fuzz = 0;
18748d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
18756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
18766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
18776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (orientationChanged || sizeChanged) {
18789626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        // Compute oriented surface dimensions, precision, scales and ranges.
18799626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        // Note that the maximum value reported is an inclusive maximum value so it is one
18809626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        // unit less than the total width or height of surface.
18816328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        switch (mLocked.surfaceOrientation) {
1882b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        case DISPLAY_ORIENTATION_90:
1883b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        case DISPLAY_ORIENTATION_270:
18846328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            mLocked.orientedSurfaceWidth = mLocked.surfaceHeight;
18856328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            mLocked.orientedSurfaceHeight = mLocked.surfaceWidth;
18869626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
18876328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            mLocked.orientedXPrecision = mLocked.yPrecision;
18886328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            mLocked.orientedYPrecision = mLocked.xPrecision;
18899626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
18909626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.x.min = 0;
18919626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.x.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue)
18929626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                    * mLocked.yScale;
18939626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.x.flat = 0;
18949626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.x.fuzz = mLocked.yScale;
18959626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
18969626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.y.min = 0;
18979626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.y.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue)
18989626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                    * mLocked.xScale;
18999626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.y.flat = 0;
19009626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.y.fuzz = mLocked.xScale;
19016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
19029626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
19036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        default:
19046328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            mLocked.orientedSurfaceWidth = mLocked.surfaceWidth;
19056328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            mLocked.orientedSurfaceHeight = mLocked.surfaceHeight;
19069626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
19076328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            mLocked.orientedXPrecision = mLocked.xPrecision;
19086328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            mLocked.orientedYPrecision = mLocked.yPrecision;
19099626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
19109626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.x.min = 0;
19119626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.x.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue)
19129626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                    * mLocked.xScale;
19139626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.x.flat = 0;
19149626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.x.fuzz = mLocked.xScale;
19159626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown
19169626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.y.min = 0;
19179626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.y.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue)
19189626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                    * mLocked.yScale;
19199626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.y.flat = 0;
19209626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            mLocked.orientedRanges.y.fuzz = mLocked.yScale;
19216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
19220b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown        }
192346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
192446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
19256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return true;
192646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
192746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1928ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid TouchInputMapper::dumpSurfaceLocked(String8& dump) {
1929ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mLocked.surfaceWidth);
1930ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mLocked.surfaceHeight);
1931ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mLocked.surfaceOrientation);
1932b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
1933b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
19346328cdc89e099806a1893b89e4c724d596272d9eJeff Brownvoid TouchInputMapper::configureVirtualKeysLocked() {
19358d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    Vector<VirtualKeyDefinition> virtualKeyDefinitions;
19369065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown    getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
19370b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
19386328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    mLocked.virtualKeys.clear();
19390b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
19406328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    if (virtualKeyDefinitions.size() == 0) {
19416328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        return;
19426328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    }
19436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
19446328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size());
19456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
19468d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    int32_t touchScreenLeft = mRawAxes.x.minValue;
19478d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    int32_t touchScreenTop = mRawAxes.y.minValue;
19489626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    int32_t touchScreenWidth = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1;
19499626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    int32_t touchScreenHeight = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1;
19506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
19516328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
19528d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        const VirtualKeyDefinition& virtualKeyDefinition =
19536328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                virtualKeyDefinitions[i];
19546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
19556328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        mLocked.virtualKeys.add();
19566328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        VirtualKey& virtualKey = mLocked.virtualKeys.editTop();
19570b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
19586328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.scanCode = virtualKeyDefinition.scanCode;
19596328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t keyCode;
19606328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        uint32_t flags;
19616f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode,
19626328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                & keyCode, & flags)) {
19638d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
19648d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    virtualKey.scanCode);
19656328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            mLocked.virtualKeys.pop(); // drop the key
19666328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            continue;
19676328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        }
19680b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
19696328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.keyCode = keyCode;
19706328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.flags = flags;
19716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
19726328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        // convert the key definition's display coordinates into touch coordinates for a hit box
19736328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t halfWidth = virtualKeyDefinition.width / 2;
19746328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t halfHeight = virtualKeyDefinition.height / 2;
19756328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
19766328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
19776328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
19786328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
19796328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
19806328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
19816328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
19826328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
19836328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
1984ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    }
1985ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown}
1986ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
1987ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid TouchInputMapper::dumpVirtualKeysLocked(String8& dump) {
1988ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    if (!mLocked.virtualKeys.isEmpty()) {
1989ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT3 "Virtual Keys:\n");
1990ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown
1991ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        for (size_t i = 0; i < mLocked.virtualKeys.size(); i++) {
1992ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown            const VirtualKey& virtualKey = mLocked.virtualKeys.itemAt(i);
1993ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown            dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, "
1994ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                    "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
1995ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                    i, virtualKey.scanCode, virtualKey.keyCode,
1996ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                    virtualKey.hitLeft, virtualKey.hitRight,
1997ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                    virtualKey.hitTop, virtualKey.hitBottom);
1998ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        }
19996328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    }
200046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
200146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
20028d60866e2100db70ecf0502c14768a384514d7e9Jeff Brownvoid TouchInputMapper::parseCalibration() {
200347e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown    const PropertyMap& in = getDevice()->getConfiguration();
20048d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    Calibration& out = mCalibration;
20058d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2006c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    // Touch Size
2007c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT;
2008c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    String8 touchSizeCalibrationString;
2009c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    if (in.tryGetProperty(String8("touch.touchSize.calibration"), touchSizeCalibrationString)) {
2010c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        if (touchSizeCalibrationString == "none") {
2011c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE;
2012c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        } else if (touchSizeCalibrationString == "geometric") {
2013c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC;
2014c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        } else if (touchSizeCalibrationString == "pressure") {
2015c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE;
2016c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        } else if (touchSizeCalibrationString != "default") {
2017c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            LOGW("Invalid value for touch.touchSize.calibration: '%s'",
2018c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    touchSizeCalibrationString.string());
20198d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
20208d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
20218d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2022c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    // Tool Size
2023c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_DEFAULT;
2024c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    String8 toolSizeCalibrationString;
2025c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    if (in.tryGetProperty(String8("touch.toolSize.calibration"), toolSizeCalibrationString)) {
2026c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        if (toolSizeCalibrationString == "none") {
2027c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE;
2028c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        } else if (toolSizeCalibrationString == "geometric") {
2029c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC;
2030c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        } else if (toolSizeCalibrationString == "linear") {
2031c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR;
2032c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        } else if (toolSizeCalibrationString == "area") {
2033c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_AREA;
2034c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        } else if (toolSizeCalibrationString != "default") {
2035c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            LOGW("Invalid value for touch.toolSize.calibration: '%s'",
2036c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    toolSizeCalibrationString.string());
20378d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
20388d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
20398d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2040c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    out.haveToolSizeLinearScale = in.tryGetProperty(String8("touch.toolSize.linearScale"),
2041c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            out.toolSizeLinearScale);
2042c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    out.haveToolSizeLinearBias = in.tryGetProperty(String8("touch.toolSize.linearBias"),
2043c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            out.toolSizeLinearBias);
2044c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    out.haveToolSizeAreaScale = in.tryGetProperty(String8("touch.toolSize.areaScale"),
2045c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            out.toolSizeAreaScale);
2046c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    out.haveToolSizeAreaBias = in.tryGetProperty(String8("touch.toolSize.areaBias"),
2047c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            out.toolSizeAreaBias);
2048c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    out.haveToolSizeIsSummed = in.tryGetProperty(String8("touch.toolSize.isSummed"),
2049c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            out.toolSizeIsSummed);
20508d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
20518d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Pressure
20528d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
20538d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    String8 pressureCalibrationString;
2054c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) {
20558d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (pressureCalibrationString == "none") {
20568d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
20578d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (pressureCalibrationString == "physical") {
20588d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
20598d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (pressureCalibrationString == "amplitude") {
20608d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
20618d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (pressureCalibrationString != "default") {
2062c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            LOGW("Invalid value for touch.pressure.calibration: '%s'",
20638d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    pressureCalibrationString.string());
20648d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
20658d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
20668d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
20678d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    out.pressureSource = Calibration::PRESSURE_SOURCE_DEFAULT;
20688d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    String8 pressureSourceString;
20698d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    if (in.tryGetProperty(String8("touch.pressure.source"), pressureSourceString)) {
20708d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (pressureSourceString == "pressure") {
20718d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
20728d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (pressureSourceString == "touch") {
20738d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
20748d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (pressureSourceString != "default") {
20758d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            LOGW("Invalid value for touch.pressure.source: '%s'",
20768d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    pressureSourceString.string());
20778d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
20788d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
20798d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
20808d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
20818d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.pressureScale);
20828d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
20838d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Size
20848d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
20858d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    String8 sizeCalibrationString;
2086c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) {
20878d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (sizeCalibrationString == "none") {
20888d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
20898d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (sizeCalibrationString == "normalized") {
20908d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
20918d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (sizeCalibrationString != "default") {
2092c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            LOGW("Invalid value for touch.size.calibration: '%s'",
20938d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    sizeCalibrationString.string());
20948d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
20958d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
20968d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
20978d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Orientation
20988d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
20998d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    String8 orientationCalibrationString;
2100c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) {
21018d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (orientationCalibrationString == "none") {
21028d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
21038d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (orientationCalibrationString == "interpolated") {
21048d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
2105517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown        } else if (orientationCalibrationString == "vector") {
2106517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR;
21078d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (orientationCalibrationString != "default") {
2108c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            LOGW("Invalid value for touch.orientation.calibration: '%s'",
21098d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    orientationCalibrationString.string());
21108d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
21118d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
21128d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
21138d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
21148d60866e2100db70ecf0502c14768a384514d7e9Jeff Brownvoid TouchInputMapper::resolveCalibration() {
21158d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Pressure
21168d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    switch (mCalibration.pressureSource) {
21178d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_SOURCE_DEFAULT:
21188d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (mRawAxes.pressure.valid) {
21198d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
21208d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else if (mRawAxes.touchMajor.valid) {
21218d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
21228d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
21238d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
21248d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
21258d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_SOURCE_PRESSURE:
21268d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (! mRawAxes.pressure.valid) {
21278d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            LOGW("Calibration property touch.pressure.source is 'pressure' but "
21288d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    "the pressure axis is not available.");
21298d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
21308d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
21318d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
21328d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_SOURCE_TOUCH:
21338d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (! mRawAxes.touchMajor.valid) {
21348d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            LOGW("Calibration property touch.pressure.source is 'touch' but "
21358d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    "the touchMajor axis is not available.");
21368d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
21378d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
21388d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
21398d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
21408d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
21418d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
21428d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
21438d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    switch (mCalibration.pressureCalibration) {
21448d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_CALIBRATION_DEFAULT:
21458d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (mCalibration.pressureSource != Calibration::PRESSURE_SOURCE_DEFAULT) {
21468d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
21478d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else {
21488d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
21498d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
21508d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
21518d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
21528d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
21538d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
21548d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
21558d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2156c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    // Tool Size
2157c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    switch (mCalibration.toolSizeCalibration) {
2158c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    case Calibration::TOOL_SIZE_CALIBRATION_DEFAULT:
21598d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (mRawAxes.toolMajor.valid) {
2160c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR;
21618d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else {
2162c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE;
21638d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
21648d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
21658d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
21668d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
21678d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
21688d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
21698d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2170c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    // Touch Size
2171c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    switch (mCalibration.touchSizeCalibration) {
2172c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    case Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT:
21738d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE
2174c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                && mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) {
2175c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE;
21768d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else {
2177c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE;
21788d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
21798d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
21808d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
21818d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
21828d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
21838d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
21848d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
21858d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Size
21868d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    switch (mCalibration.sizeCalibration) {
21878d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::SIZE_CALIBRATION_DEFAULT:
21888d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (mRawAxes.toolMajor.valid) {
21898d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
21908d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else {
21918d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
21928d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
21938d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
21948d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
21958d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
21968d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
21978d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
21988d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
21998d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Orientation
22008d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    switch (mCalibration.orientationCalibration) {
22018d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::ORIENTATION_CALIBRATION_DEFAULT:
22028d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (mRawAxes.orientation.valid) {
22038d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
22048d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else {
22058d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
22068d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
22078d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
22088d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
22098d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
22108d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
22118d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
22128d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
22138d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2214ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brownvoid TouchInputMapper::dumpCalibration(String8& dump) {
2215ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown    dump.append(INDENT3 "Calibration:\n");
2216b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
2217c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    // Touch Size
2218c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    switch (mCalibration.touchSizeCalibration) {
2219c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    case Calibration::TOUCH_SIZE_CALIBRATION_NONE:
2220c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.append(INDENT4 "touch.touchSize.calibration: none\n");
22218d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
2222c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC:
2223c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.append(INDENT4 "touch.touchSize.calibration: geometric\n");
22248d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
2225c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE:
2226c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.append(INDENT4 "touch.touchSize.calibration: pressure\n");
22278d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
22288d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
22298d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        assert(false);
22308d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
22318d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2232c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    // Tool Size
2233c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    switch (mCalibration.toolSizeCalibration) {
2234c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    case Calibration::TOOL_SIZE_CALIBRATION_NONE:
2235c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.append(INDENT4 "touch.toolSize.calibration: none\n");
22368d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
2237c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC:
2238c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.append(INDENT4 "touch.toolSize.calibration: geometric\n");
22398d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
2240c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    case Calibration::TOOL_SIZE_CALIBRATION_LINEAR:
2241c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.append(INDENT4 "touch.toolSize.calibration: linear\n");
2242c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        break;
2243c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    case Calibration::TOOL_SIZE_CALIBRATION_AREA:
2244c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.append(INDENT4 "touch.toolSize.calibration: area\n");
22458d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
22468d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
22478d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        assert(false);
22488d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
22498d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2250c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    if (mCalibration.haveToolSizeLinearScale) {
2251c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "touch.toolSize.linearScale: %0.3f\n",
2252c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                mCalibration.toolSizeLinearScale);
2253c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    }
2254c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown
2255c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    if (mCalibration.haveToolSizeLinearBias) {
2256c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "touch.toolSize.linearBias: %0.3f\n",
2257c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                mCalibration.toolSizeLinearBias);
2258c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    }
2259c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown
2260c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    if (mCalibration.haveToolSizeAreaScale) {
2261c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "touch.toolSize.areaScale: %0.3f\n",
2262c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                mCalibration.toolSizeAreaScale);
22638d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
22648d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2265c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    if (mCalibration.haveToolSizeAreaBias) {
2266c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown        dump.appendFormat(INDENT4 "touch.toolSize.areaBias: %0.3f\n",
2267c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                mCalibration.toolSizeAreaBias);
22688d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
22698d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2270c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown    if (mCalibration.haveToolSizeIsSummed) {
22711f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        dump.appendFormat(INDENT4 "touch.toolSize.isSummed: %s\n",
227247e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown                toString(mCalibration.toolSizeIsSummed));
22738d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
22748d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
22758d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Pressure
22768d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    switch (mCalibration.pressureCalibration) {
22778d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_CALIBRATION_NONE:
2278ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.pressure.calibration: none\n");
22798d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
22808d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
2281ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.pressure.calibration: physical\n");
22828d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
22838d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
2284ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.pressure.calibration: amplitude\n");
22858d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
22868d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
22878d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        assert(false);
22888d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
22898d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
22908d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    switch (mCalibration.pressureSource) {
22918d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_SOURCE_PRESSURE:
2292ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.pressure.source: pressure\n");
22938d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
22948d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_SOURCE_TOUCH:
2295ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.pressure.source: touch\n");
22968d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
22978d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::PRESSURE_SOURCE_DEFAULT:
22988d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
22998d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
23008d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        assert(false);
23018d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
23028d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
23038d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    if (mCalibration.havePressureScale) {
2304ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n",
2305ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown                mCalibration.pressureScale);
23068d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
23078d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
23088d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Size
23098d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    switch (mCalibration.sizeCalibration) {
23108d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::SIZE_CALIBRATION_NONE:
2311ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.size.calibration: none\n");
23128d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
23138d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::SIZE_CALIBRATION_NORMALIZED:
2314ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.size.calibration: normalized\n");
23158d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
23168d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
23178d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        assert(false);
23188d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
23198d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
23208d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    // Orientation
23218d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    switch (mCalibration.orientationCalibration) {
23228d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::ORIENTATION_CALIBRATION_NONE:
2323ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.orientation.calibration: none\n");
23248d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
23258d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
2326ef3d7e861154c1ce1b8f86292138fc36c30232a3Jeff Brown        dump.append(INDENT4 "touch.orientation.calibration: interpolated\n");
23278d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        break;
2328517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown    case Calibration::ORIENTATION_CALIBRATION_VECTOR:
2329517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown        dump.append(INDENT4 "touch.orientation.calibration: vector\n");
2330517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown        break;
23318d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    default:
23328d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        assert(false);
23338d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    }
23348d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown}
23358d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
23366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid TouchInputMapper::reset() {
23376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Synthesize touch up event if touch is currently down.
23386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // This will also take care of finishing virtual key processing if needed.
23396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (mLastTouch.pointerCount != 0) {
23406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
23416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.clear();
23426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        syncTouch(when, true);
23436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
23446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
23456328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    { // acquire lock
23466328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        AutoMutex _l(mLock);
23476328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        initializeLocked();
23486328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    } // release lock
23496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
23506328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    InputMapper::reset();
23516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
23520b72e82c5f5d4ab709539c3490d6c7023f680dffJeff Brown
23536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
23546328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    // Preprocess pointer data.
23556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (mParameters.useBadTouchFilter) {
23566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (applyBadTouchFilter()) {
23576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            havePointerIds = false;
235846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
23596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
236046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
23616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (mParameters.useJumpyTouchFilter) {
23626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (applyJumpyTouchFilter()) {
23636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            havePointerIds = false;
23646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
23656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
236646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
23676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (! havePointerIds) {
23686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        calculatePointerIds();
23696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
237046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
23716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    TouchData temp;
23726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    TouchData* savedTouch;
23736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (mParameters.useAveragingTouchFilter) {
23746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        temp.copyFrom(mCurrentTouch);
23756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        savedTouch = & temp;
237646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
23776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        applyAveragingTouchFilter();
23786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } else {
23796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        savedTouch = & mCurrentTouch;
238046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
238146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
238256194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    uint32_t policyFlags = 0;
238305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) {
238456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        // Hide the pointer on an initial down.
238505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        getContext()->fadePointer();
238656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
238756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        // Initial downs on external touch devices should wake the device.
238856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        // We don't do this for internal touch screens to prevent them from waking
238956194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        // up in your pocket.
239056194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        // TODO: Use the input device configuration to control this behavior more finely.
239156194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        if (getDevice()->isExternal()) {
239256194ebec6212e229f4ccdaa4b187166d20013efJeff Brown            policyFlags |= POLICY_FLAG_WAKE_DROPPED;
239356194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        }
239405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
239546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
239605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    // Process touches and virtual keys.
23976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
23986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (touchResult == DISPATCH_TOUCH) {
2399fe50892af3b365806a767298dfd8e86447682581Jeff Brown        detectGestures(when);
24006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        dispatchTouches(when, policyFlags);
24016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
240246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
24036328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    // Copy current touch to last touch in preparation for the next cycle.
24046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (touchResult == DROP_STROKE) {
24056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mLastTouch.clear();
24066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } else {
24076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mLastTouch.copyFrom(*savedTouch);
24089c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    }
24099c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
24109c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
24116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownTouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
24126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        nsecs_t when, uint32_t policyFlags) {
24136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    int32_t keyEventAction, keyEventFlags;
24146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    int32_t keyCode, scanCode, downTime;
24156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    TouchResult touchResult;
241646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
24176328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    { // acquire lock
24186328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        AutoMutex _l(mLock);
24196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
24206328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        // Update surface size and orientation, including virtual key positions.
24216328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        if (! configureSurfaceLocked()) {
24226328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            return DROP_STROKE;
24236328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        }
24246328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
24256328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        // Check for virtual key press.
24266328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        if (mLocked.currentVirtualKey.down) {
24276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (mCurrentTouch.pointerCount == 0) {
24286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // Pointer went up while virtual key was down.
24296328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                mLocked.currentVirtualKey.down = false;
24306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_VIRTUAL_KEYS
24316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
2432c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown                        mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode);
24336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
24346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                keyEventAction = AKEY_EVENT_ACTION_UP;
24356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
24366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                touchResult = SKIP_TOUCH;
24376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                goto DispatchVirtualKey;
24386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
24396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
24406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (mCurrentTouch.pointerCount == 1) {
24416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                int32_t x = mCurrentTouch.pointers[0].x;
24426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                int32_t y = mCurrentTouch.pointers[0].y;
24436328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
24446328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) {
24456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    // Pointer is still within the space of the virtual key.
24466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    return SKIP_TOUCH;
24476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
24486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
24496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
24506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            // Pointer left virtual key area or another pointer also went down.
24516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            // Send key cancellation and drop the stroke so subsequent motions will be
24526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            // considered fresh downs.  This is useful when the user swipes away from the
24536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            // virtual key area into the main display surface.
24546328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            mLocked.currentVirtualKey.down = false;
24556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_VIRTUAL_KEYS
24566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
2457c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown                    mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode);
24586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
24596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            keyEventAction = AKEY_EVENT_ACTION_UP;
24606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
24616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    | AKEY_EVENT_FLAG_CANCELED;
2462c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown
2463c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            // Check whether the pointer moved inside the display area where we should
2464c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            // start a new stroke.
2465c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            int32_t x = mCurrentTouch.pointers[0].x;
2466c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            int32_t y = mCurrentTouch.pointers[0].y;
2467c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            if (isPointInsideSurfaceLocked(x, y)) {
2468c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown                mLastTouch.clear();
2469c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown                touchResult = DISPATCH_TOUCH;
2470c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            } else {
2471c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown                touchResult = DROP_STROKE;
2472c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            }
24736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        } else {
24746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (mCurrentTouch.pointerCount >= 1 && mLastTouch.pointerCount == 0) {
24756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // Pointer just went down.  Handle off-screen touches, if needed.
24766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                int32_t x = mCurrentTouch.pointers[0].x;
24776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                int32_t y = mCurrentTouch.pointers[0].y;
24786328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                if (! isPointInsideSurfaceLocked(x, y)) {
24796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    // If exactly one pointer went down, check for virtual key hit.
24806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    // Otherwise we will drop the entire stroke.
24816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    if (mCurrentTouch.pointerCount == 1) {
24826328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                        const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
24836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        if (virtualKey) {
2484fe50892af3b365806a767298dfd8e86447682581Jeff Brown                            if (mContext->shouldDropVirtualKey(when, getDevice(),
2485fe50892af3b365806a767298dfd8e86447682581Jeff Brown                                    virtualKey->keyCode, virtualKey->scanCode)) {
2486fe50892af3b365806a767298dfd8e86447682581Jeff Brown                                return DROP_STROKE;
2487fe50892af3b365806a767298dfd8e86447682581Jeff Brown                            }
2488fe50892af3b365806a767298dfd8e86447682581Jeff Brown
24896328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                            mLocked.currentVirtualKey.down = true;
24906328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                            mLocked.currentVirtualKey.downTime = when;
24916328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                            mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
24926328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                            mLocked.currentVirtualKey.scanCode = virtualKey->scanCode;
24936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_VIRTUAL_KEYS
24946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                            LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
2495c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown                                    mLocked.currentVirtualKey.keyCode,
2496c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown                                    mLocked.currentVirtualKey.scanCode);
24976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
24986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                            keyEventAction = AKEY_EVENT_ACTION_DOWN;
24996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                            keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM
25006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                                    | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
25016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                            touchResult = SKIP_TOUCH;
25026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                            goto DispatchVirtualKey;
25036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        }
25046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    }
25056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    return DROP_STROKE;
25066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
250746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
25086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return DISPATCH_TOUCH;
250946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
25106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
25116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    DispatchVirtualKey:
25126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // Collect remaining state needed to dispatch virtual key.
25136328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        keyCode = mLocked.currentVirtualKey.keyCode;
25146328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        scanCode = mLocked.currentVirtualKey.scanCode;
25156328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        downTime = mLocked.currentVirtualKey.downTime;
25166328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    } // release lock
25176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
25186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Dispatch virtual key.
25196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    int32_t metaState = mContext->getGlobalMetaState();
25200eaf3931a31c29f3a3883aab426b595c231c2a58Jeff Brown    policyFlags |= POLICY_FLAG_VIRTUAL;
2521b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
2522b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
2523b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    return touchResult;
252446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
252546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2526fe50892af3b365806a767298dfd8e86447682581Jeff Brownvoid TouchInputMapper::detectGestures(nsecs_t when) {
2527fe50892af3b365806a767298dfd8e86447682581Jeff Brown    // Disable all virtual key touches that happen within a short time interval of the
2528fe50892af3b365806a767298dfd8e86447682581Jeff Brown    // most recent touch.  The idea is to filter out stray virtual key presses when
2529fe50892af3b365806a767298dfd8e86447682581Jeff Brown    // interacting with the touch screen.
2530fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //
2531fe50892af3b365806a767298dfd8e86447682581Jeff Brown    // Problems we're trying to solve:
2532fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //
2533fe50892af3b365806a767298dfd8e86447682581Jeff Brown    // 1. While scrolling a list or dragging the window shade, the user swipes down into a
2534fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    virtual key area that is implemented by a separate touch panel and accidentally
2535fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    triggers a virtual key.
2536fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //
2537fe50892af3b365806a767298dfd8e86447682581Jeff Brown    // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
2538fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    area and accidentally triggers a virtual key.  This often happens when virtual keys
2539fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    are layed out below the screen near to where the on screen keyboard's space bar
2540fe50892af3b365806a767298dfd8e86447682581Jeff Brown    //    is displayed.
2541fe50892af3b365806a767298dfd8e86447682581Jeff Brown    if (mParameters.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) {
2542fe50892af3b365806a767298dfd8e86447682581Jeff Brown        mContext->disableVirtualKeysUntil(when + mParameters.virtualKeyQuietTime);
2543fe50892af3b365806a767298dfd8e86447682581Jeff Brown    }
2544fe50892af3b365806a767298dfd8e86447682581Jeff Brown}
2545fe50892af3b365806a767298dfd8e86447682581Jeff Brown
25466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
25476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    uint32_t currentPointerCount = mCurrentTouch.pointerCount;
25486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    uint32_t lastPointerCount = mLastTouch.pointerCount;
25496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (currentPointerCount == 0 && lastPointerCount == 0) {
25506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        return; // nothing to do!
25516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
25526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
25536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    BitSet32 currentIdBits = mCurrentTouch.idBits;
25546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    BitSet32 lastIdBits = mLastTouch.idBits;
255546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
25566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (currentIdBits == lastIdBits) {
25576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // No pointer id changes so this is a move event.
25586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // The dispatcher takes care of batching moves so we don't have to deal with that here.
25596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t motionEventAction = AMOTION_EVENT_ACTION_MOVE;
25606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        dispatchTouch(when, policyFlags, & mCurrentTouch,
25618d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                currentIdBits, -1, currentPointerCount, motionEventAction);
25626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } else {
2563c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // There may be pointers going up and pointers going down and pointers moving
2564c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // all at the same time.
25656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        BitSet32 upIdBits(lastIdBits.value & ~ currentIdBits.value);
25666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        BitSet32 downIdBits(currentIdBits.value & ~ lastIdBits.value);
25676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        BitSet32 activeIdBits(lastIdBits.value);
25688d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        uint32_t pointerCount = lastPointerCount;
25696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
2570c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // Produce an intermediate representation of the touch data that consists of the
2571c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // old location of pointers that have just gone up and the new location of pointers that
2572c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // have just moved but omits the location of pointers that have just gone down.
2573c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        TouchData interimTouch;
2574c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        interimTouch.copyFrom(mLastTouch);
2575c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown
2576c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
2577c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        bool moveNeeded = false;
2578c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        while (!moveIdBits.isEmpty()) {
2579c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            uint32_t moveId = moveIdBits.firstMarkedBit();
2580c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            moveIdBits.clearBit(moveId);
2581c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown
2582c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            int32_t oldIndex = mLastTouch.idToIndex[moveId];
2583c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            int32_t newIndex = mCurrentTouch.idToIndex[moveId];
2584c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            if (mLastTouch.pointers[oldIndex] != mCurrentTouch.pointers[newIndex]) {
2585c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown                interimTouch.pointers[oldIndex] = mCurrentTouch.pointers[newIndex];
2586c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown                moveNeeded = true;
2587c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            }
2588c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        }
2589c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown
2590c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // Dispatch pointer up events using the interim pointer locations.
2591c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        while (!upIdBits.isEmpty()) {
25926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            uint32_t upId = upIdBits.firstMarkedBit();
25936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            upIdBits.clearBit(upId);
25946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            BitSet32 oldActiveIdBits = activeIdBits;
25956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            activeIdBits.clearBit(upId);
25966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
25976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            int32_t motionEventAction;
25986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (activeIdBits.isEmpty()) {
25996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                motionEventAction = AMOTION_EVENT_ACTION_UP;
26006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            } else {
26016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                motionEventAction = AMOTION_EVENT_ACTION_POINTER_UP;
260246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
26036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
2604c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            dispatchTouch(when, policyFlags, &interimTouch,
26058d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    oldActiveIdBits, upId, pointerCount, motionEventAction);
26068d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            pointerCount -= 1;
260746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
260846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2609c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // Dispatch move events if any of the remaining pointers moved from their old locations.
2610c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // Although applications receive new locations as part of individual pointer up
2611c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // events, they do not generally handle them except when presented in a move event.
2612c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        if (moveNeeded) {
2613c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            dispatchTouch(when, policyFlags, &mCurrentTouch,
2614c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown                    activeIdBits, -1, pointerCount, AMOTION_EVENT_ACTION_MOVE);
2615c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        }
2616c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown
2617c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        // Dispatch pointer down events using the new pointer locations.
2618c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        while (!downIdBits.isEmpty()) {
26196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            uint32_t downId = downIdBits.firstMarkedBit();
26206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            downIdBits.clearBit(downId);
26216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            BitSet32 oldActiveIdBits = activeIdBits;
26226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            activeIdBits.markBit(downId);
26236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
26246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            int32_t motionEventAction;
26256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (oldActiveIdBits.isEmpty()) {
26266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                motionEventAction = AMOTION_EVENT_ACTION_DOWN;
26276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mDownTime = when;
26286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            } else {
26296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                motionEventAction = AMOTION_EVENT_ACTION_POINTER_DOWN;
26306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
263146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
26328d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            pointerCount += 1;
2633c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            dispatchTouch(when, policyFlags, &mCurrentTouch,
26348d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    activeIdBits, downId, pointerCount, motionEventAction);
26356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
26366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
263746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
263846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
26396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
26408d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        TouchData* touch, BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
26416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t motionEventAction) {
26426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    int32_t pointerIds[MAX_POINTERS];
26436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    PointerCoords pointerCoords[MAX_POINTERS];
26449626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    int32_t motionEventEdgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE;
26456328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    float xPrecision, yPrecision;
26466328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
26476328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    { // acquire lock
26486328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        AutoMutex _l(mLock);
26496328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
26506328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        // Walk through the the active pointers and map touch screen coordinates (TouchData) into
26516328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        // display coordinates (PointerCoords) and adjust for display orientation.
26528d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        for (uint32_t outIndex = 0; ! idBits.isEmpty(); outIndex++) {
26536328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            uint32_t id = idBits.firstMarkedBit();
26546328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            idBits.clearBit(id);
26558d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            uint32_t inIndex = touch->idToIndex[id];
26568d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
26578d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            const PointerData& in = touch->pointers[inIndex];
26588d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
26598d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            // ToolMajor and ToolMinor
26608d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            float toolMajor, toolMinor;
2661c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            switch (mCalibration.toolSizeCalibration) {
2662c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC:
26638d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                toolMajor = in.toolMajor * mLocked.geometricScale;
26648d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                if (mRawAxes.toolMinor.valid) {
26658d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    toolMinor = in.toolMinor * mLocked.geometricScale;
26668d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                } else {
26678d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    toolMinor = toolMajor;
26688d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                }
26698d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
2670c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            case Calibration::TOOL_SIZE_CALIBRATION_LINEAR:
26718d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                toolMajor = in.toolMajor != 0
2672c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                        ? in.toolMajor * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias
26738d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                        : 0;
26748d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                if (mRawAxes.toolMinor.valid) {
26758d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    toolMinor = in.toolMinor != 0
2676c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                            ? in.toolMinor * mLocked.toolSizeLinearScale
2677c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                                    + mLocked.toolSizeLinearBias
26788d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                            : 0;
26798d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                } else {
26808d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    toolMinor = toolMajor;
26818d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                }
26828d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
2683c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            case Calibration::TOOL_SIZE_CALIBRATION_AREA:
2684c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                if (in.toolMajor != 0) {
2685c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    float diameter = sqrtf(in.toolMajor
2686c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                            * mLocked.toolSizeAreaScale + mLocked.toolSizeAreaBias);
2687c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    toolMajor = diameter * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias;
2688c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                } else {
2689c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                    toolMajor = 0;
2690c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                }
2691c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                toolMinor = toolMajor;
2692c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown                break;
26938d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            default:
26948d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                toolMajor = 0;
26958d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                toolMinor = 0;
26968d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
26978d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
26988d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
2699c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            if (mCalibration.haveToolSizeIsSummed && mCalibration.toolSizeIsSummed) {
27008d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                toolMajor /= pointerCount;
27018d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                toolMinor /= pointerCount;
27028d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
27038d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
27048d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            // Pressure
27058d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            float rawPressure;
27068d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            switch (mCalibration.pressureSource) {
27078d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            case Calibration::PRESSURE_SOURCE_PRESSURE:
27088d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                rawPressure = in.pressure;
27098d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
27108d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            case Calibration::PRESSURE_SOURCE_TOUCH:
27118d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                rawPressure = in.touchMajor;
27128d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
27138d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            default:
27148d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                rawPressure = 0;
27158d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
27168d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
27178d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            float pressure;
27188d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            switch (mCalibration.pressureCalibration) {
27198d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
27208d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
27218d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                pressure = rawPressure * mLocked.pressureScale;
27228d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
27238d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            default:
27248d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                pressure = 1;
27258d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
27268d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
27278d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
27288d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            // TouchMajor and TouchMinor
27298d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            float touchMajor, touchMinor;
2730c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            switch (mCalibration.touchSizeCalibration) {
2731c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC:
27328d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                touchMajor = in.touchMajor * mLocked.geometricScale;
27338d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                if (mRawAxes.touchMinor.valid) {
27348d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    touchMinor = in.touchMinor * mLocked.geometricScale;
27358d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                } else {
27368d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    touchMinor = touchMajor;
27378d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                }
27388d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
2739c6d282bb8223ed21666878f71c5a55013ee37805Jeff Brown            case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE:
27408d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                touchMajor = toolMajor * pressure;
27418d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                touchMinor = toolMinor * pressure;
27428d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
27438d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            default:
27448d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                touchMajor = 0;
27458d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                touchMinor = 0;
27468d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
27478d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
27488d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
27498d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            if (touchMajor > toolMajor) {
27508d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                touchMajor = toolMajor;
27518d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
27528d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            if (touchMinor > toolMinor) {
27538d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                touchMinor = toolMinor;
27548d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
27558d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
27568d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            // Size
27578d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            float size;
27588d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            switch (mCalibration.sizeCalibration) {
27598d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            case Calibration::SIZE_CALIBRATION_NORMALIZED: {
27608d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                float rawSize = mRawAxes.toolMinor.valid
27618d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                        ? avg(in.toolMajor, in.toolMinor)
27628d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                        : in.toolMajor;
27638d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                size = rawSize * mLocked.sizeScale;
27648d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
27658d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
27668d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            default:
27678d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                size = 0;
27688d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
27696328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
27709c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
27718d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            // Orientation
27728d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            float orientation;
27738d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            switch (mCalibration.orientationCalibration) {
27748d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
27758d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                orientation = in.orientation * mLocked.orientationScale;
27768d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                break;
2777517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown            case Calibration::ORIENTATION_CALIBRATION_VECTOR: {
2778517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown                int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
2779517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown                int32_t c2 = signExtendNybble(in.orientation & 0x0f);
2780517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown                if (c1 != 0 || c2 != 0) {
2781517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown                    orientation = atan2f(c1, c2) * 0.5f;
2782c3451d4a4479b6244bd6d1dadf289a8d44bdcca2Jeff Brown                    float scale = 1.0f + pythag(c1, c2) / 16.0f;
2783c3451d4a4479b6244bd6d1dadf289a8d44bdcca2Jeff Brown                    touchMajor *= scale;
2784c3451d4a4479b6244bd6d1dadf289a8d44bdcca2Jeff Brown                    touchMinor /= scale;
2785c3451d4a4479b6244bd6d1dadf289a8d44bdcca2Jeff Brown                    toolMajor *= scale;
2786c3451d4a4479b6244bd6d1dadf289a8d44bdcca2Jeff Brown                    toolMinor /= scale;
2787517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown                } else {
2788517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown                    orientation = 0;
2789517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown                }
2790517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown                break;
2791517bb4c859a2bb8d30316204f39bf5b6c89c3e4dJeff Brown            }
27928d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            default:
27938d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                orientation = 0;
27948d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
27958d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
27969626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            // X and Y
27979626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            // Adjust coords for surface orientation.
27989626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            float x, y;
27996328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            switch (mLocked.surfaceOrientation) {
28009626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            case DISPLAY_ORIENTATION_90:
28019626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                x = float(in.y - mRawAxes.y.minValue) * mLocked.yScale;
28029626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                y = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale;
28036328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                orientation -= M_PI_2;
28046328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                if (orientation < - M_PI_2) {
28056328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                    orientation += M_PI;
28066328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                }
28076328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                break;
28089626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            case DISPLAY_ORIENTATION_180:
28099626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                x = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale;
28109626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                y = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale;
28116328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                break;
28129626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            case DISPLAY_ORIENTATION_270:
28139626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                x = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale;
28149626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                y = float(in.x - mRawAxes.x.minValue) * mLocked.xScale;
28156328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                orientation += M_PI_2;
28166328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                if (orientation > M_PI_2) {
28176328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                    orientation -= M_PI;
28186328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                }
28196328cdc89e099806a1893b89e4c724d596272d9eJeff Brown                break;
28209626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            default:
28219626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                x = float(in.x - mRawAxes.x.minValue) * mLocked.xScale;
28229626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                y = float(in.y - mRawAxes.y.minValue) * mLocked.yScale;
28239626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                break;
28246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
28256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
28268d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            // Write output coords.
28278d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            PointerCoords& out = pointerCoords[outIndex];
282891c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            out.clear();
2829ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
2830ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
2831ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
2832ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
2833ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
2834ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
2835ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
2836ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
2837ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown            out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
28386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
28398d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            pointerIds[outIndex] = int32_t(id);
28406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
28416328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            if (id == changedId) {
28428d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                motionEventAction |= outIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
28436328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
28446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
28456328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
28466328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        // Check edge flags by looking only at the first pointer since the flags are
28476328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        // global to the event.
28486328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
28499626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            uint32_t inIndex = touch->idToIndex[pointerIds[0]];
28509626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            const PointerData& in = touch->pointers[inIndex];
285191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown
28529626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            if (in.x <= mRawAxes.x.minValue) {
28539626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_LEFT,
28549626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                        mLocked.surfaceOrientation);
28559626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            } else if (in.x >= mRawAxes.x.maxValue) {
28569626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_RIGHT,
28579626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                        mLocked.surfaceOrientation);
28586328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
28599626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            if (in.y <= mRawAxes.y.minValue) {
28609626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_TOP,
28619626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                        mLocked.surfaceOrientation);
28629626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            } else if (in.y >= mRawAxes.y.maxValue) {
28639626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_BOTTOM,
28649626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown                        mLocked.surfaceOrientation);
28656328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            }
28666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
28676328cdc89e099806a1893b89e4c724d596272d9eJeff Brown
28686328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        xPrecision = mLocked.orientedXPrecision;
28696328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        yPrecision = mLocked.orientedYPrecision;
28706328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    } // release lock
28719c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
287283c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown    getDispatcher()->notifyMotion(when, getDeviceId(), mSources, policyFlags,
287385a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown            motionEventAction, 0, getContext()->getGlobalMetaState(), motionEventEdgeFlags,
28746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointerCount, pointerIds, pointerCoords,
28756328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            xPrecision, yPrecision, mDownTime);
28769c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
28779c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
28786328cdc89e099806a1893b89e4c724d596272d9eJeff Brownbool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) {
28799626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue
28809626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown            && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue;
28819c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
28829c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
28836328cdc89e099806a1893b89e4c724d596272d9eJeff Brownconst TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked(
28846328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        int32_t x, int32_t y) {
28856328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    size_t numVirtualKeys = mLocked.virtualKeys.size();
28866328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    for (size_t i = 0; i < numVirtualKeys; i++) {
28876328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        const VirtualKey& virtualKey = mLocked.virtualKeys[i];
28889c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
28896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_VIRTUAL_KEYS
28906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
28916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                "left=%d, top=%d, right=%d, bottom=%d",
28926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                x, y,
28936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                virtualKey.keyCode, virtualKey.scanCode,
28946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                virtualKey.hitLeft, virtualKey.hitTop,
28956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                virtualKey.hitRight, virtualKey.hitBottom);
28966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
28976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
28986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (virtualKey.isHit(x, y)) {
28996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return & virtualKey;
29009c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        }
29016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
29029c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
29036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return NULL;
29049c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
29059c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
29066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid TouchInputMapper::calculatePointerIds() {
29076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    uint32_t currentPointerCount = mCurrentTouch.pointerCount;
29086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    uint32_t lastPointerCount = mLastTouch.pointerCount;
29096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
29106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (currentPointerCount == 0) {
29116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // No pointers to assign.
29126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.idBits.clear();
29136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } else if (lastPointerCount == 0) {
29146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // All pointers are new.
29156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.idBits.clear();
29166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        for (uint32_t i = 0; i < currentPointerCount; i++) {
29176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mCurrentTouch.pointers[i].id = i;
29186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mCurrentTouch.idToIndex[i] = i;
29196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mCurrentTouch.idBits.markBit(i);
29206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
29216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } else if (currentPointerCount == 1 && lastPointerCount == 1) {
29226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // Only one pointer and no change in count so it must have the same id as before.
29236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        uint32_t id = mLastTouch.pointers[0].id;
29246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.pointers[0].id = id;
29256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.idToIndex[id] = 0;
29266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.idBits.value = BitSet32::valueForBit(id);
29276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    } else {
29286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // General case.
29296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // We build a heap of squared euclidean distances between current and last pointers
29306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // associated with the current and last pointer indices.  Then, we find the best
29316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // match (by distance) for each current pointer.
29326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
29336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
29346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        uint32_t heapSize = 0;
29356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
29366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                currentPointerIndex++) {
29376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
29386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    lastPointerIndex++) {
29396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                int64_t deltaX = mCurrentTouch.pointers[currentPointerIndex].x
29406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        - mLastTouch.pointers[lastPointerIndex].x;
29416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                int64_t deltaY = mCurrentTouch.pointers[currentPointerIndex].y
29426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        - mLastTouch.pointers[lastPointerIndex].y;
29436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
29446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
29456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
29466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // Insert new element into the heap (sift up).
29476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                heap[heapSize].currentPointerIndex = currentPointerIndex;
29486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                heap[heapSize].lastPointerIndex = lastPointerIndex;
29496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                heap[heapSize].distance = distance;
29506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                heapSize += 1;
29516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
29526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
29539c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
29546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // Heapify
29556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
29566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            startIndex -= 1;
29576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            for (uint32_t parentIndex = startIndex; ;) {
29586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                uint32_t childIndex = parentIndex * 2 + 1;
29596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (childIndex >= heapSize) {
29606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    break;
29616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
29626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
29636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (childIndex + 1 < heapSize
29646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        && heap[childIndex + 1].distance < heap[childIndex].distance) {
29656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    childIndex += 1;
29666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
29676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
29686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (heap[parentIndex].distance <= heap[childIndex].distance) {
29696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    break;
29706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
29716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
29726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                swap(heap[parentIndex], heap[childIndex]);
29736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                parentIndex = childIndex;
29746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
29759c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        }
29769c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
29776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_POINTER_ASSIGNMENT
29786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        LOGD("calculatePointerIds - initial distance min-heap: size=%d", heapSize);
29796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        for (size_t i = 0; i < heapSize; i++) {
29806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            LOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
29816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
29826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    heap[i].distance);
29836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
29846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
29859c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
29866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // Pull matches out by increasing order of distance.
29876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // To avoid reassigning pointers that have already been matched, the loop keeps track
29886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // of which last and current pointers have been matched using the matchedXXXBits variables.
29896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // It also tracks the used pointer id bits.
29906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        BitSet32 matchedLastBits(0);
29916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        BitSet32 matchedCurrentBits(0);
29926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        BitSet32 usedIdBits(0);
29936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        bool first = true;
29946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        for (uint32_t i = min(currentPointerCount, lastPointerCount); i > 0; i--) {
29956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            for (;;) {
29966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (first) {
29976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    // The first time through the loop, we just consume the root element of
29986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    // the heap (the one with smallest distance).
29996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    first = false;
30006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                } else {
30016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    // Previous iterations consumed the root element of the heap.
30026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    // Pop root element off of the heap (sift down).
30036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    heapSize -= 1;
30046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    assert(heapSize > 0);
30056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
30066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    // Sift down.
30076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    heap[0] = heap[heapSize];
30086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    for (uint32_t parentIndex = 0; ;) {
30096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        uint32_t childIndex = parentIndex * 2 + 1;
30106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        if (childIndex >= heapSize) {
30116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                            break;
30126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        }
30136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
30146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        if (childIndex + 1 < heapSize
30156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                                && heap[childIndex + 1].distance < heap[childIndex].distance) {
30166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                            childIndex += 1;
30176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        }
30186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
30196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        if (heap[parentIndex].distance <= heap[childIndex].distance) {
30206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                            break;
30216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        }
30226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
30236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        swap(heap[parentIndex], heap[childIndex]);
30246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        parentIndex = childIndex;
30256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    }
30266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
30276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_POINTER_ASSIGNMENT
30286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    LOGD("calculatePointerIds - reduced distance min-heap: size=%d", heapSize);
30296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    for (size_t i = 0; i < heapSize; i++) {
30306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        LOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
30316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                                i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
30326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                                heap[i].distance);
30336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    }
30346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
30356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
303646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
30376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                uint32_t currentPointerIndex = heap[0].currentPointerIndex;
30386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
303946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
30406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                uint32_t lastPointerIndex = heap[0].lastPointerIndex;
30416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
304246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
30436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                matchedCurrentBits.markBit(currentPointerIndex);
30446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                matchedLastBits.markBit(lastPointerIndex);
304546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
30466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                uint32_t id = mLastTouch.pointers[lastPointerIndex].id;
30476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mCurrentTouch.pointers[currentPointerIndex].id = id;
30486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mCurrentTouch.idToIndex[id] = currentPointerIndex;
30496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                usedIdBits.markBit(id);
305046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
30516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_POINTER_ASSIGNMENT
30526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                LOGD("calculatePointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
30536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        lastPointerIndex, currentPointerIndex, id, heap[0].distance);
30546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
30556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                break;
30566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
30576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
305846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
30596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // Assign fresh ids to new pointers.
30606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (currentPointerCount > lastPointerCount) {
30616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            for (uint32_t i = currentPointerCount - lastPointerCount; ;) {
30626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                uint32_t currentPointerIndex = matchedCurrentBits.firstUnmarkedBit();
30636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                uint32_t id = usedIdBits.firstUnmarkedBit();
30646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
30656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mCurrentTouch.pointers[currentPointerIndex].id = id;
30666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mCurrentTouch.idToIndex[id] = currentPointerIndex;
30676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                usedIdBits.markBit(id);
30686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
30696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_POINTER_ASSIGNMENT
30706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                LOGD("calculatePointerIds - assigned: cur=%d, id=%d",
30716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        currentPointerIndex, id);
30726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
30736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
30746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (--i == 0) break; // done
30756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                matchedCurrentBits.markBit(currentPointerIndex);
30766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
30776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
30786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
30796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // Fix id bits.
30806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.idBits = usedIdBits;
30816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
308246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
308346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
30846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown/* Special hack for devices that have bad screen data: if one of the
30856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * points has moved more than a screen height from the last position,
30866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * then drop it. */
30876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool TouchInputMapper::applyBadTouchFilter() {
30886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    uint32_t pointerCount = mCurrentTouch.pointerCount;
30896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
30906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Nothing to do if there are no points.
30916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (pointerCount == 0) {
30926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        return false;
30936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
30946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
30956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Don't do anything if a finger is going down or up.  We run
30966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // here before assigning pointer IDs, so there isn't a good
30976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // way to do per-finger matching.
30986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (pointerCount != mLastTouch.pointerCount) {
30996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        return false;
31006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
31016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // We consider a single movement across more than a 7/16 of
31036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // the long size of the screen to be bad.  This was a magic value
31046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // determined by looking at the maximum distance it is feasible
31056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // to actually move in one sample.
31069626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown    int32_t maxDeltaY = (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1) * 7 / 16;
31076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // XXX The original code in InputDevice.java included commented out
31096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    //     code for testing the X axis.  Note that when we drop a point
31106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    //     we don't actually restore the old X either.  Strange.
31116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    //     The old code also tries to track when bad points were previously
31126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    //     detected but it turns out that due to the placement of a "break"
31136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    //     at the end of the loop, we never set mDroppedBadPoint to true
31146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    //     so it is effectively dead code.
31156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Need to figure out if the old code is busted or just overcomplicated
31166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // but working as intended.
31176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // Look through all new points and see if any are farther than
31196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // acceptable from all previous points.
31206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (uint32_t i = pointerCount; i-- > 0; ) {
31216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t y = mCurrentTouch.pointers[i].y;
31226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t closestY = INT_MAX;
31236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t closestDeltaY = 0;
31246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_HACKS
31266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        LOGD("BadTouchFilter: Looking at next point #%d: y=%d", i, y);
31276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
31286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        for (uint32_t j = pointerCount; j-- > 0; ) {
31306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            int32_t lastY = mLastTouch.pointers[j].y;
31316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            int32_t deltaY = abs(y - lastY);
31326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_HACKS
31346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            LOGD("BadTouchFilter: Comparing with last point #%d: y=%d deltaY=%d",
31356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    j, lastY, deltaY);
31366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
31376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (deltaY < maxDeltaY) {
31396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                goto SkipSufficientlyClosePoint;
31406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
31416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (deltaY < closestDeltaY) {
31426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                closestDeltaY = deltaY;
31436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                closestY = lastY;
31446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
31456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
31466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // Must not have found a close enough match.
31486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_HACKS
31496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        LOGD("BadTouchFilter: Dropping bad point #%d: newY=%d oldY=%d deltaY=%d maxDeltaY=%d",
31506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                i, y, closestY, closestDeltaY, maxDeltaY);
31516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
31526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.pointers[i].y = closestY;
31546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        return true; // XXX original code only corrects one point
31556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    SkipSufficientlyClosePoint: ;
31576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
31586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // No change.
31606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return false;
31616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
31626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown/* Special hack for devices that have bad screen data: drop points where
31646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * the coordinate value for one axis has jumped to the other pointer's location.
31656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown */
31666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool TouchInputMapper::applyJumpyTouchFilter() {
31676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    uint32_t pointerCount = mCurrentTouch.pointerCount;
31686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (mLastTouch.pointerCount != pointerCount) {
31696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_HACKS
31706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        LOGD("JumpyTouchFilter: Different pointer count %d -> %d",
31716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mLastTouch.pointerCount, pointerCount);
31726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        for (uint32_t i = 0; i < pointerCount; i++) {
31736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            LOGD("  Pointer %d (%d, %d)", i,
31746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y);
31756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
31766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
31776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_TRANSITION_DROPS) {
31796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (mLastTouch.pointerCount == 1 && pointerCount == 2) {
31806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // Just drop the first few events going from 1 to 2 pointers.
31816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // They're bad often enough that they're not worth considering.
31826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mCurrentTouch.pointerCount = 1;
31836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mJumpyTouchFilter.jumpyPointsDropped += 1;
31846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_HACKS
31866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                LOGD("JumpyTouchFilter: Pointer 2 dropped");
31876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
31886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                return true;
31896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            } else if (mLastTouch.pointerCount == 2 && pointerCount == 1) {
31906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // The event when we go from 2 -> 1 tends to be messed up too
31916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mCurrentTouch.pointerCount = 2;
31926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mCurrentTouch.pointers[0] = mLastTouch.pointers[0];
31936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mCurrentTouch.pointers[1] = mLastTouch.pointers[1];
31946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mJumpyTouchFilter.jumpyPointsDropped += 1;
31956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
31966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_HACKS
31976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                for (int32_t i = 0; i < 2; i++) {
31986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    LOGD("JumpyTouchFilter: Pointer %d replaced (%d, %d)", i,
31996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                            mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y);
32006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
32016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
32026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                return true;
32036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
32046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
32056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // Reset jumpy points dropped on other transitions or if limit exceeded.
32066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mJumpyTouchFilter.jumpyPointsDropped = 0;
32076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
32086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_HACKS
32096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        LOGD("JumpyTouchFilter: Transition - drop limit reset");
32106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
32116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        return false;
32126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
32136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
32146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // We have the same number of pointers as last time.
32156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // A 'jumpy' point is one where the coordinate value for one axis
32166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // has jumped to the other pointer's location. No need to do anything
32176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    // else if we only have one pointer.
32186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (pointerCount < 2) {
32196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        return false;
32206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
32216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
32226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) {
32239626b14a283ef82d16636cf5fb5ba8bb4d30381eJeff Brown        int jumpyEpsilon = (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1) / JUMPY_EPSILON_DIVISOR;
32246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
32256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // We only replace the single worst jumpy point as characterized by pointer distance
32266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // in a single axis.
32276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t badPointerIndex = -1;
32286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t badPointerReplacementIndex = -1;
32296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t badPointerDistance = INT_MIN; // distance to be corrected
32306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
32316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        for (uint32_t i = pointerCount; i-- > 0; ) {
32326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            int32_t x = mCurrentTouch.pointers[i].x;
32336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            int32_t y = mCurrentTouch.pointers[i].y;
32346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
32356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_HACKS
32366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            LOGD("JumpyTouchFilter: Point %d (%d, %d)", i, x, y);
32376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
32386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
32396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            // Check if a touch point is too close to another's coordinates
32406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            bool dropX = false, dropY = false;
32416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            for (uint32_t j = 0; j < pointerCount; j++) {
32426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (i == j) {
32436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    continue;
32446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
32456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
32466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (abs(x - mCurrentTouch.pointers[j].x) <= jumpyEpsilon) {
32476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    dropX = true;
32486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    break;
32496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
32506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
32516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (abs(y - mCurrentTouch.pointers[j].y) <= jumpyEpsilon) {
32526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    dropY = true;
32536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    break;
32546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
32556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
32566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (! dropX && ! dropY) {
32576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                continue; // not jumpy
32586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
32596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
32606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            // Find a replacement candidate by comparing with older points on the
32616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            // complementary (non-jumpy) axis.
32626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            int32_t distance = INT_MIN; // distance to be corrected
32636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            int32_t replacementIndex = -1;
32646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
32656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (dropX) {
32666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // X looks too close.  Find an older replacement point with a close Y.
32676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                int32_t smallestDeltaY = INT_MAX;
32686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                for (uint32_t j = 0; j < pointerCount; j++) {
32696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    int32_t deltaY = abs(y - mLastTouch.pointers[j].y);
32706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    if (deltaY < smallestDeltaY) {
32716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        smallestDeltaY = deltaY;
32726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        replacementIndex = j;
32736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    }
32746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
32756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                distance = abs(x - mLastTouch.pointers[replacementIndex].x);
32766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            } else {
32776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // Y looks too close.  Find an older replacement point with a close X.
32786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                int32_t smallestDeltaX = INT_MAX;
32796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                for (uint32_t j = 0; j < pointerCount; j++) {
32806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    int32_t deltaX = abs(x - mLastTouch.pointers[j].x);
32816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    if (deltaX < smallestDeltaX) {
32826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        smallestDeltaX = deltaX;
32836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        replacementIndex = j;
32846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    }
32856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
32866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                distance = abs(y - mLastTouch.pointers[replacementIndex].y);
32876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
32886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
32896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            // If replacing this pointer would correct a worse error than the previous ones
32906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            // considered, then use this replacement instead.
32916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (distance > badPointerDistance) {
32926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                badPointerIndex = i;
32936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                badPointerReplacementIndex = replacementIndex;
32946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                badPointerDistance = distance;
32956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
32966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
32976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
32986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // Correct the jumpy pointer if one was found.
32996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (badPointerIndex >= 0) {
33006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_HACKS
33016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            LOGD("JumpyTouchFilter: Replacing bad pointer %d with (%d, %d)",
33026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    badPointerIndex,
33036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    mLastTouch.pointers[badPointerReplacementIndex].x,
33046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    mLastTouch.pointers[badPointerReplacementIndex].y);
33056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
33066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mCurrentTouch.pointers[badPointerIndex].x =
33086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    mLastTouch.pointers[badPointerReplacementIndex].x;
33096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mCurrentTouch.pointers[badPointerIndex].y =
33106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    mLastTouch.pointers[badPointerReplacementIndex].y;
33116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mJumpyTouchFilter.jumpyPointsDropped += 1;
33126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return true;
33136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
33146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
33156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mJumpyTouchFilter.jumpyPointsDropped = 0;
33176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return false;
33186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
33196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown/* Special hack for devices that have bad screen data: aggregate and
33216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * compute averages of the coordinate data, to reduce the amount of
33226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown * jitter seen by applications. */
33236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid TouchInputMapper::applyAveragingTouchFilter() {
33246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (uint32_t currentIndex = 0; currentIndex < mCurrentTouch.pointerCount; currentIndex++) {
33256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        uint32_t id = mCurrentTouch.pointers[currentIndex].id;
33266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t x = mCurrentTouch.pointers[currentIndex].x;
33276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        int32_t y = mCurrentTouch.pointers[currentIndex].y;
33288d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        int32_t pressure;
33298d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        switch (mCalibration.pressureSource) {
33308d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        case Calibration::PRESSURE_SOURCE_PRESSURE:
33318d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            pressure = mCurrentTouch.pointers[currentIndex].pressure;
33328d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            break;
33338d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        case Calibration::PRESSURE_SOURCE_TOUCH:
33348d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            pressure = mCurrentTouch.pointers[currentIndex].touchMajor;
33358d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            break;
33368d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        default:
33378d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            pressure = 1;
33388d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            break;
33398d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
33406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (mLastTouch.idBits.hasBit(id)) {
33426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            // Pointer was down before and is still down now.
33436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            // Compute average over history trace.
33446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            uint32_t start = mAveragingTouchFilter.historyStart[id];
33456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            uint32_t end = mAveragingTouchFilter.historyEnd[id];
33466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            int64_t deltaX = x - mAveragingTouchFilter.historyData[end].pointers[id].x;
33486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            int64_t deltaY = y - mAveragingTouchFilter.historyData[end].pointers[id].y;
33496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
33506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_HACKS
33526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            LOGD("AveragingTouchFilter: Pointer id %d - Distance from last sample: %lld",
33536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    id, distance);
33546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
33556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (distance < AVERAGING_DISTANCE_LIMIT) {
33576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // Increment end index in preparation for recording new historical data.
33586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                end += 1;
33596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (end > AVERAGING_HISTORY_SIZE) {
33606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    end = 0;
33616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
33626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // If the end index has looped back to the start index then we have filled
33646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // the historical trace up to the desired size so we drop the historical
33656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // data at the start of the trace.
33666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (end == start) {
33676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    start += 1;
33686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    if (start > AVERAGING_HISTORY_SIZE) {
33696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        start = 0;
33706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    }
33716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
33726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // Add the raw data to the historical trace.
33746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mAveragingTouchFilter.historyStart[id] = start;
33756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mAveragingTouchFilter.historyEnd[id] = end;
33766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mAveragingTouchFilter.historyData[end].pointers[id].x = x;
33776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mAveragingTouchFilter.historyData[end].pointers[id].y = y;
33786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                mAveragingTouchFilter.historyData[end].pointers[id].pressure = pressure;
33796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                // Average over all historical positions in the trace by total pressure.
33816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                int32_t averagedX = 0;
33826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                int32_t averagedY = 0;
33836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                int32_t totalPressure = 0;
33846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                for (;;) {
33856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    int32_t historicalX = mAveragingTouchFilter.historyData[start].pointers[id].x;
33866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    int32_t historicalY = mAveragingTouchFilter.historyData[start].pointers[id].y;
33876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    int32_t historicalPressure = mAveragingTouchFilter.historyData[start]
33886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                            .pointers[id].pressure;
33896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    averagedX += historicalX * historicalPressure;
33916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    averagedY += historicalY * historicalPressure;
33926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    totalPressure += historicalPressure;
33936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    if (start == end) {
33956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        break;
33966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    }
33976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
33986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    start += 1;
33996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    if (start > AVERAGING_HISTORY_SIZE) {
34006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                        start = 0;
34016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    }
34026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
34036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34048d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                if (totalPressure != 0) {
34058d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    averagedX /= totalPressure;
34068d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    averagedY /= totalPressure;
34076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_HACKS
34098d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    LOGD("AveragingTouchFilter: Pointer id %d - "
34108d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                            "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure,
34118d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                            averagedX, averagedY);
34126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
34136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34148d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    mCurrentTouch.pointers[currentIndex].x = averagedX;
34158d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                    mCurrentTouch.pointers[currentIndex].y = averagedY;
34168d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                }
34176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            } else {
34186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_HACKS
34196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                LOGD("AveragingTouchFilter: Pointer id %d - Exceeded max distance", id);
34206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
34216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
34226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        } else {
34236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_HACKS
34246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            LOGD("AveragingTouchFilter: Pointer id %d - Pointer went up", id);
34256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
34266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
34276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        // Reset pointer history.
34296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mAveragingTouchFilter.historyStart[id] = 0;
34306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mAveragingTouchFilter.historyEnd[id] = 0;
34316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mAveragingTouchFilter.historyData[0].pointers[id].x = x;
34326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mAveragingTouchFilter.historyData[0].pointers[id].y = y;
34336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mAveragingTouchFilter.historyData[0].pointers[id].pressure = pressure;
34346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
34356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
34366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
34386328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    { // acquire lock
34396328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        AutoMutex _l(mLock);
34406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34416328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) {
34426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return AKEY_STATE_VIRTUAL;
34436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
34446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34456328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        size_t numVirtualKeys = mLocked.virtualKeys.size();
34466328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        for (size_t i = 0; i < numVirtualKeys; i++) {
34476328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
34486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (virtualKey.keyCode == keyCode) {
34496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                return AKEY_STATE_UP;
34506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
34516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
34526328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    } // release lock
34536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
34556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
34566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownint32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
34586328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    { // acquire lock
34596328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        AutoMutex _l(mLock);
34606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34616328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) {
34626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            return AKEY_STATE_VIRTUAL;
34636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
34646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34656328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        size_t numVirtualKeys = mLocked.virtualKeys.size();
34666328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        for (size_t i = 0; i < numVirtualKeys; i++) {
34676328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
34686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (virtualKey.scanCode == scanCode) {
34696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                return AKEY_STATE_UP;
34706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
34716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
34726328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    } // release lock
34736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return AKEY_STATE_UNKNOWN;
34756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
34766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownbool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
34786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        const int32_t* keyCodes, uint8_t* outFlags) {
34796328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    { // acquire lock
34806328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        AutoMutex _l(mLock);
34816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34826328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        size_t numVirtualKeys = mLocked.virtualKeys.size();
34836328cdc89e099806a1893b89e4c724d596272d9eJeff Brown        for (size_t i = 0; i < numVirtualKeys; i++) {
34846328cdc89e099806a1893b89e4c724d596272d9eJeff Brown            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
34856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            for (size_t i = 0; i < numCodes; i++) {
34876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (virtualKey.keyCode == keyCodes[i]) {
34886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    outFlags[i] = 1;
34896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
34906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
34916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
34926328cdc89e099806a1893b89e4c724d596272d9eJeff Brown    } // release lock
34936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    return true;
34956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
34966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
34986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- SingleTouchInputMapper ---
34996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
350047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff BrownSingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) :
350147e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        TouchInputMapper(device) {
35026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    initialize();
35036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
35046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownSingleTouchInputMapper::~SingleTouchInputMapper() {
35066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
35076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid SingleTouchInputMapper::initialize() {
35096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mAccumulator.clear();
35106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mDown = false;
35126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mX = 0;
35136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mY = 0;
35148d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mPressure = 0; // default to 0 for devices that don't report pressure
35158d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    mToolWidth = 0; // default to 0 for devices that don't report tool width
35166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
35176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid SingleTouchInputMapper::reset() {
35196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    TouchInputMapper::reset();
35206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    initialize();
35226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown }
35236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid SingleTouchInputMapper::process(const RawEvent* rawEvent) {
35256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    switch (rawEvent->type) {
35266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    case EV_KEY:
35276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        switch (rawEvent->scanCode) {
35286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case BTN_TOUCH:
35296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.fields |= Accumulator::FIELD_BTN_TOUCH;
35306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.btnTouch = rawEvent->value != 0;
35312dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            // Don't sync immediately.  Wait until the next SYN_REPORT since we might
35322dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            // not have received valid position information yet.  This logic assumes that
35332dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            // BTN_TOUCH is always followed by SYN_REPORT as part of a complete packet.
35346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
35356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
35366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        break;
35376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    case EV_ABS:
35396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        switch (rawEvent->scanCode) {
35406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case ABS_X:
35416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.fields |= Accumulator::FIELD_ABS_X;
35426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.absX = rawEvent->value;
35436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
35446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case ABS_Y:
35456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.fields |= Accumulator::FIELD_ABS_Y;
35466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.absY = rawEvent->value;
35476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
35486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case ABS_PRESSURE:
35496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.fields |= Accumulator::FIELD_ABS_PRESSURE;
35506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.absPressure = rawEvent->value;
35516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
35526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case ABS_TOOL_WIDTH:
35536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.fields |= Accumulator::FIELD_ABS_TOOL_WIDTH;
35546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.absToolWidth = rawEvent->value;
35556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
35566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
35576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        break;
35586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    case EV_SYN:
35606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        switch (rawEvent->scanCode) {
35616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case SYN_REPORT:
35622dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            sync(rawEvent->when);
35636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
35646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
35656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        break;
35666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
35676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
35686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid SingleTouchInputMapper::sync(nsecs_t when) {
35706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    uint32_t fields = mAccumulator.fields;
35712dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown    if (fields == 0) {
35722dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        return; // no new state changes, so nothing to do
35732dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown    }
35746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (fields & Accumulator::FIELD_BTN_TOUCH) {
35766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mDown = mAccumulator.btnTouch;
35776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
35786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (fields & Accumulator::FIELD_ABS_X) {
35806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mX = mAccumulator.absX;
35816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
35826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (fields & Accumulator::FIELD_ABS_Y) {
35846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mY = mAccumulator.absY;
35856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
35866d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35876d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (fields & Accumulator::FIELD_ABS_PRESSURE) {
35886d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mPressure = mAccumulator.absPressure;
35896d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
35906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (fields & Accumulator::FIELD_ABS_TOOL_WIDTH) {
35928d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        mToolWidth = mAccumulator.absToolWidth;
35936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
35946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mCurrentTouch.clear();
35966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
35976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    if (mDown) {
35986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.pointerCount = 1;
35996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.pointers[0].id = 0;
36006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.pointers[0].x = mX;
36016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.pointers[0].y = mY;
36026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.pointers[0].pressure = mPressure;
36038d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        mCurrentTouch.pointers[0].touchMajor = 0;
36048d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        mCurrentTouch.pointers[0].touchMinor = 0;
36058d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        mCurrentTouch.pointers[0].toolMajor = mToolWidth;
36068d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        mCurrentTouch.pointers[0].toolMinor = mToolWidth;
36076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.pointers[0].orientation = 0;
36086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.idToIndex[0] = 0;
36096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        mCurrentTouch.idBits.markBit(0);
36106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
36116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
36126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    syncTouch(when, true);
36132dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown
36142dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown    mAccumulator.clear();
36156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
36166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
36178d60866e2100db70ecf0502c14768a384514d7e9Jeff Brownvoid SingleTouchInputMapper::configureRawAxes() {
36188d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    TouchInputMapper::configureRawAxes();
36196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
36208d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x);
36218d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y);
36228d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mRawAxes.pressure);
36238d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mRawAxes.toolMajor);
36246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
36256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
36266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
36276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown// --- MultiTouchInputMapper ---
36286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
362947e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff BrownMultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) :
363047e6b1b5eef8ee99872f278f66bc498c4fcca0d8Jeff Brown        TouchInputMapper(device) {
36316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    initialize();
36326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
36336d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
36346d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff BrownMultiTouchInputMapper::~MultiTouchInputMapper() {
36356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
36366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
36376d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid MultiTouchInputMapper::initialize() {
36386d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mAccumulator.clear();
36396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
36406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
36416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid MultiTouchInputMapper::reset() {
36426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    TouchInputMapper::reset();
36436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
36446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    initialize();
36456d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
36466d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
36476d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid MultiTouchInputMapper::process(const RawEvent* rawEvent) {
36486d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    switch (rawEvent->type) {
36496d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    case EV_ABS: {
36506d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        uint32_t pointerIndex = mAccumulator.pointerCount;
36516d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        Accumulator::Pointer* pointer = & mAccumulator.pointers[pointerIndex];
36526d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
36536d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        switch (rawEvent->scanCode) {
36546d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case ABS_MT_POSITION_X:
36556d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_X;
36566d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->absMTPositionX = rawEvent->value;
36576d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
36586d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case ABS_MT_POSITION_Y:
36596d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_Y;
36606d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->absMTPositionY = rawEvent->value;
36616d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
36626d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case ABS_MT_TOUCH_MAJOR:
36636d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MAJOR;
36646d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->absMTTouchMajor = rawEvent->value;
36656d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
36666d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case ABS_MT_TOUCH_MINOR:
36676d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MINOR;
36686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->absMTTouchMinor = rawEvent->value;
36696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
36706d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case ABS_MT_WIDTH_MAJOR:
36716d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MAJOR;
36726d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->absMTWidthMajor = rawEvent->value;
36736d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
36746d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case ABS_MT_WIDTH_MINOR:
36756d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MINOR;
36766d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->absMTWidthMinor = rawEvent->value;
36776d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
36786d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case ABS_MT_ORIENTATION:
36796d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->fields |= Accumulator::FIELD_ABS_MT_ORIENTATION;
36806d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->absMTOrientation = rawEvent->value;
36816d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
36826d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case ABS_MT_TRACKING_ID:
36836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->fields |= Accumulator::FIELD_ABS_MT_TRACKING_ID;
36846d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            pointer->absMTTrackingId = rawEvent->value;
36856d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
36868d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        case ABS_MT_PRESSURE:
36878d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            pointer->fields |= Accumulator::FIELD_ABS_MT_PRESSURE;
36888d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            pointer->absMTPressure = rawEvent->value;
36898d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            break;
36906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
36916d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        break;
36926d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
36936d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
36946d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    case EV_SYN:
36956d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        switch (rawEvent->scanCode) {
36966d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case SYN_MT_REPORT: {
36976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
36986d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            uint32_t pointerIndex = mAccumulator.pointerCount;
36996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
37006d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            if (mAccumulator.pointers[pointerIndex].fields) {
37016d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (pointerIndex == MAX_POINTERS) {
37026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    LOGW("MultiTouch device driver returned more than maximum of %d pointers.",
37036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                            MAX_POINTERS);
37046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                } else {
37056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    pointerIndex += 1;
37066d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    mAccumulator.pointerCount = pointerIndex;
37076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
37086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
37096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
37106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            mAccumulator.pointers[pointerIndex].clear();
37116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
37126d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
37136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
37146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        case SYN_REPORT:
37152dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            sync(rawEvent->when);
37166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            break;
37176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
37186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        break;
37196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
37206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
37216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
37226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brownvoid MultiTouchInputMapper::sync(nsecs_t when) {
37236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    static const uint32_t REQUIRED_FIELDS =
37248d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            Accumulator::FIELD_ABS_MT_POSITION_X | Accumulator::FIELD_ABS_MT_POSITION_Y;
37256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
37266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    uint32_t inCount = mAccumulator.pointerCount;
37276d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    uint32_t outCount = 0;
37286d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    bool havePointerIds = true;
37296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
37306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mCurrentTouch.clear();
37316d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
37326d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    for (uint32_t inIndex = 0; inIndex < inCount; inIndex++) {
37332dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        const Accumulator::Pointer& inPointer = mAccumulator.pointers[inIndex];
37342dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        uint32_t fields = inPointer.fields;
37356d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
37366d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if ((fields & REQUIRED_FIELDS) != REQUIRED_FIELDS) {
37372dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            // Some drivers send empty MT sync packets without X / Y to indicate a pointer up.
37382dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            // Drop this finger.
37396d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            continue;
37406d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
37416d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
37422dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        PointerData& outPointer = mCurrentTouch.pointers[outCount];
37432dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        outPointer.x = inPointer.absMTPositionX;
37442dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        outPointer.y = inPointer.absMTPositionY;
37452dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown
37468d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) {
37478d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            if (inPointer.absMTPressure <= 0) {
3748c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown                // Some devices send sync packets with X / Y but with a 0 pressure to indicate
3749c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown                // a pointer going up.  Drop this finger.
37508d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                continue;
37518d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            }
37528d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            outPointer.pressure = inPointer.absMTPressure;
37538d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        } else {
37548d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            // Default pressure to 0 if absent.
37558d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            outPointer.pressure = 0;
37568d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        }
37578d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown
37582dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MAJOR) {
37598d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            if (inPointer.absMTTouchMajor <= 0) {
37602dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown                // Some devices send sync packets with X / Y but with a 0 touch major to indicate
37618d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                // a pointer going up.  Drop this finger.
37622dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown                continue;
37632dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            }
37642dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            outPointer.touchMajor = inPointer.absMTTouchMajor;
37652dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        } else {
37668d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            // Default touch area to 0 if absent.
37672dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            outPointer.touchMajor = 0;
37686d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
37696d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
37702dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MINOR) {
37712dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            outPointer.touchMinor = inPointer.absMTTouchMinor;
37722dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        } else {
37738d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            // Assume touch area is circular.
37742dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            outPointer.touchMinor = outPointer.touchMajor;
37752dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        }
37762dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown
37772dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MAJOR) {
37782dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            outPointer.toolMajor = inPointer.absMTWidthMajor;
37792dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        } else {
37808d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            // Default tool area to 0 if absent.
37818d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            outPointer.toolMajor = 0;
37822dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        }
37836d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
37842dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MINOR) {
37852dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            outPointer.toolMinor = inPointer.absMTWidthMinor;
37862dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        } else {
37878d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            // Assume tool area is circular.
37882dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            outPointer.toolMinor = outPointer.toolMajor;
37892dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        }
37906d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
37912dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        if (fields & Accumulator::FIELD_ABS_MT_ORIENTATION) {
37922dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            outPointer.orientation = inPointer.absMTOrientation;
37932dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        } else {
37948d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown            // Default orientation to vertical if absent.
37952dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            outPointer.orientation = 0;
37962dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown        }
37976d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
37988d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown        // Assign pointer id using tracking id if available.
37996d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        if (havePointerIds) {
38002dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown            if (fields & Accumulator::FIELD_ABS_MT_TRACKING_ID) {
38012dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown                uint32_t id = uint32_t(inPointer.absMTTrackingId);
38026d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
38036d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                if (id > MAX_POINTER_ID) {
38046d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#if DEBUG_POINTERS
38056d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    LOGD("Pointers: Ignoring driver provided pointer id %d because "
380601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                            "it is larger than max supported id %d",
38076d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                            id, MAX_POINTER_ID);
38086d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown#endif
38096d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    havePointerIds = false;
38106d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
38116d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                else {
38122dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown                    outPointer.id = id;
38136d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    mCurrentTouch.idToIndex[id] = outCount;
38146d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                    mCurrentTouch.idBits.markBit(id);
38156d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                }
38166d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            } else {
38176d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown                havePointerIds = false;
38186d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown            }
38196d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        }
38206d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
38216d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown        outCount += 1;
38226d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    }
38236d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
38246d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    mCurrentTouch.pointerCount = outCount;
38256d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
38266d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown    syncTouch(when, havePointerIds);
38272dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown
38282dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown    mAccumulator.clear();
38296d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
38306d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
38318d60866e2100db70ecf0502c14768a384514d7e9Jeff Brownvoid MultiTouchInputMapper::configureRawAxes() {
38328d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    TouchInputMapper::configureRawAxes();
38332dfd7a7cbfa565e3aca584a9e5b6f681692b5781Jeff Brown
38348d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, & mRawAxes.x);
38358d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, & mRawAxes.y);
38368d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, & mRawAxes.touchMajor);
38378d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, & mRawAxes.touchMinor);
38388d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, & mRawAxes.toolMajor);
38398d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, & mRawAxes.toolMinor);
38408d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, & mRawAxes.orientation);
38418d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, & mRawAxes.pressure);
38426d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown}
38436d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
38446d0fec2de3601821f4f44eeb7d7deedebb2b7117Jeff Brown
3845cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown// --- JoystickInputMapper ---
3846cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
3847cb1404e45639d20439d7700b06d57ca1a1aad1faJeff BrownJoystickInputMapper::JoystickInputMapper(InputDevice* device) :
3848cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        InputMapper(device) {
3849cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
3850cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
3851cb1404e45639d20439d7700b06d57ca1a1aad1faJeff BrownJoystickInputMapper::~JoystickInputMapper() {
3852cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
3853cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
3854cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownuint32_t JoystickInputMapper::getSources() {
3855cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    return AINPUT_SOURCE_JOYSTICK;
3856cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
3857cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
3858cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownvoid JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
3859cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    InputMapper::populateDeviceInfo(info);
3860cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
38616f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < mAxes.size(); i++) {
38626f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        const Axis& axis = mAxes.valueAt(i);
38638529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        info->addMotionRange(axis.axisInfo.axis, axis.min, axis.max, axis.flat, axis.fuzz);
38648529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
38658529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            info->addMotionRange(axis.axisInfo.highAxis, axis.min, axis.max, axis.flat, axis.fuzz);
38668529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
3867cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
3868cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
3869cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
3870cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownvoid JoystickInputMapper::dump(String8& dump) {
3871cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    dump.append(INDENT2 "Joystick Input Mapper:\n");
3872cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
38736f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    dump.append(INDENT3 "Axes:\n");
38746f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
38756f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
38766f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        const Axis& axis = mAxes.valueAt(i);
38778529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        const char* label = getAxisLabel(axis.axisInfo.axis);
38786f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        if (label) {
38798529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            dump.appendFormat(INDENT4 "%s", label);
38806f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        } else {
38818529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            dump.appendFormat(INDENT4 "%d", axis.axisInfo.axis);
38828529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
38838529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
38848529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            label = getAxisLabel(axis.axisInfo.highAxis);
38858529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            if (label) {
38868529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                dump.appendFormat(" / %s (split at %d)", label, axis.axisInfo.splitValue);
38878529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            } else {
38888529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                dump.appendFormat(" / %d (split at %d)", axis.axisInfo.highAxis,
38898529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        axis.axisInfo.splitValue);
38908529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            }
38918529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        } else if (axis.axisInfo.mode == AxisInfo::MODE_INVERT) {
38928529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            dump.append(" (invert)");
38936f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
38948529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown
38958529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f\n",
38968529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.min, axis.max, axis.flat, axis.fuzz);
38978529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        dump.appendFormat(INDENT4 "  scale=%0.5f, offset=%0.5f, "
38988529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                "highScale=%0.5f, highOffset=%0.5f\n",
38998529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.scale, axis.offset, axis.highScale, axis.highOffset);
39006f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        dump.appendFormat(INDENT4 "  rawAxis=%d, rawMin=%d, rawMax=%d, rawFlat=%d, rawFuzz=%d\n",
39016f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
39026f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz);
3903cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
3904cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
3905cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
3906cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownvoid JoystickInputMapper::configure() {
3907cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    InputMapper::configure();
3908cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
39096f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    // Collect all axes.
39106f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
39116f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        RawAbsoluteAxisInfo rawAxisInfo;
39126f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        getEventHub()->getAbsoluteAxisInfo(getDeviceId(), abs, &rawAxisInfo);
39136f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        if (rawAxisInfo.valid) {
39148529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            // Map axis.
39158529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            AxisInfo axisInfo;
39168529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
39176f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            if (!explicitlyMapped) {
39186f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                // Axis is not explicitly mapped, will choose a generic axis later.
39198529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axisInfo.mode = AxisInfo::MODE_NORMAL;
39208529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axisInfo.axis = -1;
39216f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            }
39226f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
39238529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            // Apply flat override.
39248529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            int32_t rawFlat = axisInfo.flatOverride < 0
39258529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    ? rawAxisInfo.flat : axisInfo.flatOverride;
39268529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown
39278529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            // Calculate scaling factors and limits.
39286f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            Axis axis;
39298529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            if (axisInfo.mode == AxisInfo::MODE_SPLIT) {
39308529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue);
39318529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
39328529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
39338529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        scale, 0.0f, highScale, 0.0f,
39348529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
39358529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            } else if (isCenteredAxis(axisInfo.axis)) {
39366f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
39376f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
39388529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
39398529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        scale, offset, scale, offset,
39408529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
39416f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            } else {
39426f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
39438529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
39448529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        scale, 0.0f, scale, 0.0f,
39458529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
39466f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            }
39476f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
39486f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            // To eliminate noise while the joystick is at rest, filter out small variations
39496f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            // in axis values up front.
39506f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            axis.filter = axis.flat * 0.25f;
39516f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
39526f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            mAxes.add(abs, axis);
39536f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
39546f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
39556f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
39566f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    // If there are too many axes, start dropping them.
39576f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    // Prefer to keep explicitly mapped axes.
39586f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    if (mAxes.size() > PointerCoords::MAX_AXES) {
39596f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        LOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.",
39606f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
39616f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        pruneAxes(true);
39626f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        pruneAxes(false);
39636f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
3964cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
39656f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    // Assign generic axis ids to remaining axes.
39666f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1;
39676f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
39686f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
39696f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        Axis& axis = mAxes.editValueAt(i);
39708529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.axis < 0) {
39716f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
39726f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                    && haveAxis(nextGenericAxisId)) {
39736f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                nextGenericAxisId += 1;
39746f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            }
39756f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
39766f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
39778529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.axisInfo.axis = nextGenericAxisId;
39786f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                nextGenericAxisId += 1;
39796f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            } else {
39806f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                LOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
39816f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                        "have already been assigned to other axes.",
39826f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                        getDeviceName().string(), mAxes.keyAt(i));
39836f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                mAxes.removeItemsAt(i--);
39846f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                numAxes -= 1;
39856f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            }
39866f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
39876f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
3988cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
3989cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
39908529745b27877d98a0c76692295a3fcac238b1e6Jeff Brownbool JoystickInputMapper::haveAxis(int32_t axisId) {
39916f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
39926f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
39938529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        const Axis& axis = mAxes.valueAt(i);
39948529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.axis == axisId
39958529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                || (axis.axisInfo.mode == AxisInfo::MODE_SPLIT
39968529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        && axis.axisInfo.highAxis == axisId)) {
39976f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            return true;
39986f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
39996f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
40006f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    return false;
40016f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown}
4002cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
40036f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brownvoid JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) {
40046f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t i = mAxes.size();
40056f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) {
40066f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) {
40076f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            continue;
40086f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
40096f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        LOGI("Discarding joystick '%s' axis %d because there are too many axes.",
40106f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown                getDeviceName().string(), mAxes.keyAt(i));
40116f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        mAxes.removeItemsAt(i);
40126f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
40136f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown}
40146f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
40156f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brownbool JoystickInputMapper::isCenteredAxis(int32_t axis) {
40166f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    switch (axis) {
40176f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_X:
40186f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_Y:
40196f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_Z:
40206f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_RX:
40216f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_RY:
40226f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_RZ:
40236f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_HAT_X:
40246f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_HAT_Y:
40256f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case AMOTION_EVENT_AXIS_ORIENTATION:
40268529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    case AMOTION_EVENT_AXIS_RUDDER:
40278529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    case AMOTION_EVENT_AXIS_WHEEL:
40286f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        return true;
40296f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    default:
40306f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        return false;
40316f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
4032cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
4033cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
4034cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownvoid JoystickInputMapper::reset() {
4035cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    // Recenter all axes.
4036cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
4037cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
40386f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
40396f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
40406f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        Axis& axis = mAxes.editValueAt(i);
40418529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        axis.resetValue();
40426f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
40436f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown
40446f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    sync(when, true /*force*/);
4045cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
4046cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    InputMapper::reset();
4047cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
4048cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
4049cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brownvoid JoystickInputMapper::process(const RawEvent* rawEvent) {
4050cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    switch (rawEvent->type) {
40516f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    case EV_ABS: {
40526f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        ssize_t index = mAxes.indexOfKey(rawEvent->scanCode);
40536f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        if (index >= 0) {
40546f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            Axis& axis = mAxes.editValueAt(index);
40558529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            float newValue, highNewValue;
40568529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            switch (axis.axisInfo.mode) {
40578529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            case AxisInfo::MODE_INVERT:
40588529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)
40598529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                        * axis.scale + axis.offset;
40608529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                highNewValue = 0.0f;
40618529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                break;
40628529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            case AxisInfo::MODE_SPLIT:
40638529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                if (rawEvent->value < axis.axisInfo.splitValue) {
40648529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    newValue = (axis.axisInfo.splitValue - rawEvent->value)
40658529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                            * axis.scale + axis.offset;
40668529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    highNewValue = 0.0f;
40678529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                } else if (rawEvent->value > axis.axisInfo.splitValue) {
40688529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    newValue = 0.0f;
40698529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    highNewValue = (rawEvent->value - axis.axisInfo.splitValue)
40708529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                            * axis.highScale + axis.highOffset;
40718529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                } else {
40728529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    newValue = 0.0f;
40738529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    highNewValue = 0.0f;
40748529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                }
40758529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                break;
40768529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            default:
40778529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                newValue = rawEvent->value * axis.scale + axis.offset;
40788529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                highNewValue = 0.0f;
40798529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                break;
40806f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            }
40818529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            axis.newValue = newValue;
40828529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            axis.highNewValue = highNewValue;
4083cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        }
4084cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        break;
40856f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    }
4086cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
4087cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    case EV_SYN:
4088cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        switch (rawEvent->scanCode) {
4089cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        case SYN_REPORT:
40906f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            sync(rawEvent->when, false /*force*/);
4091cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown            break;
4092cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        }
4093cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown        break;
4094cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
4095cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
4096cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
40976f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brownvoid JoystickInputMapper::sync(nsecs_t when, bool force) {
40988529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    if (!filterAxes(force)) {
40996f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        return;
4100cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
4101cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
4102cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    int32_t metaState = mContext->getGlobalMetaState();
4103cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
41046f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    PointerCoords pointerCoords;
41056f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    pointerCoords.clear();
4106cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
41076f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
41086f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
41098529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        const Axis& axis = mAxes.valueAt(i);
41108529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        pointerCoords.setAxisValue(axis.axisInfo.axis, axis.currentValue);
41118529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
41128529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            pointerCoords.setAxisValue(axis.axisInfo.highAxis, axis.highCurrentValue);
41138529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
4114cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
4115cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
411656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // Moving a joystick axis should not wake the devide because joysticks can
411756194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // be fairly noisy even when not in use.  On the other hand, pushing a gamepad
411856194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // button will likely wake the device.
411956194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    // TODO: Use the input device configuration to control this behavior more finely.
412056194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    uint32_t policyFlags = 0;
412156194ebec6212e229f4ccdaa4b187166d20013efJeff Brown
41226f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    int32_t pointerId = 0;
412356194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
41246f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            AMOTION_EVENT_ACTION_MOVE, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
41256f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            1, &pointerId, &pointerCoords, 0, 0, 0);
4126cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
4127cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
41288529745b27877d98a0c76692295a3fcac238b1e6Jeff Brownbool JoystickInputMapper::filterAxes(bool force) {
41298529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    bool atLeastOneSignificantChange = force;
41306f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    size_t numAxes = mAxes.size();
41316f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    for (size_t i = 0; i < numAxes; i++) {
41328529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        Axis& axis = mAxes.editValueAt(i);
41338529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (force || hasValueChangedSignificantly(axis.filter,
41348529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.newValue, axis.currentValue, axis.min, axis.max)) {
41358529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            axis.currentValue = axis.newValue;
41368529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            atLeastOneSignificantChange = true;
41378529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
41388529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
41398529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            if (force || hasValueChangedSignificantly(axis.filter,
41408529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                    axis.highNewValue, axis.highCurrentValue, axis.min, axis.max)) {
41418529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                axis.highCurrentValue = axis.highNewValue;
41428529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                atLeastOneSignificantChange = true;
41438529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            }
41448529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
41458529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    }
41468529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    return atLeastOneSignificantChange;
41478529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown}
41488529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown
41498529745b27877d98a0c76692295a3fcac238b1e6Jeff Brownbool JoystickInputMapper::hasValueChangedSignificantly(
41508529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        float filter, float newValue, float currentValue, float min, float max) {
41518529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    if (newValue != currentValue) {
41528529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        // Filter out small changes in value unless the value is converging on the axis
41538529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        // bounds or center point.  This is intended to reduce the amount of information
41548529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        // sent to applications by particularly noisy joysticks (such as PS3).
41558529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (fabs(newValue - currentValue) > filter
41568529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, min)
41578529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, max)
41588529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, 0)) {
41598529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown            return true;
41608529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        }
41618529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    }
41628529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    return false;
41638529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown}
41648529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown
41658529745b27877d98a0c76692295a3fcac238b1e6Jeff Brownbool JoystickInputMapper::hasMovedNearerToValueWithinFilteredRange(
41668529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        float filter, float newValue, float currentValue, float thresholdValue) {
41678529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    float newDistance = fabs(newValue - thresholdValue);
41688529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown    if (newDistance < filter) {
41698529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        float oldDistance = fabs(currentValue - thresholdValue);
41708529745b27877d98a0c76692295a3fcac238b1e6Jeff Brown        if (newDistance < oldDistance) {
41716f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown            return true;
41726f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown        }
4173cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown    }
41746f2fba428ca5e77a26d991ad728e346cc47609eeJeff Brown    return false;
4175cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown}
4176cb1404e45639d20439d7700b06d57ca1a1aad1faJeff Brown
417746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android
4178