12d4d9a4dSopenharmony_ci/* 22d4d9a4dSopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 32d4d9a4dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 42d4d9a4dSopenharmony_ci * you may not use this file except in compliance with the License. 52d4d9a4dSopenharmony_ci * You may obtain a copy of the License at 62d4d9a4dSopenharmony_ci * 72d4d9a4dSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 82d4d9a4dSopenharmony_ci * 92d4d9a4dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 102d4d9a4dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 112d4d9a4dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 122d4d9a4dSopenharmony_ci * See the License for the specific language governing permissions and 132d4d9a4dSopenharmony_ci * limitations under the License. 142d4d9a4dSopenharmony_ci */ 152d4d9a4dSopenharmony_ci 162d4d9a4dSopenharmony_ci#ifndef INPUT_HUB_H 172d4d9a4dSopenharmony_ci#define INPUT_HUB_H 182d4d9a4dSopenharmony_ci 192d4d9a4dSopenharmony_ci#include <atomic> 202d4d9a4dSopenharmony_ci#include <mutex> 212d4d9a4dSopenharmony_ci#include <map> 222d4d9a4dSopenharmony_ci#include <memory> 232d4d9a4dSopenharmony_ci#include <set> 242d4d9a4dSopenharmony_ci#include <unordered_map> 252d4d9a4dSopenharmony_ci 262d4d9a4dSopenharmony_ci#include <libevdev/libevdev.h> 272d4d9a4dSopenharmony_ci#include <linux/input.h> 282d4d9a4dSopenharmony_ci#include <sys/epoll.h> 292d4d9a4dSopenharmony_ci#include <sys/inotify.h> 302d4d9a4dSopenharmony_ci 312d4d9a4dSopenharmony_ci#include "constants_dinput.h" 322d4d9a4dSopenharmony_ci 332d4d9a4dSopenharmony_cinamespace OHOS { 342d4d9a4dSopenharmony_cinamespace DistributedHardware { 352d4d9a4dSopenharmony_cinamespace DistributedInput { 362d4d9a4dSopenharmony_cistruct AffectDhIds { 372d4d9a4dSopenharmony_ci std::vector<std::string> sharingDhIds; 382d4d9a4dSopenharmony_ci std::vector<std::string> noSharingDhIds; 392d4d9a4dSopenharmony_ci}; 402d4d9a4dSopenharmony_ci 412d4d9a4dSopenharmony_ciinline constexpr size_t BITS_PER_UINT8 { 8 }; 422d4d9a4dSopenharmony_ciinline constexpr size_t NBYTES(size_t nbits) 432d4d9a4dSopenharmony_ci{ 442d4d9a4dSopenharmony_ci return (nbits + BITS_PER_UINT8 - 1) / BITS_PER_UINT8; 452d4d9a4dSopenharmony_ci} 462d4d9a4dSopenharmony_ci 472d4d9a4dSopenharmony_ciclass InputHub { 482d4d9a4dSopenharmony_cipublic: 492d4d9a4dSopenharmony_ci struct Device { 502d4d9a4dSopenharmony_ci Device* next; 512d4d9a4dSopenharmony_ci int fd; // may be -1 if device is closed 522d4d9a4dSopenharmony_ci const std::string path; 532d4d9a4dSopenharmony_ci InputDevice identifier; 542d4d9a4dSopenharmony_ci uint32_t classes; 552d4d9a4dSopenharmony_ci uint8_t evBitmask[NBYTES(EV_MAX)] {}; 562d4d9a4dSopenharmony_ci uint8_t keyBitmask[NBYTES(KEY_MAX)] {}; 572d4d9a4dSopenharmony_ci uint8_t absBitmask[NBYTES(ABS_MAX)] {}; 582d4d9a4dSopenharmony_ci uint8_t relBitmask[NBYTES(REL_MAX)] {}; 592d4d9a4dSopenharmony_ci 602d4d9a4dSopenharmony_ci Device(int fd, const std::string &path); 612d4d9a4dSopenharmony_ci ~Device(); 622d4d9a4dSopenharmony_ci void Close(); 632d4d9a4dSopenharmony_ci bool enabled; // initially true 642d4d9a4dSopenharmony_ci bool isShare; 652d4d9a4dSopenharmony_ci int32_t Enable(); 662d4d9a4dSopenharmony_ci int32_t Disable(); 672d4d9a4dSopenharmony_ci bool HasValidFd() const; 682d4d9a4dSopenharmony_ci const bool isVirtual; // set if fd < 0 is passed to constructor 692d4d9a4dSopenharmony_ci }; 702d4d9a4dSopenharmony_ci 712d4d9a4dSopenharmony_ci struct AbsInfo { 722d4d9a4dSopenharmony_ci uint32_t absX; 732d4d9a4dSopenharmony_ci uint32_t absY; 742d4d9a4dSopenharmony_ci int32_t absXIndex; 752d4d9a4dSopenharmony_ci int32_t absYIndex; 762d4d9a4dSopenharmony_ci }; 772d4d9a4dSopenharmony_ci 782d4d9a4dSopenharmony_ci explicit InputHub(bool isPluginMonitor); 792d4d9a4dSopenharmony_ci ~InputHub(); 802d4d9a4dSopenharmony_ci size_t StartCollectInputEvents(RawEvent *buffer, size_t bufferSize); 812d4d9a4dSopenharmony_ci size_t StartCollectInputHandler(InputDeviceEvent *buffer, size_t bufferSize); 822d4d9a4dSopenharmony_ci void StopCollectInputEvents(); 832d4d9a4dSopenharmony_ci void StopCollectInputHandler(); 842d4d9a4dSopenharmony_ci size_t DeviceIsExists(InputDeviceEvent *buffer, size_t bufferSize); 852d4d9a4dSopenharmony_ci std::vector<InputDevice> GetAllInputDevices(); 862d4d9a4dSopenharmony_ci // return efftive dhids 872d4d9a4dSopenharmony_ci AffectDhIds SetSupportInputType(bool enabled, const uint32_t &inputTypes); 882d4d9a4dSopenharmony_ci // return efftive dhids 892d4d9a4dSopenharmony_ci AffectDhIds SetSharingDevices(bool enabled, std::vector<std::string> dhIds); 902d4d9a4dSopenharmony_ci std::vector<std::string> GetSharingDevices(); 912d4d9a4dSopenharmony_ci void GetDevicesInfoByType(const uint32_t inputTypes, std::map<int32_t, std::string> &datas); 922d4d9a4dSopenharmony_ci void GetDevicesInfoByDhId(std::vector<std::string> dhidsVec, std::map<int32_t, std::string> &datas); 932d4d9a4dSopenharmony_ci void GetSharedMousePathByDhId(const std::vector<std::string> &dhIds, std::string &sharedMousePath, 942d4d9a4dSopenharmony_ci std::string &sharedMouseDhId); 952d4d9a4dSopenharmony_ci void GetSharedKeyboardPathsByDhIds(const std::vector<std::string> &dhIds, 962d4d9a4dSopenharmony_ci std::vector<std::string> &sharedKeyboardPaths, std::vector<std::string> &sharedKeyboardDhIds); 972d4d9a4dSopenharmony_ci bool IsAllDevicesStoped(); 982d4d9a4dSopenharmony_ci void ScanInputDevices(const std::string &dirName); 992d4d9a4dSopenharmony_ci 1002d4d9a4dSopenharmony_ci void RecordDeviceStates(); 1012d4d9a4dSopenharmony_ci void CheckTargetDevicesState(std::vector<Device*> targetDevices); 1022d4d9a4dSopenharmony_ci bool IsLengthExceeds(const unsigned long *keyState, const unsigned long len, int keyIndex); 1032d4d9a4dSopenharmony_ci void CheckTargetKeyState(const InputHub::Device *dev, const unsigned long *keyState, const unsigned long len); 1042d4d9a4dSopenharmony_ci void SavePressedKeyState(const Device *dev, int32_t keyCode); 1052d4d9a4dSopenharmony_ci void ClearDeviceStates(); 1062d4d9a4dSopenharmony_ci void ClearSkipDevicePaths(); 1072d4d9a4dSopenharmony_ci /* 1082d4d9a4dSopenharmony_ci * Scan the input device node and save info. 1092d4d9a4dSopenharmony_ci */ 1102d4d9a4dSopenharmony_ci void ScanAndRecordInputDevices(); 1112d4d9a4dSopenharmony_ci 1122d4d9a4dSopenharmony_ciprivate: 1132d4d9a4dSopenharmony_ci int32_t Initialize(); 1142d4d9a4dSopenharmony_ci int32_t Release(); 1152d4d9a4dSopenharmony_ci 1162d4d9a4dSopenharmony_ci size_t GetEvents(RawEvent *buffer, size_t bufferSize); 1172d4d9a4dSopenharmony_ci size_t ReadInputEvent(int32_t readSize, Device &device); 1182d4d9a4dSopenharmony_ci void GetDeviceHandler(); 1192d4d9a4dSopenharmony_ci int32_t RefreshEpollItem(bool isSleep); 1202d4d9a4dSopenharmony_ci 1212d4d9a4dSopenharmony_ci int32_t OpenInputDeviceLocked(const std::string &devicePath); 1222d4d9a4dSopenharmony_ci int32_t QueryInputDeviceInfo(int fd, std::unique_ptr<Device> &device); 1232d4d9a4dSopenharmony_ci void QueryEventInfo(int fd, std::unique_ptr<Device> &device); 1242d4d9a4dSopenharmony_ci struct libevdev* GetLibEvDev(int fd); 1252d4d9a4dSopenharmony_ci void GetEventTypes(struct libevdev *dev, InputDevice &identifier); 1262d4d9a4dSopenharmony_ci int32_t GetEventKeys(struct libevdev *dev, InputDevice &identifier); 1272d4d9a4dSopenharmony_ci int32_t GetABSInfo(struct libevdev *dev, InputDevice &identifier); 1282d4d9a4dSopenharmony_ci int32_t GetRELTypes(struct libevdev *dev, InputDevice &identifier); 1292d4d9a4dSopenharmony_ci void GetProperties(struct libevdev *dev, InputDevice &identifier); 1302d4d9a4dSopenharmony_ci 1312d4d9a4dSopenharmony_ci void GetMSCBits(int fd, std::unique_ptr<Device> &device); 1322d4d9a4dSopenharmony_ci void GetLEDBits(int fd, std::unique_ptr<Device> &device); 1332d4d9a4dSopenharmony_ci void GetSwitchBits(int fd, std::unique_ptr<Device> &device); 1342d4d9a4dSopenharmony_ci void GetRepeatBits(int fd, std::unique_ptr<Device> &device); 1352d4d9a4dSopenharmony_ci 1362d4d9a4dSopenharmony_ci void GetEventMask(int fd, const std::string &eventName, uint32_t type, 1372d4d9a4dSopenharmony_ci std::size_t arrayLength, uint8_t *whichBitMask) const; 1382d4d9a4dSopenharmony_ci 1392d4d9a4dSopenharmony_ci int32_t MakeDevice(int fd, std::unique_ptr<Device> device); 1402d4d9a4dSopenharmony_ci void GenerateDescriptor(InputDevice &identifier) const; 1412d4d9a4dSopenharmony_ci std::string StringPrintf(const char *format, ...) const; 1422d4d9a4dSopenharmony_ci 1432d4d9a4dSopenharmony_ci int32_t RegisterFdForEpoll(int fd); 1442d4d9a4dSopenharmony_ci int32_t RegisterDeviceForEpollLocked(const Device &device); 1452d4d9a4dSopenharmony_ci void AddDeviceLocked(std::unique_ptr<Device> device); 1462d4d9a4dSopenharmony_ci void CloseDeviceLocked(Device &device); 1472d4d9a4dSopenharmony_ci void CloseDeviceForAllLocked(Device &device); 1482d4d9a4dSopenharmony_ci int32_t UnregisterDeviceFromEpollLocked(const Device &device) const; 1492d4d9a4dSopenharmony_ci int32_t UnregisterFdFromEpoll(int fd) const; 1502d4d9a4dSopenharmony_ci int32_t ReadNotifyLocked(); 1512d4d9a4dSopenharmony_ci void CloseDeviceByPathLocked(const std::string &devicePath); 1522d4d9a4dSopenharmony_ci void CloseAllDevicesLocked(); 1532d4d9a4dSopenharmony_ci void JudgeDeviceOpenOrClose(const inotify_event &event); 1542d4d9a4dSopenharmony_ci Device* GetDeviceByPathLocked(const std::string &devicePath); 1552d4d9a4dSopenharmony_ci Device* GetDeviceByFdLocked(int fd); 1562d4d9a4dSopenharmony_ci Device* GetSupportDeviceByFd(int fd); 1572d4d9a4dSopenharmony_ci bool IsDeviceRegistered(const std::string &devicePath); 1582d4d9a4dSopenharmony_ci 1592d4d9a4dSopenharmony_ci bool ContainsNonZeroByte(const uint8_t *array, uint32_t startIndex, uint32_t endIndex); 1602d4d9a4dSopenharmony_ci int64_t ProcessEventTimestamp(const input_event &event); 1612d4d9a4dSopenharmony_ci bool IsCuror(Device *device); 1622d4d9a4dSopenharmony_ci bool IsTouchPad(const InputDevice &inputDevice); 1632d4d9a4dSopenharmony_ci bool IsTouchPad(Device *device); 1642d4d9a4dSopenharmony_ci 1652d4d9a4dSopenharmony_ci /* 1662d4d9a4dSopenharmony_ci * this macro is used to tell if "bit" is set in "array" 1672d4d9a4dSopenharmony_ci * it selects a byte from the array, and does a boolean AND 1682d4d9a4dSopenharmony_ci * operation with a byte that only has the relevant bit set. 1692d4d9a4dSopenharmony_ci * eg. to check for the 12th bit, we do (array[1] & 1<<4) 1702d4d9a4dSopenharmony_ci */ 1712d4d9a4dSopenharmony_ci bool TestBit(uint32_t bit, const uint8_t *array); 1722d4d9a4dSopenharmony_ci /* this macro computes the number of bytes needed to represent a bit array of the specified size */ 1732d4d9a4dSopenharmony_ci uint32_t SizeofBitArray(uint32_t bit); 1742d4d9a4dSopenharmony_ci void RecordEventLog(const RawEvent *event); 1752d4d9a4dSopenharmony_ci // Record Event log that will change the key state. 1762d4d9a4dSopenharmony_ci void RecordChangeEventLog(const RawEvent &event); 1772d4d9a4dSopenharmony_ci void RecordDeviceLog(const std::string &devicePath, const InputDevice &identifier); 1782d4d9a4dSopenharmony_ci void HandleTouchScreenEvent(struct input_event readBuffer[], const size_t count, std::vector<bool> &needFilted); 1792d4d9a4dSopenharmony_ci int32_t QueryLocalTouchScreenInfo(int fd, std::unique_ptr<Device> &device); 1802d4d9a4dSopenharmony_ci bool CheckTouchPointRegion(struct input_event readBuffer[], const AbsInfo &absInfo); 1812d4d9a4dSopenharmony_ci size_t CollectEvent(RawEvent *buffer, size_t &capacity, Device *device, struct input_event readBuffer[], 1822d4d9a4dSopenharmony_ci const size_t count); 1832d4d9a4dSopenharmony_ci /* 1842d4d9a4dSopenharmony_ci * isEnable: true for sharing dhid, false for no sharing dhid 1852d4d9a4dSopenharmony_ci */ 1862d4d9a4dSopenharmony_ci void SaveAffectDhId(bool isEnable, const std::string &dhId, AffectDhIds &affDhIds); 1872d4d9a4dSopenharmony_ci /* 1882d4d9a4dSopenharmony_ci * Record Mouse/KeyBoard/TouchPad state such as key down. 1892d4d9a4dSopenharmony_ci */ 1902d4d9a4dSopenharmony_ci void RecordDeviceChangeStates(Device *device, struct input_event readBuffer[], const size_t count); 1912d4d9a4dSopenharmony_ci void MatchAndDealEvent(Device *device, const RawEvent &event); 1922d4d9a4dSopenharmony_ci void DealTouchPadEvent(const RawEvent &event); 1932d4d9a4dSopenharmony_ci void DealNormalKeyEvent(Device *device, const RawEvent &event); 1942d4d9a4dSopenharmony_ci 1952d4d9a4dSopenharmony_ci /* 1962d4d9a4dSopenharmony_ci * Check is this node has been scaned for collecting info. 1972d4d9a4dSopenharmony_ci * Return: True for scaned and cached. False for not scaned. 1982d4d9a4dSopenharmony_ci */ 1992d4d9a4dSopenharmony_ci bool IsInputNodeNoNeedScan(const std::string &path); 2002d4d9a4dSopenharmony_ci 2012d4d9a4dSopenharmony_ci /* 2022d4d9a4dSopenharmony_ci * Some input device should simulate state for pass through, such as Mouse, KeyBoard, TouchPad, etc. 2032d4d9a4dSopenharmony_ci * Before we prepare the pass through, we need check and get the key states of these devices. 2042d4d9a4dSopenharmony_ci */ 2052d4d9a4dSopenharmony_ci std::vector<Device*> CollectTargetDevices(); 2062d4d9a4dSopenharmony_ci 2072d4d9a4dSopenharmony_ci void RecordSkipDevicePath(std::string path); 2082d4d9a4dSopenharmony_ci bool IsSkipDevicePath(const std::string &path); 2092d4d9a4dSopenharmony_ci void IncreaseLogTimes(const std::string& dhId); 2102d4d9a4dSopenharmony_ci bool IsNeedPrintLog(const std::string& dhId) const; 2112d4d9a4dSopenharmony_ci 2122d4d9a4dSopenharmony_ciprivate: 2132d4d9a4dSopenharmony_ci int epollFd_; 2142d4d9a4dSopenharmony_ci int iNotifyFd_; 2152d4d9a4dSopenharmony_ci int inputWd_; 2162d4d9a4dSopenharmony_ci /* 2172d4d9a4dSopenharmony_ci * true: for just monitor device plugin/unplugin; 2182d4d9a4dSopenharmony_ci * false: for read device events. 2192d4d9a4dSopenharmony_ci */ 2202d4d9a4dSopenharmony_ci bool isPluginMonitor_; 2212d4d9a4dSopenharmony_ci 2222d4d9a4dSopenharmony_ci std::vector<std::unique_ptr<Device>> openingDevices_; 2232d4d9a4dSopenharmony_ci std::vector<std::unique_ptr<Device>> closingDevices_; 2242d4d9a4dSopenharmony_ci std::unordered_map<std::string, std::unique_ptr<Device>> devices_; 2252d4d9a4dSopenharmony_ci std::mutex devicesMutex_; 2262d4d9a4dSopenharmony_ci 2272d4d9a4dSopenharmony_ci std::mutex skipDevicePathsMutex_; 2282d4d9a4dSopenharmony_ci std::set<std::string> skipDevicePaths_; 2292d4d9a4dSopenharmony_ci 2302d4d9a4dSopenharmony_ci std::atomic<bool> needToScanDevices_; 2312d4d9a4dSopenharmony_ci std::string touchDescriptor; 2322d4d9a4dSopenharmony_ci 2332d4d9a4dSopenharmony_ci // The array of pending epoll events and the index of the next event to be handled. 2342d4d9a4dSopenharmony_ci struct epoll_event mPendingEventItems[EPOLL_MAX_EVENTS]; 2352d4d9a4dSopenharmony_ci std::atomic<int32_t> pendingEventCount_; 2362d4d9a4dSopenharmony_ci std::atomic<int32_t> pendingEventIndex_; 2372d4d9a4dSopenharmony_ci std::atomic<bool> pendingINotify_; 2382d4d9a4dSopenharmony_ci std::mutex operationMutex_; 2392d4d9a4dSopenharmony_ci 2402d4d9a4dSopenharmony_ci std::atomic<bool> deviceChanged_; 2412d4d9a4dSopenharmony_ci std::atomic<uint32_t> inputTypes_; 2422d4d9a4dSopenharmony_ci std::atomic<bool> isStartCollectEvent_; 2432d4d9a4dSopenharmony_ci std::atomic<bool> isStartCollectHandler_; 2442d4d9a4dSopenharmony_ci std::unordered_map<std::string, bool> sharedDHIds_; 2452d4d9a4dSopenharmony_ci std::unordered_map<std::string, int32_t> logTimesMap_; 2462d4d9a4dSopenharmony_ci}; 2472d4d9a4dSopenharmony_ci} // namespace DistributedInput 2482d4d9a4dSopenharmony_ci} // namespace DistributedHardware 2492d4d9a4dSopenharmony_ci} // namespace OHOS 2502d4d9a4dSopenharmony_ci 2512d4d9a4dSopenharmony_ci#endif // INPUT_HUB_H 252