1 /*
2  * Copyright (c) 2022-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 DEVICE_H
17 #define 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 #include "i_device.h"
28 #include "i_epoll_event_source.h"
29 
30 namespace OHOS {
31 namespace Msdp {
32 namespace DeviceStatus {
33 inline constexpr size_t BIT_PER_UINT8 { 8 };
34 
NBYTES(size_t nbits)35 inline constexpr size_t NBYTES(size_t nbits)
36 {
37     return (nbits + BIT_PER_UINT8 - 1) / BIT_PER_UINT8;
38 }
39 
BYTE(size_t bit)40 inline constexpr size_t BYTE(size_t bit)
41 {
42     return (bit / BIT_PER_UINT8);
43 }
44 
OFFSET(size_t bit)45 inline constexpr size_t OFFSET(size_t bit)
46 {
47     return (bit % BIT_PER_UINT8);
48 }
49 
TestBit(size_t bit,const uint8_t * array)50 inline bool TestBit(size_t bit, const uint8_t *array)
51 {
52     return ((array)[BYTE(bit)] & (1 << OFFSET(bit)));
53 }
54 
55 class Device final : public IDevice,
56                      public IEpollEventSource {
57 public:
58 
59     explicit Device(int32_t deviceId);
60     DISALLOW_COPY_AND_MOVE(Device);
61     ~Device();
62 
63     int32_t Open() override;
64     void Close() override;
65     int32_t GetFd() const override;
66     void Dispatch(const struct epoll_event &ev) override;
67 
68     void SetId(int32_t id) override;
69     void SetDevPath(const std::string &devPath) override;
70     void SetSysPath(const std::string &sysPath) override;
71     void SetName(const std::string &name) override;
72     void SetBus(int32_t bus) override;
73     void SetVersion(int32_t version) override;
74     void SetProduct(int32_t product) override;
75     void SetVendor(int32_t vendor) override;
76     void SetPhys(const std::string &phys) override;
77     void SetUniq(const std::string &uniq) override;
78     void SetKeyboardType(KeyboardType keyboardType) override;
79     void AddCapability(Capability capability) override;
80 
81     int32_t GetId() const override;
82     std::string GetDevPath() const override;
83     std::string GetSysPath() const override;
84     std::string GetName() const override;
85     int32_t GetBus() const override;
86     int32_t GetVersion() const override;
87     int32_t GetProduct() const override;
88     int32_t GetVendor() const override;
89     std::string GetPhys() const override;
90     std::string GetUniq() const override;
91     IDevice::KeyboardType GetKeyboardType() const override;
92     bool IsPointerDevice() const override;
93     bool IsKeyboard() const override;
94     bool IsRemote() const override;
95 
96     bool HasAbs(size_t abs) const;
97     bool HasKey(size_t key) const;
98     bool HasRel(size_t rel) 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 HasAbsCoord() const;
107     bool HasMtCoord() const;
108     bool HasRelCoord() const;
109     bool HasAxesOrButton(size_t start, size_t end, const uint8_t* whichBitMask) const;
110     bool HasJoystickAxesOrButtons() const;
111     void CheckPointers();
112     void CheckAbs();
113     void CheckJoystick();
114     void CheckMt();
115     void CheckAdditional();
116     void CheckPencilMouse();
117     void CheckKeys();
118     std::string MakeConfigFileName() const;
119     int32_t ReadConfigFile(const std::string &filePath);
120     int32_t ConfigItemSwitch(const std::string &configItem, const std::string &value);
121     int32_t ReadTomlFile(const std::string &filePath);
122     void JudgeKeyboardType();
123     void LoadDeviceConfig();
124     void PrintCapsDevice() const;
125     void GetEventMask(const std::string &eventName, uint32_t type, std::size_t arrayLength,
126         uint8_t *whichBitMask) const;
127     void GetPropMask(const std::string &eventName, std::size_t arrayLength, uint8_t *whichBitMask) const;
128 
129     int32_t fd_ { -1 };
130     int32_t deviceId_ { -1 };
131     int32_t bus_ { 0 };
132     int32_t version_ { 0 };
133     int32_t product_ { 0 };
134     int32_t vendor_ { 0 };
135     std::string devPath_;
136     std::string sysPath_;
137     std::string dhid_;
138     std::string name_;
139     std::string phys_;
140     std::string uniq_;
141     std::string networkId_;
142     std::bitset<DEVICE_CAP_MAX> caps_;
143     uint8_t evBitmask_[NBYTES(EV_MAX)] {};
144     uint8_t keyBitmask_[NBYTES(KEY_MAX)] {};
145     uint8_t absBitmask_[NBYTES(ABS_MAX)] {};
146     uint8_t relBitmask_[NBYTES(REL_MAX)] {};
147     uint8_t propBitmask_[NBYTES(INPUT_PROP_MAX)] {};
148     IDevice::KeyboardType keyboardType_ { IDevice::KEYBOARD_TYPE_NONE };
149 };
150 
GetFd()151 inline int32_t Device::GetFd() const
152 {
153     return fd_;
154 }
155 
SetId(int32_t id)156 inline void Device::SetId(int32_t id)
157 {
158     deviceId_ = id;
159 }
160 
SetDevPath(const std::string & devPath)161 inline void Device::SetDevPath(const std::string &devPath)
162 {
163     devPath_ = devPath;
164 }
165 
SetSysPath(const std::string & sysPath)166 inline void Device::SetSysPath(const std::string &sysPath)
167 {
168     sysPath_ = sysPath;
169 }
170 
SetName(const std::string & name)171 inline void Device::SetName(const std::string &name)
172 {
173     name_ = name;
174 }
175 
SetBus(int32_t bus)176 inline void Device::SetBus(int32_t bus)
177 {
178     bus_ = bus;
179 }
180 
SetVersion(int32_t version)181 inline void Device::SetVersion(int32_t version)
182 {
183     version_ = version;
184 }
185 
SetProduct(int32_t product)186 inline void Device::SetProduct(int32_t product)
187 {
188     product_ = product;
189 }
190 
SetVendor(int32_t vendor)191 inline void Device::SetVendor(int32_t vendor)
192 {
193     vendor_ = vendor;
194 }
195 
SetPhys(const std::string & phys)196 inline void Device::SetPhys(const std::string &phys)
197 {
198     phys_ = phys;
199 }
200 
SetUniq(const std::string & uniq)201 inline void Device::SetUniq(const std::string &uniq)
202 {
203     uniq_ = uniq;
204 }
205 
SetKeyboardType(KeyboardType type)206 inline void Device::SetKeyboardType(KeyboardType type)
207 {
208     if (type >= KEYBOARD_TYPE_NONE && type < KEYBOARD_TYPE_MAX) {
209         keyboardType_ = type;
210     }
211 }
212 
AddCapability(Capability capability)213 inline void Device::AddCapability(Capability capability)
214 {
215     if (capability >= DEVICE_CAP_KEYBOARD && capability < DEVICE_CAP_MAX) {
216         caps_.set(capability);
217     }
218 }
219 
GetId()220 inline int32_t Device::GetId() const
221 {
222     return deviceId_;
223 }
224 
GetDevPath()225 inline std::string Device::GetDevPath() const
226 {
227     return devPath_;
228 }
229 
GetSysPath()230 inline std::string Device::GetSysPath() const
231 {
232     return sysPath_;
233 }
234 
GetName()235 inline std::string Device::GetName() const
236 {
237     return name_;
238 }
239 
GetBus()240 inline int32_t Device::GetBus() const
241 {
242     return bus_;
243 }
244 
GetVersion()245 inline int32_t Device::GetVersion() const
246 {
247     return version_;
248 }
249 
GetProduct()250 inline int32_t Device::GetProduct() const
251 {
252     return product_;
253 }
254 
GetVendor()255 inline int32_t Device::GetVendor() const
256 {
257     return vendor_;
258 }
259 
GetPhys()260 inline std::string Device::GetPhys() const
261 {
262     return phys_;
263 }
264 
GetUniq()265 inline std::string Device::GetUniq() const
266 {
267     return uniq_;
268 }
269 
GetKeyboardType()270 inline IDevice::KeyboardType Device::GetKeyboardType() const
271 {
272     return keyboardType_;
273 }
274 
IsPointerDevice()275 inline bool Device::IsPointerDevice() const
276 {
277     return caps_.test(DEVICE_CAP_POINTER);
278 }
279 
IsKeyboard()280 inline bool Device::IsKeyboard() const
281 {
282     return caps_.test(DEVICE_CAP_KEYBOARD);
283 }
284 
IsRemote()285 inline bool Device::IsRemote() const
286 {
287     return GetName().find("DistributedInput ") != std::string::npos;
288 }
289 
HasAbs(size_t abs)290 inline bool Device::HasAbs(size_t abs) const
291 {
292     return TestBit(abs, absBitmask_);
293 }
294 
HasRel(size_t rel)295 inline bool Device::HasRel(size_t rel) const
296 {
297     return TestBit(rel, relBitmask_);
298 }
299 
HasKey(size_t key)300 inline bool Device::HasKey(size_t key) const
301 {
302     return TestBit(key, keyBitmask_);
303 }
304 
HasProperty(size_t property)305 inline bool Device::HasProperty(size_t property) const
306 {
307     return TestBit(property, propBitmask_);
308 }
309 
HasCapability(Capability capability)310 inline bool Device::HasCapability(Capability capability) const
311 {
312     return caps_.test(capability);
313 }
314 } // namespace DeviceStatus
315 } // namespace Msdp
316 } // namespace OHOS
317 #endif // DEVICE_H