1d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright/*
2d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * Copyright (C) 2010 The Android Open Source Project
3d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *
4d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * Licensed under the Apache License, Version 2.0 (the "License");
5d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * you may not use this file except in compliance with the License.
6d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * You may obtain a copy of the License at
7d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *
8d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *      http://www.apache.org/licenses/LICENSE-2.0
9d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright *
10d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * Unless required by applicable law or agreed to in writing, software
11d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * distributed under the License is distributed on an "AS IS" BASIS,
12d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * See the License for the specific language governing permissions and
14d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright * limitations under the License.
15d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright */
16d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
17d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include "../InputReader.h"
18d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
19d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <utils/List.h>
20d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <gtest/gtest.h>
21d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright#include <math.h>
22d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
23d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightnamespace android {
24d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
25d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// An arbitrary time value.
26d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic const nsecs_t ARBITRARY_TIME = 1234;
27d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
28d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Arbitrary display properties.
29d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic const int32_t DISPLAY_ID = 0;
30d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic const int32_t DISPLAY_WIDTH = 480;
31d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic const int32_t DISPLAY_HEIGHT = 800;
3206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordonstatic const int32_t VIRTUAL_DISPLAY_ID = 1;
3306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordonstatic const int32_t VIRTUAL_DISPLAY_WIDTH = 400;
3406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordonstatic const int32_t VIRTUAL_DISPLAY_HEIGHT = 500;
3506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordonstatic const char* VIRTUAL_DISPLAY_UNIQUE_ID = "Vr-display-unique-ID";
36d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
37d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// Error tolerance for floating point assertions.
38d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic const float EPSILON = 0.001f;
39d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
40d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrighttemplate<typename T>
41d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic inline T min(T a, T b) {
42d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return a < b ? a : b;
43d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
44d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
45d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightstatic inline float avg(float x, float y) {
46d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    return (x + y) / 2;
47d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright}
48d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
49d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
50d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- FakePointerController ---
51d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
52d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightclass FakePointerController : public PointerControllerInterface {
53d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool mHaveBounds;
54d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float mMinX, mMinY, mMaxX, mMaxY;
55d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    float mX, mY;
56d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    int32_t mButtonState;
57d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
58d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected:
59d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual ~FakePointerController() { }
60d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
61d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightpublic:
62d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    FakePointerController() :
63d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0), mX(0), mY(0),
64d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mButtonState(0) {
65d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
66d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
67d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void setBounds(float minX, float minY, float maxX, float maxY) {
68d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mHaveBounds = true;
69d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mMinX = minX;
70d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mMinY = minY;
71d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mMaxX = maxX;
72d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mMaxY = maxY;
73d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
74d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
75d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual void setPosition(float x, float y) {
76d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mX = x;
77d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mY = y;
78d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
79d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
80d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual void setButtonState(int32_t buttonState) {
81d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mButtonState = buttonState;
82d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
83d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
84d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual int32_t getButtonState() const {
85d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return mButtonState;
86d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
87d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
88d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual void getPosition(float* outX, float* outY) const {
89d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *outX = mX;
90d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *outY = mY;
91d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
92d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
93d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate:
94d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const {
95d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *outMinX = mMinX;
96d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *outMinY = mMinY;
97d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *outMaxX = mMaxX;
98d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *outMaxY = mMaxY;
99d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return mHaveBounds;
100d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
101d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
102d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual void move(float deltaX, float deltaY) {
103d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mX += deltaX;
104d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mX < mMinX) mX = mMinX;
105d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mX > mMaxX) mX = mMaxX;
106d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mY += deltaY;
107d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mY < mMinY) mY = mMinY;
108d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mY > mMaxY) mY = mMaxY;
109d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
110d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
11139efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath    virtual void fade(Transition) {
112d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
113d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
11439efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath    virtual void unfade(Transition) {
115d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
116d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
11739efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath    virtual void setPresentation(Presentation) {
118d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
119d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
12039efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath    virtual void setSpots(const PointerCoords*, const uint32_t*, BitSet32) {
121d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
122d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
123d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual void clearSpots() {
124d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
125d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright};
126d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
127d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
128d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- FakeInputReaderPolicy ---
129d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
130d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightclass FakeInputReaderPolicy : public InputReaderPolicyInterface {
131d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    InputReaderConfiguration mConfig;
132d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    KeyedVector<int32_t, sp<FakePointerController> > mPointerControllers;
133d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    Vector<InputDeviceInfo> mInputDevices;
134489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke    TouchAffineTransformation transform;
135d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
136d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected:
137d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual ~FakeInputReaderPolicy() { }
138d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
139d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightpublic:
140d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    FakeInputReaderPolicy() {
141d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
142d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
14306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    void setDisplayViewport(int32_t displayId, int32_t width, int32_t height, int32_t orientation,
14406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            const String8& uniqueId) {
14506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        DisplayViewport v = createDisplayViewport(displayId, width, height, orientation, uniqueId);
146d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        // Set the size of both the internal and external display at the same time.
14706936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        mConfig.setPhysicalDisplayViewport(ViewportType::VIEWPORT_INTERNAL, v);
14806936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        mConfig.setPhysicalDisplayViewport(ViewportType::VIEWPORT_EXTERNAL, v);
14906936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    }
15006936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon
15106936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    void setVirtualDisplayViewport(int32_t displayId, int32_t width, int32_t height, int32_t orientation,
15206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            const String8& uniqueId) {
15306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        Vector<DisplayViewport> viewports;
15406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        viewports.push_back(createDisplayViewport(displayId, width, height, orientation, uniqueId));
15506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        mConfig.setVirtualDisplayViewports(viewports);
156d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
157d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
158d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void addExcludedDeviceName(const String8& deviceName) {
159d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mConfig.excludedDeviceNames.push(deviceName);
160d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
161d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
162d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void setPointerController(int32_t deviceId, const sp<FakePointerController>& controller) {
163d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mPointerControllers.add(deviceId, controller);
164d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
165d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
166d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    const InputReaderConfiguration* getReaderConfiguration() const {
167d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return &mConfig;
168d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
169d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
170d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    const Vector<InputDeviceInfo>& getInputDevices() const {
171d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return mInputDevices;
172d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
173d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
17471b16e81f9cbf2e288611f32c43ea7fb4a331fcfJason Gerecke    TouchAffineTransformation getTouchAffineTransformation(const String8& inputDeviceDescriptor,
17571b16e81f9cbf2e288611f32c43ea7fb4a331fcfJason Gerecke            int32_t surfaceRotation) {
176489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke        return transform;
177489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke    }
178489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke
179489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke    void setTouchAffineTransformation(const TouchAffineTransformation t) {
180489fda8d476f3fc10b0251263cc69528b736257bJason Gerecke        transform = t;
18112d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke    }
18212d6baa9b832f16a28f048ed5ffab75a76ed9c41Jason Gerecke
18378f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev    void setPointerCapture(bool enabled) {
18478f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev        mConfig.pointerCapture = enabled;
18578f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev    }
18678f97b3263053c388080a738b56499139517c3b6Vladislav Kaznacheev
187d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate:
18806936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    DisplayViewport createDisplayViewport(int32_t displayId, int32_t width, int32_t height,
18906936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon            int32_t orientation, const String8& uniqueId) {
19006936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        bool isRotated = (orientation == DISPLAY_ORIENTATION_90
19106936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon                || orientation == DISPLAY_ORIENTATION_270);
19206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        DisplayViewport v;
19306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        v.displayId = displayId;
19406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        v.orientation = orientation;
19506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        v.logicalLeft = 0;
19606936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        v.logicalTop = 0;
19706936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        v.logicalRight = isRotated ? height : width;
19806936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        v.logicalBottom = isRotated ? width : height;
19906936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        v.physicalLeft = 0;
20006936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        v.physicalTop = 0;
20106936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        v.physicalRight = isRotated ? height : width;
20206936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        v.physicalBottom = isRotated ? width : height;
20306936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        v.deviceWidth = isRotated ? height : width;
20406936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        v.deviceHeight = isRotated ? width : height;
20506936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        v.uniqueId = uniqueId;
20606936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon        return v;
20706936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon    }
20806936feb07bf6fbef262e4adebeb8e53910d8cf4Santos Cordon
209d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) {
210d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *outConfig = mConfig;
211d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
212d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
213d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) {
214d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return mPointerControllers.valueFor(deviceId);
215d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
216d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
217d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) {
218d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mInputDevices = inputDevices;
219d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
220d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
22139efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath    virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const InputDeviceIdentifier&) {
222d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return NULL;
223d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
224d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
22539efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath    virtual String8 getDeviceAlias(const InputDeviceIdentifier&) {
226d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return String8::empty();
227d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
228d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright};
229d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
230d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
231d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- FakeInputListener ---
232d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
233d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightclass FakeInputListener : public InputListenerInterface {
234d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate:
235d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    List<NotifyConfigurationChangedArgs> mNotifyConfigurationChangedArgsQueue;
236d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    List<NotifyDeviceResetArgs> mNotifyDeviceResetArgsQueue;
237d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    List<NotifyKeyArgs> mNotifyKeyArgsQueue;
238d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    List<NotifyMotionArgs> mNotifyMotionArgsQueue;
239d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    List<NotifySwitchArgs> mNotifySwitchArgsQueue;
240d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
241d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected:
242d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual ~FakeInputListener() { }
243d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
244d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightpublic:
245d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    FakeInputListener() {
246d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
247d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
248d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void assertNotifyConfigurationChangedWasCalled(
249d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            NotifyConfigurationChangedArgs* outEventArgs = NULL) {
250d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ASSERT_FALSE(mNotifyConfigurationChangedArgsQueue.empty())
251d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                << "Expected notifyConfigurationChanged() to have been called.";
252d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (outEventArgs) {
253d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outEventArgs = *mNotifyConfigurationChangedArgsQueue.begin();
254d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
255d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mNotifyConfigurationChangedArgsQueue.erase(mNotifyConfigurationChangedArgsQueue.begin());
256d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
257d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
258d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void assertNotifyDeviceResetWasCalled(
259d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            NotifyDeviceResetArgs* outEventArgs = NULL) {
260d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ASSERT_FALSE(mNotifyDeviceResetArgsQueue.empty())
261d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                << "Expected notifyDeviceReset() to have been called.";
262d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (outEventArgs) {
263d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outEventArgs = *mNotifyDeviceResetArgsQueue.begin();
264d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
265d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mNotifyDeviceResetArgsQueue.erase(mNotifyDeviceResetArgsQueue.begin());
266d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
267d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
268d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void assertNotifyKeyWasCalled(NotifyKeyArgs* outEventArgs = NULL) {
269d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ASSERT_FALSE(mNotifyKeyArgsQueue.empty())
270d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                << "Expected notifyKey() to have been called.";
271d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (outEventArgs) {
272d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outEventArgs = *mNotifyKeyArgsQueue.begin();
273d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
274d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mNotifyKeyArgsQueue.erase(mNotifyKeyArgsQueue.begin());
275d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
276d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
277d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void assertNotifyKeyWasNotCalled() {
278d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ASSERT_TRUE(mNotifyKeyArgsQueue.empty())
279d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                << "Expected notifyKey() to not have been called.";
280d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
281d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
282d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void assertNotifyMotionWasCalled(NotifyMotionArgs* outEventArgs = NULL) {
283d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ASSERT_FALSE(mNotifyMotionArgsQueue.empty())
284d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                << "Expected notifyMotion() to have been called.";
285d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (outEventArgs) {
286d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outEventArgs = *mNotifyMotionArgsQueue.begin();
287d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
288d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mNotifyMotionArgsQueue.erase(mNotifyMotionArgsQueue.begin());
289d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
290d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
291d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void assertNotifyMotionWasNotCalled() {
292d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ASSERT_TRUE(mNotifyMotionArgsQueue.empty())
293d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                << "Expected notifyMotion() to not have been called.";
294d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
295d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
296d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void assertNotifySwitchWasCalled(NotifySwitchArgs* outEventArgs = NULL) {
297d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ASSERT_FALSE(mNotifySwitchArgsQueue.empty())
298d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                << "Expected notifySwitch() to have been called.";
299d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (outEventArgs) {
300d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outEventArgs = *mNotifySwitchArgsQueue.begin();
301d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
302d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mNotifySwitchArgsQueue.erase(mNotifySwitchArgsQueue.begin());
303d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
304d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
305d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate:
306d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
307d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mNotifyConfigurationChangedArgsQueue.push_back(*args);
308d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
309d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
310d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) {
311d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mNotifyDeviceResetArgsQueue.push_back(*args);
312d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
313d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
314d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual void notifyKey(const NotifyKeyArgs* args) {
315d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mNotifyKeyArgsQueue.push_back(*args);
316d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
317d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
318d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual void notifyMotion(const NotifyMotionArgs* args) {
319d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mNotifyMotionArgsQueue.push_back(*args);
320d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
321d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
322d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual void notifySwitch(const NotifySwitchArgs* args) {
323d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mNotifySwitchArgsQueue.push_back(*args);
324d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
325d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright};
326d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
327d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
328d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright// --- FakeEventHub ---
329d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
330d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightclass FakeEventHub : public EventHubInterface {
331d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    struct KeyInfo {
332d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        int32_t keyCode;
333d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t flags;
334d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    };
335d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
336d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    struct Device {
337d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        InputDeviceIdentifier identifier;
338d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        uint32_t classes;
339d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        PropertyMap configuration;
340d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        KeyedVector<int, RawAbsoluteAxisInfo> absoluteAxes;
341d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        KeyedVector<int, bool> relativeAxes;
342d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        KeyedVector<int32_t, int32_t> keyCodeStates;
343d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        KeyedVector<int32_t, int32_t> scanCodeStates;
344d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        KeyedVector<int32_t, int32_t> switchStates;
345d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        KeyedVector<int32_t, int32_t> absoluteAxisValue;
346d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        KeyedVector<int32_t, KeyInfo> keysByScanCode;
347d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        KeyedVector<int32_t, KeyInfo> keysByUsageCode;
348d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        KeyedVector<int32_t, bool> leds;
349d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Vector<VirtualKeyDefinition> virtualKeys;
350d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
3516ca70efdaef8c07e91692101c7a3ae35dc1e0cbbChih-Hung Hsieh        explicit Device(uint32_t classes) :
352d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                classes(classes) {
353d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
354d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    };
355d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
356d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    KeyedVector<int32_t, Device*> mDevices;
357d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    Vector<String8> mExcludedDevices;
358d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    List<RawEvent> mEvents;
359d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
360d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprotected:
361d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual ~FakeEventHub() {
362d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        for (size_t i = 0; i < mDevices.size(); i++) {
363d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            delete mDevices.valueAt(i);
364d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
365d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
366d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
367d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightpublic:
368d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    FakeEventHub() { }
369d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
370d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void addDevice(int32_t deviceId, const String8& name, uint32_t classes) {
371d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = new Device(classes);
372d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->identifier.name = name;
373d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDevices.add(deviceId, device);
374d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
375d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_ADDED, 0, 0);
376d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
377d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
378d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void removeDevice(int32_t deviceId) {
379d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        delete mDevices.valueFor(deviceId);
380d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mDevices.removeItem(deviceId);
381d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
382d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_REMOVED, 0, 0);
383d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
384d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
385d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void finishDeviceScan() {
386d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        enqueueEvent(ARBITRARY_TIME, 0, EventHubInterface::FINISHED_DEVICE_SCAN, 0, 0);
387d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
388d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
389d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void addConfigurationProperty(int32_t deviceId, const String8& key, const String8& value) {
390d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
391d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->configuration.addProperty(key, value);
392d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
393d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
394d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void addConfigurationMap(int32_t deviceId, const PropertyMap* configuration) {
395d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
396d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->configuration.addAll(configuration);
397d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
398d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
399d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void addAbsoluteAxis(int32_t deviceId, int axis,
400d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t minValue, int32_t maxValue, int flat, int fuzz, int resolution = 0) {
401d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
402d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
403d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        RawAbsoluteAxisInfo info;
404d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info.valid = true;
405d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info.minValue = minValue;
406d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info.maxValue = maxValue;
407d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info.flat = flat;
408d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info.fuzz = fuzz;
409d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info.resolution = resolution;
410d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->absoluteAxes.add(axis, info);
411d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
412d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
413d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void addRelativeAxis(int32_t deviceId, int32_t axis) {
414d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
415d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->relativeAxes.add(axis, true);
416d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
417d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
418d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void setKeyCodeState(int32_t deviceId, int32_t keyCode, int32_t state) {
419d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
420d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->keyCodeStates.replaceValueFor(keyCode, state);
421d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
422d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
423d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void setScanCodeState(int32_t deviceId, int32_t scanCode, int32_t state) {
424d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
425d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->scanCodeStates.replaceValueFor(scanCode, state);
426d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
427d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
428d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void setSwitchState(int32_t deviceId, int32_t switchCode, int32_t state) {
429d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
430d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->switchStates.replaceValueFor(switchCode, state);
431d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
432d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
433d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void setAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t value) {
434d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
435d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->absoluteAxisValue.replaceValueFor(axis, value);
436d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
437d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
438d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void addKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
439d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t keyCode, uint32_t flags) {
440d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
441d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        KeyInfo info;
442d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info.keyCode = keyCode;
443d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        info.flags = flags;
444d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (scanCode) {
445d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            device->keysByScanCode.add(scanCode, info);
446d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
447d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (usageCode) {
448d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            device->keysByUsageCode.add(usageCode, info);
449d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
450d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
451d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
452d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void addLed(int32_t deviceId, int32_t led, bool initialState) {
453d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
454d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->leds.add(led, initialState);
455d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
456d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
457d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    bool getLedState(int32_t deviceId, int32_t led) {
458d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
459d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return device->leds.valueFor(led);
460d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
461d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
462d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    Vector<String8>& getExcludedDevices() {
463d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return mExcludedDevices;
464d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
465d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
466d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void addVirtualKeyDefinition(int32_t deviceId, const VirtualKeyDefinition& definition) {
467d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
468d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        device->virtualKeys.push(definition);
469d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
470d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
471d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void enqueueEvent(nsecs_t when, int32_t deviceId, int32_t type,
472d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t code, int32_t value) {
473d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        RawEvent event;
474d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        event.when = when;
475d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        event.deviceId = deviceId;
476d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        event.type = type;
477d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        event.code = code;
478d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        event.value = value;
479d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mEvents.push_back(event);
480d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
481d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (type == EV_ABS) {
482d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            setAbsoluteAxisValue(deviceId, code, value);
483d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
484d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
485d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
486d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    void assertQueueIsEmpty() {
487d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ASSERT_EQ(size_t(0), mEvents.size())
488d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                << "Expected the event queue to be empty (fully consumed).";
489d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
490d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
491d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wrightprivate:
492d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    Device* getDevice(int32_t deviceId) const {
493d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        ssize_t index = mDevices.indexOfKey(deviceId);
494d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return index >= 0 ? mDevices.valueAt(index) : NULL;
495d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
496d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
497d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual uint32_t getDeviceClasses(int32_t deviceId) const {
498d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
499d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return device ? device->classes : 0;
500d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
501d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
502d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const {
503d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
504d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return device ? device->identifier : InputDeviceIdentifier();
505d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
506d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
50739efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath    virtual int32_t getDeviceControllerNumber(int32_t) const {
508d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return 0;
509d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
510d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
511d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const {
512d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
513d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (device) {
514d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            *outConfiguration = device->configuration;
515d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
516d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
517d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
518d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
519d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            RawAbsoluteAxisInfo* outAxisInfo) const {
520d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
521d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (device) {
522d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ssize_t index = device->absoluteAxes.indexOfKey(axis);
523d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (index >= 0) {
524d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                *outAxisInfo = device->absoluteAxes.valueAt(index);
525d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return OK;
526d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
527d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
528d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        outAxisInfo->clear();
529d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return -1;
530d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
531d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
532d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual bool hasRelativeAxis(int32_t deviceId, int axis) const {
533d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
534d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (device) {
535d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return device->relativeAxes.indexOfKey(axis) >= 0;
536d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
537d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return false;
538d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
539d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
54039efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath    virtual bool hasInputProperty(int32_t, int) const {
541d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return false;
542d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
543d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
5440faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov    virtual status_t mapKey(int32_t deviceId,
5450faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov            int32_t scanCode, int32_t usageCode, int32_t metaState,
5460faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov            int32_t* outKeycode, int32_t *outMetaState, uint32_t* outFlags) const {
547d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
548d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (device) {
549d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            const KeyInfo* key = getKey(device, scanCode, usageCode);
550d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (key) {
551d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (outKeycode) {
552d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    *outKeycode = key->keyCode;
553d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
554d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                if (outFlags) {
555d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    *outFlags = key->flags;
556d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
5570faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov                if (outMetaState) {
5580faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov                    *outMetaState = metaState;
5590faaa0bd7aa5dadea7c365fbb1f186da6eb097efDmitry Torokhov                }
560d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return OK;
561d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
562d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
563d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return NAME_NOT_FOUND;
564d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
565d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
566d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    const KeyInfo* getKey(Device* device, int32_t scanCode, int32_t usageCode) const {
567d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (usageCode) {
568d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ssize_t index = device->keysByUsageCode.indexOfKey(usageCode);
569d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (index >= 0) {
570d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return &device->keysByUsageCode.valueAt(index);
571d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
572d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
573d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (scanCode) {
574d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ssize_t index = device->keysByScanCode.indexOfKey(scanCode);
575d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (index >= 0) {
576d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return &device->keysByScanCode.valueAt(index);
577d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
578d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
579d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return NULL;
580d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
581d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
58239efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath    virtual status_t mapAxis(int32_t, int32_t, AxisInfo*) const {
583d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return NAME_NOT_FOUND;
584d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
585d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
586d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual void setExcludedDevices(const Vector<String8>& devices) {
587d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mExcludedDevices = devices;
588d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
589d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
59039efe3e5bf6282a4851e0eb3b938060c8f7790aeNarayan Kamath    virtual size_t getEvents(int, RawEvent* buffer, size_t) {
591d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (mEvents.empty()) {
592d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            return 0;
593d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
594d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
595d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *buffer = *mEvents.begin();
596d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        mEvents.erase(mEvents.begin());
597d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return 1;
598d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
599d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
600d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const {
601d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
602d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (device) {
603d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ssize_t index = device->scanCodeStates.indexOfKey(scanCode);
604d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (index >= 0) {
605d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return device->scanCodeStates.valueAt(index);
606d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
607d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
608d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AKEY_STATE_UNKNOWN;
609d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
610d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
611d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const {
612d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
613d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (device) {
614d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ssize_t index = device->keyCodeStates.indexOfKey(keyCode);
615d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (index >= 0) {
616d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return device->keyCodeStates.valueAt(index);
617d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
618d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
619d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AKEY_STATE_UNKNOWN;
620d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
621d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
622d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const {
623d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
624d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (device) {
625d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ssize_t index = device->switchStates.indexOfKey(sw);
626d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (index >= 0) {
627d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return device->switchStates.valueAt(index);
628d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
629d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
630d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return AKEY_STATE_UNKNOWN;
631d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
632d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
633d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
634d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            int32_t* outValue) const {
635d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
636d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (device) {
637d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            ssize_t index = device->absoluteAxisValue.indexOfKey(axis);
638d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            if (index >= 0) {
639d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                *outValue = device->absoluteAxisValue.valueAt(index);
640d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                return OK;
641d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            }
642d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        }
643d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        *outValue = 0;
644d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        return -1;
645d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    }
646d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright
647d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
648d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            uint8_t* outFlags) const {
649d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        bool result = false;
650d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        Device* device = getDevice(deviceId);
651d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright        if (device) {
652d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright            for (size_t i = 0; i < numCodes; i++) {
653d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                for (size_t j = 0; j < device->keysByScanCode.size(); j++) {
654d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (keyCodes[i] == device->keysByScanCode.valueAt(j).keyCode) {
655d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        outFlags[i] = 1;
656d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        result = true;
657d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
658d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
659d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                for (size_t j = 0; j < device->keysByUsageCode.size(); j++) {
660d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    if (keyCodes[i] == device->keysByUsageCode.valueAt(j).keyCode) {
661d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        outFlags[i] = 1;
662d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                        result = true;
663d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                    }
664d02c5b6aace05d9fd938e2d03705ac4f60f8da19Michael Wright                }
665