1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _UI_INPUTREADER_INPUT_DEVICE_H
18 #define _UI_INPUTREADER_INPUT_DEVICE_H
19 
20 #include <input/DisplayViewport.h>
21 #include <input/InputDevice.h>
22 #include <stdint.h>
23 #include <utils/PropertyMap.h>
24 
25 #include <optional>
26 #include <unordered_map>
27 #include <vector>
28 
29 #include "EventHub.h"
30 #include "InputReaderBase.h"
31 #include "InputReaderContext.h"
32 
33 namespace android {
34 
35 class InputDeviceContext;
36 class InputMapper;
37 
38 /* Represents the state of a single input device. */
39 class InputDevice {
40 public:
41     InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
42                 const InputDeviceIdentifier& identifier);
43     ~InputDevice();
44 
getContext()45     inline InputReaderContext* getContext() { return mContext; }
getId()46     inline int32_t getId() const { return mId; }
getControllerNumber()47     inline int32_t getControllerNumber() const { return mControllerNumber; }
getGeneration()48     inline int32_t getGeneration() const { return mGeneration; }
getName()49     inline const std::string getName() const { return mIdentifier.name; }
getDescriptor()50     inline const std::string getDescriptor() { return mIdentifier.descriptor; }
getClasses()51     inline uint32_t getClasses() const { return mClasses; }
getSources()52     inline uint32_t getSources() const { return mSources; }
hasEventHubDevices()53     inline bool hasEventHubDevices() const { return !mDevices.empty(); }
54 
isExternal()55     inline bool isExternal() { return mIsExternal; }
getAssociatedDisplayPort()56     inline std::optional<uint8_t> getAssociatedDisplayPort() const {
57         return mAssociatedDisplayPort;
58     }
getAssociatedViewport()59     inline std::optional<DisplayViewport> getAssociatedViewport() const {
60         return mAssociatedViewport;
61     }
hasMic()62     inline bool hasMic() const { return mHasMic; }
63 
isIgnored()64     inline bool isIgnored() { return !getMapperCount(); }
65 
66     bool isEnabled();
67     void setEnabled(bool enabled, nsecs_t when);
68 
69     void dump(std::string& dump);
70     void addEventHubDevice(int32_t eventHubId, bool populateMappers = true);
71     void removeEventHubDevice(int32_t eventHubId);
72     void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
73     void reset(nsecs_t when);
74     void process(const RawEvent* rawEvents, size_t count);
75     void timeoutExpired(nsecs_t when);
76     void updateExternalStylusState(const StylusState& state);
77 
78     void getDeviceInfo(InputDeviceInfo* outDeviceInfo);
79     int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
80     int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
81     int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
82     bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, const int32_t* keyCodes,
83                                uint8_t* outFlags);
84     void vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat, int32_t token);
85     void cancelVibrate(int32_t token);
86     void cancelTouch(nsecs_t when);
87 
88     int32_t getMetaState();
89     void updateMetaState(int32_t keyCode);
90 
91     void bumpGeneration();
92 
93     void notifyReset(nsecs_t when);
94 
getConfiguration()95     inline const PropertyMap& getConfiguration() { return mConfiguration; }
getEventHub()96     inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
97 
98     std::optional<int32_t> getAssociatedDisplayId();
99 
100     size_t getMapperCount();
101 
102     // construct and add a mapper to the input device
103     template <class T, typename... Args>
addMapper(int32_t eventHubId,Args...args)104     T& addMapper(int32_t eventHubId, Args... args) {
105         // ensure a device entry exists for this eventHubId
106         addEventHubDevice(eventHubId, false);
107 
108         // create mapper
109         auto& devicePair = mDevices[eventHubId];
110         auto& deviceContext = devicePair.first;
111         auto& mappers = devicePair.second;
112         T* mapper = new T(*deviceContext, args...);
113         mappers.emplace_back(mapper);
114         return *mapper;
115     }
116 
117 private:
118     InputReaderContext* mContext;
119     int32_t mId;
120     int32_t mGeneration;
121     int32_t mControllerNumber;
122     InputDeviceIdentifier mIdentifier;
123     std::string mAlias;
124     uint32_t mClasses;
125 
126     // map from eventHubId to device context and mappers
127     using MapperVector = std::vector<std::unique_ptr<InputMapper>>;
128     using DevicePair = std::pair<std::unique_ptr<InputDeviceContext>, MapperVector>;
129     std::unordered_map<int32_t, DevicePair> mDevices;
130 
131     uint32_t mSources;
132     bool mIsExternal;
133     std::optional<uint8_t> mAssociatedDisplayPort;
134     std::optional<DisplayViewport> mAssociatedViewport;
135     bool mHasMic;
136     bool mDropUntilNextSync;
137 
138     typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code);
139     int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc);
140 
141     PropertyMap mConfiguration;
142 
143     // helpers to interate over the devices collection
144     // run a function against every mapper on every subdevice
for_each_mapper(std::function<void (InputMapper &)> f)145     inline void for_each_mapper(std::function<void(InputMapper&)> f) {
146         for (auto& deviceEntry : mDevices) {
147             auto& devicePair = deviceEntry.second;
148             auto& mappers = devicePair.second;
149             for (auto& mapperPtr : mappers) {
150                 f(*mapperPtr);
151             }
152         }
153     }
154 
155     // run a function against every mapper on a specific subdevice
for_each_mapper_in_subdevice(int32_t eventHubDevice,std::function<void (InputMapper &)> f)156     inline void for_each_mapper_in_subdevice(int32_t eventHubDevice,
157                                              std::function<void(InputMapper&)> f) {
158         auto deviceIt = mDevices.find(eventHubDevice);
159         if (deviceIt != mDevices.end()) {
160             auto& devicePair = deviceIt->second;
161             auto& mappers = devicePair.second;
162             for (auto& mapperPtr : mappers) {
163                 f(*mapperPtr);
164             }
165         }
166     }
167 
168     // run a function against every subdevice
for_each_subdevice(std::function<void (InputDeviceContext &)> f)169     inline void for_each_subdevice(std::function<void(InputDeviceContext&)> f) {
170         for (auto& deviceEntry : mDevices) {
171             auto& devicePair = deviceEntry.second;
172             auto& contextPtr = devicePair.first;
173             f(*contextPtr);
174         }
175     }
176 
177     // return the first value returned by a function over every mapper.
178     // if all mappers return nullopt, return nullopt.
179     template <typename T>
first_in_mappers(std::function<std::optional<T> (InputMapper &)> f)180     inline std::optional<T> first_in_mappers(std::function<std::optional<T>(InputMapper&)> f) {
181         for (auto& deviceEntry : mDevices) {
182             auto& devicePair = deviceEntry.second;
183             auto& mappers = devicePair.second;
184             for (auto& mapperPtr : mappers) {
185                 std::optional<T> ret = f(*mapperPtr);
186                 if (ret) {
187                     return ret;
188                 }
189             }
190         }
191         return std::nullopt;
192     }
193 };
194 
195 /* Provides access to EventHub methods, but limits access to the current InputDevice.
196  * Essentially an implementation of EventHubInterface, but for a specific device id.
197  * Helps hide implementation details of InputDevice and EventHub. Used by mappers to
198  * check the status of the associated hardware device
199  */
200 class InputDeviceContext {
201 public:
202     InputDeviceContext(InputDevice& device, int32_t eventHubId);
203     ~InputDeviceContext();
204 
getContext()205     inline InputReaderContext* getContext() { return mContext; }
getId()206     inline int32_t getId() { return mDeviceId; }
getEventHubId()207     inline int32_t getEventHubId() { return mId; }
208 
getDeviceClasses()209     inline uint32_t getDeviceClasses() const { return mEventHub->getDeviceClasses(mId); }
getDeviceIdentifier()210     inline InputDeviceIdentifier getDeviceIdentifier() const {
211         return mEventHub->getDeviceIdentifier(mId);
212     }
getDeviceControllerNumber()213     inline int32_t getDeviceControllerNumber() const {
214         return mEventHub->getDeviceControllerNumber(mId);
215     }
getConfiguration(PropertyMap * outConfiguration)216     inline void getConfiguration(PropertyMap* outConfiguration) const {
217         return mEventHub->getConfiguration(mId, outConfiguration);
218     }
getAbsoluteAxisInfo(int32_t code,RawAbsoluteAxisInfo * axisInfo)219     inline status_t getAbsoluteAxisInfo(int32_t code, RawAbsoluteAxisInfo* axisInfo) const {
220         return mEventHub->getAbsoluteAxisInfo(mId, code, axisInfo);
221     }
hasRelativeAxis(int32_t code)222     inline bool hasRelativeAxis(int32_t code) const {
223         return mEventHub->hasRelativeAxis(mId, code);
224     }
hasInputProperty(int property)225     inline bool hasInputProperty(int property) const {
226         return mEventHub->hasInputProperty(mId, property);
227     }
mapKey(int32_t scanCode,int32_t usageCode,int32_t metaState,int32_t * outKeycode,int32_t * outMetaState,uint32_t * outFlags)228     inline status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t metaState,
229                            int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const {
230         return mEventHub->mapKey(mId, scanCode, usageCode, metaState, outKeycode, outMetaState,
231                                  outFlags);
232     }
mapAxis(int32_t scanCode,AxisInfo * outAxisInfo)233     inline status_t mapAxis(int32_t scanCode, AxisInfo* outAxisInfo) const {
234         return mEventHub->mapAxis(mId, scanCode, outAxisInfo);
235     }
getVideoFrames()236     inline std::vector<TouchVideoFrame> getVideoFrames() { return mEventHub->getVideoFrames(mId); }
getScanCodeState(int32_t scanCode)237     inline int32_t getScanCodeState(int32_t scanCode) const {
238         return mEventHub->getScanCodeState(mId, scanCode);
239     }
getKeyCodeState(int32_t keyCode)240     inline int32_t getKeyCodeState(int32_t keyCode) const {
241         return mEventHub->getKeyCodeState(mId, keyCode);
242     }
getSwitchState(int32_t sw)243     inline int32_t getSwitchState(int32_t sw) const { return mEventHub->getSwitchState(mId, sw); }
getAbsoluteAxisValue(int32_t code,int32_t * outValue)244     inline status_t getAbsoluteAxisValue(int32_t code, int32_t* outValue) const {
245         return mEventHub->getAbsoluteAxisValue(mId, code, outValue);
246     }
markSupportedKeyCodes(size_t numCodes,const int32_t * keyCodes,uint8_t * outFlags)247     inline bool markSupportedKeyCodes(size_t numCodes, const int32_t* keyCodes,
248                                       uint8_t* outFlags) const {
249         return mEventHub->markSupportedKeyCodes(mId, numCodes, keyCodes, outFlags);
250     }
hasScanCode(int32_t scanCode)251     inline bool hasScanCode(int32_t scanCode) const {
252         return mEventHub->hasScanCode(mId, scanCode);
253     }
hasLed(int32_t led)254     inline bool hasLed(int32_t led) const { return mEventHub->hasLed(mId, led); }
setLedState(int32_t led,bool on)255     inline void setLedState(int32_t led, bool on) { return mEventHub->setLedState(mId, led, on); }
getVirtualKeyDefinitions(std::vector<VirtualKeyDefinition> & outVirtualKeys)256     inline void getVirtualKeyDefinitions(std::vector<VirtualKeyDefinition>& outVirtualKeys) const {
257         return mEventHub->getVirtualKeyDefinitions(mId, outVirtualKeys);
258     }
getKeyCharacterMap()259     inline sp<KeyCharacterMap> getKeyCharacterMap() const {
260         return mEventHub->getKeyCharacterMap(mId);
261     }
setKeyboardLayoutOverlay(const sp<KeyCharacterMap> & map)262     inline bool setKeyboardLayoutOverlay(const sp<KeyCharacterMap>& map) {
263         return mEventHub->setKeyboardLayoutOverlay(mId, map);
264     }
vibrate(nsecs_t duration)265     inline void vibrate(nsecs_t duration) { return mEventHub->vibrate(mId, duration); }
cancelVibrate()266     inline void cancelVibrate() { return mEventHub->cancelVibrate(mId); }
267 
hasAbsoluteAxis(int32_t code)268     inline bool hasAbsoluteAxis(int32_t code) const {
269         RawAbsoluteAxisInfo info;
270         mEventHub->getAbsoluteAxisInfo(mId, code, &info);
271         return info.valid;
272     }
isKeyPressed(int32_t code)273     inline bool isKeyPressed(int32_t code) const {
274         return mEventHub->getScanCodeState(mId, code) == AKEY_STATE_DOWN;
275     }
getAbsoluteAxisValue(int32_t code)276     inline int32_t getAbsoluteAxisValue(int32_t code) const {
277         int32_t value;
278         mEventHub->getAbsoluteAxisValue(mId, code, &value);
279         return value;
280     }
isDeviceEnabled()281     inline bool isDeviceEnabled() { return mEventHub->isDeviceEnabled(mId); }
enableDevice()282     inline status_t enableDevice() { return mEventHub->enableDevice(mId); }
disableDevice()283     inline status_t disableDevice() { return mEventHub->disableDevice(mId); }
284 
getName()285     inline const std::string getName() { return mDevice.getName(); }
getDescriptor()286     inline const std::string getDescriptor() { return mDevice.getDescriptor(); }
isExternal()287     inline bool isExternal() { return mDevice.isExternal(); }
getAssociatedDisplayPort()288     inline std::optional<uint8_t> getAssociatedDisplayPort() const {
289         return mDevice.getAssociatedDisplayPort();
290     }
getAssociatedViewport()291     inline std::optional<DisplayViewport> getAssociatedViewport() const {
292         return mDevice.getAssociatedViewport();
293     }
cancelTouch(nsecs_t when)294     inline void cancelTouch(nsecs_t when) { mDevice.cancelTouch(when); }
bumpGeneration()295     inline void bumpGeneration() { mDevice.bumpGeneration(); }
getConfiguration()296     inline const PropertyMap& getConfiguration() { return mDevice.getConfiguration(); }
297 
298 private:
299     InputDevice& mDevice;
300     InputReaderContext* mContext;
301     EventHubInterface* mEventHub;
302     int32_t mId;
303     int32_t mDeviceId;
304 };
305 
306 } // namespace android
307 
308 #endif //_UI_INPUTREADER_INPUT_DEVICE_H
309