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