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