1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef V_INPUT_DEVICE_H
17 #define V_INPUT_DEVICE_H
18 
19 #include <bitset>
20 #include <string>
21 #include <vector>
22 
23 #include <linux/input.h>
24 
25 #include "nocopyable.h"
26 
27 namespace OHOS {
28 namespace MMI {
29 inline constexpr size_t BITS_PER_UINT8 { 8 };
30 
OFFSET(size_t bit)31 inline constexpr size_t OFFSET(size_t bit)
32 {
33     return (bit % BITS_PER_UINT8);
34 }
35 
BYTE(size_t bit)36 inline constexpr size_t BYTE(size_t bit)
37 {
38     return (bit / BITS_PER_UINT8);
39 }
40 
TestBit(size_t bit,const uint8_t * array)41 inline bool TestBit(size_t bit, const uint8_t *array)
42 {
43     return ((array)[BYTE(bit)] & (1 << OFFSET(bit)));
44 }
45 
NBYTES(size_t nbits)46 inline constexpr size_t NBYTES(size_t nbits)
47 {
48     return (nbits + BITS_PER_UINT8 - 1) / BITS_PER_UINT8;
49 }
50 
51 class VInputDevice final {
52 public:
53     enum Capability {
54         DEVICE_CAP_KEYBOARD = 0,
55         DEVICE_CAP_TOUCH,
56         DEVICE_CAP_POINTER,
57         DEVICE_CAP_TABLET_TOOL,
58         DEVICE_CAP_TABLET_PAD,
59         DEVICE_CAP_GESTURE,
60         DEVICE_CAP_SWITCH,
61         DEVICE_CAP_JOYSTICK,
62         DEVICE_CAP_MAX
63     };
64 
65 public:
66     explicit VInputDevice(const std::string &node);
67     ~VInputDevice();
68     DISALLOW_COPY_AND_MOVE(VInputDevice);
69 
70     int32_t Open();
71     void Close();
72     bool IsActive() const;
73     bool SupportEventType(size_t ev) const;
74     bool SupportKey(size_t key) const;
75     bool SupportAbs(size_t abs) const;
76     bool SupportRel(size_t rel) const;
77     bool SupportMsc(size_t msc) const;
78     bool SupportLed(size_t led) const;
79     bool SupportRep(size_t rep) const;
80     bool SupportProperty(size_t prop) const;
81     bool QueryAbsInfo(size_t abs, struct input_absinfo &absInfo);
82     int32_t SendEvent(uint16_t type, uint16_t code, int32_t value);
83 
84     int32_t GetFd() const;
85     std::string GetDevPath() const;
86     std::string GetSysPath() const;
87     std::string GetName() const;
88     struct input_id GetInputId() const;
89     std::string GetPhys() const;
90     std::string GetUniq() const;
91     bool IsMouse() const;
92     bool IsKeyboard() const;
93     bool IsTouchscreen() const;
94 
95     bool HasAbs(size_t abs) const;
96     bool HasRel(size_t rel) const;
97     bool HasKey(size_t key) const;
98     bool HasProperty(size_t property) const;
99     bool HasCapability(Capability capability) const;
100 
101 private:
102     void QueryDeviceInfo();
103     void QuerySupportedEvents();
104     void UpdateCapability();
105     bool HasAxesOrButton(size_t start, size_t end, const uint8_t* whichBitMask) const;
106     bool HasJoystickAxesOrButtons() const;
107     bool HasAbsCoord() const;
108     bool HasMtCoord() const;
109     bool HasRelCoord() const;
110     void CheckPointers();
111     void CheckKeys();
112     void CheckAbs();
113     void CheckMt();
114     void CheckAdditional();
115     void GetEventMask(const std::string &eventName, uint32_t type, std::size_t arrayLength,
116         uint8_t *whichBitMask) const;
117     void GetPropMask(const std::string &eventName, std::size_t arrayLength, uint8_t *whichBitMask) const;
118     void PrintCapsDevice() const;
119 
120 private:
121     int32_t fd_ { -1 };
122     struct input_id inputId_ {};
123     std::string devPath_;
124     std::string sysPath_;
125     std::string name_;
126     std::string phys_;
127     std::string uniq_;
128     std::string dhid_;
129     std::string networkId_;
130     std::bitset<DEVICE_CAP_MAX> caps_;
131     uint8_t evBitmask_[NBYTES(EV_MAX)] {};
132     uint8_t keyBitmask_[NBYTES(KEY_MAX)] {};
133     uint8_t absBitmask_[NBYTES(ABS_MAX)] {};
134     uint8_t relBitmask_[NBYTES(REL_MAX)] {};
135     uint8_t mscBitmask_[NBYTES(MSC_MAX)] {};
136     uint8_t ledBitmask_[NBYTES(LED_MAX)] {};
137     uint8_t repBitmask_[NBYTES(REP_MAX)] {};
138     uint8_t propBitmask_[NBYTES(INPUT_PROP_MAX)] {};
139 };
140 
IsActive()141 inline bool VInputDevice::IsActive() const
142 {
143     return (fd_ >= 0);
144 }
145 
SupportEventType(size_t ev)146 inline bool VInputDevice::SupportEventType(size_t ev) const
147 {
148     return TestBit(ev, evBitmask_);
149 }
150 
SupportKey(size_t key)151 inline bool VInputDevice::SupportKey(size_t key) const
152 {
153     return (TestBit(EV_KEY, evBitmask_) && TestBit(key, keyBitmask_));
154 }
155 
SupportAbs(size_t abs)156 inline bool VInputDevice::SupportAbs(size_t abs) const
157 {
158     return (TestBit(EV_ABS, evBitmask_) && TestBit(abs, absBitmask_));
159 }
160 
SupportRel(size_t rel)161 inline bool VInputDevice::SupportRel(size_t rel) const
162 {
163     return (TestBit(EV_REL, evBitmask_) && TestBit(rel, relBitmask_));
164 }
165 
SupportMsc(size_t msc)166 inline bool VInputDevice::SupportMsc(size_t msc) const
167 {
168     return (TestBit(EV_MSC, evBitmask_) && TestBit(msc, mscBitmask_));
169 }
170 
SupportLed(size_t led)171 inline bool VInputDevice::SupportLed(size_t led) const
172 {
173     return (TestBit(EV_LED, evBitmask_) && TestBit(led, ledBitmask_));
174 }
175 
SupportRep(size_t rep)176 inline bool VInputDevice::SupportRep(size_t rep) const
177 {
178     return (TestBit(EV_REP, evBitmask_) && TestBit(rep, repBitmask_));
179 }
180 
SupportProperty(size_t prop)181 inline bool VInputDevice::SupportProperty(size_t prop) const
182 {
183     return TestBit(prop, propBitmask_);
184 }
185 
GetFd()186 inline int32_t VInputDevice::GetFd() const
187 {
188     return fd_;
189 }
190 
GetDevPath()191 inline std::string VInputDevice::GetDevPath() const
192 {
193     return devPath_;
194 }
195 
GetSysPath()196 inline std::string VInputDevice::GetSysPath() const
197 {
198     return sysPath_;
199 }
200 
GetName()201 inline std::string VInputDevice::GetName() const
202 {
203     return name_;
204 }
205 
GetInputId()206 inline struct input_id VInputDevice::GetInputId() const
207 {
208     return inputId_;
209 }
210 
GetPhys()211 inline std::string VInputDevice::GetPhys() const
212 {
213     return phys_;
214 }
215 
GetUniq()216 inline std::string VInputDevice::GetUniq() const
217 {
218     return uniq_;
219 }
220 
IsMouse()221 inline bool VInputDevice::IsMouse() const
222 {
223     return caps_.test(DEVICE_CAP_POINTER);
224 }
225 
IsKeyboard()226 inline bool VInputDevice::IsKeyboard() const
227 {
228     return caps_.test(DEVICE_CAP_KEYBOARD);
229 }
230 
IsTouchscreen()231 inline bool VInputDevice::IsTouchscreen() const
232 {
233     return caps_.test(DEVICE_CAP_TOUCH);
234 }
235 
HasAbs(size_t abs)236 inline bool VInputDevice::HasAbs(size_t abs) const
237 {
238     return TestBit(abs, absBitmask_);
239 }
240 
HasRel(size_t rel)241 inline bool VInputDevice::HasRel(size_t rel) const
242 {
243     return TestBit(rel, relBitmask_);
244 }
245 
HasKey(size_t key)246 inline bool VInputDevice::HasKey(size_t key) const
247 {
248     return TestBit(key, keyBitmask_);
249 }
250 
HasProperty(size_t property)251 inline bool VInputDevice::HasProperty(size_t property) const
252 {
253     return TestBit(property, propBitmask_);
254 }
255 
HasCapability(Capability capability)256 inline bool VInputDevice::HasCapability(Capability capability) const
257 {
258     return caps_.test(capability);
259 }
260 } // namespace MMI
261 } // namespace OHOS
262 #endif // V_INPUT_DEVICE_H