• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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         return ERR_DH_INPUT_HUB_QUERY_INPUT_DEVICE_INFO_FAIL;
564     }
565     GenerateDescriptor(device->identifier);
566     IncreaseLogTimes(device->identifier.descriptor);
567     RecordDeviceLog(devicePath, device->identifier);
568     std::string descriptor = device->identifier.descriptor;
569     if (MakeDevice(fd, std::move(device)) < 0) {
570         if (IsNeedPrintLog(descriptor)) {
571             DHLOGI("Opening device error: %{public}s", devicePath.c_str());
572         }
573         return ERR_DH_INPUT_HUB_MAKE_DEVICE_FAIL;
574     }
575 
576     DHLOGI("Opening device finish: %{public}s", devicePath.c_str());
577     return DH_SUCCESS;
578 }
579 
RecordSkipDevicePath(std::string path)580 void InputHub::RecordSkipDevicePath(std::string path)
581 {
582     std::lock_guard<std::mutex> lock(skipDevicePathsMutex_);
583     skipDevicePaths_.insert(path);
584 }
585 
IsSkipDevicePath(const std::string & path)586 bool InputHub::IsSkipDevicePath(const std::string &path)
587 {
588     std::lock_guard<std::mutex> lock(skipDevicePathsMutex_);
589     return skipDevicePaths_.find(path) != skipDevicePaths_.end();
590 }
591 
IncreaseLogTimes(const std::string & dhId)592 void InputHub::IncreaseLogTimes(const std::string& dhId)
593 {
594     if (logTimesMap_.find(dhId) != logTimesMap_.end() && logTimesMap_[dhId] >= INT32_MAX - 1) {
595         logTimesMap_[dhId] = 0;
596     } else {
597         logTimesMap_[dhId]++;
598     }
599 }
600 
IsNeedPrintLog(const std::string & dhId) const601 bool InputHub::IsNeedPrintLog(const std::string& dhId) const
602 {
603     return logTimesMap_.find(dhId) == logTimesMap_.end() || logTimesMap_.at(dhId) <= MAX_LOG_TIMES;
604 }
605 
QueryInputDeviceInfo(int fd,std::unique_ptr<Device> & device)606 int32_t InputHub::QueryInputDeviceInfo(int fd, std::unique_ptr<Device> &device)
607 {
608     char buffer[INPUT_EVENT_BUFFER_SIZE] = {0};
609     // Get device name.
610     if (ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) {
611         DHLOGE("Could not get device name for %{public}s", ConvertErrNo().c_str());
612     } else {
613         buffer[sizeof(buffer) - 1] = '\0';
614         device->identifier.name = buffer;
615     }
616     DHLOGD("QueryInputDeviceInfo deviceName: %{public}s", buffer);
617     // If the device is already a virtual device, don't monitor it.
618     if (device->identifier.name.find(VIRTUAL_DEVICE_NAME) != std::string::npos) {
619         DHLOGE("this is a virtual driver, skip it.");
620         RecordSkipDevicePath(device->path);
621         return ERR_DH_INPUT_HUB_IS_VIRTUAL_DEVICE;
622     }
623     // Get device driver version.
624     int driverVersion;
625     if (ioctl(fd, EVIOCGVERSION, &driverVersion)) {
626         DHLOGE("could not get driver version for %{public}s\n", ConvertErrNo().c_str());
627         RecordSkipDevicePath(device->path);
628         return ERR_DH_INPUT_HUB_QUERY_INPUT_DEVICE_INFO_FAIL;
629     }
630     // Get device identifier.
631     struct input_id inputId;
632     if (ioctl(fd, EVIOCGID, &inputId)) {
633         DHLOGE("could not get device input id for %{public}s\n", ConvertErrNo().c_str());
634         RecordSkipDevicePath(device->path);
635         return ERR_DH_INPUT_HUB_QUERY_INPUT_DEVICE_INFO_FAIL;
636     }
637     device->identifier.bus = inputId.bustype;
638     device->identifier.product = inputId.product;
639     device->identifier.vendor = inputId.vendor;
640     device->identifier.version = inputId.version;
641     // Get device physical physicalPath.
642     if (ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) {
643         DHLOGE("could not get physicalPath for %{public}s\n", ConvertErrNo().c_str());
644     } else {
645         buffer[sizeof(buffer) - 1] = '\0';
646         device->identifier.physicalPath = buffer;
647     }
648     // Get device unique id.
649     if (ioctl(fd, EVIOCGUNIQ(sizeof(buffer) - 1), &buffer) < 1) {
650         DHLOGE("could not get idstring for %{public}s\n", ConvertErrNo().c_str());
651     } else {
652         buffer[sizeof(buffer) - 1] = '\0';
653         device->identifier.uniqueId = buffer;
654     }
655 
656     QueryEventInfo(fd, device);
657     return DH_SUCCESS;
658 }
659 
QueryEventInfo(int fd,std::unique_ptr<Device> & device)660 void InputHub::QueryEventInfo(int fd, std::unique_ptr<Device> &device)
661 {
662     if (device == nullptr) {
663         DHLOGE("device is nullptr!");
664         return;
665     }
666     if (IsNeedPrintLog(device->identifier.descriptor)) {
667         DHLOGI("QueryEventInfo: devName: %{public}s, dhId: %{public}s!", device->identifier.name.c_str(),
668             GetAnonyString(device->identifier.descriptor).c_str());
669     }
670     struct libevdev *dev = GetLibEvDev(fd);
671     if (dev == nullptr) {
672         if (IsNeedPrintLog(device->identifier.descriptor)) {
673             DHLOGE("dev is nullptr");
674         }
675         return;
676     }
677     GetEventTypes(dev, device->identifier);
678     GetEventKeys(dev, device->identifier);
679     GetABSInfo(dev, device->identifier);
680     GetRELTypes(dev, device->identifier);
681     GetProperties(dev, device->identifier);
682 
683     GetMSCBits(fd, device);
684     GetLEDBits(fd, device);
685     GetSwitchBits(fd, device);
686     GetRepeatBits(fd, device);
687 
688     libevdev_free(dev);
689 }
690 
GetEventMask(int fd,const std::string & eventName,uint32_t type,std::size_t arrayLength,uint8_t * whichBitMask) const691 void InputHub::GetEventMask(int fd, const std::string &eventName, uint32_t type,
692     std::size_t arrayLength, uint8_t *whichBitMask) const
693 {
694     int32_t rc = ioctl(fd, EVIOCGBIT(type, arrayLength), whichBitMask);
695     if (rc < 0) {
696         DHLOGE("Could not get events %{public}s mask: %{public}s", eventName.c_str(), strerror(errno));
697     }
698 }
699 
GetMSCBits(int fd,std::unique_ptr<Device> & device)700 void InputHub::GetMSCBits(int fd, std::unique_ptr<Device> &device)
701 {
702     uint8_t mscBitmask[NBYTES(MSC_MAX)] {};
703     GetEventMask(fd, "msc", EV_MSC, sizeof(mscBitmask), mscBitmask);
704 
705     for (uint32_t msc = MSC_SERIAL; msc < MSC_MAX; ++msc) {
706         if (TestBit(EV_MSC, device->evBitmask) && TestBit(msc, mscBitmask)) {
707             DHLOGI("Get MSC event: %{public}d", msc);
708             device->identifier.miscellaneous.push_back(msc);
709         }
710     }
711 }
712 
GetLEDBits(int fd,std::unique_ptr<Device> & device)713 void InputHub::GetLEDBits(int fd, std::unique_ptr<Device> &device)
714 {
715     uint8_t ledBitmask[NBYTES(LED_MAX)] {};
716     GetEventMask(fd, "led", EV_LED, sizeof(ledBitmask), ledBitmask);
717     for (uint32_t led = LED_NUML; led < LED_MAX; ++led) {
718         if (TestBit(EV_LED, device->evBitmask) && TestBit(led, ledBitmask)) {
719             DHLOGI("Get LED event: %{public}d", led);
720             device->identifier.leds.push_back(led);
721         }
722     }
723 }
724 
GetSwitchBits(int fd,std::unique_ptr<Device> & device)725 void InputHub::GetSwitchBits(int fd, std::unique_ptr<Device> &device)
726 {
727     uint8_t switchBitmask[NBYTES(SW_MAX)] {};
728     GetEventMask(fd, "switch", EV_SW, sizeof(switchBitmask), switchBitmask);
729 
730     for (uint32_t sw = SW_LID; sw < SW_MAX; ++sw) {
731         if (TestBit(EV_SW, device->evBitmask) && TestBit(sw, switchBitmask)) {
732             DHLOGI("Get Switch event: %{public}d", sw);
733             device->identifier.switchs.push_back(sw);
734         }
735     }
736 }
737 
GetRepeatBits(int fd,std::unique_ptr<Device> & device)738 void InputHub::GetRepeatBits(int fd, std::unique_ptr<Device> &device)
739 {
740     uint8_t repBitmask[NBYTES(REP_MAX)] {};
741     GetEventMask(fd, "repeat", EV_REP, sizeof(repBitmask), repBitmask);
742 
743     for (uint32_t rep = REP_DELAY; rep < REP_MAX; ++rep) {
744         if (TestBit(EV_REP, device->evBitmask) && TestBit(rep, repBitmask)) {
745             DHLOGI("Get Repeat event: %{public}d", rep);
746             device->identifier.repeats.push_back(rep);
747         }
748     }
749 }
750 
GetLibEvDev(int fd)751 struct libevdev* InputHub::GetLibEvDev(int fd)
752 {
753     struct libevdev *dev = nullptr;
754     int rc = 1;
755     rc = libevdev_new_from_fd(fd, &dev);
756     if (rc < 0) {
757         DHLOGE("Failed to init libevdev (%{public}s)", strerror(-rc));
758         return nullptr;
759     }
760     return dev;
761 }
762 
GetEventTypes(struct libevdev * dev,InputDevice & identifier)763 void InputHub::GetEventTypes(struct libevdev *dev, InputDevice &identifier)
764 {
765     for (uint32_t eventType = 0; eventType < EV_CNT; eventType++) {
766         if (!libevdev_has_event_type(dev, eventType)) {
767             DHLOGD("The device is not support eventType: %{public}d", eventType);
768             continue;
769         }
770         identifier.eventTypes.push_back(eventType);
771     }
772 }
773 
GetEventKeys(struct libevdev * dev,InputDevice & identifier)774 int32_t InputHub::GetEventKeys(struct libevdev *dev, InputDevice &identifier)
775 {
776     if (!libevdev_has_event_type(dev, EV_KEY)) {
777         if (IsNeedPrintLog(identifier.descriptor)) {
778             DHLOGE("The device doesn't has EV_KEY type!");
779         }
780         return ERR_DH_INPUT_HUB_QUERY_INPUT_DEVICE_INFO_FAIL;
781     }
782     for (uint32_t eventKey = 0; eventKey < KEY_CNT; eventKey++) {
783         if (!libevdev_has_event_code(dev, EV_KEY, eventKey)) {
784             DHLOGD("The device is not support eventKey: %{public}d", eventKey);
785             continue;
786         }
787         identifier.eventKeys.push_back(eventKey);
788     }
789     return DH_SUCCESS;
790 }
791 
GetABSInfo(struct libevdev * dev,InputDevice & identifier)792 int32_t InputHub::GetABSInfo(struct libevdev *dev, InputDevice &identifier)
793 {
794     if (!libevdev_has_event_type(dev, EV_ABS)) {
795         if (IsNeedPrintLog(identifier.descriptor)) {
796             DHLOGE("The device doesn't has EV_ABS type!");
797         }
798         return ERR_DH_INPUT_HUB_QUERY_INPUT_DEVICE_INFO_FAIL;
799     }
800     DHLOGI("The device has abs info, devName: %{public}s, dhId: %{public}s!",
801         identifier.name.c_str(), GetAnonyString(identifier.descriptor).c_str());
802     for (uint32_t absType = 0; absType < ABS_CNT; absType++) {
803         if (!libevdev_has_event_code(dev, EV_ABS, absType)) {
804             DHLOGD("The device is not support absType: %{public}d", absType);
805             continue;
806         }
807         identifier.absTypes.push_back(absType);
808         const struct input_absinfo *abs = libevdev_get_abs_info(dev, absType);
809         if (abs == nullptr) {
810             DHLOGE("absInfo is nullptr!");
811             continue;
812         }
813         identifier.absInfos[absType].push_back(abs->value);
814         identifier.absInfos[absType].push_back(abs->minimum);
815         identifier.absInfos[absType].push_back(abs->maximum);
816         identifier.absInfos[absType].push_back(abs->fuzz);
817         identifier.absInfos[absType].push_back(abs->flat);
818         identifier.absInfos[absType].push_back(abs->resolution);
819     }
820     return DH_SUCCESS;
821 }
822 
GetRELTypes(struct libevdev * dev,InputDevice & identifier)823 int32_t InputHub::GetRELTypes(struct libevdev *dev, InputDevice &identifier)
824 {
825     if (!libevdev_has_event_type(dev, EV_REL)) {
826         if (IsNeedPrintLog(identifier.descriptor)) {
827             DHLOGE("The device doesn't has EV_REL type!");
828         }
829         return ERR_DH_INPUT_HUB_QUERY_INPUT_DEVICE_INFO_FAIL;
830     }
831     for (uint32_t code = 0; code < REL_CNT; code++) {
832         if (!libevdev_has_event_code(dev, EV_REL, code)) {
833             DHLOGD("The device is not support rel code: %{public}d", code);
834             continue;
835         }
836         identifier.relTypes.push_back(code);
837     }
838     return DH_SUCCESS;
839 }
840 
GetProperties(struct libevdev * dev,InputDevice & identifier)841 void InputHub::GetProperties(struct libevdev *dev, InputDevice &identifier)
842 {
843     for (uint32_t prop = 0; prop < INPUT_PROP_CNT; prop++) {
844         if (libevdev_has_property(dev, prop)) {
845             DHLOGI("QueryInputDeviceInfo rel prop: %{public}d", prop);
846             identifier.properties.push_back(prop);
847         }
848     }
849 }
850 
MakeDevice(int fd,std::unique_ptr<Device> device)851 int32_t InputHub::MakeDevice(int fd, std::unique_ptr<Device> device)
852 {
853     // See if this is a multi-touch touchscreen device.
854     if (TestBit(BTN_TOUCH, device->keyBitmask) &&
855         TestBit(ABS_MT_POSITION_X, device->absBitmask) &&
856         TestBit(ABS_MT_POSITION_Y, device->absBitmask)) {
857         QueryLocalTouchScreenInfo(fd, device);
858         device->classes |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT;
859     } else if (TestBit(BTN_TOUCH, device->keyBitmask) &&
860         TestBit(ABS_X, device->absBitmask) &&
861         TestBit(ABS_Y, device->absBitmask)) {
862         QueryLocalTouchScreenInfo(fd, device);
863         device->classes |= INPUT_DEVICE_CLASS_TOUCH;
864     }
865 
866     // See if this is a cursor device such as a trackball or mouse.
867     if (TestBit(BTN_MOUSE, device->keyBitmask)
868         && TestBit(REL_X, device->relBitmask)
869         && TestBit(REL_Y, device->relBitmask)) {
870         device->classes |= INPUT_DEVICE_CLASS_CURSOR;
871     }
872 
873     // for Linux version 4.14.116, touchpad recognized as mouse and keyboard at same time,
874     // need to avoid device->classes to be 0x09, which mmi can't handler.
875     // See if this is a keyboard.
876     if (device->classes == 0) {
877         bool haveKeyboardKeys = ContainsNonZeroByte(device->keyBitmask, 0, SizeofBitArray(BTN_MISC));
878         if (haveKeyboardKeys) {
879             device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
880         }
881     }
882 
883     // If the device isn't recognized as something we handle, don't monitor it.
884     if (device->classes == 0) {
885         if (IsNeedPrintLog(device->identifier.descriptor)) {
886             DHLOGI("Dropping device: name='%{public}s'", device->identifier.name.c_str());
887         }
888         return ERR_DH_INPUT_HUB_MAKE_DEVICE_FAIL;
889     }
890 
891     if (RegisterDeviceForEpollLocked(*device) != DH_SUCCESS) {
892         return ERR_DH_INPUT_HUB_MAKE_DEVICE_FAIL;
893     }
894 
895     device->identifier.classes = device->classes;
896 
897     DHLOGI("inputType=%{public}d", inputTypes_.load());
898     DHLOGI("New device: fd=%{public}d, name='%{public}s', classes=0x%{public}x", fd, device->identifier.name.c_str(),
899         device->classes);
900 
901     AddDeviceLocked(std::move(device));
902     return DH_SUCCESS;
903 }
904 
QueryLocalTouchScreenInfo(int fd,std::unique_ptr<Device> & device)905 int32_t InputHub::QueryLocalTouchScreenInfo(int fd, std::unique_ptr<Device> &device)
906 {
907     LocalTouchScreenInfo info = DInputContext::GetInstance().GetLocalTouchScreenInfo();
908     device->identifier.classes |= INPUT_DEVICE_CLASS_TOUCH_MT;
909     info.localAbsInfo.deviceInfo = device->identifier;
910 
911     struct input_absinfo absInfo;
912     ioctl(fd, EVIOCGABS(ABS_MT_POSITION_X), &absInfo);
913     info.localAbsInfo.absXMin = absInfo.minimum;
914     info.localAbsInfo.absXMax = absInfo.maximum;
915     info.localAbsInfo.absMtPositionXMin = absInfo.minimum;
916     info.localAbsInfo.absMtPositionXMax = absInfo.maximum;
917     info.sinkPhyWidth = static_cast<uint32_t>(absInfo.maximum + 1);
918 
919     ioctl(fd, EVIOCGABS(ABS_MT_POSITION_Y), &absInfo);
920     info.localAbsInfo.absYMin = absInfo.minimum;
921     info.localAbsInfo.absYMax = absInfo.maximum;
922     info.localAbsInfo.absMtPositionYMin = absInfo.minimum;
923     info.localAbsInfo.absMtPositionYMax = absInfo.maximum;
924     info.sinkPhyHeight = static_cast<uint32_t>(absInfo.maximum + 1);
925 
926     ioctl(fd, EVIOCGABS(ABS_PRESSURE), &absInfo);
927     info.localAbsInfo.absPressureMin = absInfo.minimum;
928     info.localAbsInfo.absPressureMax = absInfo.maximum;
929     info.localAbsInfo.absMtPressureMin = absInfo.minimum;
930     info.localAbsInfo.absMtPressureMax = absInfo.maximum;
931 
932     ioctl(fd, EVIOCGABS(ABS_MT_TOUCH_MAJOR), &absInfo);
933     info.localAbsInfo.absMtTouchMajorMin = absInfo.minimum;
934     info.localAbsInfo.absMtTouchMajorMax = absInfo.maximum;
935 
936     ioctl(fd, EVIOCGABS(ABS_MT_TOUCH_MINOR), &absInfo);
937     info.localAbsInfo.absMtTouchMinorMin = absInfo.minimum;
938     info.localAbsInfo.absMtTouchMinorMax = absInfo.maximum;
939 
940     ioctl(fd, EVIOCGABS(ABS_MT_ORIENTATION), &absInfo);
941     info.localAbsInfo.absMtOrientationMin = absInfo.minimum;
942     info.localAbsInfo.absMtOrientationMax = absInfo.maximum;
943 
944     ioctl(fd, EVIOCGABS(ABS_MT_BLOB_ID), &absInfo);
945     info.localAbsInfo.absMtBlobIdMin = absInfo.minimum;
946     info.localAbsInfo.absMtBlobIdMax = absInfo.maximum;
947 
948     ioctl(fd, EVIOCGABS(ABS_MT_TRACKING_ID), &absInfo);
949     info.localAbsInfo.absMtTrackingIdMin = absInfo.minimum;
950     info.localAbsInfo.absMtTrackingIdMax = absInfo.maximum;
951 
952     DInputContext::GetInstance().SetLocalTouchScreenInfo(info);
953     return DH_SUCCESS;
954 }
955 
StringPrintf(const char * format,...) const956 std::string InputHub::StringPrintf(const char *format, ...) const
957 {
958     char space[SPACELENGTH] = {0};
959     va_list ap;
960     va_start(ap, format);
961     std::string result;
962     int32_t ret = vsnprintf_s(space, sizeof(space), sizeof(space) - 1, format, ap);
963     if (ret >= DH_SUCCESS && static_cast<size_t>(ret) < sizeof(space)) {
964         result = space;
965     } else {
966         va_end(ap);
967         return "the buffer is overflow!";
968     }
969     va_end(ap);
970     return result;
971 }
972 
GenerateDescriptor(InputDevice & identifier) const973 void InputHub::GenerateDescriptor(InputDevice &identifier) const
974 {
975     std::string rawDescriptor;
976     rawDescriptor += StringPrintf(":%04x:%04x:", identifier.vendor,
977         identifier.product);
978     // add handling for USB devices to not uniqueify kbs that show up twice
979     if (!identifier.uniqueId.empty()) {
980         rawDescriptor += "uniqueId:";
981         rawDescriptor += identifier.uniqueId;
982     }
983     if (!identifier.physicalPath.empty()) {
984         rawDescriptor += "physicalPath:";
985         rawDescriptor += identifier.physicalPath;
986     }
987     if (!identifier.name.empty()) {
988         rawDescriptor += "name:";
989         std::string name = identifier.name;
990         rawDescriptor += regex_replace(name, std::regex(" "), "");
991     }
992 
993     identifier.descriptor = DH_ID_PREFIX + Sha256(rawDescriptor);
994     if (IsNeedPrintLog(identifier.descriptor)) {
995         DHLOGI("Created descriptor: raw=%{public}s, cooked=%{public}s", rawDescriptor.c_str(),
996             GetAnonyString(identifier.descriptor).c_str());
997     }
998 }
999 
RegisterDeviceForEpollLocked(const Device & device)1000 int32_t InputHub::RegisterDeviceForEpollLocked(const Device &device)
1001 {
1002     int32_t result = RegisterFdForEpoll(device.fd);
1003     if (result != DH_SUCCESS) {
1004         DHLOGE("Could not add input device fd to epoll for device, path: %{public}s", device.path.c_str());
1005         return result;
1006     }
1007     return result;
1008 }
1009 
RegisterFdForEpoll(int fd)1010 int32_t InputHub::RegisterFdForEpoll(int fd)
1011 {
1012     struct epoll_event eventItem = {};
1013     eventItem.events = EPOLLIN | EPOLLWAKEUP;
1014     eventItem.data.fd = fd;
1015     if (epoll_ctl(epollFd_, EPOLL_CTL_ADD, fd, &eventItem)) {
1016         DHLOGE("Could not add fd to epoll instance: %{public}s", ConvertErrNo().c_str());
1017         return -errno;
1018     }
1019     return DH_SUCCESS;
1020 }
1021 
AddDeviceLocked(std::unique_ptr<Device> device)1022 void InputHub::AddDeviceLocked(std::unique_ptr<Device> device)
1023 {
1024     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1025     openingDevices_.push_back(std::move(device));
1026 }
1027 
CloseDeviceLocked(Device & device)1028 void InputHub::CloseDeviceLocked(Device &device)
1029 {
1030     DHLOGI("Removed device: path=%{public}s name=%{public}s fd=%{public}d classes=0x%{public}x",
1031         device.path.c_str(), device.identifier.name.c_str(), device.fd, device.classes);
1032 
1033     UnregisterDeviceFromEpollLocked(device);
1034     device.Close();
1035     {
1036         std::lock_guard<std::mutex> devicesLock(devicesMutex_);
1037         closingDevices_.push_back(std::move(devices_[device.path]));
1038         devices_.erase(device.path);
1039     }
1040 }
1041 
CloseDeviceForAllLocked(Device & device)1042 void InputHub::CloseDeviceForAllLocked(Device &device)
1043 {
1044     DHLOGI("Removed device: path=%{public}s name=%{public}s fd=%{public}d classes=0x%{public}x",
1045         device.path.c_str(), device.identifier.name.c_str(), device.fd, device.classes);
1046 
1047     UnregisterDeviceFromEpollLocked(device);
1048     device.Close();
1049     closingDevices_.push_back(std::move(devices_[device.path]));
1050     devices_.erase(device.path);
1051 }
1052 
UnregisterDeviceFromEpollLocked(const Device & device) const1053 int32_t InputHub::UnregisterDeviceFromEpollLocked(const Device &device) const
1054 {
1055     if (device.HasValidFd()) {
1056         int32_t result = UnregisterFdFromEpoll(device.fd);
1057         if (result != DH_SUCCESS) {
1058             DHLOGE("Could not remove input device fd from epoll for device, path: %{public}s", device.path.c_str());
1059             return result;
1060         }
1061     }
1062     return DH_SUCCESS;
1063 }
1064 
UnregisterFdFromEpoll(int fd) const1065 int32_t InputHub::UnregisterFdFromEpoll(int fd) const
1066 {
1067     if (epoll_ctl(epollFd_, EPOLL_CTL_DEL, fd, nullptr)) {
1068         DHLOGE("Could not remove fd from epoll instance: %{public}s", ConvertErrNo().c_str());
1069         return ERR_DH_INPUT_HUB_UNREGISTER_FD_FAIL;
1070     }
1071     return DH_SUCCESS;
1072 }
1073 
ReadNotifyLocked()1074 int32_t InputHub::ReadNotifyLocked()
1075 {
1076     size_t res;
1077     char eventBuf[EVENT_BUFFER_MAX] = {0};
1078     struct inotify_event *event;
1079 
1080     DHLOGI("readNotify nfd: %{public}d\n", iNotifyFd_);
1081     res = static_cast<size_t>(read(iNotifyFd_, eventBuf, sizeof(eventBuf)));
1082     if (res < sizeof(*event)) {
1083         if (errno == EINTR) {
1084             return DH_SUCCESS;
1085         }
1086         DHLOGE("could not get event, %{public}s\n", ConvertErrNo().c_str());
1087         return ERR_DH_INPUT_HUB_GET_EVENT_FAIL;
1088     }
1089 
1090     {
1091         size_t eventSize = 0;
1092         size_t eventPos = 0;
1093         while (res >= sizeof(*event) && eventPos < static_cast<size_t>(EVENT_BUFFER_MAX)) {
1094             event = reinterpret_cast<struct inotify_event *>(eventBuf + eventPos);
1095             JudgeDeviceOpenOrClose(*event);
1096             eventSize = sizeof(*event) + event->len;
1097             res -= eventSize;
1098             eventPos += eventSize;
1099         }
1100     }
1101     return DH_SUCCESS;
1102 }
1103 
JudgeDeviceOpenOrClose(const inotify_event & event)1104 void InputHub::JudgeDeviceOpenOrClose(const inotify_event &event)
1105 {
1106     if (event.len) {
1107         if (event.wd == inputWd_) {
1108             std::string filename = std::string(DEVICE_PATH) + "/" + event.name;
1109             if (event.mask & IN_CREATE) {
1110                 OpenInputDeviceLocked(filename);
1111             } else {
1112                 DHLOGI("Removing device '%{public}s' due to inotify event\n", filename.c_str());
1113                 CloseDeviceByPathLocked(filename);
1114             }
1115         } else {
1116             DHLOGI("Unexpected inotify event, wd = %i", event.wd);
1117         }
1118     }
1119 }
1120 
CloseDeviceByPathLocked(const std::string & devicePath)1121 void InputHub::CloseDeviceByPathLocked(const std::string &devicePath)
1122 {
1123     Device* device = GetDeviceByPathLocked(devicePath);
1124     if (device) {
1125         CloseDeviceLocked(*device);
1126         return;
1127     }
1128     DHLOGI("Remove device: %{public}s not found, device may already have been removed.", devicePath.c_str());
1129 }
1130 
CloseAllDevicesLocked()1131 void InputHub::CloseAllDevicesLocked()
1132 {
1133     DHLOGI("Close All Devices");
1134     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1135     while (!devices_.empty()) {
1136         CloseDeviceForAllLocked(*(devices_.begin()->second));
1137     }
1138 }
1139 
GetDeviceByPathLocked(const std::string & devicePath)1140 InputHub::Device* InputHub::GetDeviceByPathLocked(const std::string &devicePath)
1141 {
1142     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1143     for (const auto &[id, device] : devices_) {
1144         if (device->path == devicePath) {
1145             return device.get();
1146         }
1147     }
1148     return nullptr;
1149 }
1150 
GetDeviceByFdLocked(int fd)1151 InputHub::Device* InputHub::GetDeviceByFdLocked(int fd)
1152 {
1153     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1154     for (const auto &[id, device] : devices_) {
1155         if (device->fd == fd) {
1156             return device.get();
1157         }
1158     }
1159     return nullptr;
1160 }
1161 
GetSupportDeviceByFd(int fd)1162 InputHub::Device* InputHub::GetSupportDeviceByFd(int fd)
1163 {
1164     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1165     for (const auto &[id, device] : devices_) {
1166         if (device != nullptr && device->fd == fd) {
1167             return device.get();
1168         }
1169     }
1170     return nullptr;
1171 }
1172 
ContainsNonZeroByte(const uint8_t * array,uint32_t startIndex,uint32_t endIndex)1173 bool InputHub::ContainsNonZeroByte(const uint8_t *array, uint32_t startIndex, uint32_t endIndex)
1174 {
1175     const uint8_t* end = array + endIndex;
1176     array += startIndex;
1177     while (array != end) {
1178         if (*(array++) != 0) {
1179             return true;
1180         }
1181     }
1182     return false;
1183 }
1184 
ProcessEventTimestamp(const input_event & event)1185 int64_t InputHub::ProcessEventTimestamp(const input_event &event)
1186 {
1187     const int64_t inputEventTime = event.input_event_sec * 1000000000LL + event.input_event_usec * 1000LL;
1188     return inputEventTime;
1189 }
1190 
TestBit(uint32_t bit,const uint8_t * array)1191 bool InputHub::TestBit(uint32_t bit, const uint8_t *array)
1192 {
1193     constexpr int units = 8;
1194     return (array)[(bit) / units] & (1 << ((bit) % units));
1195 }
1196 
SizeofBitArray(uint32_t bit)1197 uint32_t InputHub::SizeofBitArray(uint32_t bit)
1198 {
1199     constexpr int round = 7;
1200     constexpr int divisor = 8;
1201     return ((bit) + round) / divisor;
1202 }
1203 
SaveAffectDhId(bool isEnable,const std::string & dhId,AffectDhIds & affDhIds)1204 void InputHub::SaveAffectDhId(bool isEnable, const std::string &dhId, AffectDhIds &affDhIds)
1205 {
1206     if (isEnable) {
1207         affDhIds.sharingDhIds.push_back(dhId);
1208     } else {
1209         affDhIds.noSharingDhIds.push_back(dhId);
1210     }
1211 }
1212 
SetSupportInputType(bool enabled,const uint32_t & inputTypes)1213 AffectDhIds InputHub::SetSupportInputType(bool enabled, const uint32_t &inputTypes)
1214 {
1215     AffectDhIds affDhIds;
1216     inputTypes_ = inputTypes;
1217     DHLOGI("SetSupportInputType: inputTypes=0x%x,", inputTypes_.load());
1218     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1219     for (const auto &[id, device] : devices_) {
1220         if (device->classes & inputTypes_) {
1221             device->isShare = enabled;
1222             DHLOGW("ByType dhid:%{public}s, isshare:%{public}d",
1223                 GetAnonyString(device->identifier.descriptor).c_str(), enabled);
1224             SaveAffectDhId(enabled, device->identifier.descriptor, affDhIds);
1225         }
1226     }
1227 
1228     return affDhIds;
1229 }
1230 
SetSharingDevices(bool enabled,std::vector<std::string> dhIds)1231 AffectDhIds InputHub::SetSharingDevices(bool enabled, std::vector<std::string> dhIds)
1232 {
1233     AffectDhIds affDhIds;
1234     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1235     DHLOGI("SetSharingDevices start");
1236     for (auto dhId : dhIds) {
1237         DHLOGI("SetSharingDevices dhId: %{public}s, size: %{public}zu, enabled: %{public}d",
1238             GetAnonyString(dhId).c_str(), devices_.size(), enabled);
1239         sharedDHIds_[dhId] = enabled;
1240         for (const auto &[id, device] : devices_) {
1241             DHLOGI("deviceName %{public}s ,dhId: %{public}s ", device->identifier.name.c_str(),
1242                 GetAnonyString(device->identifier.descriptor).c_str());
1243             if (device->identifier.descriptor == dhId) {
1244                 device->isShare = enabled;
1245                 DHLOGW("dhid:%{public}s, isshare:%{public}d",
1246                     GetAnonyString(device->identifier.descriptor).c_str(), enabled);
1247                 SaveAffectDhId(enabled, device->identifier.descriptor, affDhIds);
1248                 break;
1249             }
1250         }
1251     }
1252     DHLOGI("SetSharingDevices end");
1253     return affDhIds;
1254 }
1255 
GetSharingDevices()1256 std::vector<std::string> InputHub::GetSharingDevices()
1257 {
1258     std::vector<std::string> sharingDevices;
1259     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1260     for (const auto &[id, device] : devices_) {
1261         if (device->isShare) {
1262             DHLOGI("Find sharing dhid: %{public}s", GetAnonyString(device->identifier.descriptor).c_str());
1263             sharingDevices.push_back(device->identifier.descriptor);
1264         }
1265     }
1266     return sharingDevices;
1267 }
1268 
GetSharedMousePathByDhId(const std::vector<std::string> & dhIds,std::string & sharedMousePath,std::string & sharedMouseDhId)1269 void InputHub::GetSharedMousePathByDhId(const std::vector<std::string> &dhIds, std::string &sharedMousePath,
1270     std::string &sharedMouseDhId)
1271 {
1272     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1273     DHLOGI("GetSharedMousePathByDhId: devices_.size:%{public}zu,", devices_.size());
1274     for (const auto &dhId : dhIds) {
1275         for (const auto &[id, device] : devices_) {
1276             if (device == nullptr) {
1277                 DHLOGE("device is nullptr");
1278                 continue;
1279             }
1280             DHLOGI("descriptor:%{public}s, isShare[%{public}d], type[%{public}d]",
1281                 GetAnonyString(device->identifier.descriptor).c_str(), device->isShare, device->classes);
1282             if ((device->identifier.descriptor == dhId) && ((device->classes & INPUT_DEVICE_CLASS_CURSOR) != 0 ||
1283                 (device->classes & INPUT_DEVICE_CLASS_TOUCH) != 0 ||
1284                 ((device->classes & INPUT_DEVICE_CLASS_TOUCH_MT) != 0 && IsTouchPad(device->identifier)))) {
1285                 sharedMouseDhId = dhId;
1286                 sharedMousePath = device->path;
1287                 return; // return First shared mouse
1288             }
1289         }
1290     }
1291 }
1292 
GetSharedKeyboardPathsByDhIds(const std::vector<std::string> & dhIds,std::vector<std::string> & sharedKeyboardPaths,std::vector<std::string> & sharedKeyboardDhIds)1293 void InputHub::GetSharedKeyboardPathsByDhIds(const std::vector<std::string> &dhIds,
1294     std::vector<std::string> &sharedKeyboardPaths, std::vector<std::string> &sharedKeyboardDhIds)
1295 {
1296     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1297     DHLOGI("GetSharedKeyboardPathsByDhIds: devices_.size:%{public}zu,", devices_.size());
1298     for (const auto &dhId : dhIds) {
1299         for (const auto &[id, device] : devices_) {
1300             if (device == nullptr) {
1301                 DHLOGE("device is nullptr");
1302                 continue;
1303             }
1304             DHLOGI("descriptor:%{public}s, isShare[%{public}d], type[%{public}d]",
1305                 GetAnonyString(device->identifier.descriptor).c_str(), device->isShare, device->classes);
1306             if ((device->identifier.descriptor == dhId) &&
1307                 ((device->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0)) {
1308                 sharedKeyboardDhIds.push_back(dhId);
1309                 sharedKeyboardPaths.push_back(device->path);
1310             }
1311         }
1312     }
1313 }
1314 
GetDevicesInfoByType(const uint32_t inputTypes,std::map<int32_t,std::string> & datas)1315 void InputHub::GetDevicesInfoByType(const uint32_t inputTypes, std::map<int32_t, std::string> &datas)
1316 {
1317     uint32_t dhType = 0;
1318 
1319     if ((inputTypes & static_cast<uint32_t>(DInputDeviceType::MOUSE)) != 0) {
1320         dhType |= INPUT_DEVICE_CLASS_CURSOR;
1321     }
1322 
1323     if ((inputTypes & static_cast<uint32_t>(DInputDeviceType::KEYBOARD)) != 0) {
1324         dhType |= INPUT_DEVICE_CLASS_KEYBOARD;
1325     }
1326 
1327     if ((inputTypes & static_cast<uint32_t>(DInputDeviceType::TOUCHSCREEN)) != 0) {
1328         dhType |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT;
1329     }
1330 
1331     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1332     for (const auto &[id, device] : devices_) {
1333         if (device->classes & dhType) {
1334             datas.insert(std::pair<int32_t, std::string>(device->fd, device->identifier.descriptor));
1335         }
1336     }
1337 }
1338 
GetDevicesInfoByDhId(std::vector<std::string> dhidsVec,std::map<int32_t,std::string> & datas)1339 void InputHub::GetDevicesInfoByDhId(std::vector<std::string> dhidsVec, std::map<int32_t, std::string> &datas)
1340 {
1341     for (auto dhId : dhidsVec) {
1342         std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1343         for (const auto &[id, device] : devices_) {
1344             if (device->identifier.descriptor == dhId) {
1345                 datas.insert(std::pair<int32_t, std::string>(device->fd, dhId));
1346             }
1347         }
1348     }
1349 }
1350 
IsAllDevicesStoped()1351 bool InputHub::IsAllDevicesStoped()
1352 {
1353     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1354     for (const auto &[dhId, isShared] : sharedDHIds_) {
1355         DHLOGI("the dhId: %{public}s, isShared: %{public}d", GetAnonyString(dhId).c_str(), isShared);
1356         if (isShared) {
1357             return false;
1358         }
1359     }
1360     return true;
1361 }
1362 
RecordDeviceLog(const std::string & devicePath,const InputDevice & identifier)1363 void InputHub::RecordDeviceLog(const std::string &devicePath, const InputDevice &identifier)
1364 {
1365     if (IsNeedPrintLog(identifier.descriptor)) {
1366         DHLOGI("add device: %{public}s\n", devicePath.c_str());
1367         DHLOGI("  bus:        %{public}04x\n"
1368                "  vendor      %{public}04x\n"
1369                "  product     %{public}04x\n"
1370                "  version     %{public}04x\n",
1371                identifier.bus, identifier.vendor, identifier.product, identifier.version);
1372         DHLOGI("  name:       \"%{public}s\"\n", identifier.name.c_str());
1373         DHLOGI("  physicalPath:   \"%{public}s\"\n", identifier.physicalPath.c_str());
1374         DHLOGI("  unique id:  \"%{public}s\"\n", identifier.uniqueId.c_str());
1375         DHLOGI("  descriptor: \"%{public}s\"\n", GetAnonyString(identifier.descriptor).c_str());
1376     }
1377 }
1378 
RecordChangeEventLog(const RawEvent & event)1379 void InputHub::RecordChangeEventLog(const RawEvent &event)
1380 {
1381     std::string eventType = "";
1382     switch (event.type) {
1383         case EV_KEY:
1384             eventType = "EV_KEY";
1385             break;
1386         case EV_REL:
1387             eventType = "EV_REL";
1388             break;
1389         case EV_ABS:
1390             eventType = "EV_ABS";
1391             break;
1392         case EV_SYN:
1393             eventType = "EV_SYN";
1394             break;
1395         default:
1396             eventType = "other type " + std::to_string(event.type);
1397             break;
1398     }
1399     DHLOGI("0.E2E-Test Sink collect change event, EventType: %{public}s, Code: %{public}d, Value: %{public}d, "
1400         "Path: %{public}s, descriptor: %{public}s, When: %{public}" PRId64 "", eventType.c_str(), event.code,
1401         event.value, event.path.c_str(), GetAnonyString(event.descriptor).c_str(), event.when);
1402 }
1403 
RecordEventLog(const RawEvent * event)1404 void InputHub::RecordEventLog(const RawEvent *event)
1405 {
1406     std::string eventType = "";
1407     switch (event->type) {
1408         case EV_KEY:
1409             eventType = "EV_KEY";
1410             break;
1411         case EV_REL:
1412             eventType = "EV_REL";
1413             break;
1414         case EV_ABS:
1415             eventType = "EV_ABS";
1416             break;
1417         case EV_SYN:
1418             eventType = "EV_SYN";
1419             break;
1420         default:
1421             eventType = "other type " + std::to_string(event->type);
1422             break;
1423     }
1424     DHLOGD("1.E2E-Test Sink collect event, EventType: %{public}s, Code: %{public}d, Value: %{public}d, "
1425         "Path: %{public}s, descriptor: %{public}s, When: %{public}" PRId64 "", eventType.c_str(), event->code,
1426         event->value, event->path.c_str(), GetAnonyString(event->descriptor).c_str(), event->when);
1427 }
1428 
HandleTouchScreenEvent(struct input_event readBuffer[],const size_t count,std::vector<bool> & needFilted)1429 void InputHub::HandleTouchScreenEvent(struct input_event readBuffer[], const size_t count,
1430     std::vector<bool> &needFilted)
1431 {
1432     std::vector<std::pair<size_t, size_t>> absIndexs;
1433     int32_t firstIndex = -1;
1434     int32_t lastIndex = -1;
1435 
1436     for (size_t i = 0; i < count; i++) {
1437         struct input_event& iev = readBuffer[i];
1438         if ((iev.type == EV_ABS) && (iev.code == ABS_X || iev.code == ABS_MT_POSITION_X)) {
1439             firstIndex = static_cast<int32_t>(i);
1440         } else if (iev.type  == EV_SYN) {
1441             lastIndex = static_cast<int32_t>(i);
1442         }
1443         if ((firstIndex >= 0) && (lastIndex > firstIndex)) {
1444             absIndexs.emplace_back(std::make_pair((size_t)firstIndex, (size_t)lastIndex));
1445         }
1446     }
1447 
1448     AbsInfo absInfo = {
1449         .absX = 0,
1450         .absY = 0,
1451         .absXIndex = -1,
1452         .absYIndex = -1,
1453     };
1454     for (auto iter : absIndexs) {
1455         absInfo.absXIndex = -1;
1456         absInfo.absYIndex = -1;
1457 
1458         for (size_t j = iter.first; j <= iter.second; j++) {
1459             struct input_event &iev = readBuffer[j];
1460             if (iev.code == ABS_X || iev.code == ABS_MT_POSITION_X) {
1461                 absInfo.absX = static_cast<uint32_t>(iev.value);
1462                 absInfo.absXIndex = static_cast<int32_t>(j);
1463             }
1464             if (iev.code == ABS_Y || iev.code == ABS_MT_POSITION_Y) {
1465                 absInfo.absY = static_cast<uint32_t>(iev.value);
1466                 absInfo.absYIndex = static_cast<int32_t>(j);
1467             }
1468         }
1469 
1470         if ((absInfo.absXIndex < 0) || (absInfo.absYIndex < 0)) {
1471             for (size_t j = iter.first; j <= iter.second; j++) {
1472                 needFilted[j] = true;
1473             }
1474             continue;
1475         }
1476         if (!CheckTouchPointRegion(readBuffer, absInfo)) {
1477             for (size_t j = iter.first; j <= iter.second; j++) {
1478                 needFilted[j] = true;
1479             }
1480         }
1481     }
1482 }
1483 
CheckTouchPointRegion(struct input_event readBuffer[],const AbsInfo & absInfo)1484 bool InputHub::CheckTouchPointRegion(struct input_event readBuffer[], const AbsInfo &absInfo)
1485 {
1486     auto sinkInfos = DInputContext::GetInstance().GetAllSinkScreenInfo();
1487 
1488     for (const auto &[id, sinkInfo] : sinkInfos) {
1489         auto info = sinkInfo.transformInfo;
1490         if ((absInfo.absX >= info.sinkWinPhyX) && (absInfo.absX <= (info.sinkWinPhyX + info.sinkProjPhyWidth))
1491             && (absInfo.absY >= info.sinkWinPhyY) && (absInfo.absY <= (info.sinkWinPhyY + info.sinkProjPhyHeight))) {
1492             touchDescriptor = sinkInfo.srcScreenInfo.sourcePhyId;
1493             readBuffer[absInfo.absXIndex].value = (absInfo.absX - info.sinkWinPhyX) * info.coeffWidth;
1494             readBuffer[absInfo.absYIndex].value = (absInfo.absY - info.sinkWinPhyY) * info.coeffHeight;
1495             return true;
1496         }
1497     }
1498     return false;
1499 }
1500 
CollectTargetDevices()1501 std::vector<InputHub::Device*> InputHub::CollectTargetDevices()
1502 {
1503     std::lock_guard<std::mutex> deviceLock(devicesMutex_);
1504     std::vector<InputHub::Device*> tarVec;
1505     for (const auto &dev : devices_) {
1506         if (((dev.second->classes & INPUT_DEVICE_CLASS_TOUCH) != 0) ||
1507             ((dev.second->classes & INPUT_DEVICE_CLASS_TOUCH_MT) != 0) ||
1508             ((dev.second->classes & INPUT_DEVICE_CLASS_CURSOR) != 0) ||
1509             ((dev.second->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0)) {
1510             DHLOGI("Find target devs need check stat, path: %{public}s, name: %{public}s",
1511                 dev.first.c_str(), dev.second->identifier.name.c_str());
1512             tarVec.push_back(dev.second.get());
1513         }
1514     }
1515 
1516     return tarVec;
1517 }
1518 
SavePressedKeyState(const InputHub::Device * dev,int32_t keyCode)1519 void InputHub::SavePressedKeyState(const InputHub::Device *dev, int32_t keyCode)
1520 {
1521     struct RawEvent event = {
1522         .type = EV_KEY,
1523         .code = keyCode,
1524         .value = KEY_DOWN_STATE,
1525         .descriptor = dev->identifier.descriptor,
1526         .path = dev->path
1527     };
1528     DInputSinkState::GetInstance().AddKeyDownState(event);
1529     DHLOGI("Find Pressed key: %{public}d, device path: %{public}s, dhId: %{public}s", keyCode, dev->path.c_str(),
1530         GetAnonyString(dev->identifier.descriptor).c_str());
1531 }
1532 
IsLengthExceeds(const unsigned long * keyState,const unsigned long len,int keyIndex)1533 bool InputHub::IsLengthExceeds(const unsigned long *keyState, const unsigned long len, int keyIndex)
1534 {
1535     if (len < (keyIndex / LONG_BITS) + 1) {
1536         DHLOGE("Length exceeds for key index: %{public}d", keyIndex);
1537         return true;
1538     }
1539     return false;
1540 }
1541 
CheckTargetKeyState(const InputHub::Device * dev,const unsigned long * keyState,const unsigned long len)1542 void InputHub::CheckTargetKeyState(const InputHub::Device *dev, const unsigned long *keyState, const unsigned long len)
1543 {
1544     // If device is a mouse, record the mouse pressed key.
1545     if ((dev->classes & INPUT_DEVICE_CLASS_CURSOR) != 0) {
1546         if (IsLengthExceeds(keyState, len, BTN_LEFT)) {
1547             return;
1548         }
1549         int mouseLeftBtnState = BitIsSet(keyState, BTN_LEFT);
1550         if (mouseLeftBtnState != 0) {
1551             SavePressedKeyState(dev, BTN_LEFT);
1552         }
1553         if (IsLengthExceeds(keyState, len, BTN_RIGHT)) {
1554             return;
1555         }
1556         int mouseRightBtnState = BitIsSet(keyState, BTN_RIGHT);
1557         if (mouseRightBtnState != 0) {
1558             SavePressedKeyState(dev, BTN_RIGHT);
1559         }
1560         if (IsLengthExceeds(keyState, len, BTN_MIDDLE)) {
1561             return;
1562         }
1563         int mouseMidBtnState = BitIsSet(keyState, BTN_MIDDLE);
1564         if (mouseMidBtnState != 0) {
1565             SavePressedKeyState(dev, BTN_MIDDLE);
1566         }
1567     }
1568 
1569     // If device is a keyboard, record all the pressed keys.
1570     if ((dev->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0) {
1571         for (int32_t keyIndex = 0; keyIndex < KEY_MAX; keyIndex++) {
1572             if (IsLengthExceeds(keyState, len, keyIndex)) {
1573                 return;
1574             }
1575             if (BitIsSet(keyState, keyIndex) != 0) {
1576                 SavePressedKeyState(dev, keyIndex);
1577             }
1578         }
1579     }
1580 
1581     // If device is a touchscreen or touchpad, record the touch event.
1582     if ((dev->classes & INPUT_DEVICE_CLASS_TOUCH) != 0 || (dev->classes & INPUT_DEVICE_CLASS_TOUCH_MT) != 0) {
1583         if (IsLengthExceeds(keyState, len, BTN_TOUCH)) {
1584             return;
1585         }
1586         int btnTouchState = BitIsSet(keyState, BTN_TOUCH);
1587         if (btnTouchState != 0) {
1588             SavePressedKeyState(dev, BTN_TOUCH);
1589         }
1590     }
1591 }
1592 
1593 
CheckTargetDevicesState(std::vector<InputHub::Device * > targetDevices)1594 void InputHub::CheckTargetDevicesState(std::vector<InputHub::Device*> targetDevices)
1595 {
1596     uint32_t count = 0;
1597     unsigned long keyState[NLONGS(KEY_CNT)] = { 0 };
1598     for (const auto *dev : targetDevices) {
1599         while (true) {
1600             if (count > READ_RETRY_MAX) {
1601                 break;
1602             }
1603             // Query all key state
1604             int rc = ioctl(dev->fd, EVIOCGKEY(sizeof(keyState)), keyState);
1605             if (rc < 0) {
1606                 DHLOGE("read all key state failed, rc=%{public}d", rc);
1607                 count += 1;
1608                 std::this_thread::sleep_for(std::chrono::milliseconds(READ_SLEEP_TIME_MS));
1609                 continue;
1610             }
1611             CheckTargetKeyState(dev, keyState, NLONGS(KEY_CNT));
1612             break;
1613         }
1614     }
1615 }
1616 
RecordDeviceStates()1617 void InputHub::RecordDeviceStates()
1618 {
1619     DHLOGI("Start Record keys states");
1620     ScanAndRecordInputDevices();
1621     std::vector<InputHub::Device*> tarDevices = CollectTargetDevices();
1622     DHLOGI("Check target states device num: %{public}zu", tarDevices.size());
1623     CheckTargetDevicesState(tarDevices);
1624     DHLOGI("Finish Record Keys states");
1625 }
1626 
ClearDeviceStates()1627 void InputHub::ClearDeviceStates()
1628 {
1629     DHLOGI("Clear Device state");
1630     DInputSinkState::GetInstance().ClearDeviceStates();
1631 }
1632 
ClearSkipDevicePaths()1633 void InputHub::ClearSkipDevicePaths()
1634 {
1635     DHLOGI("Clear Skip device path");
1636     std::lock_guard<std::mutex> lock(skipDevicePathsMutex_);
1637     skipDevicePaths_.clear();
1638 }
1639 
Device(int fd,const std::string & path)1640 InputHub::Device::Device(int fd, const std::string &path)
1641     : next(nullptr), fd(fd), path(path), identifier({}), classes(0), enabled(false),
1642       isShare(false), isVirtual(fd < 0) {
1643     // Figure out the kinds of events the device reports.
1644     DHLOGI("Ctor Device for get event mask, fd: %{public}d, path: %{public}s", fd, path.c_str());
1645     ioctl(fd, EVIOCGBIT(0, sizeof(evBitmask)), evBitmask);
1646     ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keyBitmask)), keyBitmask);
1647     ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absBitmask)), absBitmask);
1648     ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relBitmask)), relBitmask);
1649 }
1650 
~Device()1651 InputHub::Device::~Device()
1652 {
1653     Close();
1654 }
1655 
Close()1656 void InputHub::Device::Close()
1657 {
1658     if (fd >= 0) {
1659         ::close(fd);
1660         fd = UN_INIT_FD_VALUE;
1661     }
1662 }
1663 
Enable()1664 int32_t InputHub::Device::Enable()
1665 {
1666     char canonicalPath[PATH_MAX + 1] = {0x00};
1667 
1668     if (path.length() == 0 || path.length() > PATH_MAX || realpath(path.c_str(), canonicalPath) == nullptr) {
1669         DHLOGE("path check fail, error path: %{public}s", path.c_str());
1670         return ERR_DH_INPUT_HUB_DEVICE_ENABLE_FAIL;
1671     }
1672     fd = open(canonicalPath, O_RDWR | O_CLOEXEC | O_NONBLOCK);
1673     if (fd < 0) {
1674         DHLOGE("could not open %{public}s, %{public}s\n", path.c_str(), ConvertErrNo().c_str());
1675         return ERR_DH_INPUT_HUB_DEVICE_ENABLE_FAIL;
1676     }
1677     enabled = true;
1678     return DH_SUCCESS;
1679 }
1680 
Disable()1681 int32_t InputHub::Device::Disable()
1682 {
1683     Close();
1684     enabled = false;
1685     return DH_SUCCESS;
1686 }
1687 
HasValidFd() const1688 bool InputHub::Device::HasValidFd() const
1689 {
1690     return !isVirtual && enabled;
1691 }
1692 } // namespace DistributedInput
1693 } // namespace DistributedHardware
1694 } // namespace OHOS
1695