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