1 /*
2  * Copyright (c) 2023 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 Msdp {
29 namespace DeviceStatus {
30 inline constexpr size_t BITS_PER_UINT8 { 8 };
31 
OFFSET(size_t bit)32 inline constexpr size_t OFFSET(size_t bit)
33 {
34     return (bit % BITS_PER_UINT8);
35 }
36 
BYTE(size_t bit)37 inline constexpr size_t BYTE(size_t bit)
38 {
39     return (bit / BITS_PER_UINT8);
40 }
41 
TestBit(size_t bit,const uint8_t * array)42 inline bool TestBit(size_t bit, const uint8_t *array)
43 {
44     return ((array)[BYTE(bit)] & (1 << OFFSET(bit)));
45 }
46 
NBYTES(size_t nbits)47 inline constexpr size_t NBYTES(size_t nbits)
48 {
49     return (nbits + BITS_PER_UINT8 - 1) / BITS_PER_UINT8;
50 }
51 
52 class VInputDevice final {
53 public:
54     enum Capability {
55         DEVICE_CAP_KEYBOARD = 0,
56         DEVICE_CAP_TOUCH,
57         DEVICE_CAP_POINTER,
58         DEVICE_CAP_TABLET_TOOL,
59         DEVICE_CAP_TABLET_PAD,
60         DEVICE_CAP_GESTURE,
61         DEVICE_CAP_SWITCH,
62         DEVICE_CAP_JOYSTICK,
63         DEVICE_CAP_MAX
64     };
65 
66 public:
67     explicit VInputDevice(const std::string &node);
68     ~VInputDevice();
69     DISALLOW_COPY_AND_MOVE(VInputDevice);
70 
71     int32_t Open();
72     void Close();
73     bool IsActive() const;
74     bool SupportEventType(size_t ev) const;
75     bool SupportKey(size_t key) const;
76     bool SupportAbs(size_t abs) const;
77     bool SupportRel(size_t rel) const;
78     bool SupportMsc(size_t msc) const;
79     bool SupportLed(size_t led) const;
80     bool SupportRep(size_t rep) const;
81     bool SupportProperty(size_t prop) const;
82     bool QueryAbsInfo(size_t abs, struct input_absinfo &absInfo);
83     int32_t SendEvent(uint16_t type, uint16_t code, int32_t value);
84 
85     int32_t GetFd() const;
86     std::string GetDevPath() const;
87     std::string GetSysPath() const;
88     std::string GetName() const;
89     struct input_id GetInputId() const;
90     std::string GetPhys() const;
91     std::string GetUniq() const;
92     bool IsMouse() const;
93     bool IsKeyboard() const;
94     bool IsTouchscreen() const;
95 
96     bool HasAbs(size_t abs) const;
97     bool HasRel(size_t rel) const;
98     bool HasKey(size_t key) const;
99     bool HasProperty(size_t property) const;
100     bool HasCapability(Capability capability) const;
101 
102 private:
103     void QueryDeviceInfo();
104     void QuerySupportedEvents();
105     void UpdateCapability();
106     bool HasAxesOrButton(size_t start, size_t end, const uint8_t* whichBitMask) const;
107     bool HasJoystickAxesOrButtons() const;
108     bool HasAbsCoord() const;
109     bool HasMtCoord() const;
110     bool HasRelCoord() const;
111     void CheckPointers();
112     void CheckKeys();
113     void CheckAbs();
114     void CheckMt();
115     void CheckAdditional();
116     void GetEventMask(const std::string &eventName, uint32_t type, std::size_t arrayLength,
117         uint8_t *whichBitMask) const;
118     void GetPropMask(const std::string &eventName, std::size_t arrayLength, uint8_t *whichBitMask) const;
119     void PrintCapsDevice() const;
120 
121 private:
122     int32_t fd_ { -1 };
123     struct input_id inputId_ {};
124     std::string devPath_;
125     std::string sysPath_;
126     std::string name_;
127     std::string phys_;
128     std::string uniq_;
129     std::string dhid_;
130     std::string networkId_;
131     std::bitset<DEVICE_CAP_MAX> caps_;
132     uint8_t evBitmask_[NBYTES(EV_MAX)] {};
133     uint8_t keyBitmask_[NBYTES(KEY_MAX)] {};
134     uint8_t absBitmask_[NBYTES(ABS_MAX)] {};
135     uint8_t relBitmask_[NBYTES(REL_MAX)] {};
136     uint8_t mscBitmask_[NBYTES(MSC_MAX)] {};
137     uint8_t ledBitmask_[NBYTES(LED_MAX)] {};
138     uint8_t repBitmask_[NBYTES(REP_MAX)] {};
139     uint8_t propBitmask_[NBYTES(INPUT_PROP_MAX)] {};
140 };
141 
IsActive()142 inline bool VInputDevice::IsActive() const
143 {
144     return (fd_ >= 0);
145 }
146 
SupportEventType(size_t ev)147 inline bool VInputDevice::SupportEventType(size_t ev) const
148 {
149     return TestBit(ev, evBitmask_);
150 }
151 
SupportKey(size_t key)152 inline bool VInputDevice::SupportKey(size_t key) const
153 {
154     return (TestBit(EV_KEY, evBitmask_) && TestBit(key, keyBitmask_));
155 }
156 
SupportAbs(size_t abs)157 inline bool VInputDevice::SupportAbs(size_t abs) const
158 {
159     return (TestBit(EV_ABS, evBitmask_) && TestBit(abs, absBitmask_));
160 }
161 
SupportRel(size_t rel)162 inline bool VInputDevice::SupportRel(size_t rel) const
163 {
164     return (TestBit(EV_REL, evBitmask_) && TestBit(rel, relBitmask_));
165 }
166 
SupportMsc(size_t msc)167 inline bool VInputDevice::SupportMsc(size_t msc) const
168 {
169     return (TestBit(EV_MSC, evBitmask_) && TestBit(msc, mscBitmask_));
170 }
171 
SupportLed(size_t led)172 inline bool VInputDevice::SupportLed(size_t led) const
173 {
174     return (TestBit(EV_LED, evBitmask_) && TestBit(led, ledBitmask_));
175 }
176 
SupportRep(size_t rep)177 inline bool VInputDevice::SupportRep(size_t rep) const
178 {
179     return (TestBit(EV_REP, evBitmask_) && TestBit(rep, repBitmask_));
180 }
181 
SupportProperty(size_t prop)182 inline bool VInputDevice::SupportProperty(size_t prop) const
183 {
184     return TestBit(prop, propBitmask_);
185 }
186 
GetFd()187 inline int32_t VInputDevice::GetFd() const
188 {
189     return fd_;
190 }
191 
GetDevPath()192 inline std::string VInputDevice::GetDevPath() const
193 {
194     return devPath_;
195 }
196 
GetSysPath()197 inline std::string VInputDevice::GetSysPath() const
198 {
199     return sysPath_;
200 }
201 
GetName()202 inline std::string VInputDevice::GetName() const
203 {
204     return name_;
205 }
206 
GetInputId()207 inline struct input_id VInputDevice::GetInputId() const
208 {
209     return inputId_;
210 }
211 
GetPhys()212 inline std::string VInputDevice::GetPhys() const
213 {
214     return phys_;
215 }
216 
GetUniq()217 inline std::string VInputDevice::GetUniq() const
218 {
219     return uniq_;
220 }
221 
IsMouse()222 inline bool VInputDevice::IsMouse() const
223 {
224     return caps_.test(DEVICE_CAP_POINTER);
225 }
226 
IsKeyboard()227 inline bool VInputDevice::IsKeyboard() const
228 {
229     return caps_.test(DEVICE_CAP_KEYBOARD);
230 }
231 
IsTouchscreen()232 inline bool VInputDevice::IsTouchscreen() const
233 {
234     return caps_.test(DEVICE_CAP_TOUCH);
235 }
236 
HasAbs(size_t abs)237 inline bool VInputDevice::HasAbs(size_t abs) const
238 {
239     return TestBit(abs, absBitmask_);
240 }
241 
HasRel(size_t rel)242 inline bool VInputDevice::HasRel(size_t rel) const
243 {
244     return TestBit(rel, relBitmask_);
245 }
246 
HasKey(size_t key)247 inline bool VInputDevice::HasKey(size_t key) const
248 {
249     return TestBit(key, keyBitmask_);
250 }
251 
HasProperty(size_t property)252 inline bool VInputDevice::HasProperty(size_t property) const
253 {
254     return TestBit(property, propBitmask_);
255 }
256 
HasCapability(Capability capability)257 inline bool VInputDevice::HasCapability(Capability capability) const
258 {
259     return caps_.test(capability);
260 }
261 } // namespace DeviceStatus
262 } // namespace Msdp
263 } // namespace OHOS
264 #endif // V_INPUT_DEVICE_H