1/*
2 * Copyright (c) 2021-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 INPUT_HUB_H
17#define INPUT_HUB_H
18
19#include <atomic>
20#include <mutex>
21#include <map>
22#include <memory>
23#include <set>
24#include <unordered_map>
25
26#include <libevdev/libevdev.h>
27#include <linux/input.h>
28#include <sys/epoll.h>
29#include <sys/inotify.h>
30
31#include "constants_dinput.h"
32
33namespace OHOS {
34namespace DistributedHardware {
35namespace DistributedInput {
36struct AffectDhIds {
37    std::vector<std::string> sharingDhIds;
38    std::vector<std::string> noSharingDhIds;
39};
40
41inline constexpr size_t BITS_PER_UINT8 { 8 };
42inline constexpr size_t NBYTES(size_t nbits)
43{
44    return (nbits + BITS_PER_UINT8 - 1) / BITS_PER_UINT8;
45}
46
47class InputHub {
48public:
49    struct Device  {
50        Device* next;
51        int fd; // may be -1 if device is closed
52        const std::string path;
53        InputDevice identifier;
54        uint32_t classes;
55        uint8_t evBitmask[NBYTES(EV_MAX)] {};
56        uint8_t keyBitmask[NBYTES(KEY_MAX)] {};
57        uint8_t absBitmask[NBYTES(ABS_MAX)] {};
58        uint8_t relBitmask[NBYTES(REL_MAX)] {};
59
60        Device(int fd, const std::string &path);
61        ~Device();
62        void Close();
63        bool enabled; // initially true
64        bool isShare;
65        int32_t Enable();
66        int32_t Disable();
67        bool HasValidFd() const;
68        const bool isVirtual; // set if fd < 0 is passed to constructor
69    };
70
71    struct AbsInfo {
72        uint32_t absX;
73        uint32_t absY;
74        int32_t absXIndex;
75        int32_t absYIndex;
76    };
77
78    explicit InputHub(bool isPluginMonitor);
79    ~InputHub();
80    size_t StartCollectInputEvents(RawEvent *buffer, size_t bufferSize);
81    size_t StartCollectInputHandler(InputDeviceEvent *buffer, size_t bufferSize);
82    void StopCollectInputEvents();
83    void StopCollectInputHandler();
84    size_t DeviceIsExists(InputDeviceEvent *buffer, size_t bufferSize);
85    std::vector<InputDevice> GetAllInputDevices();
86    // return efftive dhids
87    AffectDhIds SetSupportInputType(bool enabled, const uint32_t &inputTypes);
88    // return efftive dhids
89    AffectDhIds SetSharingDevices(bool enabled, std::vector<std::string> dhIds);
90    std::vector<std::string> GetSharingDevices();
91    void GetDevicesInfoByType(const uint32_t inputTypes, std::map<int32_t, std::string> &datas);
92    void GetDevicesInfoByDhId(std::vector<std::string> dhidsVec, std::map<int32_t, std::string> &datas);
93    void GetSharedMousePathByDhId(const std::vector<std::string> &dhIds, std::string &sharedMousePath,
94        std::string &sharedMouseDhId);
95    void GetSharedKeyboardPathsByDhIds(const std::vector<std::string> &dhIds,
96        std::vector<std::string> &sharedKeyboardPaths, std::vector<std::string> &sharedKeyboardDhIds);
97    bool IsAllDevicesStoped();
98    void ScanInputDevices(const std::string &dirName);
99
100    void RecordDeviceStates();
101    void CheckTargetDevicesState(std::vector<Device*> targetDevices);
102    bool IsLengthExceeds(const unsigned long *keyState, const unsigned long len, int keyIndex);
103    void CheckTargetKeyState(const InputHub::Device *dev, const unsigned long *keyState, const unsigned long len);
104    void SavePressedKeyState(const Device *dev, int32_t keyCode);
105    void ClearDeviceStates();
106    void ClearSkipDevicePaths();
107    /*
108     * Scan the input device node and save info.
109     */
110    void ScanAndRecordInputDevices();
111
112private:
113    int32_t Initialize();
114    int32_t Release();
115
116    size_t GetEvents(RawEvent *buffer, size_t bufferSize);
117    size_t ReadInputEvent(int32_t readSize, Device &device);
118    void GetDeviceHandler();
119    int32_t RefreshEpollItem(bool isSleep);
120
121    int32_t OpenInputDeviceLocked(const std::string &devicePath);
122    int32_t QueryInputDeviceInfo(int fd, std::unique_ptr<Device> &device);
123    void QueryEventInfo(int fd, std::unique_ptr<Device> &device);
124    struct libevdev* GetLibEvDev(int fd);
125    void GetEventTypes(struct libevdev *dev, InputDevice &identifier);
126    int32_t GetEventKeys(struct libevdev *dev, InputDevice &identifier);
127    int32_t GetABSInfo(struct libevdev *dev, InputDevice &identifier);
128    int32_t GetRELTypes(struct libevdev *dev, InputDevice &identifier);
129    void GetProperties(struct libevdev *dev, InputDevice &identifier);
130
131    void GetMSCBits(int fd, std::unique_ptr<Device> &device);
132    void GetLEDBits(int fd, std::unique_ptr<Device> &device);
133    void GetSwitchBits(int fd, std::unique_ptr<Device> &device);
134    void GetRepeatBits(int fd, std::unique_ptr<Device> &device);
135
136    void GetEventMask(int fd, const std::string &eventName, uint32_t type,
137        std::size_t arrayLength, uint8_t *whichBitMask) const;
138
139    int32_t MakeDevice(int fd, std::unique_ptr<Device> device);
140    void GenerateDescriptor(InputDevice &identifier) const;
141    std::string StringPrintf(const char *format, ...) const;
142
143    int32_t RegisterFdForEpoll(int fd);
144    int32_t RegisterDeviceForEpollLocked(const Device &device);
145    void AddDeviceLocked(std::unique_ptr<Device> device);
146    void CloseDeviceLocked(Device &device);
147    void CloseDeviceForAllLocked(Device &device);
148    int32_t UnregisterDeviceFromEpollLocked(const Device &device) const;
149    int32_t UnregisterFdFromEpoll(int fd) const;
150    int32_t ReadNotifyLocked();
151    void CloseDeviceByPathLocked(const std::string &devicePath);
152    void CloseAllDevicesLocked();
153    void JudgeDeviceOpenOrClose(const inotify_event &event);
154    Device* GetDeviceByPathLocked(const std::string &devicePath);
155    Device* GetDeviceByFdLocked(int fd);
156    Device* GetSupportDeviceByFd(int fd);
157    bool IsDeviceRegistered(const std::string &devicePath);
158
159    bool ContainsNonZeroByte(const uint8_t *array, uint32_t startIndex, uint32_t endIndex);
160    int64_t ProcessEventTimestamp(const input_event &event);
161    bool IsCuror(Device *device);
162    bool IsTouchPad(const InputDevice &inputDevice);
163    bool IsTouchPad(Device *device);
164
165    /*
166     * this macro is used to tell if "bit" is set in "array"
167     * it selects a byte from the array, and does a boolean AND
168     * operation with a byte that only has the relevant bit set.
169     * eg. to check for the 12th bit, we do (array[1] & 1<<4)
170     */
171    bool TestBit(uint32_t bit, const uint8_t *array);
172    /* this macro computes the number of bytes needed to represent a bit array of the specified size */
173    uint32_t SizeofBitArray(uint32_t bit);
174    void RecordEventLog(const RawEvent *event);
175    // Record Event log that will change the key state.
176    void RecordChangeEventLog(const RawEvent &event);
177    void RecordDeviceLog(const std::string &devicePath, const InputDevice &identifier);
178    void HandleTouchScreenEvent(struct input_event readBuffer[], const size_t count, std::vector<bool> &needFilted);
179    int32_t QueryLocalTouchScreenInfo(int fd, std::unique_ptr<Device> &device);
180    bool CheckTouchPointRegion(struct input_event readBuffer[], const AbsInfo &absInfo);
181    size_t CollectEvent(RawEvent *buffer, size_t &capacity, Device *device, struct input_event readBuffer[],
182        const size_t count);
183    /*
184     * isEnable: true for sharing dhid, false for no sharing dhid
185     */
186    void SaveAffectDhId(bool isEnable, const std::string &dhId, AffectDhIds &affDhIds);
187    /*
188     * Record Mouse/KeyBoard/TouchPad state such as key down.
189     */
190    void RecordDeviceChangeStates(Device *device, struct input_event readBuffer[], const size_t count);
191    void MatchAndDealEvent(Device *device, const RawEvent &event);
192    void DealTouchPadEvent(const RawEvent &event);
193    void DealNormalKeyEvent(Device *device, const RawEvent &event);
194
195    /*
196     * Check is this node has been scaned for collecting info.
197     * Return: True for scaned and cached. False for not scaned.
198     */
199    bool IsInputNodeNoNeedScan(const std::string &path);
200
201    /*
202     * Some input device should simulate state for pass through, such as Mouse, KeyBoard, TouchPad, etc.
203     * Before we prepare the pass through, we need check and get the key states of these devices.
204     */
205    std::vector<Device*> CollectTargetDevices();
206
207    void RecordSkipDevicePath(std::string path);
208    bool IsSkipDevicePath(const std::string &path);
209    void IncreaseLogTimes(const std::string& dhId);
210    bool IsNeedPrintLog(const std::string& dhId) const;
211
212private:
213    int epollFd_;
214    int iNotifyFd_;
215    int inputWd_;
216    /*
217     * true: for just monitor device plugin/unplugin;
218     * false: for read device events.
219     */
220    bool isPluginMonitor_;
221
222    std::vector<std::unique_ptr<Device>> openingDevices_;
223    std::vector<std::unique_ptr<Device>> closingDevices_;
224    std::unordered_map<std::string, std::unique_ptr<Device>> devices_;
225    std::mutex devicesMutex_;
226
227    std::mutex skipDevicePathsMutex_;
228    std::set<std::string> skipDevicePaths_;
229
230    std::atomic<bool> needToScanDevices_;
231    std::string touchDescriptor;
232
233    // The array of pending epoll events and the index of the next event to be handled.
234    struct epoll_event mPendingEventItems[EPOLL_MAX_EVENTS];
235    std::atomic<int32_t> pendingEventCount_;
236    std::atomic<int32_t> pendingEventIndex_;
237    std::atomic<bool> pendingINotify_;
238    std::mutex operationMutex_;
239
240    std::atomic<bool> deviceChanged_;
241    std::atomic<uint32_t> inputTypes_;
242    std::atomic<bool> isStartCollectEvent_;
243    std::atomic<bool> isStartCollectHandler_;
244    std::unordered_map<std::string, bool> sharedDHIds_;
245    std::unordered_map<std::string, int32_t> logTimesMap_;
246};
247} // namespace DistributedInput
248} // namespace DistributedHardware
249} // namespace OHOS
250
251#endif // INPUT_HUB_H
252