1/* 2 * Copyright (c) 2022 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_device_manager.h" 17#include <algorithm> 18#include <cstdio> 19#include <cstdlib> 20#include <cstring> 21#include <dirent.h> 22#include <fcntl.h> 23#include <fstream> 24#include <functional> 25#include <future> 26#include <iostream> 27#include <memory> 28#include <sstream> 29#include <sys/epoll.h> 30#include <sys/inotify.h> 31#include <sys/ioctl.h> 32#include <unistd.h> 33#include <vector> 34#include "input_uhdf_log.h" 35#include "osal_mem.h" 36#include "securec.h" 37 38#define HDF_LOG_TAG InputDeviceHdiManager 39 40namespace OHOS { 41namespace Input { 42using namespace std; 43constexpr uint32_t DEV_INDEX_MAX = 32; 44void InputDeviceManager::Init() 45{ 46 inputDevList_.clear(); 47 reportEventPkgCallBackLock_.lock(); 48 reportEventPkgCallback_.clear(); 49 reportEventPkgCallBackLock_.unlock(); 50 GetInputDeviceInfoList(); 51 std::thread t1([this] {this->WorkerThread();}); 52 std::string wholeName1 = std::to_string(getpid()) + "_" + std::to_string(gettid()); 53 thread_ = std::move(t1); 54 thread_.detach(); 55 for (auto &inputDev : inputDevList_) { 56 dumpInfoList(inputDev.second); 57 } 58} 59 60static void FreeEventPkgs(InputEventPackage **eventPkgs, size_t count) 61{ 62 for (size_t i = 0; i < count; i++) { 63 if (eventPkgs[i] != NULL) { 64 OsalMemFree(eventPkgs[i]); 65 eventPkgs[i] = nullptr; 66 } 67 } 68 return; 69} 70 71// get the nodefile list 72vector<string> InputDeviceManager::GetFiles(string path) 73{ 74 vector<string> fileList; 75 struct dirent *dEnt = nullptr; 76 77 DIR *dir = opendir(path.c_str()); 78 if (dir == nullptr) { 79 HDF_LOGE("%{public}s: no files", __func__); 80 return fileList; 81 } 82 string sDot = "."; 83 string sDotDot = ".."; 84 while ((dEnt = readdir(dir)) != nullptr) { 85 if ((string(dEnt->d_name) != sDot) && 86 (string(dEnt->d_name) != sDotDot)) { 87 if (dEnt->d_type != DT_DIR) { 88 string d_name(dEnt->d_name); 89 fileList.push_back(string(dEnt->d_name)); 90 } 91 } 92 } 93 // sort the returned files 94 sort(fileList.begin(), fileList.end()); 95 closedir(dir); 96 return fileList; 97} 98 99void InputDeviceManager::ReportEventPkg(int32_t iFd, InputEventPackage **iEvtPkg, size_t iCount) 100{ 101 if (iEvtPkg == nullptr) { 102 HDF_LOGE("%{public}s: param invalid, line: %{public}d", __func__, __LINE__); 103 return; 104 } 105 std::lock_guard<std::mutex> guard(reportEventPkgCallBackLock_); 106 for (auto &callbackFunc : reportEventPkgCallback_) { 107 uint32_t index {0}; 108 auto ret = FindIndexFromFd(iFd, &index); 109 if (callbackFunc.second != nullptr && ret != INPUT_FAILURE) { 110 callbackFunc.second->EventPkgCallback(const_cast<const InputEventPackage **>(iEvtPkg), iCount, index); 111 } 112 } 113 return; 114} 115 116int32_t CheckReadResult(int32_t readResult) 117{ 118 if (readResult == 0 || (readResult < 0 && errno == ENODEV)) { 119 return INPUT_FAILURE; 120 } 121 if (readResult < 0) { 122 if (errno != EAGAIN && errno != EINTR) { 123 HDF_LOGE("%{public}s: could not get event (errno = %{public}d)", __func__, errno); 124 } 125 return INPUT_FAILURE; 126 } 127 if ((readResult % sizeof(struct input_event)) != 0) { 128 HDF_LOGE("%{public}s: could not get one event size %{public}lu readResult size: %{public}d", __func__, 129 sizeof(struct input_event), readResult); 130 return INPUT_FAILURE; 131 } 132 return INPUT_SUCCESS; 133} 134 135// read action 136void InputDeviceManager::DoRead(int32_t fd, struct input_event *event, size_t size) 137{ 138 int32_t readLen = read(fd, event, sizeof(struct input_event) * size); 139 if (CheckReadResult(readLen) == INPUT_FAILURE) { 140 return; 141 } 142 size_t count = size_t(readLen) / sizeof(struct input_event); 143 InputEventPackage **evtPkg = (InputEventPackage **)OsalMemAlloc(sizeof(InputEventPackage *) * count); 144 if (evtPkg == nullptr) { 145 HDF_LOGE("%{public}s: OsalMemAlloc failed, line: %{public}d", __func__, __LINE__); 146 return; 147 } 148 for (size_t i = 0; i < count; i++) { 149 struct input_event &iEvent = event[i]; 150 // device action events happened 151 *(evtPkg + i) = (InputEventPackage *)OsalMemAlloc(sizeof(InputEventPackage)); 152 if (evtPkg[i] == nullptr) { 153 HDF_LOGE("%{public}s: OsalMemAlloc failed, line: %{public}d", __func__, __LINE__); 154 FreeEventPkgs(evtPkg, i); 155 OsalMemFree(evtPkg); 156 evtPkg = nullptr; 157 return; 158 } 159 evtPkg[i]->type = iEvent.type; 160 evtPkg[i]->code = iEvent.code; 161 evtPkg[i]->value = iEvent.value; 162 evtPkg[i]->timestamp = (uint64_t)iEvent.time.tv_sec * MS_THOUSAND * MS_THOUSAND + 163 (uint64_t)iEvent.time.tv_usec; 164 } 165 ReportEventPkg(fd, evtPkg, count); 166 for (size_t i = 0; i < count; i++) { 167 OsalMemFree(evtPkg[i]); 168 evtPkg[i] = nullptr; 169 } 170 OsalMemFree(evtPkg); 171 evtPkg = nullptr; 172} 173 174// open input device node 175int32_t InputDeviceManager::OpenInputDevice(string devPath) 176{ 177 char devRealPath[PATH_MAX + 1] = { '\0' }; 178 if (realpath(devPath.c_str(), devRealPath) == nullptr) { 179 HDF_LOGE("%{public}s: The absolute path does not exist.", __func__); 180 return INPUT_FAILURE; 181 } 182 183 int32_t nodeFd = open(devRealPath, O_RDWR | O_CLOEXEC | O_NONBLOCK); 184 if (nodeFd < 0) { 185 HDF_LOGE("%{public}s: could not open %{public}s, %{public}d %{public}s", __func__, 186 devRealPath, errno, strerror(errno)); 187 return INPUT_FAILURE; 188 } 189 return nodeFd; 190} 191 192// close input device node 193RetStatus InputDeviceManager::CloseInputDevice(string devPath) 194{ 195 for (auto &inputDev : inputDevList_) { 196 if (string(inputDev.second.devPathNode) == devPath) { 197 int32_t fd = inputDev.second.fd; 198 if (fd > 0) { 199 RemoveEpoll(mEpollId_, fd); 200 close(fd); 201 inputDev.second.fd = -1; 202 inputDev.second.status = INPUT_DEVICE_STATUS_CLOSED; 203 return INPUT_SUCCESS; 204 } 205 } 206 } 207 // device list remove this node 208 return INPUT_FAILURE; 209} 210 211int32_t InputDeviceManager::GetInputDeviceInfo(int32_t fd, InputDeviceInfo *detailInfo) 212{ 213 char buffer[DEVICE_INFO_SIZE] {}; 214 struct input_id inputId {}; 215 // get the abilitys. 216 (void)ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(detailInfo->abilitySet.keyCode)), &detailInfo->abilitySet.keyCode); 217 (void)ioctl(fd, EVIOCGBIT(EV_REL, sizeof(detailInfo->abilitySet.relCode)), &detailInfo->abilitySet.relCode); 218 (void)ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(detailInfo->abilitySet.absCode)), &detailInfo->abilitySet.absCode); 219 (void)ioctl(fd, EVIOCGBIT(EV_MSC, sizeof(detailInfo->abilitySet.miscCode)), &detailInfo->abilitySet.miscCode); 220 (void)ioctl(fd, EVIOCGBIT(EV_SW, sizeof(detailInfo->abilitySet.switchCode)), &detailInfo->abilitySet.switchCode); 221 (void)ioctl(fd, EVIOCGBIT(EV_LED, sizeof(detailInfo->abilitySet.ledType)), &detailInfo->abilitySet.ledType); 222 (void)ioctl(fd, EVIOCGBIT(EV_SND, sizeof(detailInfo->abilitySet.soundCode)), &detailInfo->abilitySet.soundCode); 223 (void)ioctl(fd, EVIOCGBIT(EV_FF, sizeof(detailInfo->abilitySet.forceCode)), &detailInfo->abilitySet.forceCode); 224 // device name. 225 if (ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) { 226 HDF_LOGE("%{public}s: get device name failed errormsg %{public}s", __func__, strerror(errno)); 227 } else { 228 buffer[sizeof(buffer) - 1] = '\0'; 229 int32_t ret = strcpy_s(detailInfo->attrSet.devName, DEV_NAME_LEN, buffer); 230 if (ret) { 231 HDF_LOGE("%{public}s: strcpy_s failed, ret %{public}d", __func__, ret); 232 return INPUT_FAILURE; 233 } 234 } 235 // device detailInfo. 236 if (ioctl(fd, EVIOCGID, &inputId)) { 237 HDF_LOGE("%{public}s: get device input id errormsg %{public}s", __func__, strerror(errno)); 238 } 239 detailInfo->attrSet.id.busType = inputId.bustype; 240 detailInfo->attrSet.id.product = inputId.product; 241 detailInfo->attrSet.id.vendor = inputId.vendor; 242 detailInfo->attrSet.id.version = inputId.version; 243 // ABS Info 244 for (uint32_t i = 0; i < BITS_TO_UINT64(ABS_CNT); i++) { 245 if (detailInfo->abilitySet.absCode[i] > 0) { 246 if (ioctl(fd, EVIOCGABS(i), &detailInfo->attrSet.axisInfo[i])) { 247 HDF_LOGE("%{public}s: get axis info failed fd = %{public}d name = %{public}s errormsg = %{public}s", 248 __func__, fd, detailInfo->attrSet.devName, strerror(errno)); 249 continue; 250 } 251 } 252 } 253 return INPUT_SUCCESS; 254} 255 256uint32_t GetInputDeviceTypeInfo(const string &devName) 257{ 258 uint32_t type {INDEV_TYPE_UNKNOWN}; 259 if (devName.find("input_mt_wrapper") != std::string::npos) { 260 type = INDEV_TYPE_TOUCH; 261 } else if ((devName.find("Keyboard") != std::string::npos) && 262 (devName.find("Headset") == std::string::npos)) { 263 type = INDEV_TYPE_KEYBOARD; 264 } else if (devName.find("Mouse") != std::string::npos) { 265 type = INDEV_TYPE_MOUSE; 266 } else if ((devName.find("_gpio_key") != std::string::npos) || 267 (devName.find("ponkey_on") != std::string::npos)) { 268 type = INDEV_TYPE_KEY; 269 } else if (devName.find("Touchpad") != std::string::npos) { 270 type = INDEV_TYPE_TOUCHPAD; 271 } 272 return type; 273} 274 275void InputDeviceManager::GetInputDeviceInfoList(int32_t epollFd) 276{ 277 inputDevList_.clear(); 278 std::vector<std::string> flist = GetFiles(devPath_); 279 std::shared_ptr<InputDeviceInfo> detailInfo; 280 InputDevListNode inputDevList {}; 281 282 for (unsigned i = 0; i < flist.size(); i++) { 283 string devPathNode = devPath_ + "/" + flist[i]; 284 std::string::size_type n = devPathNode.find("event"); 285 if (n == std::string::npos) { 286 continue; 287 } 288 auto fd = OpenInputDevice(devPathNode); 289 if (fd < 0) { 290 HDF_LOGE("%{public}s: open node failed", __func__); 291 continue; 292 } 293 detailInfo = std::make_shared<InputDeviceInfo>(); 294 (void)memset_s(detailInfo.get(), sizeof(InputDeviceInfo), 0, sizeof(InputDeviceInfo)); 295 (void)GetInputDeviceInfo(fd, detailInfo.get()); 296 auto sDevName = string(detailInfo->attrSet.devName); 297 uint32_t type = GetInputDeviceTypeInfo(sDevName); 298 if (type == INDEV_TYPE_UNKNOWN) { 299 continue; 300 } 301 inputDevList.index = devIndex_; 302 inputDevList.status = INPUT_DEVICE_STATUS_OPENED; 303 inputDevList.fd = fd; 304 detailInfo->devIndex = devIndex_; 305 detailInfo->devType = type; 306 if (memcpy_s(&inputDevList.devPathNode, devPathNode.length(), 307 devPathNode.c_str(), devPathNode.length()) != EOK || 308 memcpy_s(&inputDevList.detailInfo, sizeof(InputDeviceInfo), detailInfo.get(), 309 sizeof(InputDeviceInfo)) != EOK) { 310 HDF_LOGE("%{public}s: memcpy_s failed, line: %{public}d", __func__, __LINE__); 311 return; 312 } 313 inputDevList_.insert_or_assign(devIndex_, inputDevList); 314 devIndex_ += 1; 315 } 316} 317 318int32_t InputDeviceManager::DoInputDeviceAction(void) 319{ 320 struct input_event evtBuffer[EVENT_BUFFER_SIZE] {}; 321 int32_t result = 0; 322 323 mEpollId_ = epoll_create1(EPOLL_CLOEXEC); 324 if (mEpollId_ == INPUT_FAILURE) { 325 HDF_LOGE("%{public}s: epoll create failed", __func__); 326 return mEpollId_; 327 } 328 mInotifyId_ = inotify_init(); 329 result = inotify_add_watch(mInotifyId_, devPath_.c_str(), IN_DELETE | IN_CREATE); 330 if (result == INPUT_FAILURE) { 331 HDF_LOGE("%{public}s: add file watch failed", __func__); 332 return result; 333 } 334 AddToEpoll(mEpollId_, mInotifyId_); 335 while (true) { 336 result = epoll_wait(mEpollId_, epollEventList_, EPOLL_MAX_EVENTS, EPOLL_WAIT_TIMEOUT); 337 if (result <= 0) { 338 continue; 339 } 340 for (int32_t i = 0; i < result; i++) { 341 if (epollEventList_[i].data.fd != mInotifyId_) { 342 DoRead(epollEventList_[i].data.fd, evtBuffer, EVENT_BUFFER_SIZE); 343 continue; 344 } 345 if (INPUT_FAILURE == InotifyEventHandler(mEpollId_, mInotifyId_)) { 346 HDF_LOGE("%{public}s: inotify handler failed", __func__); 347 return INPUT_FAILURE; 348 } 349 } 350 } 351 return INPUT_SUCCESS; 352} 353 354void InputDeviceManager::DeleteDevListNode(int index) 355{ 356 for (auto it = inputDevList_.begin(); it != inputDevList_.end();) { 357 if (it->first == (uint32_t)index) { 358 it = inputDevList_.erase(it); 359 if (devIndex_ < 1 || devIndex_ > DEV_INDEX_MAX) { 360 return; 361 } 362 devIndex_ -= 1; 363 } else { 364 ++it; 365 } 366 } 367 return; 368} 369 370int32_t InputDeviceManager::AddDeviceNodeToList( 371 int32_t &epollFd, int32_t &fd, string devPath, std::shared_ptr<InputDeviceInfo> &detailInfo) 372{ 373 if (epollFd < 0 || fd < 0) { 374 HDF_LOGE("%{public}s: param invalid, %{public}d", __func__, __LINE__); 375 return INPUT_FAILURE; 376 } 377 InputDevListNode inputDevList {}; 378 inputDevList.index = devIndex_; 379 inputDevList.status = INPUT_DEVICE_STATUS_OPENED; 380 inputDevList.fd = fd; 381 detailInfo->devIndex = devIndex_; 382 if (memcpy_s(inputDevList.devPathNode, devPath.length(), devPath.c_str(), devPath.length()) != EOK || 383 memcpy_s(&inputDevList.detailInfo, sizeof(InputDeviceInfo), detailInfo.get(), 384 sizeof(InputDeviceInfo)) != EOK) { 385 HDF_LOGE("%{public}s: memcpy_s failed, line: %{public}d", __func__, __LINE__); 386 return INPUT_FAILURE; 387 } 388 inputDevList_.insert_or_assign(devIndex_, inputDevList); 389 devIndex_ += 1; 390 if (AddToEpoll(epollFd, inputDevList.fd) != INPUT_SUCCESS) { 391 HDF_LOGE("%{public}s: add to epoll failed, line: %{public}d", __func__, __LINE__); 392 DeleteDevListNode(devIndex_); 393 return INPUT_FAILURE; 394 } 395 return INPUT_SUCCESS; 396} 397 398void InputDeviceManager::DoWithEventDeviceAdd(int32_t &epollFd, int32_t &fd, string devPath) 399{ 400 bool findDeviceFlag = false; 401 uint32_t type {}; 402 uint32_t index {}; 403 uint32_t status {}; 404 405 std::shared_ptr<InputDeviceInfo> detailInfo = std::make_shared<InputDeviceInfo>(); 406 (void)memset_s(detailInfo.get(), sizeof(InputDeviceInfo), 0, sizeof(InputDeviceInfo)); 407 (void)GetInputDeviceInfo(fd, detailInfo.get()); 408 auto sDevName = string(detailInfo->attrSet.devName); 409 for (auto it = inputDevList_.begin(); it != inputDevList_.end();) { 410 if (string(it->second.detailInfo.attrSet.devName) == sDevName) { 411 it->second.fd = fd; 412 it->second.status = INPUT_DEVICE_STATUS_OPENED; 413 findDeviceFlag = true; 414 index = it->first; 415 break; 416 } else { 417 ++it; 418 } 419 } 420 if (sDevName.find("Keyboard") != std::string::npos) { 421 detailInfo->devType = INDEV_TYPE_KEYBOARD; 422 } 423 if (sDevName.find("Mouse") != std::string::npos) { 424 detailInfo->devType = INDEV_TYPE_MOUSE; 425 } 426 type = detailInfo->devType; 427 if (!findDeviceFlag) { 428 if (AddDeviceNodeToList(epollFd, fd, devPath, detailInfo) != INPUT_SUCCESS) { 429 HDF_LOGE("%{public}s: add device node failed, line: %{public}d", __func__, __LINE__); 430 return; 431 } 432 } 433 status = INPUT_DEVICE_STATUS_OPENED; 434 SendHotPlugEvent(type, index, status); 435} 436 437void InputDeviceManager::SendHotPlugEvent(uint32_t &type, uint32_t &index, uint32_t status) 438{ 439 // hot plug evnets happened 440 InputHotPlugEvent *evtPlusPkg = (InputHotPlugEvent *)OsalMemAlloc(sizeof(InputHotPlugEvent)); 441 if (evtPlusPkg == nullptr) { 442 HDF_LOGE("%{public}s: OsalMemAlloc failed", __func__); 443 return; 444 } 445 446 evtPlusPkg->devType = type; 447 evtPlusPkg->devIndex = index; 448 evtPlusPkg->status = status; 449 450 if (reportHotPlugEventCallback_ != nullptr) { 451 HDF_LOGD("devType: %{public}u devIndex: %{public}u status: %{public}u", type, index, status); 452 reportHotPlugEventCallback_->HotPlugCallback(evtPlusPkg); 453 } 454 455 OsalMemFree(evtPlusPkg); 456 evtPlusPkg = nullptr; 457} 458 459void InputDeviceManager::DoWithEventDeviceDel(int32_t &epollFd, uint32_t &index) 460{ 461 uint32_t type {}; 462 uint32_t devIndex {}; 463 uint32_t status {}; 464 465 HDF_LOGD("%{public}s: index: %{public}d fd: %{public}d devName: %{public}s", __func__, 466 index, inputDevList_[index].fd, inputDevList_[index].detailInfo.attrSet.devName); 467 468 // hot plug evnets happened 469 auto sDevName = string(inputDevList_[index].detailInfo.attrSet.devName); 470 if (sDevName.find("Keyboard") != std::string::npos) { 471 type = INDEV_TYPE_KEYBOARD; 472 } 473 if (sDevName.find("Mouse") != std::string::npos) { 474 type = INDEV_TYPE_MOUSE; 475 } 476 auto ret = FindIndexFromDevName(sDevName, &devIndex); 477 if (ret != INPUT_SUCCESS) { 478 HDF_LOGE("%{public}s: no found device maybe it has been removed", __func__); 479 SendHotPlugEvent(type, devIndex_, status); 480 return; 481 } 482 status = INPUT_DEVICE_STATUS_CLOSED; 483 SendHotPlugEvent(type, devIndex, status); 484 CloseInputDevice(inputDevList_[index].devPathNode); 485 DeleteDevListNode(index); 486} 487 488int32_t InputDeviceManager::InotifyEventHandler(int32_t epollFd, int32_t notifyFd) 489{ 490 char InfoBuf[BUFFER_SIZE]; 491 struct inotify_event *event {}; 492 char nodeRealPath[PATH_MAX + 1] = { '\0' }; 493 char *p {}; 494 int32_t tmpFd {}; 495 496 (void)memset_s(InfoBuf, BUFFER_SIZE, 0, BUFFER_SIZE); 497 int32_t result = read(notifyFd, InfoBuf, BUFFER_SIZE); 498 for (p = InfoBuf; p < InfoBuf + result;) { 499 event = (struct inotify_event *)(p); 500 auto nodePath = devPath_ + "/" + string(event->name); 501 if (event->mask & IN_CREATE) { 502 if (realpath(nodePath.c_str(), nodeRealPath) == nullptr) { 503 HDF_LOGE("%{public}s: The absolute path does not exist.", __func__); 504 return INPUT_FAILURE; 505 } 506 tmpFd = open(nodeRealPath, O_RDWR); 507 if (tmpFd == INPUT_FAILURE) { 508 HDF_LOGE("%{public}s: open file failure: %{public}s", __func__, nodeRealPath); 509 return INPUT_FAILURE; 510 } 511 if (nodePath.find("event") == std::string::npos) { 512 break; 513 } 514 DoWithEventDeviceAdd(epollFd, tmpFd, nodePath); 515 } else if (event->mask & IN_DELETE) { 516 for (auto &inputDev : inputDevList_) { 517 if (!strcmp(inputDev.second.devPathNode, nodePath.c_str())) { 518 DoWithEventDeviceDel(epollFd, inputDev.second.index); 519 break; 520 } 521 } 522 } else { 523 // do nothing 524 HDF_LOGI("%{public}s: others actions has done", __func__); 525 } 526 p += sizeof(struct inotify_event) + event->len; 527 } 528 return 0; 529} 530 531int32_t InputDeviceManager::AddToEpoll(int32_t epollFd, int32_t fileFd) 532{ 533 int32_t result {0}; 534 struct epoll_event eventItem {}; 535 536 (void)memset_s(&eventItem, sizeof(eventItem), 0, sizeof(eventItem)); 537 eventItem.events = EPOLLIN; 538 eventItem.data.fd = fileFd; 539 result = epoll_ctl(epollFd, EPOLL_CTL_ADD, fileFd, &eventItem); 540 return result; 541} 542void InputDeviceManager::RemoveEpoll(int32_t epollFd, int32_t fileFd) 543{ 544 epoll_ctl(epollFd, EPOLL_CTL_DEL, fileFd, nullptr); 545} 546 547int32_t InputDeviceManager::FindIndexFromFd(int32_t &fd, uint32_t *index) 548{ 549 std::lock_guard<std::mutex> guard(lock_); 550 for (const auto &inputDev : inputDevList_) { 551 if (fd == inputDev.second.fd) { 552 *index = inputDev.first; 553 return INPUT_SUCCESS; 554 } 555 } 556 return INPUT_FAILURE; 557} 558 559int32_t InputDeviceManager::FindIndexFromDevName(string devName, uint32_t *index) 560{ 561 std::lock_guard<std::mutex> guard(lock_); 562 for (const auto &inputDev : inputDevList_) { 563 if (!strcmp(devName.c_str(), inputDev.second.detailInfo.attrSet.devName)) { 564 *index = inputDev.first; 565 return INPUT_SUCCESS; 566 } 567 } 568 return INPUT_FAILURE; 569} 570 571// InputManager 572RetStatus InputDeviceManager::ScanDevice(InputDevDesc *staArr, uint32_t arrLen) 573{ 574 if (staArr == nullptr) { 575 HDF_LOGE("%{public}s: param is null", __func__); 576 return INPUT_NULL_PTR; 577 } 578 579 auto scanCount = (arrLen >= inputDevList_.size() ? inputDevList_.size() : arrLen); 580 if (inputDevList_.size() == 0) { 581 HDF_LOGE("%{public}s: inputDevList_.size is 0", __func__); 582 return INPUT_FAILURE; 583 } 584 585 for (size_t i = 0; i <= scanCount; i++) { 586 (staArr + i)->devIndex = inputDevList_[i].index; 587 (staArr + i)->devType = inputDevList_[i].detailInfo.devType; 588 } 589 590 return INPUT_SUCCESS; 591} 592 593RetStatus InputDeviceManager::OpenDevice(uint32_t deviceIndex) 594{ 595 std::lock_guard<std::mutex> guard(lock_); 596 auto ret = INPUT_FAILURE; 597 598 if (deviceIndex >= inputDevList_.size()) { 599 HDF_LOGE("%{public}s: param is wrong", __func__); 600 return ret; 601 } 602 auto searchIndex = inputDevList_.find(deviceIndex); 603 if (searchIndex != inputDevList_.end()) { 604 if (searchIndex->second.status != INPUT_DEVICE_STATUS_OPENED) { 605 auto openRet = OpenInputDevice(searchIndex->second.devPathNode); 606 if (openRet > 0) { 607 AddToEpoll(mEpollId_, openRet); 608 ret = INPUT_SUCCESS; 609 } else { 610 HDF_LOGE("%{public}s: open error: %{public}d errormsg: %{public}s", 611 __func__, openRet, strerror(errno)); 612 return ret; 613 } 614 searchIndex->second.fd = openRet; 615 } else { 616 HDF_LOGD("%{public}s: open devPathNoth: %{public}s fd: %{public}d", 617 __func__, searchIndex->second.devPathNode, searchIndex->second.fd); 618 HDF_LOGD("%{public}s: open devPathNoth: %{public}s status: %{public}d index: %{public}d", 619 __func__, searchIndex->second.devPathNode, searchIndex->second.status, searchIndex->first); 620 AddToEpoll(mEpollId_, searchIndex->second.fd); 621 ret = INPUT_SUCCESS; 622 } 623 } 624 for (auto &e : inputDevList_) { 625 dumpInfoList(e.second); 626 } 627 return ret; 628} 629 630RetStatus InputDeviceManager::CloseDevice(uint32_t deviceIndex) 631{ 632 std::lock_guard<std::mutex> guard(lock_); 633 auto ret = INPUT_FAILURE; 634 635 if (deviceIndex >= inputDevList_.size()) { 636 HDF_LOGE("%{public}s: param is wrong", __func__); 637 return ret; 638 } 639 auto searchIndex = inputDevList_.find(deviceIndex); 640 if (searchIndex != inputDevList_.end()) { 641 ret = CloseInputDevice(searchIndex->second.devPathNode); 642 } 643 HDF_LOGD("%{public}s: close devIndex: %{public}u ret: %{public}d inputDevList_ size:%{public}lu ", 644 __func__, deviceIndex, ret, inputDevList_.size()); 645 return ret; 646} 647 648int32_t InputDeviceManager::GetDevice(int32_t deviceIndex, InputDeviceInfo **devInfo) 649{ 650 std::lock_guard<std::mutex> guard(lock_); 651 auto ret = INPUT_FAILURE; 652 653 if (devInfo == nullptr || deviceIndex >= static_cast<int32_t>(inputDevList_.size()) || *devInfo != nullptr) { 654 HDF_LOGE("%{public}s: param is wrong", __func__); 655 return ret; 656 } 657 auto it = inputDevList_.find(deviceIndex); 658 if (it != inputDevList_.end()) { 659 int inputDeviceInfoSize = sizeof(InputDeviceInfo); 660 *devInfo = reinterpret_cast<InputDeviceInfo *>(OsalMemAlloc(inputDeviceInfoSize)); 661 if (*devInfo == nullptr) { 662 HDF_LOGE("%{public}s: %{public}d OsalMemAlloc failed", __func__, __LINE__); 663 return ret; 664 } 665 if (memcpy_s(*devInfo, inputDeviceInfoSize, &it->second.detailInfo, inputDeviceInfoSize) != EOK) { 666 OsalMemFree(*devInfo); 667 HDF_LOGE("%{public}s: memcpy_s failed, line: %{public}d", __func__, __LINE__); 668 return ret; 669 } 670 ret = INPUT_SUCCESS; 671 } 672 HDF_LOGD("%{public}s: devIndex: %{public}d ret: %{public}d", __func__, deviceIndex, ret); 673 return ret; 674} 675 676int32_t InputDeviceManager::GetDeviceList(uint32_t *devNum, InputDeviceInfo **deviceList, uint32_t size) 677{ 678 std::lock_guard<std::mutex> guard(lock_); 679 auto ret = INPUT_FAILURE; 680 681 auto scanCount = (size >= inputDevList_.size() ? inputDevList_.size() : size); 682 if ((devNum == nullptr) || (deviceList == nullptr) || inputDevList_.size() == 0 || *deviceList != nullptr) { 683 HDF_LOGE("%{public}s: param is wrong", __func__); 684 return ret; 685 } 686 687 int inputDeviceInfoSize = sizeof(InputDeviceInfo); 688 *deviceList = reinterpret_cast<InputDeviceInfo *>(OsalMemAlloc(inputDeviceInfoSize * scanCount)); 689 if (*deviceList == nullptr) { 690 HDF_LOGE("%{public}s: %{public}d OsalMemAlloc failed", __func__, __LINE__); 691 return ret; 692 } 693 for (size_t i = 0; i < scanCount; i++) { 694 if (memcpy_s((*deviceList) + i, inputDeviceInfoSize, &inputDevList_[i].detailInfo, inputDeviceInfoSize) != 695 EOK) { 696 OsalMemFree(*deviceList); 697 HDF_LOGE("%{public}s: memcpy_s failed, line: %{public}d", __func__, __LINE__); 698 return ret; 699 } 700 } 701 *devNum = inputDevList_.size(); 702 ret = INPUT_SUCCESS; 703 HDF_LOGD("%{public}s: devNum: %{public}u devIndex_: %{public}d", __func__, *devNum, devIndex_); 704 705 return ret; 706} 707 708// InputController 709RetStatus InputDeviceManager::SetPowerStatus(uint32_t devIndex, uint32_t status) 710{ 711 RetStatus rc = INPUT_SUCCESS; 712 if ((devIndex >= inputDevList_.size()) || (status >= INPUT_POWER_STATUS_UNKNOWN)) { 713 HDF_LOGE("%{public}s: param is wrong", __func__); 714 return INPUT_FAILURE; 715 } 716 return rc; 717} 718 719RetStatus InputDeviceManager::GetPowerStatus(uint32_t devIndex, uint32_t *status) 720{ 721 RetStatus rc = INPUT_SUCCESS; 722 if ((devIndex >= inputDevList_.size()) || (status == nullptr)) { 723 HDF_LOGE("%{public}s: param is wrong", __func__); 724 return INPUT_FAILURE; 725 } 726 return rc; 727} 728 729RetStatus InputDeviceManager::GetDeviceType(uint32_t devIndex, uint32_t *deviceType) 730{ 731 RetStatus rc = INPUT_SUCCESS; 732 if ((devIndex >= inputDevList_.size()) || (deviceType == nullptr)) { 733 HDF_LOGE("%{public}s: param is wrong", __func__); 734 return INPUT_FAILURE; 735 } 736 737 *deviceType = inputDevList_[devIndex].detailInfo.devType; 738 HDF_LOGI("%{public}s: devType: %{public}u", __func__, *deviceType); 739 return rc; 740} 741 742RetStatus InputDeviceManager::GetChipInfo(uint32_t devIndex, char *chipInfo, uint32_t length) 743{ 744 RetStatus rc = INPUT_SUCCESS; 745 if ((devIndex >= inputDevList_.size()) || (chipInfo == nullptr)) { 746 HDF_LOGE("%{public}s: param is wrong", __func__); 747 return INPUT_FAILURE; 748 } 749 750 if (memcpy_s(chipInfo, length, inputDevList_[devIndex].detailInfo.chipInfo, length) != EOK) { 751 HDF_LOGE("%{public}s: memcpy_s failed, line: %{public}d", __func__, __LINE__); 752 rc = INPUT_FAILURE; 753 } 754 HDF_LOGI("%{public}s: chipInfo: %{public}s", __func__, chipInfo); 755 return rc; 756} 757 758RetStatus InputDeviceManager::GetVendorName(uint32_t devIndex, char *vendorName, uint32_t length) 759{ 760 RetStatus rc = INPUT_SUCCESS; 761 if ((devIndex >= inputDevList_.size()) || (vendorName == nullptr)) { 762 HDF_LOGE("%{public}s: param is wrong", __func__); 763 return INPUT_FAILURE; 764 } 765 766 if (memcpy_s(vendorName, length, inputDevList_[devIndex].detailInfo.vendorName, length) != EOK) { 767 HDF_LOGE("%{public}s: memcpy_s failed, line: %{public}d", __func__, __LINE__); 768 rc = INPUT_FAILURE; 769 } 770 HDF_LOGI("%{public}s: vendorName: %{public}s", __func__, vendorName); 771 return rc; 772} 773 774RetStatus InputDeviceManager::GetChipName(uint32_t devIndex, char *chipName, uint32_t length) 775{ 776 RetStatus rc = INPUT_SUCCESS; 777 if ((devIndex >= inputDevList_.size()) || (chipName == nullptr)) { 778 HDF_LOGE("%{public}s: param is wrong", __func__); 779 return INPUT_FAILURE; 780 } 781 782 if (memcpy_s(chipName, length, inputDevList_[devIndex].detailInfo.chipName, length) != EOK) { 783 HDF_LOGE("%{public}s: memcpy_s failed, line: %{public}d", __func__, __LINE__); 784 rc = INPUT_FAILURE; 785 } 786 HDF_LOGI("%{public}s: chipName: %{public}s", __func__, chipName); 787 return rc; 788} 789 790RetStatus InputDeviceManager::SetGestureMode(uint32_t devIndex, uint32_t gestureMode) 791{ 792 RetStatus rc = INPUT_SUCCESS; 793 if ((devIndex >= inputDevList_.size())) { 794 HDF_LOGE("%{public}s: param is wrong", __func__); 795 return INPUT_FAILURE; 796 } 797 return rc; 798} 799 800RetStatus InputDeviceManager::RunCapacitanceTest(uint32_t devIndex, uint32_t testType, char *result, uint32_t length) 801{ 802 RetStatus rc = INPUT_SUCCESS; 803 if ((devIndex >= inputDevList_.size()) || (testType >= TEST_TYPE_UNKNOWN) || 804 (result == nullptr) || (length < SELF_TEST_RESULT_LEN)) { 805 HDF_LOGE("%{public}s: param is wrong", __func__); 806 return INPUT_FAILURE; 807 } 808 return rc; 809} 810 811RetStatus InputDeviceManager::RunExtraCommand(uint32_t devIndex, InputExtraCmd *cmd) 812{ 813 RetStatus rc = INPUT_SUCCESS; 814 if ((devIndex >= inputDevList_.size()) || (cmd == nullptr) || (cmd->cmdCode == nullptr || 815 (cmd->cmdValue == nullptr))) { 816 HDF_LOGE("%{public}s: param is wrong", __func__); 817 return INPUT_FAILURE; 818 } 819 return rc; 820} 821 822// InputReporter 823RetStatus InputDeviceManager::RegisterReportCallback(uint32_t devIndex, InputEventCb *callback) 824{ 825 RetStatus rc = INPUT_SUCCESS; 826 if ((devIndex >= inputDevList_.size()) || (callback == nullptr) || (callback->EventPkgCallback == nullptr)) { 827 HDF_LOGE("%{public}s: param is wrong", __func__); 828 return INPUT_FAILURE; 829 } 830 std::lock_guard<std::mutex> guard(reportEventPkgCallBackLock_); 831 reportEventPkgCallback_[devIndex] = callback; 832 return rc; 833} 834 835RetStatus InputDeviceManager::UnregisterReportCallback(uint32_t devIndex) 836{ 837 HDF_LOGI("%{public}s: %{public}d dev is unregister", __func__, devIndex); 838 RetStatus rc = INPUT_SUCCESS; 839 if (devIndex >= inputDevList_.size()) { 840 HDF_LOGE("%{public}s: param is wrong", __func__); 841 return INPUT_FAILURE; 842 } 843 std::lock_guard<std::mutex> guard(reportEventPkgCallBackLock_); 844 reportEventPkgCallback_[devIndex] = nullptr; 845 return rc; 846} 847 848RetStatus InputDeviceManager::RegisterHotPlugCallback(InputHostCb *callback) 849{ 850 RetStatus rc = INPUT_SUCCESS; 851 reportHotPlugEventCallback_ = callback; 852 HDF_LOGI("%{public}s: called line %{public}d ret %{public}d", __func__, __LINE__, rc); 853 return rc; 854} 855 856RetStatus InputDeviceManager::UnregisterHotPlugCallback(void) 857{ 858 RetStatus rc = INPUT_SUCCESS; 859 reportHotPlugEventCallback_ = nullptr; 860 HDF_LOGI("%{public}s: called line %{public}d ret:%{public}d", __func__, __LINE__, rc); 861 return rc; 862} 863 864void InputDeviceManager::WorkerThread() 865{ 866 HDF_LOGI("%{public}s: called line %{public}d ", __func__, __LINE__); 867 std::future<void> fuResult = std::async(std::launch::async, [this]() { 868 DoInputDeviceAction(); 869 return; 870 }); 871 fuResult.get(); 872} 873} 874} 875