1 /*
2  * Copyright (c) 2021-2024 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 #include "input_hub.h"
17 
18 #include <algorithm>
19 #include <cinttypes>
20 #include <cstring>
21 #include <fcntl.h>
22 #include <filesystem>
23 #include <regex>
24 #include <securec.h>
25 #include <sstream>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <thread>
29 #include <unistd.h>
30 #include <utility>
31 
32 #include "constants_dinput.h"
33 #include "dinput_context.h"
34 #include "dinput_errcode.h"
35 #include "dinput_log.h"
36 #include "dinput_sink_state.h"
37 #include "dinput_utils_tool.h"
38 
39 namespace OHOS {
40 namespace DistributedHardware {
41 namespace DistributedInput {
42 namespace {
43 const uint32_t SLEEP_TIME_US = 100 * 1000;
44 const std::string MOUSE_NODE_KEY = "mouse";
45 const uint32_t SPACELENGTH = 1024;
46 }
47 
InputHub(bool isPluginMonitor)48 InputHub::InputHub(bool isPluginMonitor) : epollFd_(-1), iNotifyFd_(-1), inputWd_(-1),
49     isPluginMonitor_(isPluginMonitor), needToScanDevices_(true), mPendingEventItems{},
50     pendingEventCount_(0), pendingEventIndex_(0), pendingINotify_(false), deviceChanged_(false),
51     inputTypes_(0), isStartCollectEvent_(false), isStartCollectHandler_(false)
52 {
53     Initialize();
54 }
55 
~InputHub()56 InputHub::~InputHub()
57 {
58     Release();
59 }
60 
Initialize()61 int32_t InputHub::Initialize()
62 {
63     epollFd_ = epoll_create1(EPOLL_CLOEXEC);
64     if (epollFd_ < 0) {
65         DHLOGE("Could not create epoll instance: %{public}s", ConvertErrNo().c_str());
66         return ERR_DH_INPUT_HUB_EPOLL_INIT_FAIL;
67     }
68 
69     if (isPluginMonitor_) {
70         DHLOGI("Init InputHub for device plugin monitor");
71         iNotifyFd_ = inotify_init();
72         inputWd_ = inotify_add_watch(iNotifyFd_, DEVICE_PATH, IN_DELETE | IN_CREATE);
73         if (inputWd_ < 0) {
74             DHLOGE("Could not register INotify for %{public}s: %{public}s", DEVICE_PATH, ConvertErrNo().c_str());
75             return ERR_DH_INPUT_HUB_EPOLL_INIT_FAIL;
76         }
77 
78         struct epoll_event eventItem = {};
79         eventItem.events = EPOLLIN;
80         eventItem.data.fd = iNotifyFd_;
81         int result = epoll_ctl(epollFd_, EPOLL_CTL_ADD, iNotifyFd_, &eventItem);
82         if (result != 0) {
83             DHLOGE("Could not add INotify to epoll instance.  errno=%{public}d", errno);
84             return ERR_DH_INPUT_HUB_EPOLL_INIT_FAIL;
85         }
86     } else {
87         DHLOGI("Init InputHub for read device events");
88     }
89 
90     return DH_SUCCESS;
91 }
92 
Release()93 int32_t InputHub::Release()
94 {
95     CloseAllDevicesLocked();
96     if (epollFd_ != -1) {
97         ::close(epollFd_);
98         epollFd_ = -1;
99     }
100 
101     if (iNotifyFd_ != -1) {
102         ::close(iNotifyFd_);
103         iNotifyFd_ = -1;
104     }
105 
106     if (isPluginMonitor_) {
107         StopCollectInputHandler();
108     } else {
109         StopCollectInputEvents();
110     }
111 
112     sharedDHIds_.clear();
113     logTimesMap_.clear();
114     return DH_SUCCESS;
115 }
116 
IsInputNodeNoNeedScan(const std::string & path)117 bool InputHub::IsInputNodeNoNeedScan(const std::string &path)
118 {
119     {
120         std::lock_guard<std::mutex> deviceLock(devicesMutex_);
121         auto iter = devices_.find(path);
122         if (iter != devices_.end()) {
123             return true;
124         }
125     }
126 
127     if (path.find(MOUSE_NODE_KEY) != std::string::npos) {
128         return true;
129     }
130 
131     return IsSkipDevicePath(path);
132 }
133 
ScanAndRecordInputDevices()134 void InputHub::ScanAndRecordInputDevices()
135 {
136     ScanInputDevices(DEVICE_PATH);
137 
138     {
139         std::lock_guard<std::mutex> deviceLock(devicesMutex_);
140         while (!openingDevices_.empty()) {
141             std::unique_ptr<Device> device = std::move(*openingDevices_.rbegin());
142             openingDevices_.pop_back();
143             DHLOGI("Reporting device opened: path=%{public}s, name=%{public}s\n",
144                 device->path.c_str(), device->identifier.name.c_str());
145             std::string devPath = device->path;
146             auto [dev_it, inserted] = devices_.insert_or_assign(device->path, std::move(device));
147             if (!inserted) {
148                 DHLOGI("Device with this path %{public}s exists, replaced. \n", devPath.c_str());
149             }
150         }
151     }
152 }
153 
StartCollectInputEvents(RawEvent * buffer,size_t bufferSize)154 size_t InputHub::StartCollectInputEvents(RawEvent *buffer, size_t bufferSize)
155 {
156     size_t count = 0;
157     isStartCollectEvent_ = true;
158     while (isStartCollectEvent_) {
159         ScanAndRecordInputDevices();
160         count = GetEvents(buffer, bufferSize);
161         if (count > 0) {
162             break;
163         }
164 
165         if (RefreshEpollItem(false) < 0) {
166             break;
167         }
168     }
169 
170     // All done, return the number of events we read.
171     return count;
172 }
173 
StopCollectInputEvents()174 void InputHub::StopCollectInputEvents()
175 {
176     DHLOGI("Stop Collect Input Events Thread");
177     isStartCollectEvent_ = false;
178 }
179 
GetEvents(RawEvent * buffer,size_t bufferSize)180 size_t InputHub::GetEvents(RawEvent *buffer, size_t bufferSize)
181 {
182     RawEvent* event = buffer;
183     size_t capacity = bufferSize;
184     while (pendingEventIndex_ < pendingEventCount_) {
185         std::lock_guard<std::mutex> my_lock(operationMutex_);
186         const struct epoll_event& eventItem = mPendingEventItems[pendingEventIndex_++];
187         if (eventItem.data.fd == iNotifyFd_) {
188             continue;
189         }
190         struct input_event readBuffer[bufferSize];
191         int32_t readSize = read(eventItem.data.fd, readBuffer, sizeof(struct input_event) * capacity);
192         Device* deviceByFd = GetDeviceByFdLocked(eventItem.data.fd);
193         if (!deviceByFd) {
194             DHLOGE("Find device by fd: %{public}d failed", eventItem.data.fd);
195             continue;
196         }
197         size_t count = ReadInputEvent(readSize, *deviceByFd);
198         Device* device = GetSupportDeviceByFd(eventItem.data.fd);
199         if (!device) {
200             DHLOGE("Can not find device by fd: %{public}d", eventItem.data.fd);
201             continue;
202         }
203         if (!sharedDHIds_[device->identifier.descriptor]) {
204             RecordDeviceChangeStates(device, readBuffer, count);
205             DHLOGD("Not in sharing stat, device descriptor: %{public}s",
206                 GetAnonyString(device->identifier.descriptor).c_str());
207             continue;
208         }
209         if (eventItem.events & EPOLLIN) {
210             event += CollectEvent(event, capacity, device, readBuffer, count);
211 
212             if (capacity == 0) {
213                 pendingEventIndex_ -= 1;
214                 break;
215             }
216         } else if (eventItem.events & EPOLLHUP) {
217             DHLOGI("Removing device %{public}s due to epoll hang-up event.", device->identifier.name.c_str());
218             CloseDeviceLocked(*device);
219         }
220     }
221     return event - buffer;
222 }
223 
IsCuror(Device * device)224 bool InputHub::IsCuror(Device *device)
225 {
226     return device->classes & INPUT_DEVICE_CLASS_CURSOR;
227 }
228 
IsTouchPad(Device * device)229 bool InputHub::IsTouchPad(Device *device)
230 {
231     return ((device->classes & INPUT_DEVICE_CLASS_TOUCH_MT) || (device->classes & INPUT_DEVICE_CLASS_TOUCH)) &&
232         IsTouchPad(device->identifier);
233 }
234 
IsTouchPad(const InputDevice & inputDevice)235 bool InputHub::IsTouchPad(const InputDevice &inputDevice)
236 {
237     std::string dhName = inputDevice.name;
238     transform(dhName.begin(), dhName.end(), dhName.begin(), ::tolower);
239     if (dhName.find(DH_TOUCH_PAD) == std::string::npos) {
240         return false;
241     }
242     return true;
243 }
244 
MatchAndDealEvent(Device * device,const RawEvent & event)245 void InputHub::MatchAndDealEvent(Device *device, const RawEvent &event)
246 {
247     bool isTouchPad = IsTouchPad(device);
248     if (!isTouchPad) {
249         // Deal Normal key state, such as keys of keyboard or mouse
250         DealNormalKeyEvent(device, event);
251     } else {
252         // Deal TouchPad events
253         DealTouchPadEvent(event);
254     }
255 }
256 
DealTouchPadEvent(const RawEvent & event)257 void InputHub::DealTouchPadEvent(const RawEvent &event)
258 {
259     auto ret = DInputSinkState::GetInstance().GetTouchPadEventFragMgr()->PushEvent(event.descriptor, event);
260     if (ret.first) {
261         DInputSinkState::GetInstance().SimulateTouchPadStateReset(ret.second);
262     }
263 }
264 
DealNormalKeyEvent(Device * device,const RawEvent & event)265 void InputHub::DealNormalKeyEvent(Device *device, const RawEvent &event)
266 {
267     if (event.type == EV_KEY && event.value == KEY_DOWN_STATE) {
268         DInputSinkState::GetInstance().AddKeyDownState(event);
269         RecordChangeEventLog(event);
270     }
271     if (event.type == EV_KEY && event.value == KEY_UP_STATE) {
272         // Deal mouse left keydown reset
273         if (IsCuror(device) && event.code == BTN_MOUSE &&
274             !DInputSinkState::GetInstance().IsDhIdDown(event.descriptor)) {
275             DHLOGI("Find mouse BTN_MOUSE UP state that not down effective at sink side, dhId: %{public}s",
276                 GetAnonyString(event.descriptor).c_str());
277             DInputSinkState::GetInstance().SimulateMouseBtnMouseUpState(event.descriptor, event);
278         }
279         DInputSinkState::GetInstance().RemoveKeyDownState(event);
280         RecordChangeEventLog(event);
281     }
282     if (event.type == EV_KEY && event.value == KEY_REPEAT) {
283         DInputSinkState::GetInstance().CheckAndSetLongPressedKeyOrder(event);
284     }
285 }
286 
RecordDeviceChangeStates(Device * device,struct input_event readBuffer[],const size_t count)287 void InputHub::RecordDeviceChangeStates(Device *device, struct input_event readBuffer[], const size_t count)
288 {
289     bool isTouchEvent = false;
290     if ((device->classes & INPUT_DEVICE_CLASS_TOUCH_MT) || (device->classes & INPUT_DEVICE_CLASS_TOUCH)) {
291         if (!IsTouchPad(device->identifier)) {
292             isTouchEvent = true;
293         }
294     }
295 
296     for (size_t i = 0; i < count; i++) {
297         const struct input_event& iev = readBuffer[i];
298         RawEvent event;
299         event.when = ProcessEventTimestamp(iev);
300         event.type = iev.type;
301         event.code = iev.code;
302         event.value = iev.value;
303         event.path = device->path;
304         event.descriptor = isTouchEvent ? touchDescriptor : device->identifier.descriptor;
305         MatchAndDealEvent(device, event);
306     }
307 }
308 
CollectEvent(RawEvent * buffer,size_t & capacity,Device * device,struct input_event readBuffer[],const size_t count)309 size_t InputHub::CollectEvent(RawEvent *buffer, size_t &capacity, Device *device, struct input_event readBuffer[],
310     const size_t count)
311 {
312     std::vector<bool> needFilted(capacity, false);
313     bool isTouchEvent = false;
314     if ((device->classes & INPUT_DEVICE_CLASS_TOUCH_MT) || (device->classes & INPUT_DEVICE_CLASS_TOUCH)) {
315         if (!IsTouchPad(device->identifier)) {
316             isTouchEvent = true;
317             HandleTouchScreenEvent(readBuffer, count, needFilted);
318         }
319     }
320 
321     RawEvent* event = buffer;
322     for (size_t i = 0; i < count; i++) {
323         if (needFilted[i]) {
324             continue;
325         }
326         const struct input_event& iev = readBuffer[i];
327         event->when = ProcessEventTimestamp(iev);
328         event->type = iev.type;
329         event->code = iev.code;
330         event->value = iev.value;
331         event->path = device->path;
332         event->descriptor = isTouchEvent ? touchDescriptor : device->identifier.descriptor;
333         RecordEventLog(event);
334         event += 1;
335         capacity -= 1;
336         if (capacity == 0) {
337             break;
338         }
339     }
340     return event - buffer;
341 }
342 
ReadInputEvent(int32_t readSize,Device & device)343 size_t InputHub::ReadInputEvent(int32_t readSize, Device &device)
344 {
345     size_t count = 0;
346     if (readSize == 0 || (readSize < 0 && errno == ENODEV)) {
347         // Device was removed before INotify noticed.
348         DHLOGE("could not get event, removed? (fd: %{public}d size: %{public}d, errno: %{public}d)\n",
349             device.fd, readSize, errno);
350         CloseDeviceLocked(device);
351     } else if (readSize < 0) {
352         if (errno != EAGAIN && errno != EINTR) {
353             DHLOGW("could not get event (errno=%{public}d)", errno);
354         }
355     } else if ((readSize % sizeof(struct input_event)) != 0) {
356         DHLOGW("could not get event (wrong size: %{public}d)", readSize);
357     } else {
358         count = size_t(readSize) / sizeof(struct input_event);
359         return count;
360     }
361     return count;
362 }
363 
DeviceIsExists(InputDeviceEvent * buffer,size_t bufferSize)364 size_t InputHub::DeviceIsExists(InputDeviceEvent *buffer, size_t bufferSize)
365 {
366     InputDeviceEvent* event = buffer;
367     size_t capacity = bufferSize;
368     // Report any devices that had last been added/removed.
369     {
370         std::lock_guard<std::mutex> deviceLock(devicesMutex_);
371         for (auto it = closingDevices_.begin(); it != closingDevices_.end();) {
372             std::unique_ptr<Device> device = std::move(*it);
373             DHLOGI("Reporting device closed: id=%{public}s, name=%{public}s",
374                 device->path.c_str(), device->identifier.name.c_str());
375             event->type = DeviceType::DEVICE_REMOVED;
376             event->deviceInfo = device->identifier;
377             event += 1;
378             it = closingDevices_.erase(it);
379             if (capacity == 0) {
380                 break;
381             }
382             capacity--;
383         }
384     }
385 
386     if (needToScanDevices_) {
387         needToScanDevices_ = false;
388         ScanInputDevices(DEVICE_PATH);
389     }
390 
391     {
392         std::lock_guard<std::mutex> deviceLock(devicesMutex_);
393         while (!openingDevices_.empty()) {
394             std::unique_ptr<Device> device = std::move(*openingDevices_.rbegin());
395             openingDevices_.pop_back();
396             DHLOGI("Reporting device opened: id=%{public}s, name=%{public}s",
397                 device->path.c_str(), device->identifier.name.c_str());
398             event->type = DeviceType::DEVICE_ADDED;
399             event->deviceInfo = device->identifier;
400             event += 1;
401 
402             std::string devPath = device->path;
403             auto [dev_it, inserted] = devices_.insert_or_assign(device->path, std::move(device));
404             if (!inserted) {
405                 DHLOGI("Device path %{public}s exists, replaced.", devPath.c_str());
406             }
407             if (capacity == 0) {
408                 break;
409             }
410             capacity--;
411         }
412     }
413     return event - buffer;
414 }
415 
StartCollectInputHandler(InputDeviceEvent * buffer,size_t bufferSize)416 size_t InputHub::StartCollectInputHandler(InputDeviceEvent *buffer, size_t bufferSize)
417 {
418     size_t count = 0;
419     isStartCollectHandler_ = true;
420     while (isStartCollectHandler_) {
421         count = DeviceIsExists(buffer, bufferSize);
422         deviceChanged_ = false;
423         GetDeviceHandler();
424 
425         if (pendingINotify_ && pendingEventIndex_ >= pendingEventCount_) {
426             pendingINotify_ = false;
427             ReadNotifyLocked();
428             deviceChanged_ = true;
429         }
430 
431         // Report added or removed devices immediately.
432         if (deviceChanged_) {
433             continue;
434         }
435         if (count > 0) {
436             break;
437         }
438         if (RefreshEpollItem(true) < 0) {
439             break;
440         }
441     }
442 
443     // All done, return the number of events we read.
444     return count;
445 }
446 
StopCollectInputHandler()447 void InputHub::StopCollectInputHandler()
448 {
449     DHLOGI("Stop Collect Input Handler Thread");
450     isStartCollectHandler_ = false;
451 }
452 
GetDeviceHandler()453 void InputHub::GetDeviceHandler()
454 {
455     while (pendingEventIndex_ < pendingEventCount_) {
456         std::lock_guard<std::mutex> my_lock(operationMutex_);
457         const struct epoll_event& eventItem = mPendingEventItems[pendingEventIndex_++];
458         if (eventItem.data.fd == iNotifyFd_) {
459             if (eventItem.events & EPOLLIN) {
460                 pendingINotify_ = true;
461             } else {
462                 DHLOGI("Received unexpected epoll event 0x%08x for INotify.", eventItem.events);
463             }
464             continue;
465         }
466 
467         if (eventItem.events & EPOLLHUP) {
468             Device* device = GetDeviceByFdLocked(eventItem.data.fd);
469             if (!device) {
470                 DHLOGE("Received unexpected epoll event 0x%{public}08x for unknown fd %{public}d.",
471                     eventItem.events, eventItem.data.fd);
472                 continue;
473             }
474             DHLOGI("Removing device %{public}s due to epoll hang-up event.", device->identifier.name.c_str());
475             deviceChanged_ = true;
476             CloseDeviceLocked(*device);
477         }
478     }
479 }
480 
RefreshEpollItem(bool isSleep)481 int32_t InputHub::RefreshEpollItem(bool isSleep)
482 {
483     pendingEventIndex_ = 0;
484     int pollResult = epoll_wait(epollFd_, mPendingEventItems, EPOLL_MAX_EVENTS, EPOLL_WAITTIME);
485     if (pollResult == 0) {
486         // Timed out.
487         pendingEventCount_ = 0;
488         return ERR_DH_INPUT_HUB_EPOLL_WAIT_TIMEOUT;
489     }
490 
491     if (pollResult < 0) {
492         // An error occurred.
493         pendingEventCount_ = 0;
494 
495         // Sleep after errors to avoid locking up the system.
496         // Hopefully the error is transient.
497         if (errno != EINTR) {
498             DHLOGE("poll failed (errno=%{public}d)\n", errno);
499             usleep(SLEEP_TIME_US);
500         }
501     } else {
502         // Some events occurred.
503         pendingEventCount_ = pollResult;
504     }
505     if (isSleep) {
506         usleep(SLEEP_TIME_US);
507     }
508     return DH_SUCCESS;
509 }
510 
GetAllInputDevices()511 std::vector<InputDevice> InputHub::GetAllInputDevices()
512 {
513     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
514     std::vector<InputDevice> vecDevice;
515     for (const auto &[id, device] : devices_) {
516         vecDevice.push_back(device->identifier);
517     }
518     return vecDevice;
519 }
520 
ScanInputDevices(const std::string & dirName)521 void InputHub::ScanInputDevices(const std::string &dirName)
522 {
523     std::vector<std::string> inputDevPaths;
524     ScanInputDevicesPath(dirName, inputDevPaths);
525     for (const auto &tempPath: inputDevPaths) {
526         if (IsInputNodeNoNeedScan(tempPath)) {
527             continue;
528         }
529         OpenInputDeviceLocked(tempPath);
530     }
531 }
532 
IsDeviceRegistered(const std::string & devicePath)533 bool InputHub::IsDeviceRegistered(const std::string &devicePath)
534 {
535     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
536     for (const auto &[deviceId, device] : devices_) {
537         if (device->path == devicePath) {
538             DHLOGI("Device node already registered, node path: %{public}s", device->path.c_str());
539             return true; // device was already registered
540         }
541     }
542     return false;
543 }
544 
OpenInputDeviceLocked(const std::string & devicePath)545 int32_t InputHub::OpenInputDeviceLocked(const std::string &devicePath)
546 {
547     if (IsDeviceRegistered(devicePath)) {
548         return DH_SUCCESS;
549     }
550 
551     std::lock_guard<std::mutex> my_lock(operationMutex_);
552     DHLOGD("Opening device start: %{public}s", devicePath.c_str());
553     int fd = OpenInputDeviceFdByPath(devicePath);
554     if (fd == UN_INIT_FD_VALUE) {
555         DHLOGE("The fd open failed, devicePath %{public}s.", devicePath.c_str());
556         return ERR_DH_INPUT_HUB_OPEN_DEVICEPATH_FAIL;
557     }
558 
559     // Allocate device. (The device object takes ownership of the fd at this point.)
560     std::unique_ptr<Device> device = std::make_unique<Device>(fd, devicePath);
561 
562     if (QueryInputDeviceInfo(fd, device) < 0) {
563         CloseFd(fd);
564         return ERR_DH_INPUT_HUB_QUERY_INPUT_DEVICE_INFO_FAIL;
565     }
566     GenerateDescriptor(device->identifier);
567     IncreaseLogTimes(device->identifier.descriptor);
568     RecordDeviceLog(devicePath, device->identifier);
569     std::string descriptor = device->identifier.descriptor;
570     if (MakeDevice(fd, std::move(device)) < 0) {
571         CloseFd(fd);
572         if (IsNeedPrintLog(descriptor)) {
573             DHLOGI("Opening device error: %{public}s", devicePath.c_str());
574         }
575         return ERR_DH_INPUT_HUB_MAKE_DEVICE_FAIL;
576     }
577 
578     DHLOGI("Opening device finish: %{public}s", devicePath.c_str());
579     return DH_SUCCESS;
580 }
581 
RecordSkipDevicePath(std::string path)582 void InputHub::RecordSkipDevicePath(std::string path)
583 {
584     std::lock_guard<std::mutex> lock(skipDevicePathsMutex_);
585     skipDevicePaths_.insert(path);
586 }
587 
IsSkipDevicePath(const std::string & path)588 bool InputHub::IsSkipDevicePath(const std::string &path)
589 {
590     std::lock_guard<std::mutex> lock(skipDevicePathsMutex_);
591     return skipDevicePaths_.find(path) != skipDevicePaths_.end();
592 }
593 
IncreaseLogTimes(const std::string & dhId)594 void InputHub::IncreaseLogTimes(const std::string& dhId)
595 {
596     if (logTimesMap_.find(dhId) != logTimesMap_.end() && logTimesMap_[dhId] >= INT32_MAX - 1) {
597         logTimesMap_[dhId] = 0;
598     } else {
599         logTimesMap_[dhId]++;
600     }
601 }
602 
IsNeedPrintLog(const std::string & dhId) const603 bool InputHub::IsNeedPrintLog(const std::string& dhId) const
604 {
605     return logTimesMap_.find(dhId) == logTimesMap_.end() || logTimesMap_.at(dhId) <= MAX_LOG_TIMES;
606 }
607 
QueryInputDeviceInfo(int fd,std::unique_ptr<Device> & device)608 int32_t InputHub::QueryInputDeviceInfo(int fd, std::unique_ptr<Device> &device)
609 {
610     char buffer[INPUT_EVENT_BUFFER_SIZE] = {0};
611     // Get device name.
612     if (ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) {
613         DHLOGE("Could not get device name for %{public}s", ConvertErrNo().c_str());
614     } else {
615         buffer[sizeof(buffer) - 1] = '\0';
616         device->identifier.name = buffer;
617     }
618     DHLOGD("QueryInputDeviceInfo deviceName: %{public}s", buffer);
619     // If the device is already a virtual device, don't monitor it.
620     if (device->identifier.name.find(VIRTUAL_DEVICE_NAME) != std::string::npos) {
621         DHLOGE("this is a virtual driver, skip it.");
622         RecordSkipDevicePath(device->path);
623         return ERR_DH_INPUT_HUB_IS_VIRTUAL_DEVICE;
624     }
625     // Get device driver version.
626     int driverVersion;
627     if (ioctl(fd, EVIOCGVERSION, &driverVersion)) {
628         DHLOGE("could not get driver version for %{public}s\n", ConvertErrNo().c_str());
629         RecordSkipDevicePath(device->path);
630         return ERR_DH_INPUT_HUB_QUERY_INPUT_DEVICE_INFO_FAIL;
631     }
632     // Get device identifier.
633     struct input_id inputId;
634     if (ioctl(fd, EVIOCGID, &inputId)) {
635         DHLOGE("could not get device input id for %{public}s\n", ConvertErrNo().c_str());
636         RecordSkipDevicePath(device->path);
637         return ERR_DH_INPUT_HUB_QUERY_INPUT_DEVICE_INFO_FAIL;
638     }
639     device->identifier.bus = inputId.bustype;
640     device->identifier.product = inputId.product;
641     device->identifier.vendor = inputId.vendor;
642     device->identifier.version = inputId.version;
643     // Get device physical physicalPath.
644     if (ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) {
645         DHLOGE("could not get physicalPath for %{public}s\n", ConvertErrNo().c_str());
646     } else {
647         buffer[sizeof(buffer) - 1] = '\0';
648         device->identifier.physicalPath = buffer;
649     }
650     // Get device unique id.
651     if (ioctl(fd, EVIOCGUNIQ(sizeof(buffer) - 1), &buffer) < 1) {
652         DHLOGE("could not get idstring for %{public}s\n", ConvertErrNo().c_str());
653     } else {
654         buffer[sizeof(buffer) - 1] = '\0';
655         device->identifier.uniqueId = buffer;
656     }
657 
658     QueryEventInfo(fd, device);
659     return DH_SUCCESS;
660 }
661 
QueryEventInfo(int fd,std::unique_ptr<Device> & device)662 void InputHub::QueryEventInfo(int fd, std::unique_ptr<Device> &device)
663 {
664     if (device == nullptr) {
665         DHLOGE("device is nullptr!");
666         return;
667     }
668     if (IsNeedPrintLog(device->identifier.descriptor)) {
669         DHLOGI("QueryEventInfo: devName: %{public}s, dhId: %{public}s!", device->identifier.name.c_str(),
670             GetAnonyString(device->identifier.descriptor).c_str());
671     }
672     struct libevdev *dev = GetLibEvDev(fd);
673     if (dev == nullptr) {
674         if (IsNeedPrintLog(device->identifier.descriptor)) {
675             DHLOGE("dev is nullptr");
676         }
677         return;
678     }
679     GetEventTypes(dev, device->identifier);
680     GetEventKeys(dev, device->identifier);
681     GetABSInfo(dev, device->identifier);
682     GetRELTypes(dev, device->identifier);
683     GetProperties(dev, device->identifier);
684 
685     GetMSCBits(fd, device);
686     GetLEDBits(fd, device);
687     GetSwitchBits(fd, device);
688     GetRepeatBits(fd, device);
689 
690     libevdev_free(dev);
691 }
692 
GetEventMask(int fd,const std::string & eventName,uint32_t type,std::size_t arrayLength,uint8_t * whichBitMask) const693 void InputHub::GetEventMask(int fd, const std::string &eventName, uint32_t type,
694     std::size_t arrayLength, uint8_t *whichBitMask) const
695 {
696     int32_t rc = ioctl(fd, EVIOCGBIT(type, arrayLength), whichBitMask);
697     if (rc < 0) {
698         DHLOGE("Could not get events %{public}s mask: %{public}s", eventName.c_str(), strerror(errno));
699     }
700 }
701 
GetMSCBits(int fd,std::unique_ptr<Device> & device)702 void InputHub::GetMSCBits(int fd, std::unique_ptr<Device> &device)
703 {
704     uint8_t mscBitmask[NBYTES(MSC_MAX)] {};
705     GetEventMask(fd, "msc", EV_MSC, sizeof(mscBitmask), mscBitmask);
706 
707     for (uint32_t msc = MSC_SERIAL; msc < MSC_MAX; ++msc) {
708         if (TestBit(EV_MSC, device->evBitmask) && TestBit(msc, mscBitmask)) {
709             DHLOGI("Get MSC event: %{public}d", msc);
710             device->identifier.miscellaneous.push_back(msc);
711         }
712     }
713 }
714 
GetLEDBits(int fd,std::unique_ptr<Device> & device)715 void InputHub::GetLEDBits(int fd, std::unique_ptr<Device> &device)
716 {
717     uint8_t ledBitmask[NBYTES(LED_MAX)] {};
718     GetEventMask(fd, "led", EV_LED, sizeof(ledBitmask), ledBitmask);
719     for (uint32_t led = LED_NUML; led < LED_MAX; ++led) {
720         if (TestBit(EV_LED, device->evBitmask) && TestBit(led, ledBitmask)) {
721             DHLOGI("Get LED event: %{public}d", led);
722             device->identifier.leds.push_back(led);
723         }
724     }
725 }
726 
GetSwitchBits(int fd,std::unique_ptr<Device> & device)727 void InputHub::GetSwitchBits(int fd, std::unique_ptr<Device> &device)
728 {
729     uint8_t switchBitmask[NBYTES(SW_MAX)] {};
730     GetEventMask(fd, "switch", EV_SW, sizeof(switchBitmask), switchBitmask);
731 
732     for (uint32_t sw = SW_LID; sw < SW_MAX; ++sw) {
733         if (TestBit(EV_SW, device->evBitmask) && TestBit(sw, switchBitmask)) {
734             DHLOGI("Get Switch event: %{public}d", sw);
735             device->identifier.switchs.push_back(sw);
736         }
737     }
738 }
739 
GetRepeatBits(int fd,std::unique_ptr<Device> & device)740 void InputHub::GetRepeatBits(int fd, std::unique_ptr<Device> &device)
741 {
742     uint8_t repBitmask[NBYTES(REP_MAX)] {};
743     GetEventMask(fd, "repeat", EV_REP, sizeof(repBitmask), repBitmask);
744 
745     for (uint32_t rep = REP_DELAY; rep < REP_MAX; ++rep) {
746         if (TestBit(EV_REP, device->evBitmask) && TestBit(rep, repBitmask)) {
747             DHLOGI("Get Repeat event: %{public}d", rep);
748             device->identifier.repeats.push_back(rep);
749         }
750     }
751 }
752 
GetLibEvDev(int fd)753 struct libevdev* InputHub::GetLibEvDev(int fd)
754 {
755     struct libevdev *dev = nullptr;
756     int rc = 1;
757     rc = libevdev_new_from_fd(fd, &dev);
758     if (rc < 0) {
759         DHLOGE("Failed to init libevdev (%{public}s)", strerror(-rc));
760         return nullptr;
761     }
762     return dev;
763 }
764 
GetEventTypes(struct libevdev * dev,InputDevice & identifier)765 void InputHub::GetEventTypes(struct libevdev *dev, InputDevice &identifier)
766 {
767     for (uint32_t eventType = 0; eventType < EV_CNT; eventType++) {
768         if (!libevdev_has_event_type(dev, eventType)) {
769             DHLOGD("The device is not support eventType: %{public}d", eventType);
770             continue;
771         }
772         identifier.eventTypes.push_back(eventType);
773     }
774 }
775 
GetEventKeys(struct libevdev * dev,InputDevice & identifier)776 int32_t InputHub::GetEventKeys(struct libevdev *dev, InputDevice &identifier)
777 {
778     if (!libevdev_has_event_type(dev, EV_KEY)) {
779         if (IsNeedPrintLog(identifier.descriptor)) {
780             DHLOGE("The device doesn't has EV_KEY type!");
781         }
782         return ERR_DH_INPUT_HUB_QUERY_INPUT_DEVICE_INFO_FAIL;
783     }
784     for (uint32_t eventKey = 0; eventKey < KEY_CNT; eventKey++) {
785         if (!libevdev_has_event_code(dev, EV_KEY, eventKey)) {
786             DHLOGD("The device is not support eventKey: %{public}d", eventKey);
787             continue;
788         }
789         identifier.eventKeys.push_back(eventKey);
790     }
791     return DH_SUCCESS;
792 }
793 
GetABSInfo(struct libevdev * dev,InputDevice & identifier)794 int32_t InputHub::GetABSInfo(struct libevdev *dev, InputDevice &identifier)
795 {
796     if (!libevdev_has_event_type(dev, EV_ABS)) {
797         if (IsNeedPrintLog(identifier.descriptor)) {
798             DHLOGE("The device doesn't has EV_ABS type!");
799         }
800         return ERR_DH_INPUT_HUB_QUERY_INPUT_DEVICE_INFO_FAIL;
801     }
802     DHLOGI("The device has abs info, devName: %{public}s, dhId: %{public}s!",
803         identifier.name.c_str(), GetAnonyString(identifier.descriptor).c_str());
804     for (uint32_t absType = 0; absType < ABS_CNT; absType++) {
805         if (!libevdev_has_event_code(dev, EV_ABS, absType)) {
806             DHLOGD("The device is not support absType: %{public}d", absType);
807             continue;
808         }
809         identifier.absTypes.push_back(absType);
810         const struct input_absinfo *abs = libevdev_get_abs_info(dev, absType);
811         if (abs == nullptr) {
812             DHLOGE("absInfo is nullptr!");
813             continue;
814         }
815         identifier.absInfos[absType].push_back(abs->value);
816         identifier.absInfos[absType].push_back(abs->minimum);
817         identifier.absInfos[absType].push_back(abs->maximum);
818         identifier.absInfos[absType].push_back(abs->fuzz);
819         identifier.absInfos[absType].push_back(abs->flat);
820         identifier.absInfos[absType].push_back(abs->resolution);
821     }
822     return DH_SUCCESS;
823 }
824 
GetRELTypes(struct libevdev * dev,InputDevice & identifier)825 int32_t InputHub::GetRELTypes(struct libevdev *dev, InputDevice &identifier)
826 {
827     if (!libevdev_has_event_type(dev, EV_REL)) {
828         if (IsNeedPrintLog(identifier.descriptor)) {
829             DHLOGE("The device doesn't has EV_REL type!");
830         }
831         return ERR_DH_INPUT_HUB_QUERY_INPUT_DEVICE_INFO_FAIL;
832     }
833     for (uint32_t code = 0; code < REL_CNT; code++) {
834         if (!libevdev_has_event_code(dev, EV_REL, code)) {
835             DHLOGD("The device is not support rel code: %{public}d", code);
836             continue;
837         }
838         identifier.relTypes.push_back(code);
839     }
840     return DH_SUCCESS;
841 }
842 
GetProperties(struct libevdev * dev,InputDevice & identifier)843 void InputHub::GetProperties(struct libevdev *dev, InputDevice &identifier)
844 {
845     for (uint32_t prop = 0; prop < INPUT_PROP_CNT; prop++) {
846         if (libevdev_has_property(dev, prop)) {
847             DHLOGI("QueryInputDeviceInfo rel prop: %{public}d", prop);
848             identifier.properties.push_back(prop);
849         }
850     }
851 }
852 
MakeDevice(int fd,std::unique_ptr<Device> device)853 int32_t InputHub::MakeDevice(int fd, std::unique_ptr<Device> device)
854 {
855     // See if this is a multi-touch touchscreen device.
856     if (TestBit(BTN_TOUCH, device->keyBitmask) &&
857         TestBit(ABS_MT_POSITION_X, device->absBitmask) &&
858         TestBit(ABS_MT_POSITION_Y, device->absBitmask)) {
859         QueryLocalTouchScreenInfo(fd, device);
860         device->classes |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT;
861     } else if (TestBit(BTN_TOUCH, device->keyBitmask) &&
862         TestBit(ABS_X, device->absBitmask) &&
863         TestBit(ABS_Y, device->absBitmask)) {
864         QueryLocalTouchScreenInfo(fd, device);
865         device->classes |= INPUT_DEVICE_CLASS_TOUCH;
866     }
867 
868     // See if this is a cursor device such as a trackball or mouse.
869     if (TestBit(BTN_MOUSE, device->keyBitmask)
870         && TestBit(REL_X, device->relBitmask)
871         && TestBit(REL_Y, device->relBitmask)) {
872         device->classes |= INPUT_DEVICE_CLASS_CURSOR;
873     }
874 
875     // for Linux version 4.14.116, touchpad recognized as mouse and keyboard at same time,
876     // need to avoid device->classes to be 0x09, which mmi can't handler.
877     // See if this is a keyboard.
878     if (device->classes == 0) {
879         bool haveKeyboardKeys = ContainsNonZeroByte(device->keyBitmask, 0, SizeofBitArray(BTN_MISC));
880         if (haveKeyboardKeys) {
881             device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
882         }
883     }
884 
885     // If the device isn't recognized as something we handle, don't monitor it.
886     if (device->classes == 0) {
887         if (IsNeedPrintLog(device->identifier.descriptor)) {
888             DHLOGI("Dropping device: name='%{public}s'", device->identifier.name.c_str());
889         }
890         return ERR_DH_INPUT_HUB_MAKE_DEVICE_FAIL;
891     }
892 
893     if (RegisterDeviceForEpollLocked(*device) != DH_SUCCESS) {
894         return ERR_DH_INPUT_HUB_MAKE_DEVICE_FAIL;
895     }
896 
897     device->identifier.classes = device->classes;
898 
899     DHLOGI("inputType=%{public}d", inputTypes_.load());
900     DHLOGI("New device: fd=%{public}d, name='%{public}s', classes=0x%{public}x", fd, device->identifier.name.c_str(),
901         device->classes);
902 
903     AddDeviceLocked(std::move(device));
904     return DH_SUCCESS;
905 }
906 
QueryLocalTouchScreenInfo(int fd,std::unique_ptr<Device> & device)907 int32_t InputHub::QueryLocalTouchScreenInfo(int fd, std::unique_ptr<Device> &device)
908 {
909     LocalTouchScreenInfo info = DInputContext::GetInstance().GetLocalTouchScreenInfo();
910     device->identifier.classes |= INPUT_DEVICE_CLASS_TOUCH_MT;
911     info.localAbsInfo.deviceInfo = device->identifier;
912 
913     struct input_absinfo absInfo;
914     ioctl(fd, EVIOCGABS(ABS_MT_POSITION_X), &absInfo);
915     info.localAbsInfo.absXMin = absInfo.minimum;
916     info.localAbsInfo.absXMax = absInfo.maximum;
917     info.localAbsInfo.absMtPositionXMin = absInfo.minimum;
918     info.localAbsInfo.absMtPositionXMax = absInfo.maximum;
919     info.sinkPhyWidth = static_cast<uint32_t>(absInfo.maximum + 1);
920 
921     ioctl(fd, EVIOCGABS(ABS_MT_POSITION_Y), &absInfo);
922     info.localAbsInfo.absYMin = absInfo.minimum;
923     info.localAbsInfo.absYMax = absInfo.maximum;
924     info.localAbsInfo.absMtPositionYMin = absInfo.minimum;
925     info.localAbsInfo.absMtPositionYMax = absInfo.maximum;
926     info.sinkPhyHeight = static_cast<uint32_t>(absInfo.maximum + 1);
927 
928     ioctl(fd, EVIOCGABS(ABS_PRESSURE), &absInfo);
929     info.localAbsInfo.absPressureMin = absInfo.minimum;
930     info.localAbsInfo.absPressureMax = absInfo.maximum;
931     info.localAbsInfo.absMtPressureMin = absInfo.minimum;
932     info.localAbsInfo.absMtPressureMax = absInfo.maximum;
933 
934     ioctl(fd, EVIOCGABS(ABS_MT_TOUCH_MAJOR), &absInfo);
935     info.localAbsInfo.absMtTouchMajorMin = absInfo.minimum;
936     info.localAbsInfo.absMtTouchMajorMax = absInfo.maximum;
937 
938     ioctl(fd, EVIOCGABS(ABS_MT_TOUCH_MINOR), &absInfo);
939     info.localAbsInfo.absMtTouchMinorMin = absInfo.minimum;
940     info.localAbsInfo.absMtTouchMinorMax = absInfo.maximum;
941 
942     ioctl(fd, EVIOCGABS(ABS_MT_ORIENTATION), &absInfo);
943     info.localAbsInfo.absMtOrientationMin = absInfo.minimum;
944     info.localAbsInfo.absMtOrientationMax = absInfo.maximum;
945 
946     ioctl(fd, EVIOCGABS(ABS_MT_BLOB_ID), &absInfo);
947     info.localAbsInfo.absMtBlobIdMin = absInfo.minimum;
948     info.localAbsInfo.absMtBlobIdMax = absInfo.maximum;
949 
950     ioctl(fd, EVIOCGABS(ABS_MT_TRACKING_ID), &absInfo);
951     info.localAbsInfo.absMtTrackingIdMin = absInfo.minimum;
952     info.localAbsInfo.absMtTrackingIdMax = absInfo.maximum;
953 
954     DInputContext::GetInstance().SetLocalTouchScreenInfo(info);
955     return DH_SUCCESS;
956 }
957 
StringPrintf(const char * format,...) const958 std::string InputHub::StringPrintf(const char *format, ...) const
959 {
960     char space[SPACELENGTH] = {0};
961     va_list ap;
962     va_start(ap, format);
963     std::string result;
964     int32_t ret = vsnprintf_s(space, sizeof(space), sizeof(space) - 1, format, ap);
965     if (ret >= DH_SUCCESS && static_cast<size_t>(ret) < sizeof(space)) {
966         result = space;
967     } else {
968         va_end(ap);
969         return "the buffer is overflow!";
970     }
971     va_end(ap);
972     return result;
973 }
974 
GenerateDescriptor(InputDevice & identifier) const975 void InputHub::GenerateDescriptor(InputDevice &identifier) const
976 {
977     std::string rawDescriptor;
978     rawDescriptor += StringPrintf(":%04x:%04x:", identifier.vendor,
979         identifier.product);
980     // add handling for USB devices to not uniqueify kbs that show up twice
981     if (!identifier.uniqueId.empty()) {
982         rawDescriptor += "uniqueId:";
983         rawDescriptor += identifier.uniqueId;
984     }
985     if (!identifier.physicalPath.empty()) {
986         rawDescriptor += "physicalPath:";
987         rawDescriptor += identifier.physicalPath;
988     }
989     if (!identifier.name.empty()) {
990         rawDescriptor += "name:";
991         std::string name = identifier.name;
992         rawDescriptor += regex_replace(name, std::regex(" "), "");
993     }
994 
995     identifier.descriptor = DH_ID_PREFIX + Sha256(rawDescriptor);
996     if (IsNeedPrintLog(identifier.descriptor)) {
997         DHLOGI("Created descriptor: raw=%{public}s, cooked=%{public}s", rawDescriptor.c_str(),
998             GetAnonyString(identifier.descriptor).c_str());
999     }
1000 }
1001 
RegisterDeviceForEpollLocked(const Device & device)1002 int32_t InputHub::RegisterDeviceForEpollLocked(const Device &device)
1003 {
1004     int32_t result = RegisterFdForEpoll(device.fd);
1005     if (result != DH_SUCCESS) {
1006         DHLOGE("Could not add input device fd to epoll for device, path: %{public}s", device.path.c_str());
1007         return result;
1008     }
1009     return result;
1010 }
1011 
RegisterFdForEpoll(int fd)1012 int32_t InputHub::RegisterFdForEpoll(int fd)
1013 {
1014     struct epoll_event eventItem = {};
1015     eventItem.events = EPOLLIN | EPOLLWAKEUP;
1016     eventItem.data.fd = fd;
1017     if (epoll_ctl(epollFd_, EPOLL_CTL_ADD, fd, &eventItem)) {
1018         DHLOGE("Could not add fd to epoll instance: %{public}s", ConvertErrNo().c_str());
1019         return -errno;
1020     }
1021     return DH_SUCCESS;
1022 }
1023 
AddDeviceLocked(std::unique_ptr<Device> device)1024 void InputHub::AddDeviceLocked(std::unique_ptr<Device> device)
1025 {
1026     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1027     openingDevices_.push_back(std::move(device));
1028 }
1029 
CloseDeviceLocked(Device & device)1030 void InputHub::CloseDeviceLocked(Device &device)
1031 {
1032     DHLOGI("Removed device: path=%{public}s name=%{public}s fd=%{public}d classes=0x%{public}x",
1033         device.path.c_str(), device.identifier.name.c_str(), device.fd, device.classes);
1034 
1035     UnregisterDeviceFromEpollLocked(device);
1036     device.Close();
1037     {
1038         std::lock_guard<std::mutex> devicesLock(devicesMutex_);
1039         closingDevices_.push_back(std::move(devices_[device.path]));
1040         devices_.erase(device.path);
1041     }
1042 }
1043 
CloseDeviceForAllLocked(Device & device)1044 void InputHub::CloseDeviceForAllLocked(Device &device)
1045 {
1046     DHLOGI("Removed device: path=%{public}s name=%{public}s fd=%{public}d classes=0x%{public}x",
1047         device.path.c_str(), device.identifier.name.c_str(), device.fd, device.classes);
1048 
1049     UnregisterDeviceFromEpollLocked(device);
1050     device.Close();
1051     closingDevices_.push_back(std::move(devices_[device.path]));
1052     devices_.erase(device.path);
1053 }
1054 
UnregisterDeviceFromEpollLocked(const Device & device) const1055 int32_t InputHub::UnregisterDeviceFromEpollLocked(const Device &device) const
1056 {
1057     if (device.HasValidFd()) {
1058         int32_t result = UnregisterFdFromEpoll(device.fd);
1059         if (result != DH_SUCCESS) {
1060             DHLOGE("Could not remove input device fd from epoll for device, path: %{public}s", device.path.c_str());
1061             return result;
1062         }
1063     }
1064     return DH_SUCCESS;
1065 }
1066 
UnregisterFdFromEpoll(int fd) const1067 int32_t InputHub::UnregisterFdFromEpoll(int fd) const
1068 {
1069     if (epoll_ctl(epollFd_, EPOLL_CTL_DEL, fd, nullptr)) {
1070         DHLOGE("Could not remove fd from epoll instance: %{public}s", ConvertErrNo().c_str());
1071         return ERR_DH_INPUT_HUB_UNREGISTER_FD_FAIL;
1072     }
1073     return DH_SUCCESS;
1074 }
1075 
ReadNotifyLocked()1076 int32_t InputHub::ReadNotifyLocked()
1077 {
1078     size_t res;
1079     char eventBuf[EVENT_BUFFER_MAX] = {0};
1080     struct inotify_event *event;
1081 
1082     DHLOGI("readNotify nfd: %{public}d\n", iNotifyFd_);
1083     res = static_cast<size_t>(read(iNotifyFd_, eventBuf, sizeof(eventBuf)));
1084     if (res < sizeof(*event)) {
1085         if (errno == EINTR) {
1086             return DH_SUCCESS;
1087         }
1088         DHLOGE("could not get event, %{public}s\n", ConvertErrNo().c_str());
1089         return ERR_DH_INPUT_HUB_GET_EVENT_FAIL;
1090     }
1091 
1092     {
1093         size_t eventSize = 0;
1094         size_t eventPos = 0;
1095         while (res >= sizeof(*event) && eventPos < static_cast<size_t>(EVENT_BUFFER_MAX)) {
1096             event = reinterpret_cast<struct inotify_event *>(eventBuf + eventPos);
1097             JudgeDeviceOpenOrClose(*event);
1098             eventSize = sizeof(*event) + event->len;
1099             res -= eventSize;
1100             eventPos += eventSize;
1101         }
1102     }
1103     return DH_SUCCESS;
1104 }
1105 
JudgeDeviceOpenOrClose(const inotify_event & event)1106 void InputHub::JudgeDeviceOpenOrClose(const inotify_event &event)
1107 {
1108     if (event.len) {
1109         if (event.wd == inputWd_) {
1110             std::string filename = std::string(DEVICE_PATH) + "/" + event.name;
1111             if (event.mask & IN_CREATE) {
1112                 OpenInputDeviceLocked(filename);
1113             } else {
1114                 DHLOGI("Removing device '%{public}s' due to inotify event\n", filename.c_str());
1115                 CloseDeviceByPathLocked(filename);
1116             }
1117         } else {
1118             DHLOGI("Unexpected inotify event, wd = %i", event.wd);
1119         }
1120     }
1121 }
1122 
CloseDeviceByPathLocked(const std::string & devicePath)1123 void InputHub::CloseDeviceByPathLocked(const std::string &devicePath)
1124 {
1125     Device* device = GetDeviceByPathLocked(devicePath);
1126     if (device) {
1127         CloseDeviceLocked(*device);
1128         return;
1129     }
1130     DHLOGI("Remove device: %{public}s not found, device may already have been removed.", devicePath.c_str());
1131 }
1132 
CloseAllDevicesLocked()1133 void InputHub::CloseAllDevicesLocked()
1134 {
1135     DHLOGI("Close All Devices");
1136     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1137     while (!devices_.empty()) {
1138         CloseDeviceForAllLocked(*(devices_.begin()->second));
1139     }
1140 }
1141 
GetDeviceByPathLocked(const std::string & devicePath)1142 InputHub::Device* InputHub::GetDeviceByPathLocked(const std::string &devicePath)
1143 {
1144     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1145     for (const auto &[id, device] : devices_) {
1146         if (device->path == devicePath) {
1147             return device.get();
1148         }
1149     }
1150     return nullptr;
1151 }
1152 
GetDeviceByFdLocked(int fd)1153 InputHub::Device* InputHub::GetDeviceByFdLocked(int fd)
1154 {
1155     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1156     for (const auto &[id, device] : devices_) {
1157         if (device->fd == fd) {
1158             return device.get();
1159         }
1160     }
1161     return nullptr;
1162 }
1163 
GetSupportDeviceByFd(int fd)1164 InputHub::Device* InputHub::GetSupportDeviceByFd(int fd)
1165 {
1166     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1167     for (const auto &[id, device] : devices_) {
1168         if (device != nullptr && device->fd == fd) {
1169             return device.get();
1170         }
1171     }
1172     return nullptr;
1173 }
1174 
ContainsNonZeroByte(const uint8_t * array,uint32_t startIndex,uint32_t endIndex)1175 bool InputHub::ContainsNonZeroByte(const uint8_t *array, uint32_t startIndex, uint32_t endIndex)
1176 {
1177     const uint8_t* end = array + endIndex;
1178     array += startIndex;
1179     while (array != end) {
1180         if (*(array++) != 0) {
1181             return true;
1182         }
1183     }
1184     return false;
1185 }
1186 
ProcessEventTimestamp(const input_event & event)1187 int64_t InputHub::ProcessEventTimestamp(const input_event &event)
1188 {
1189     const int64_t inputEventTime = event.input_event_sec * 1000000000LL + event.input_event_usec * 1000LL;
1190     return inputEventTime;
1191 }
1192 
TestBit(uint32_t bit,const uint8_t * array)1193 bool InputHub::TestBit(uint32_t bit, const uint8_t *array)
1194 {
1195     constexpr int units = 8;
1196     return (array)[(bit) / units] & (1 << ((bit) % units));
1197 }
1198 
SizeofBitArray(uint32_t bit)1199 uint32_t InputHub::SizeofBitArray(uint32_t bit)
1200 {
1201     constexpr int round = 7;
1202     constexpr int divisor = 8;
1203     return ((bit) + round) / divisor;
1204 }
1205 
SaveAffectDhId(bool isEnable,const std::string & dhId,AffectDhIds & affDhIds)1206 void InputHub::SaveAffectDhId(bool isEnable, const std::string &dhId, AffectDhIds &affDhIds)
1207 {
1208     if (isEnable) {
1209         affDhIds.sharingDhIds.push_back(dhId);
1210     } else {
1211         affDhIds.noSharingDhIds.push_back(dhId);
1212     }
1213 }
1214 
SetSupportInputType(bool enabled,const uint32_t & inputTypes)1215 AffectDhIds InputHub::SetSupportInputType(bool enabled, const uint32_t &inputTypes)
1216 {
1217     AffectDhIds affDhIds;
1218     inputTypes_ = inputTypes;
1219     DHLOGI("SetSupportInputType: inputTypes=0x%x,", inputTypes_.load());
1220     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1221     for (const auto &[id, device] : devices_) {
1222         if (device->classes & inputTypes_) {
1223             device->isShare = enabled;
1224             DHLOGW("ByType dhid:%{public}s, isshare:%{public}d",
1225                 GetAnonyString(device->identifier.descriptor).c_str(), enabled);
1226             SaveAffectDhId(enabled, device->identifier.descriptor, affDhIds);
1227         }
1228     }
1229 
1230     return affDhIds;
1231 }
1232 
SetSharingDevices(bool enabled,std::vector<std::string> dhIds)1233 AffectDhIds InputHub::SetSharingDevices(bool enabled, std::vector<std::string> dhIds)
1234 {
1235     AffectDhIds affDhIds;
1236     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1237     DHLOGI("SetSharingDevices start");
1238     for (auto dhId : dhIds) {
1239         DHLOGI("SetSharingDevices dhId: %{public}s, size: %{public}zu, enabled: %{public}d",
1240             GetAnonyString(dhId).c_str(), devices_.size(), enabled);
1241         sharedDHIds_[dhId] = enabled;
1242         for (const auto &[id, device] : devices_) {
1243             DHLOGI("deviceName %{public}s ,dhId: %{public}s ", device->identifier.name.c_str(),
1244                 GetAnonyString(device->identifier.descriptor).c_str());
1245             if (device->identifier.descriptor == dhId) {
1246                 device->isShare = enabled;
1247                 DHLOGW("dhid:%{public}s, isshare:%{public}d",
1248                     GetAnonyString(device->identifier.descriptor).c_str(), enabled);
1249                 SaveAffectDhId(enabled, device->identifier.descriptor, affDhIds);
1250                 break;
1251             }
1252         }
1253     }
1254     DHLOGI("SetSharingDevices end");
1255     return affDhIds;
1256 }
1257 
GetSharingDevices()1258 std::vector<std::string> InputHub::GetSharingDevices()
1259 {
1260     std::vector<std::string> sharingDevices;
1261     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1262     for (const auto &[id, device] : devices_) {
1263         if (device->isShare) {
1264             DHLOGI("Find sharing dhid: %{public}s", GetAnonyString(device->identifier.descriptor).c_str());
1265             sharingDevices.push_back(device->identifier.descriptor);
1266         }
1267     }
1268     return sharingDevices;
1269 }
1270 
GetSharedMousePathByDhId(const std::vector<std::string> & dhIds,std::string & sharedMousePath,std::string & sharedMouseDhId)1271 void InputHub::GetSharedMousePathByDhId(const std::vector<std::string> &dhIds, std::string &sharedMousePath,
1272     std::string &sharedMouseDhId)
1273 {
1274     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1275     DHLOGI("GetSharedMousePathByDhId: devices_.size:%{public}zu,", devices_.size());
1276     for (const auto &dhId : dhIds) {
1277         for (const auto &[id, device] : devices_) {
1278             if (device == nullptr) {
1279                 DHLOGE("device is nullptr");
1280                 continue;
1281             }
1282             DHLOGI("descriptor:%{public}s, isShare[%{public}d], type[%{public}d]",
1283                 GetAnonyString(device->identifier.descriptor).c_str(), device->isShare, device->classes);
1284             if ((device->identifier.descriptor == dhId) && ((device->classes & INPUT_DEVICE_CLASS_CURSOR) != 0 ||
1285                 (device->classes & INPUT_DEVICE_CLASS_TOUCH) != 0 ||
1286                 ((device->classes & INPUT_DEVICE_CLASS_TOUCH_MT) != 0 && IsTouchPad(device->identifier)))) {
1287                 sharedMouseDhId = dhId;
1288                 sharedMousePath = device->path;
1289                 return; // return First shared mouse
1290             }
1291         }
1292     }
1293 }
1294 
GetSharedKeyboardPathsByDhIds(const std::vector<std::string> & dhIds,std::vector<std::string> & sharedKeyboardPaths,std::vector<std::string> & sharedKeyboardDhIds)1295 void InputHub::GetSharedKeyboardPathsByDhIds(const std::vector<std::string> &dhIds,
1296     std::vector<std::string> &sharedKeyboardPaths, std::vector<std::string> &sharedKeyboardDhIds)
1297 {
1298     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1299     DHLOGI("GetSharedKeyboardPathsByDhIds: devices_.size:%{public}zu,", devices_.size());
1300     for (const auto &dhId : dhIds) {
1301         for (const auto &[id, device] : devices_) {
1302             if (device == nullptr) {
1303                 DHLOGE("device is nullptr");
1304                 continue;
1305             }
1306             DHLOGI("descriptor:%{public}s, isShare[%{public}d], type[%{public}d]",
1307                 GetAnonyString(device->identifier.descriptor).c_str(), device->isShare, device->classes);
1308             if ((device->identifier.descriptor == dhId) &&
1309                 ((device->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0)) {
1310                 sharedKeyboardDhIds.push_back(dhId);
1311                 sharedKeyboardPaths.push_back(device->path);
1312             }
1313         }
1314     }
1315 }
1316 
GetDevicesInfoByType(const uint32_t inputTypes,std::map<int32_t,std::string> & datas)1317 void InputHub::GetDevicesInfoByType(const uint32_t inputTypes, std::map<int32_t, std::string> &datas)
1318 {
1319     uint32_t dhType = 0;
1320 
1321     if ((inputTypes & static_cast<uint32_t>(DInputDeviceType::MOUSE)) != 0) {
1322         dhType |= INPUT_DEVICE_CLASS_CURSOR;
1323     }
1324 
1325     if ((inputTypes & static_cast<uint32_t>(DInputDeviceType::KEYBOARD)) != 0) {
1326         dhType |= INPUT_DEVICE_CLASS_KEYBOARD;
1327     }
1328 
1329     if ((inputTypes & static_cast<uint32_t>(DInputDeviceType::TOUCHSCREEN)) != 0) {
1330         dhType |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT;
1331     }
1332 
1333     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1334     for (const auto &[id, device] : devices_) {
1335         if (device->classes & dhType) {
1336             datas.insert(std::pair<int32_t, std::string>(device->fd, device->identifier.descriptor));
1337         }
1338     }
1339 }
1340 
GetDevicesInfoByDhId(std::vector<std::string> dhidsVec,std::map<int32_t,std::string> & datas)1341 void InputHub::GetDevicesInfoByDhId(std::vector<std::string> dhidsVec, std::map<int32_t, std::string> &datas)
1342 {
1343     for (auto dhId : dhidsVec) {
1344         std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1345         for (const auto &[id, device] : devices_) {
1346             if (device->identifier.descriptor == dhId) {
1347                 datas.insert(std::pair<int32_t, std::string>(device->fd, dhId));
1348             }
1349         }
1350     }
1351 }
1352 
IsAllDevicesStoped()1353 bool InputHub::IsAllDevicesStoped()
1354 {
1355     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1356     for (const auto &[dhId, isShared] : sharedDHIds_) {
1357         DHLOGI("the dhId: %{public}s, isShared: %{public}d", GetAnonyString(dhId).c_str(), isShared);
1358         if (isShared) {
1359             return false;
1360         }
1361     }
1362     return true;
1363 }
1364 
RecordDeviceLog(const std::string & devicePath,const InputDevice & identifier)1365 void InputHub::RecordDeviceLog(const std::string &devicePath, const InputDevice &identifier)
1366 {
1367     if (IsNeedPrintLog(identifier.descriptor)) {
1368         DHLOGI("add device: %{public}s\n", devicePath.c_str());
1369         DHLOGI("  bus:        %{public}04x\n"
1370                "  vendor      %{public}04x\n"
1371                "  product     %{public}04x\n"
1372                "  version     %{public}04x\n",
1373                identifier.bus, identifier.vendor, identifier.product, identifier.version);
1374         DHLOGI("  name:       \"%{public}s\"\n", identifier.name.c_str());
1375         DHLOGI("  physicalPath:   \"%{public}s\"\n", identifier.physicalPath.c_str());
1376         DHLOGI("  unique id:  \"%{public}s\"\n", identifier.uniqueId.c_str());
1377         DHLOGI("  descriptor: \"%{public}s\"\n", GetAnonyString(identifier.descriptor).c_str());
1378     }
1379 }
1380 
RecordChangeEventLog(const RawEvent & event)1381 void InputHub::RecordChangeEventLog(const RawEvent &event)
1382 {
1383     std::string eventType = "";
1384     switch (event.type) {
1385         case EV_KEY:
1386             eventType = "EV_KEY";
1387             break;
1388         case EV_REL:
1389             eventType = "EV_REL";
1390             break;
1391         case EV_ABS:
1392             eventType = "EV_ABS";
1393             break;
1394         case EV_SYN:
1395             eventType = "EV_SYN";
1396             break;
1397         default:
1398             eventType = "other type " + std::to_string(event.type);
1399             break;
1400     }
1401     DHLOGI("0.E2E-Test Sink collect change event, EventType: %{public}s, Code: %{public}d, Value: %{public}d, "
1402         "Path: %{public}s, descriptor: %{public}s, When: %{public}" PRId64 "", eventType.c_str(), event.code,
1403         event.value, event.path.c_str(), GetAnonyString(event.descriptor).c_str(), event.when);
1404 }
1405 
RecordEventLog(const RawEvent * event)1406 void InputHub::RecordEventLog(const RawEvent *event)
1407 {
1408     std::string eventType = "";
1409     switch (event->type) {
1410         case EV_KEY:
1411             eventType = "EV_KEY";
1412             break;
1413         case EV_REL:
1414             eventType = "EV_REL";
1415             break;
1416         case EV_ABS:
1417             eventType = "EV_ABS";
1418             break;
1419         case EV_SYN:
1420             eventType = "EV_SYN";
1421             break;
1422         default:
1423             eventType = "other type " + std::to_string(event->type);
1424             break;
1425     }
1426     DHLOGD("1.E2E-Test Sink collect event, EventType: %{public}s, Code: %{public}d, Value: %{public}d, "
1427         "Path: %{public}s, descriptor: %{public}s, When: %{public}" PRId64 "", eventType.c_str(), event->code,
1428         event->value, event->path.c_str(), GetAnonyString(event->descriptor).c_str(), event->when);
1429 }
1430 
HandleTouchScreenEvent(struct input_event readBuffer[],const size_t count,std::vector<bool> & needFilted)1431 void InputHub::HandleTouchScreenEvent(struct input_event readBuffer[], const size_t count,
1432     std::vector<bool> &needFilted)
1433 {
1434     std::vector<std::pair<size_t, size_t>> absIndexs;
1435     int32_t firstIndex = -1;
1436     int32_t lastIndex = -1;
1437 
1438     for (size_t i = 0; i < count; i++) {
1439         struct input_event& iev = readBuffer[i];
1440         if ((iev.type == EV_ABS) && (iev.code == ABS_X || iev.code == ABS_MT_POSITION_X)) {
1441             firstIndex = static_cast<int32_t>(i);
1442         } else if (iev.type  == EV_SYN) {
1443             lastIndex = static_cast<int32_t>(i);
1444         }
1445         if ((firstIndex >= 0) && (lastIndex > firstIndex)) {
1446             absIndexs.emplace_back(std::make_pair((size_t)firstIndex, (size_t)lastIndex));
1447         }
1448     }
1449 
1450     AbsInfo absInfo = {
1451         .absX = 0,
1452         .absY = 0,
1453         .absXIndex = -1,
1454         .absYIndex = -1,
1455     };
1456     for (auto iter : absIndexs) {
1457         absInfo.absXIndex = -1;
1458         absInfo.absYIndex = -1;
1459 
1460         for (size_t j = iter.first; j <= iter.second; j++) {
1461             struct input_event &iev = readBuffer[j];
1462             if (iev.code == ABS_X || iev.code == ABS_MT_POSITION_X) {
1463                 absInfo.absX = static_cast<uint32_t>(iev.value);
1464                 absInfo.absXIndex = static_cast<int32_t>(j);
1465             }
1466             if (iev.code == ABS_Y || iev.code == ABS_MT_POSITION_Y) {
1467                 absInfo.absY = static_cast<uint32_t>(iev.value);
1468                 absInfo.absYIndex = static_cast<int32_t>(j);
1469             }
1470         }
1471 
1472         if ((absInfo.absXIndex < 0) || (absInfo.absYIndex < 0)) {
1473             for (size_t j = iter.first; j <= iter.second; j++) {
1474                 needFilted[j] = true;
1475             }
1476             continue;
1477         }
1478         if (!CheckTouchPointRegion(readBuffer, absInfo)) {
1479             for (size_t j = iter.first; j <= iter.second; j++) {
1480                 needFilted[j] = true;
1481             }
1482         }
1483     }
1484 }
1485 
CheckTouchPointRegion(struct input_event readBuffer[],const AbsInfo & absInfo)1486 bool InputHub::CheckTouchPointRegion(struct input_event readBuffer[], const AbsInfo &absInfo)
1487 {
1488     auto sinkInfos = DInputContext::GetInstance().GetAllSinkScreenInfo();
1489 
1490     for (const auto &[id, sinkInfo] : sinkInfos) {
1491         auto info = sinkInfo.transformInfo;
1492         if ((absInfo.absX >= info.sinkWinPhyX) && (absInfo.absX <= (info.sinkWinPhyX + info.sinkProjPhyWidth))
1493             && (absInfo.absY >= info.sinkWinPhyY) && (absInfo.absY <= (info.sinkWinPhyY + info.sinkProjPhyHeight))) {
1494             touchDescriptor = sinkInfo.srcScreenInfo.sourcePhyId;
1495             readBuffer[absInfo.absXIndex].value = (absInfo.absX - info.sinkWinPhyX) * info.coeffWidth;
1496             readBuffer[absInfo.absYIndex].value = (absInfo.absY - info.sinkWinPhyY) * info.coeffHeight;
1497             return true;
1498         }
1499     }
1500     return false;
1501 }
1502 
CollectTargetDevices()1503 std::vector<InputHub::Device*> InputHub::CollectTargetDevices()
1504 {
1505     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1506     std::vector<InputHub::Device*> tarVec;
1507     for (const auto &dev : devices_) {
1508         if (((dev.second->classes & INPUT_DEVICE_CLASS_TOUCH) != 0) ||
1509             ((dev.second->classes & INPUT_DEVICE_CLASS_TOUCH_MT) != 0) ||
1510             ((dev.second->classes & INPUT_DEVICE_CLASS_CURSOR) != 0) ||
1511             ((dev.second->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0)) {
1512             DHLOGI("Find target devs need check stat, path: %{public}s, name: %{public}s",
1513                 dev.first.c_str(), dev.second->identifier.name.c_str());
1514             tarVec.push_back(dev.second.get());
1515         }
1516     }
1517 
1518     return tarVec;
1519 }
1520 
SavePressedKeyState(const InputHub::Device * dev,int32_t keyCode)1521 void InputHub::SavePressedKeyState(const InputHub::Device *dev, int32_t keyCode)
1522 {
1523     struct RawEvent event = {
1524         .type = EV_KEY,
1525         .code = keyCode,
1526         .value = KEY_DOWN_STATE,
1527         .descriptor = dev->identifier.descriptor,
1528         .path = dev->path
1529     };
1530     DInputSinkState::GetInstance().AddKeyDownState(event);
1531     DHLOGI("Find Pressed key: %{public}d, device path: %{public}s, dhId: %{public}s", keyCode, dev->path.c_str(),
1532         GetAnonyString(dev->identifier.descriptor).c_str());
1533 }
1534 
IsLengthExceeds(const unsigned long * keyState,const unsigned long len,int keyIndex)1535 bool InputHub::IsLengthExceeds(const unsigned long *keyState, const unsigned long len, int keyIndex)
1536 {
1537     if (len < (keyIndex / LONG_BITS) + 1) {
1538         DHLOGE("Length exceeds for key index: %{public}d", keyIndex);
1539         return true;
1540     }
1541     return false;
1542 }
1543 
CheckTargetKeyState(const InputHub::Device * dev,const unsigned long * keyState,const unsigned long len)1544 void InputHub::CheckTargetKeyState(const InputHub::Device *dev, const unsigned long *keyState, const unsigned long len)
1545 {
1546     // If device is a mouse, record the mouse pressed key.
1547     if ((dev->classes & INPUT_DEVICE_CLASS_CURSOR) != 0) {
1548         if (IsLengthExceeds(keyState, len, BTN_LEFT)) {
1549             return;
1550         }
1551         int mouseLeftBtnState = BitIsSet(keyState, BTN_LEFT);
1552         if (mouseLeftBtnState != 0) {
1553             SavePressedKeyState(dev, BTN_LEFT);
1554         }
1555         if (IsLengthExceeds(keyState, len, BTN_RIGHT)) {
1556             return;
1557         }
1558         int mouseRightBtnState = BitIsSet(keyState, BTN_RIGHT);
1559         if (mouseRightBtnState != 0) {
1560             SavePressedKeyState(dev, BTN_RIGHT);
1561         }
1562         if (IsLengthExceeds(keyState, len, BTN_MIDDLE)) {
1563             return;
1564         }
1565         int mouseMidBtnState = BitIsSet(keyState, BTN_MIDDLE);
1566         if (mouseMidBtnState != 0) {
1567             SavePressedKeyState(dev, BTN_MIDDLE);
1568         }
1569     }
1570 
1571     // If device is a keyboard, record all the pressed keys.
1572     if ((dev->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0) {
1573         for (int32_t keyIndex = 0; keyIndex < KEY_MAX; keyIndex++) {
1574             if (IsLengthExceeds(keyState, len, keyIndex)) {
1575                 return;
1576             }
1577             if (BitIsSet(keyState, keyIndex) != 0) {
1578                 SavePressedKeyState(dev, keyIndex);
1579             }
1580         }
1581     }
1582 
1583     // If device is a touchscreen or touchpad, record the touch event.
1584     if ((dev->classes & INPUT_DEVICE_CLASS_TOUCH) != 0 || (dev->classes & INPUT_DEVICE_CLASS_TOUCH_MT) != 0) {
1585         if (IsLengthExceeds(keyState, len, BTN_TOUCH)) {
1586             return;
1587         }
1588         int btnTouchState = BitIsSet(keyState, BTN_TOUCH);
1589         if (btnTouchState != 0) {
1590             SavePressedKeyState(dev, BTN_TOUCH);
1591         }
1592     }
1593 }
1594 
1595 
CheckTargetDevicesState(std::vector<InputHub::Device * > targetDevices)1596 void InputHub::CheckTargetDevicesState(std::vector<InputHub::Device*> targetDevices)
1597 {
1598     uint32_t count = 0;
1599     unsigned long keyState[NLONGS(KEY_CNT)] = { 0 };
1600     for (const auto *dev : targetDevices) {
1601         while (true) {
1602             if (count > READ_RETRY_MAX) {
1603                 break;
1604             }
1605             // Query all key state
1606             int rc = ioctl(dev->fd, EVIOCGKEY(sizeof(keyState)), keyState);
1607             if (rc < 0) {
1608                 DHLOGE("read all key state failed, rc=%{public}d", rc);
1609                 count += 1;
1610                 std::this_thread::sleep_for(std::chrono::milliseconds(READ_SLEEP_TIME_MS));
1611                 continue;
1612             }
1613             CheckTargetKeyState(dev, keyState, NLONGS(KEY_CNT));
1614             break;
1615         }
1616     }
1617 }
1618 
RecordDeviceStates()1619 void InputHub::RecordDeviceStates()
1620 {
1621     DHLOGI("Start Record keys states");
1622     ScanAndRecordInputDevices();
1623     std::vector<InputHub::Device*> tarDevices = CollectTargetDevices();
1624     DHLOGI("Check target states device num: %{public}zu", tarDevices.size());
1625     CheckTargetDevicesState(tarDevices);
1626     DHLOGI("Finish Record Keys states");
1627 }
1628 
ClearDeviceStates()1629 void InputHub::ClearDeviceStates()
1630 {
1631     DHLOGI("Clear Device state");
1632     DInputSinkState::GetInstance().ClearDeviceStates();
1633 }
1634 
ClearSkipDevicePaths()1635 void InputHub::ClearSkipDevicePaths()
1636 {
1637     DHLOGI("Clear Skip device path");
1638     std::lock_guard<std::mutex> lock(skipDevicePathsMutex_);
1639     skipDevicePaths_.clear();
1640 }
1641 
Device(int fd,const std::string & path)1642 InputHub::Device::Device(int fd, const std::string &path)
1643     : next(nullptr), fd(fd), path(path), identifier({}), classes(0), enabled(false),
1644       isShare(false), isVirtual(fd < 0) {
1645     // Figure out the kinds of events the device reports.
1646     DHLOGI("Ctor Device for get event mask, fd: %{public}d, path: %{public}s", fd, path.c_str());
1647     ioctl(fd, EVIOCGBIT(0, sizeof(evBitmask)), evBitmask);
1648     ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keyBitmask)), keyBitmask);
1649     ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absBitmask)), absBitmask);
1650     ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relBitmask)), relBitmask);
1651 }
1652 
~Device()1653 InputHub::Device::~Device()
1654 {
1655     Close();
1656 }
1657 
Close()1658 void InputHub::Device::Close()
1659 {
1660     if (fd >= 0) {
1661         ::close(fd);
1662         fd = UN_INIT_FD_VALUE;
1663     }
1664 }
1665 
Enable()1666 int32_t InputHub::Device::Enable()
1667 {
1668     char canonicalPath[PATH_MAX + 1] = {0x00};
1669 
1670     if (path.length() == 0 || path.length() > PATH_MAX || realpath(path.c_str(), canonicalPath) == nullptr) {
1671         DHLOGE("path check fail, error path: %{public}s", path.c_str());
1672         return ERR_DH_INPUT_HUB_DEVICE_ENABLE_FAIL;
1673     }
1674     fd = open(canonicalPath, O_RDWR | O_CLOEXEC | O_NONBLOCK);
1675     if (fd < 0) {
1676         DHLOGE("could not open %{public}s, %{public}s\n", path.c_str(), ConvertErrNo().c_str());
1677         return ERR_DH_INPUT_HUB_DEVICE_ENABLE_FAIL;
1678     }
1679     enabled = true;
1680     return DH_SUCCESS;
1681 }
1682 
Disable()1683 int32_t InputHub::Device::Disable()
1684 {
1685     Close();
1686     enabled = false;
1687     return DH_SUCCESS;
1688 }
1689 
HasValidFd() const1690 bool InputHub::Device::HasValidFd() const
1691 {
1692     return !isVirtual && enabled;
1693 }
1694 } // namespace DistributedInput
1695 } // namespace DistributedHardware
1696 } // namespace OHOS
1697