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
27namespace OHOS {
28namespace Msdp {
29namespace DeviceStatus {
30inline constexpr size_t BITS_PER_UINT8 { 8 };
31
32inline constexpr size_t OFFSET(size_t bit)
33{
34    return (bit % BITS_PER_UINT8);
35}
36
37inline constexpr size_t BYTE(size_t bit)
38{
39    return (bit / BITS_PER_UINT8);
40}
41
42inline bool TestBit(size_t bit, const uint8_t *array)
43{
44    return ((array)[BYTE(bit)] & (1 << OFFSET(bit)));
45}
46
47inline constexpr size_t NBYTES(size_t nbits)
48{
49    return (nbits + BITS_PER_UINT8 - 1) / BITS_PER_UINT8;
50}
51
52class VInputDevice final {
53public:
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
66public:
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
102private:
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
121private:
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
142inline bool VInputDevice::IsActive() const
143{
144    return (fd_ >= 0);
145}
146
147inline bool VInputDevice::SupportEventType(size_t ev) const
148{
149    return TestBit(ev, evBitmask_);
150}
151
152inline bool VInputDevice::SupportKey(size_t key) const
153{
154    return (TestBit(EV_KEY, evBitmask_) && TestBit(key, keyBitmask_));
155}
156
157inline bool VInputDevice::SupportAbs(size_t abs) const
158{
159    return (TestBit(EV_ABS, evBitmask_) && TestBit(abs, absBitmask_));
160}
161
162inline bool VInputDevice::SupportRel(size_t rel) const
163{
164    return (TestBit(EV_REL, evBitmask_) && TestBit(rel, relBitmask_));
165}
166
167inline bool VInputDevice::SupportMsc(size_t msc) const
168{
169    return (TestBit(EV_MSC, evBitmask_) && TestBit(msc, mscBitmask_));
170}
171
172inline bool VInputDevice::SupportLed(size_t led) const
173{
174    return (TestBit(EV_LED, evBitmask_) && TestBit(led, ledBitmask_));
175}
176
177inline bool VInputDevice::SupportRep(size_t rep) const
178{
179    return (TestBit(EV_REP, evBitmask_) && TestBit(rep, repBitmask_));
180}
181
182inline bool VInputDevice::SupportProperty(size_t prop) const
183{
184    return TestBit(prop, propBitmask_);
185}
186
187inline int32_t VInputDevice::GetFd() const
188{
189    return fd_;
190}
191
192inline std::string VInputDevice::GetDevPath() const
193{
194    return devPath_;
195}
196
197inline std::string VInputDevice::GetSysPath() const
198{
199    return sysPath_;
200}
201
202inline std::string VInputDevice::GetName() const
203{
204    return name_;
205}
206
207inline struct input_id VInputDevice::GetInputId() const
208{
209    return inputId_;
210}
211
212inline std::string VInputDevice::GetPhys() const
213{
214    return phys_;
215}
216
217inline std::string VInputDevice::GetUniq() const
218{
219    return uniq_;
220}
221
222inline bool VInputDevice::IsMouse() const
223{
224    return caps_.test(DEVICE_CAP_POINTER);
225}
226
227inline bool VInputDevice::IsKeyboard() const
228{
229    return caps_.test(DEVICE_CAP_KEYBOARD);
230}
231
232inline bool VInputDevice::IsTouchscreen() const
233{
234    return caps_.test(DEVICE_CAP_TOUCH);
235}
236
237inline bool VInputDevice::HasAbs(size_t abs) const
238{
239    return TestBit(abs, absBitmask_);
240}
241
242inline bool VInputDevice::HasRel(size_t rel) const
243{
244    return TestBit(rel, relBitmask_);
245}
246
247inline bool VInputDevice::HasKey(size_t key) const
248{
249    return TestBit(key, keyBitmask_);
250}
251
252inline bool VInputDevice::HasProperty(size_t property) const
253{
254    return TestBit(property, propBitmask_);
255}
256
257inline 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