• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <unordered_map>
23 
24 #include <libevdev/libevdev.h>
25 #include <linux/input.h>
26 #include <sys/epoll.h>
27 #include <sys/inotify.h>
28 
29 #include "constants_dinput.h"
30 
31 namespace OHOS {
32 namespace DistributedHardware {
33 namespace DistributedInput {
34 struct AffectDhIds {
35     std::vector<std::string> sharingDhIds;
36     std::vector<std::string> noSharingDhIds;
37 };
38 
39 class InputHub {
40 public:
41     InputHub();
42     ~InputHub();
43     size_t StartCollectInputEvents(RawEvent *buffer, size_t bufferSize);
44     size_t StartCollectInputHandler(InputDeviceEvent *buffer, size_t bufferSize);
45     void StopCollectInputEvents();
46     void StopCollectInputHandler();
47     size_t DeviceIsExists(InputDeviceEvent *buffer, size_t bufferSize);
48     std::vector<InputDevice> GetAllInputDevices();
49     // return efftive dhids
50     AffectDhIds SetSupportInputType(bool enabled, const uint32_t &inputTypes);
51     // return efftive dhids
52     AffectDhIds SetSharingDevices(bool enabled, std::vector<std::string> dhIds);
53     void GetDevicesInfoByType(const uint32_t inputTypes, std::map<int32_t, std::string> &datas);
54     void GetDevicesInfoByDhId(std::vector<std::string> dhidsVec, std::map<int32_t, std::string> &datas);
55     void GetShareMousePathByDhId(std::vector<std::string> dhIds, std::string &path, std::string &dhId);
56     void GetShareKeyboardPathsByDhIds(std::vector<std::string> dhIds, std::vector<std::string> &shareDhidsPaths,
57         std::vector<std::string> &shareDhIds);
58     bool IsAllDevicesStoped();
59     void ScanInputDevices(const std::string &dirName);
60 
61 private:
62     struct Device  {
63         Device* next;
64         int fd; // may be -1 if device is closed
65         const int32_t id;
66         const std::string path;
67         InputDevice identifier;
68         uint32_t classes;
69         uint8_t keyBitmask[(KEY_MAX + 1) / 8];
70         uint8_t absBitmask[(ABS_MAX + 1) / 8];
71         uint8_t relBitmask[(REL_MAX + 1) / 8];
72 
73         Device(int fd, int32_t id, const std::string &path, const InputDevice &identifier);
74         ~Device();
75         void Close();
76         bool enabled; // initially true
77         bool isShare;
78         int32_t Enable();
79         int32_t Disable();
80         bool HasValidFd() const;
81         const bool isVirtual; // set if fd < 0 is passed to constructor
82     };
83 
84     struct AbsInfo {
85         uint32_t absX;
86         uint32_t absY;
87         int32_t absXIndex;
88         int32_t absYIndex;
89     };
90 
91     int32_t Initialize();
92     int32_t Release();
93 
94     size_t GetEvents(RawEvent *buffer, size_t bufferSize);
95     size_t ReadInputEvent(int32_t readSize, Device &device);
96     void GetDeviceHandler();
97     int32_t RefreshEpollItem(bool isSleep);
98 
99     int32_t OpenInputDeviceLocked(const std::string &devicePath);
100     int32_t QueryInputDeviceInfo(int fd, InputDevice &identifier);
101     void QueryEventInfo(int fd, InputDevice &identifier);
102     struct libevdev* GetLibEvDev(int fd);
103     void GetEventTypes(struct libevdev *dev, InputDevice &identifier);
104     int32_t GetEventKeys(struct libevdev *dev, InputDevice &identifier);
105     int32_t GetABSInfo(struct libevdev *dev, InputDevice &identifier);
106     int32_t GetRELTypes(struct libevdev *dev, InputDevice &identifier);
107     void GetProperties(struct libevdev *dev, InputDevice &identifier);
108     int32_t MakeDevice(int fd, std::unique_ptr<Device> device);
109     void GenerateDescriptor(InputDevice &identifier) const;
110     std::string StringPrintf(const char *format, ...) const;
111 
112     int32_t RegisterFdForEpoll(int fd);
113     int32_t RegisterDeviceForEpollLocked(const Device &device);
114     void AddDeviceLocked(std::unique_ptr<Device> device);
115     void CloseDeviceLocked(Device &device);
116     void CloseDeviceForAllLocked(Device &device);
117     int32_t UnregisterDeviceFromEpollLocked(const Device &device) const;
118     int32_t UnregisterFdFromEpoll(int fd) const;
119     int32_t ReadNotifyLocked();
120     void CloseDeviceByPathLocked(const std::string &devicePath);
121     void CloseAllDevicesLocked();
122     void JudgeDeviceOpenOrClose(const inotify_event &event);
123     Device* GetDeviceByPathLocked(const std::string &devicePath);
124     Device* GetDeviceByFdLocked(int fd);
125     Device* GetSupportDeviceByFd(int fd);
126     bool IsDeviceRegistered(const std::string &devicePath);
127 
128     bool ContainsNonZeroByte(const uint8_t *array, uint32_t startIndex, uint32_t endIndex);
129     int64_t ProcessEventTimestamp(const input_event &event);
130     bool IsTouchPad(const InputDevice &inputDevice);
131 
132     /*
133      * this macro is used to tell if "bit" is set in "array"
134      * it selects a byte from the array, and does a boolean AND
135      * operation with a byte that only has the relevant bit set.
136      * eg. to check for the 12th bit, we do (array[1] & 1<<4)
137      */
138     bool TestBit(uint32_t bit, const uint8_t *array);
139     /* this macro computes the number of bytes needed to represent a bit array of the specified size */
140     uint32_t SizeofBitArray(uint32_t bit);
141     void RecordEventLog(const RawEvent *event);
142     void RecordDeviceLog(const int32_t deviceId, const std::string &devicePath, const InputDevice &identifier);
143     void HandleTouchScreenEvent(struct input_event readBuffer[], const size_t count, std::vector<bool> &needFilted);
144     int32_t QueryLocalTouchScreenInfo(int fd);
145     bool CheckTouchPointRegion(struct input_event readBuffer[], const AbsInfo &absInfo);
146     size_t CollectEvent(RawEvent *buffer, size_t &capacity, Device *device, struct input_event readBuffer[],
147         const size_t count);
148     /*
149      * isEnable: true for sharing dhid, false for no sharing dhid
150      */
151     void SaveAffectDhId(bool isEnable, const std::string &dhId, AffectDhIds &affDhIds);
152 
153     int epollFd_;
154     int iNotifyFd_;
155     int inputWd_;
156 
157     std::vector<std::unique_ptr<Device>> openingDevices_;
158     std::vector<std::unique_ptr<Device>> closingDevices_;
159     std::unordered_map<int32_t, std::unique_ptr<Device>> devices_;
160     std::mutex devicesMutex_;
161 
162     std::atomic<bool> needToScanDevices_;
163     std::string deviceId_;
164     std::string touchDescriptor;
165     std::atomic<int32_t> nextDeviceId_;
166 
167     // The array of pending epoll events and the index of the next event to be handled.
168     struct epoll_event mPendingEventItems[EPOLL_MAX_EVENTS];
169     std::atomic<int32_t> pendingEventCount_;
170     std::atomic<int32_t> pendingEventIndex_;
171     std::atomic<bool> pendingINotify_;
172     std::mutex operationMutex_;
173 
174     std::atomic<bool> deviceChanged_;
175     std::atomic<uint32_t> inputTypes_;
176     std::atomic<bool> isStartCollectEvent_;
177     std::atomic<bool> isStartCollectHandler_;
178     std::unordered_map<std::string, bool> sharedDHIds_;
179 };
180 } // namespace DistributedInput
181 } // namespace DistributedHardware
182 } // namespace OHOS
183 
184 #endif // INPUT_HUB_H
185