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
30namespace OHOS {
31namespace Msdp {
32namespace DeviceStatus {
33inline constexpr size_t BIT_PER_UINT8 { 8 };
34
35inline constexpr size_t NBYTES(size_t nbits)
36{
37    return (nbits + BIT_PER_UINT8 - 1) / BIT_PER_UINT8;
38}
39
40inline constexpr size_t BYTE(size_t bit)
41{
42    return (bit / BIT_PER_UINT8);
43}
44
45inline constexpr size_t OFFSET(size_t bit)
46{
47    return (bit % BIT_PER_UINT8);
48}
49
50inline bool TestBit(size_t bit, const uint8_t *array)
51{
52    return ((array)[BYTE(bit)] & (1 << OFFSET(bit)));
53}
54
55class Device final : public IDevice,
56                     public IEpollEventSource {
57public:
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
102private:
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
151inline int32_t Device::GetFd() const
152{
153    return fd_;
154}
155
156inline void Device::SetId(int32_t id)
157{
158    deviceId_ = id;
159}
160
161inline void Device::SetDevPath(const std::string &devPath)
162{
163    devPath_ = devPath;
164}
165
166inline void Device::SetSysPath(const std::string &sysPath)
167{
168    sysPath_ = sysPath;
169}
170
171inline void Device::SetName(const std::string &name)
172{
173    name_ = name;
174}
175
176inline void Device::SetBus(int32_t bus)
177{
178    bus_ = bus;
179}
180
181inline void Device::SetVersion(int32_t version)
182{
183    version_ = version;
184}
185
186inline void Device::SetProduct(int32_t product)
187{
188    product_ = product;
189}
190
191inline void Device::SetVendor(int32_t vendor)
192{
193    vendor_ = vendor;
194}
195
196inline void Device::SetPhys(const std::string &phys)
197{
198    phys_ = phys;
199}
200
201inline void Device::SetUniq(const std::string &uniq)
202{
203    uniq_ = uniq;
204}
205
206inline void Device::SetKeyboardType(KeyboardType type)
207{
208    if (type >= KEYBOARD_TYPE_NONE && type < KEYBOARD_TYPE_MAX) {
209        keyboardType_ = type;
210    }
211}
212
213inline void Device::AddCapability(Capability capability)
214{
215    if (capability >= DEVICE_CAP_KEYBOARD && capability < DEVICE_CAP_MAX) {
216        caps_.set(capability);
217    }
218}
219
220inline int32_t Device::GetId() const
221{
222    return deviceId_;
223}
224
225inline std::string Device::GetDevPath() const
226{
227    return devPath_;
228}
229
230inline std::string Device::GetSysPath() const
231{
232    return sysPath_;
233}
234
235inline std::string Device::GetName() const
236{
237    return name_;
238}
239
240inline int32_t Device::GetBus() const
241{
242    return bus_;
243}
244
245inline int32_t Device::GetVersion() const
246{
247    return version_;
248}
249
250inline int32_t Device::GetProduct() const
251{
252    return product_;
253}
254
255inline int32_t Device::GetVendor() const
256{
257    return vendor_;
258}
259
260inline std::string Device::GetPhys() const
261{
262    return phys_;
263}
264
265inline std::string Device::GetUniq() const
266{
267    return uniq_;
268}
269
270inline IDevice::KeyboardType Device::GetKeyboardType() const
271{
272    return keyboardType_;
273}
274
275inline bool Device::IsPointerDevice() const
276{
277    return caps_.test(DEVICE_CAP_POINTER);
278}
279
280inline bool Device::IsKeyboard() const
281{
282    return caps_.test(DEVICE_CAP_KEYBOARD);
283}
284
285inline bool Device::IsRemote() const
286{
287    return GetName().find("DistributedInput ") != std::string::npos;
288}
289
290inline bool Device::HasAbs(size_t abs) const
291{
292    return TestBit(abs, absBitmask_);
293}
294
295inline bool Device::HasRel(size_t rel) const
296{
297    return TestBit(rel, relBitmask_);
298}
299
300inline bool Device::HasKey(size_t key) const
301{
302    return TestBit(key, keyBitmask_);
303}
304
305inline bool Device::HasProperty(size_t property) const
306{
307    return TestBit(property, propBitmask_);
308}
309
310inline 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