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