summaryrefslogtreecommitdiff
path: root/services/inputflinger/reader/include/InputReader.h
blob: 693ec30b7d7d44d9ecf3509daad646d19bed364e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _UI_INPUTREADER_INPUT_READER_H
#define _UI_INPUTREADER_INPUT_READER_H

#include "EventHub.h"
#include "InputListener.h"
#include "InputReaderBase.h"
#include "InputReaderContext.h"
#include "InputThread.h"

#include <PointerControllerInterface.h>
#include <utils/Condition.h>
#include <utils/Mutex.h>

#include <unordered_map>
#include <vector>

namespace android {

class InputDevice;
class InputMapper;
struct StylusState;

/* The input reader reads raw event data from the event hub and processes it into input events
 * that it sends to the input listener.  Some functions of the input reader, such as early
 * event filtering in low power states, are controlled by a separate policy object.
 *
 * The InputReader owns a collection of InputMappers. InputReader starts its own thread, where
 * most of the work happens, but the InputReader can receive queries from other system
 * components running on arbitrary threads.  To keep things manageable, the InputReader
 * uses a single Mutex to guard its state.  The Mutex may be held while calling into the
 * EventHub or the InputReaderPolicy but it is never held while calling into the
 * InputListener. All calls to InputListener must happen from InputReader's thread.
 */
class InputReader : public InputReaderInterface {
public:
    InputReader(std::shared_ptr<EventHubInterface> eventHub,
                const sp<InputReaderPolicyInterface>& policy,
                const sp<InputListenerInterface>& listener);
    virtual ~InputReader();

    virtual void dump(std::string& dump) override;
    virtual void monitor() override;

    virtual status_t start() override;
    virtual status_t stop() override;

    virtual void getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) override;

    virtual bool isInputDeviceEnabled(int32_t deviceId) override;

    virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
                                     int32_t scanCode) override;
    virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
                                    int32_t keyCode) override;
    virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t sw) override;

    virtual void toggleCapsLockState(int32_t deviceId) override;

    virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
                         const int32_t* keyCodes, uint8_t* outFlags) override;

    virtual void requestRefreshConfiguration(uint32_t changes) override;

    virtual void vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
                         ssize_t repeat, int32_t token) override;
    virtual void cancelVibrate(int32_t deviceId, int32_t token) override;

    virtual bool canDispatchToDisplay(int32_t deviceId, int32_t displayId) override;

protected:
    // These members are protected so they can be instrumented by test cases.
    virtual std::shared_ptr<InputDevice> createDeviceLocked(
            int32_t deviceId, const InputDeviceIdentifier& identifier);

    // With each iteration of the loop, InputReader reads and processes one incoming message from
    // the EventHub.
    void loopOnce();

    class ContextImpl : public InputReaderContext {
        InputReader* mReader;
        IdGenerator mIdGenerator;

    public:
        explicit ContextImpl(InputReader* reader);

        virtual void updateGlobalMetaState() override;
        virtual int32_t getGlobalMetaState() override;
        virtual void disableVirtualKeysUntil(nsecs_t time) override;
        virtual bool shouldDropVirtualKey(nsecs_t now, int32_t keyCode, int32_t scanCode) override;
        virtual void fadePointer() override;
        virtual sp<PointerControllerInterface> getPointerController(int32_t deviceId) override;
        virtual void requestTimeoutAtTime(nsecs_t when) override;
        virtual int32_t bumpGeneration() override;
        virtual void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) override;
        virtual void dispatchExternalStylusState(const StylusState& outState) override;
        virtual InputReaderPolicyInterface* getPolicy() override;
        virtual InputListenerInterface* getListener() override;
        virtual EventHubInterface* getEventHub() override;
        virtual int32_t getNextId() override;
    } mContext;

    friend class ContextImpl;

private:
    std::unique_ptr<InputThread> mThread;

    Mutex mLock;

    Condition mReaderIsAliveCondition;

    // This could be unique_ptr, but due to the way InputReader tests are written,
    // it is made shared_ptr here. In the tests, an EventHub reference is retained by the test
    // in parallel to passing it to the InputReader.
    std::shared_ptr<EventHubInterface> mEventHub;
    sp<InputReaderPolicyInterface> mPolicy;
    sp<QueuedInputListener> mQueuedListener;

    InputReaderConfiguration mConfig;

    // The event queue.
    static const int EVENT_BUFFER_SIZE = 256;
    RawEvent mEventBuffer[EVENT_BUFFER_SIZE];

    // An input device can represent a collection of EventHub devices. This map provides a way
    // to lookup the input device instance from the EventHub device id.
    std::unordered_map<int32_t /*eventHubId*/, std::shared_ptr<InputDevice>> mDevices;

    // low-level input event decoding and device management
    void processEventsLocked(const RawEvent* rawEvents, size_t count);

    void addDeviceLocked(nsecs_t when, int32_t eventHubId);
    void removeDeviceLocked(nsecs_t when, int32_t eventHubId);
    void processEventsForDeviceLocked(int32_t eventHubId, const RawEvent* rawEvents, size_t count);
    void timeoutExpiredLocked(nsecs_t when);

    void handleConfigurationChangedLocked(nsecs_t when);

    int32_t mGlobalMetaState;
    void updateGlobalMetaStateLocked();
    int32_t getGlobalMetaStateLocked();

    void notifyExternalStylusPresenceChanged();
    void getExternalStylusDevicesLocked(std::vector<InputDeviceInfo>& outDevices);
    void dispatchExternalStylusState(const StylusState& state);

    // The PointerController that is shared among all the input devices that need it.
    wp<PointerControllerInterface> mPointerController;
    sp<PointerControllerInterface> getPointerControllerLocked(int32_t deviceId);
    void updatePointerDisplayLocked();
    void fadePointerLocked();

    int32_t mGeneration;
    int32_t bumpGenerationLocked();

    int32_t mNextInputDeviceId;
    int32_t nextInputDeviceIdLocked();

    void getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices);

    nsecs_t mDisableVirtualKeysTimeout;
    void disableVirtualKeysUntilLocked(nsecs_t time);
    bool shouldDropVirtualKeyLocked(nsecs_t now, int32_t keyCode, int32_t scanCode);

    nsecs_t mNextTimeout;
    void requestTimeoutAtTimeLocked(nsecs_t when);

    uint32_t mConfigurationChangesToRefresh;
    void refreshConfigurationLocked(uint32_t changes);

    // state queries
    typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
    int32_t getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
                           GetStateFunc getStateFunc);
    bool markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
                                     const int32_t* keyCodes, uint8_t* outFlags);

    // find an InputDevice from an InputDevice id
    InputDevice* findInputDevice(int32_t deviceId);
};

} // namespace android

#endif // _UI_INPUTREADER_INPUT_READER_H