1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "input_device_manager.h" 17094332d3Sopenharmony_ci#include <algorithm> 18094332d3Sopenharmony_ci#include <cstdio> 19094332d3Sopenharmony_ci#include <cstdlib> 20094332d3Sopenharmony_ci#include <cstring> 21094332d3Sopenharmony_ci#include <dirent.h> 22094332d3Sopenharmony_ci#include <fcntl.h> 23094332d3Sopenharmony_ci#include <fstream> 24094332d3Sopenharmony_ci#include <functional> 25094332d3Sopenharmony_ci#include <future> 26094332d3Sopenharmony_ci#include <iostream> 27094332d3Sopenharmony_ci#include <memory> 28094332d3Sopenharmony_ci#include <sstream> 29094332d3Sopenharmony_ci#include <sys/epoll.h> 30094332d3Sopenharmony_ci#include <sys/inotify.h> 31094332d3Sopenharmony_ci#include <sys/ioctl.h> 32094332d3Sopenharmony_ci#include <unistd.h> 33094332d3Sopenharmony_ci#include <vector> 34094332d3Sopenharmony_ci#include "input_uhdf_log.h" 35094332d3Sopenharmony_ci#include "osal_mem.h" 36094332d3Sopenharmony_ci#include "securec.h" 37094332d3Sopenharmony_ci 38094332d3Sopenharmony_ci#define HDF_LOG_TAG InputDeviceHdiManager 39094332d3Sopenharmony_ci 40094332d3Sopenharmony_cinamespace OHOS { 41094332d3Sopenharmony_cinamespace Input { 42094332d3Sopenharmony_ciusing namespace std; 43094332d3Sopenharmony_ciconstexpr uint32_t DEV_INDEX_MAX = 32; 44094332d3Sopenharmony_civoid InputDeviceManager::Init() 45094332d3Sopenharmony_ci{ 46094332d3Sopenharmony_ci inputDevList_.clear(); 47094332d3Sopenharmony_ci reportEventPkgCallBackLock_.lock(); 48094332d3Sopenharmony_ci reportEventPkgCallback_.clear(); 49094332d3Sopenharmony_ci reportEventPkgCallBackLock_.unlock(); 50094332d3Sopenharmony_ci GetInputDeviceInfoList(); 51094332d3Sopenharmony_ci std::thread t1([this] {this->WorkerThread();}); 52094332d3Sopenharmony_ci std::string wholeName1 = std::to_string(getpid()) + "_" + std::to_string(gettid()); 53094332d3Sopenharmony_ci thread_ = std::move(t1); 54094332d3Sopenharmony_ci thread_.detach(); 55094332d3Sopenharmony_ci for (auto &inputDev : inputDevList_) { 56094332d3Sopenharmony_ci dumpInfoList(inputDev.second); 57094332d3Sopenharmony_ci } 58094332d3Sopenharmony_ci} 59094332d3Sopenharmony_ci 60094332d3Sopenharmony_cistatic void FreeEventPkgs(InputEventPackage **eventPkgs, size_t count) 61094332d3Sopenharmony_ci{ 62094332d3Sopenharmony_ci for (size_t i = 0; i < count; i++) { 63094332d3Sopenharmony_ci if (eventPkgs[i] != NULL) { 64094332d3Sopenharmony_ci OsalMemFree(eventPkgs[i]); 65094332d3Sopenharmony_ci eventPkgs[i] = nullptr; 66094332d3Sopenharmony_ci } 67094332d3Sopenharmony_ci } 68094332d3Sopenharmony_ci return; 69094332d3Sopenharmony_ci} 70094332d3Sopenharmony_ci 71094332d3Sopenharmony_ci// get the nodefile list 72094332d3Sopenharmony_civector<string> InputDeviceManager::GetFiles(string path) 73094332d3Sopenharmony_ci{ 74094332d3Sopenharmony_ci vector<string> fileList; 75094332d3Sopenharmony_ci struct dirent *dEnt = nullptr; 76094332d3Sopenharmony_ci 77094332d3Sopenharmony_ci DIR *dir = opendir(path.c_str()); 78094332d3Sopenharmony_ci if (dir == nullptr) { 79094332d3Sopenharmony_ci HDF_LOGE("%{public}s: no files", __func__); 80094332d3Sopenharmony_ci return fileList; 81094332d3Sopenharmony_ci } 82094332d3Sopenharmony_ci string sDot = "."; 83094332d3Sopenharmony_ci string sDotDot = ".."; 84094332d3Sopenharmony_ci while ((dEnt = readdir(dir)) != nullptr) { 85094332d3Sopenharmony_ci if ((string(dEnt->d_name) != sDot) && 86094332d3Sopenharmony_ci (string(dEnt->d_name) != sDotDot)) { 87094332d3Sopenharmony_ci if (dEnt->d_type != DT_DIR) { 88094332d3Sopenharmony_ci string d_name(dEnt->d_name); 89094332d3Sopenharmony_ci fileList.push_back(string(dEnt->d_name)); 90094332d3Sopenharmony_ci } 91094332d3Sopenharmony_ci } 92094332d3Sopenharmony_ci } 93094332d3Sopenharmony_ci // sort the returned files 94094332d3Sopenharmony_ci sort(fileList.begin(), fileList.end()); 95094332d3Sopenharmony_ci closedir(dir); 96094332d3Sopenharmony_ci return fileList; 97094332d3Sopenharmony_ci} 98094332d3Sopenharmony_ci 99094332d3Sopenharmony_civoid InputDeviceManager::ReportEventPkg(int32_t iFd, InputEventPackage **iEvtPkg, size_t iCount) 100094332d3Sopenharmony_ci{ 101094332d3Sopenharmony_ci if (iEvtPkg == nullptr) { 102094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param invalid, line: %{public}d", __func__, __LINE__); 103094332d3Sopenharmony_ci return; 104094332d3Sopenharmony_ci } 105094332d3Sopenharmony_ci std::lock_guard<std::mutex> guard(reportEventPkgCallBackLock_); 106094332d3Sopenharmony_ci for (auto &callbackFunc : reportEventPkgCallback_) { 107094332d3Sopenharmony_ci uint32_t index {0}; 108094332d3Sopenharmony_ci auto ret = FindIndexFromFd(iFd, &index); 109094332d3Sopenharmony_ci if (callbackFunc.second != nullptr && ret != INPUT_FAILURE) { 110094332d3Sopenharmony_ci callbackFunc.second->EventPkgCallback(const_cast<const InputEventPackage **>(iEvtPkg), iCount, index); 111094332d3Sopenharmony_ci } 112094332d3Sopenharmony_ci } 113094332d3Sopenharmony_ci return; 114094332d3Sopenharmony_ci} 115094332d3Sopenharmony_ci 116094332d3Sopenharmony_ciint32_t CheckReadResult(int32_t readResult) 117094332d3Sopenharmony_ci{ 118094332d3Sopenharmony_ci if (readResult == 0 || (readResult < 0 && errno == ENODEV)) { 119094332d3Sopenharmony_ci return INPUT_FAILURE; 120094332d3Sopenharmony_ci } 121094332d3Sopenharmony_ci if (readResult < 0) { 122094332d3Sopenharmony_ci if (errno != EAGAIN && errno != EINTR) { 123094332d3Sopenharmony_ci HDF_LOGE("%{public}s: could not get event (errno = %{public}d)", __func__, errno); 124094332d3Sopenharmony_ci } 125094332d3Sopenharmony_ci return INPUT_FAILURE; 126094332d3Sopenharmony_ci } 127094332d3Sopenharmony_ci if ((readResult % sizeof(struct input_event)) != 0) { 128094332d3Sopenharmony_ci HDF_LOGE("%{public}s: could not get one event size %{public}lu readResult size: %{public}d", __func__, 129094332d3Sopenharmony_ci sizeof(struct input_event), readResult); 130094332d3Sopenharmony_ci return INPUT_FAILURE; 131094332d3Sopenharmony_ci } 132094332d3Sopenharmony_ci return INPUT_SUCCESS; 133094332d3Sopenharmony_ci} 134094332d3Sopenharmony_ci 135094332d3Sopenharmony_ci// read action 136094332d3Sopenharmony_civoid InputDeviceManager::DoRead(int32_t fd, struct input_event *event, size_t size) 137094332d3Sopenharmony_ci{ 138094332d3Sopenharmony_ci int32_t readLen = read(fd, event, sizeof(struct input_event) * size); 139094332d3Sopenharmony_ci if (CheckReadResult(readLen) == INPUT_FAILURE) { 140094332d3Sopenharmony_ci return; 141094332d3Sopenharmony_ci } 142094332d3Sopenharmony_ci size_t count = size_t(readLen) / sizeof(struct input_event); 143094332d3Sopenharmony_ci InputEventPackage **evtPkg = (InputEventPackage **)OsalMemAlloc(sizeof(InputEventPackage *) * count); 144094332d3Sopenharmony_ci if (evtPkg == nullptr) { 145094332d3Sopenharmony_ci HDF_LOGE("%{public}s: OsalMemAlloc failed, line: %{public}d", __func__, __LINE__); 146094332d3Sopenharmony_ci return; 147094332d3Sopenharmony_ci } 148094332d3Sopenharmony_ci for (size_t i = 0; i < count; i++) { 149094332d3Sopenharmony_ci struct input_event &iEvent = event[i]; 150094332d3Sopenharmony_ci // device action events happened 151094332d3Sopenharmony_ci *(evtPkg + i) = (InputEventPackage *)OsalMemAlloc(sizeof(InputEventPackage)); 152094332d3Sopenharmony_ci if (evtPkg[i] == nullptr) { 153094332d3Sopenharmony_ci HDF_LOGE("%{public}s: OsalMemAlloc failed, line: %{public}d", __func__, __LINE__); 154094332d3Sopenharmony_ci FreeEventPkgs(evtPkg, i); 155094332d3Sopenharmony_ci OsalMemFree(evtPkg); 156094332d3Sopenharmony_ci evtPkg = nullptr; 157094332d3Sopenharmony_ci return; 158094332d3Sopenharmony_ci } 159094332d3Sopenharmony_ci evtPkg[i]->type = iEvent.type; 160094332d3Sopenharmony_ci evtPkg[i]->code = iEvent.code; 161094332d3Sopenharmony_ci evtPkg[i]->value = iEvent.value; 162094332d3Sopenharmony_ci evtPkg[i]->timestamp = (uint64_t)iEvent.time.tv_sec * MS_THOUSAND * MS_THOUSAND + 163094332d3Sopenharmony_ci (uint64_t)iEvent.time.tv_usec; 164094332d3Sopenharmony_ci } 165094332d3Sopenharmony_ci ReportEventPkg(fd, evtPkg, count); 166094332d3Sopenharmony_ci for (size_t i = 0; i < count; i++) { 167094332d3Sopenharmony_ci OsalMemFree(evtPkg[i]); 168094332d3Sopenharmony_ci evtPkg[i] = nullptr; 169094332d3Sopenharmony_ci } 170094332d3Sopenharmony_ci OsalMemFree(evtPkg); 171094332d3Sopenharmony_ci evtPkg = nullptr; 172094332d3Sopenharmony_ci} 173094332d3Sopenharmony_ci 174094332d3Sopenharmony_ci// open input device node 175094332d3Sopenharmony_ciint32_t InputDeviceManager::OpenInputDevice(string devPath) 176094332d3Sopenharmony_ci{ 177094332d3Sopenharmony_ci char devRealPath[PATH_MAX + 1] = { '\0' }; 178094332d3Sopenharmony_ci if (realpath(devPath.c_str(), devRealPath) == nullptr) { 179094332d3Sopenharmony_ci HDF_LOGE("%{public}s: The absolute path does not exist.", __func__); 180094332d3Sopenharmony_ci return INPUT_FAILURE; 181094332d3Sopenharmony_ci } 182094332d3Sopenharmony_ci 183094332d3Sopenharmony_ci int32_t nodeFd = open(devRealPath, O_RDWR | O_CLOEXEC | O_NONBLOCK); 184094332d3Sopenharmony_ci if (nodeFd < 0) { 185094332d3Sopenharmony_ci HDF_LOGE("%{public}s: could not open %{public}s, %{public}d %{public}s", __func__, 186094332d3Sopenharmony_ci devRealPath, errno, strerror(errno)); 187094332d3Sopenharmony_ci return INPUT_FAILURE; 188094332d3Sopenharmony_ci } 189094332d3Sopenharmony_ci return nodeFd; 190094332d3Sopenharmony_ci} 191094332d3Sopenharmony_ci 192094332d3Sopenharmony_ci// close input device node 193094332d3Sopenharmony_ciRetStatus InputDeviceManager::CloseInputDevice(string devPath) 194094332d3Sopenharmony_ci{ 195094332d3Sopenharmony_ci for (auto &inputDev : inputDevList_) { 196094332d3Sopenharmony_ci if (string(inputDev.second.devPathNode) == devPath) { 197094332d3Sopenharmony_ci int32_t fd = inputDev.second.fd; 198094332d3Sopenharmony_ci if (fd > 0) { 199094332d3Sopenharmony_ci RemoveEpoll(mEpollId_, fd); 200094332d3Sopenharmony_ci close(fd); 201094332d3Sopenharmony_ci inputDev.second.fd = -1; 202094332d3Sopenharmony_ci inputDev.second.status = INPUT_DEVICE_STATUS_CLOSED; 203094332d3Sopenharmony_ci return INPUT_SUCCESS; 204094332d3Sopenharmony_ci } 205094332d3Sopenharmony_ci } 206094332d3Sopenharmony_ci } 207094332d3Sopenharmony_ci // device list remove this node 208094332d3Sopenharmony_ci return INPUT_FAILURE; 209094332d3Sopenharmony_ci} 210094332d3Sopenharmony_ci 211094332d3Sopenharmony_ciint32_t InputDeviceManager::GetInputDeviceInfo(int32_t fd, InputDeviceInfo *detailInfo) 212094332d3Sopenharmony_ci{ 213094332d3Sopenharmony_ci char buffer[DEVICE_INFO_SIZE] {}; 214094332d3Sopenharmony_ci struct input_id inputId {}; 215094332d3Sopenharmony_ci // get the abilitys. 216094332d3Sopenharmony_ci (void)ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(detailInfo->abilitySet.keyCode)), &detailInfo->abilitySet.keyCode); 217094332d3Sopenharmony_ci (void)ioctl(fd, EVIOCGBIT(EV_REL, sizeof(detailInfo->abilitySet.relCode)), &detailInfo->abilitySet.relCode); 218094332d3Sopenharmony_ci (void)ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(detailInfo->abilitySet.absCode)), &detailInfo->abilitySet.absCode); 219094332d3Sopenharmony_ci (void)ioctl(fd, EVIOCGBIT(EV_MSC, sizeof(detailInfo->abilitySet.miscCode)), &detailInfo->abilitySet.miscCode); 220094332d3Sopenharmony_ci (void)ioctl(fd, EVIOCGBIT(EV_SW, sizeof(detailInfo->abilitySet.switchCode)), &detailInfo->abilitySet.switchCode); 221094332d3Sopenharmony_ci (void)ioctl(fd, EVIOCGBIT(EV_LED, sizeof(detailInfo->abilitySet.ledType)), &detailInfo->abilitySet.ledType); 222094332d3Sopenharmony_ci (void)ioctl(fd, EVIOCGBIT(EV_SND, sizeof(detailInfo->abilitySet.soundCode)), &detailInfo->abilitySet.soundCode); 223094332d3Sopenharmony_ci (void)ioctl(fd, EVIOCGBIT(EV_FF, sizeof(detailInfo->abilitySet.forceCode)), &detailInfo->abilitySet.forceCode); 224094332d3Sopenharmony_ci // device name. 225094332d3Sopenharmony_ci if (ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) { 226094332d3Sopenharmony_ci HDF_LOGE("%{public}s: get device name failed errormsg %{public}s", __func__, strerror(errno)); 227094332d3Sopenharmony_ci } else { 228094332d3Sopenharmony_ci buffer[sizeof(buffer) - 1] = '\0'; 229094332d3Sopenharmony_ci int32_t ret = strcpy_s(detailInfo->attrSet.devName, DEV_NAME_LEN, buffer); 230094332d3Sopenharmony_ci if (ret) { 231094332d3Sopenharmony_ci HDF_LOGE("%{public}s: strcpy_s failed, ret %{public}d", __func__, ret); 232094332d3Sopenharmony_ci return INPUT_FAILURE; 233094332d3Sopenharmony_ci } 234094332d3Sopenharmony_ci } 235094332d3Sopenharmony_ci // device detailInfo. 236094332d3Sopenharmony_ci if (ioctl(fd, EVIOCGID, &inputId)) { 237094332d3Sopenharmony_ci HDF_LOGE("%{public}s: get device input id errormsg %{public}s", __func__, strerror(errno)); 238094332d3Sopenharmony_ci } 239094332d3Sopenharmony_ci detailInfo->attrSet.id.busType = inputId.bustype; 240094332d3Sopenharmony_ci detailInfo->attrSet.id.product = inputId.product; 241094332d3Sopenharmony_ci detailInfo->attrSet.id.vendor = inputId.vendor; 242094332d3Sopenharmony_ci detailInfo->attrSet.id.version = inputId.version; 243094332d3Sopenharmony_ci // ABS Info 244094332d3Sopenharmony_ci for (uint32_t i = 0; i < BITS_TO_UINT64(ABS_CNT); i++) { 245094332d3Sopenharmony_ci if (detailInfo->abilitySet.absCode[i] > 0) { 246094332d3Sopenharmony_ci if (ioctl(fd, EVIOCGABS(i), &detailInfo->attrSet.axisInfo[i])) { 247094332d3Sopenharmony_ci HDF_LOGE("%{public}s: get axis info failed fd = %{public}d name = %{public}s errormsg = %{public}s", 248094332d3Sopenharmony_ci __func__, fd, detailInfo->attrSet.devName, strerror(errno)); 249094332d3Sopenharmony_ci continue; 250094332d3Sopenharmony_ci } 251094332d3Sopenharmony_ci } 252094332d3Sopenharmony_ci } 253094332d3Sopenharmony_ci return INPUT_SUCCESS; 254094332d3Sopenharmony_ci} 255094332d3Sopenharmony_ci 256094332d3Sopenharmony_ciuint32_t GetInputDeviceTypeInfo(const string &devName) 257094332d3Sopenharmony_ci{ 258094332d3Sopenharmony_ci uint32_t type {INDEV_TYPE_UNKNOWN}; 259094332d3Sopenharmony_ci if (devName.find("input_mt_wrapper") != std::string::npos) { 260094332d3Sopenharmony_ci type = INDEV_TYPE_TOUCH; 261094332d3Sopenharmony_ci } else if ((devName.find("Keyboard") != std::string::npos) && 262094332d3Sopenharmony_ci (devName.find("Headset") == std::string::npos)) { 263094332d3Sopenharmony_ci type = INDEV_TYPE_KEYBOARD; 264094332d3Sopenharmony_ci } else if (devName.find("Mouse") != std::string::npos) { 265094332d3Sopenharmony_ci type = INDEV_TYPE_MOUSE; 266094332d3Sopenharmony_ci } else if ((devName.find("_gpio_key") != std::string::npos) || 267094332d3Sopenharmony_ci (devName.find("ponkey_on") != std::string::npos)) { 268094332d3Sopenharmony_ci type = INDEV_TYPE_KEY; 269094332d3Sopenharmony_ci } else if (devName.find("Touchpad") != std::string::npos) { 270094332d3Sopenharmony_ci type = INDEV_TYPE_TOUCHPAD; 271094332d3Sopenharmony_ci } 272094332d3Sopenharmony_ci return type; 273094332d3Sopenharmony_ci} 274094332d3Sopenharmony_ci 275094332d3Sopenharmony_civoid InputDeviceManager::GetInputDeviceInfoList(int32_t epollFd) 276094332d3Sopenharmony_ci{ 277094332d3Sopenharmony_ci inputDevList_.clear(); 278094332d3Sopenharmony_ci std::vector<std::string> flist = GetFiles(devPath_); 279094332d3Sopenharmony_ci std::shared_ptr<InputDeviceInfo> detailInfo; 280094332d3Sopenharmony_ci InputDevListNode inputDevList {}; 281094332d3Sopenharmony_ci 282094332d3Sopenharmony_ci for (unsigned i = 0; i < flist.size(); i++) { 283094332d3Sopenharmony_ci string devPathNode = devPath_ + "/" + flist[i]; 284094332d3Sopenharmony_ci std::string::size_type n = devPathNode.find("event"); 285094332d3Sopenharmony_ci if (n == std::string::npos) { 286094332d3Sopenharmony_ci continue; 287094332d3Sopenharmony_ci } 288094332d3Sopenharmony_ci auto fd = OpenInputDevice(devPathNode); 289094332d3Sopenharmony_ci if (fd < 0) { 290094332d3Sopenharmony_ci HDF_LOGE("%{public}s: open node failed", __func__); 291094332d3Sopenharmony_ci continue; 292094332d3Sopenharmony_ci } 293094332d3Sopenharmony_ci detailInfo = std::make_shared<InputDeviceInfo>(); 294094332d3Sopenharmony_ci (void)memset_s(detailInfo.get(), sizeof(InputDeviceInfo), 0, sizeof(InputDeviceInfo)); 295094332d3Sopenharmony_ci (void)GetInputDeviceInfo(fd, detailInfo.get()); 296094332d3Sopenharmony_ci auto sDevName = string(detailInfo->attrSet.devName); 297094332d3Sopenharmony_ci uint32_t type = GetInputDeviceTypeInfo(sDevName); 298094332d3Sopenharmony_ci if (type == INDEV_TYPE_UNKNOWN) { 299094332d3Sopenharmony_ci continue; 300094332d3Sopenharmony_ci } 301094332d3Sopenharmony_ci inputDevList.index = devIndex_; 302094332d3Sopenharmony_ci inputDevList.status = INPUT_DEVICE_STATUS_OPENED; 303094332d3Sopenharmony_ci inputDevList.fd = fd; 304094332d3Sopenharmony_ci detailInfo->devIndex = devIndex_; 305094332d3Sopenharmony_ci detailInfo->devType = type; 306094332d3Sopenharmony_ci if (memcpy_s(&inputDevList.devPathNode, devPathNode.length(), 307094332d3Sopenharmony_ci devPathNode.c_str(), devPathNode.length()) != EOK || 308094332d3Sopenharmony_ci memcpy_s(&inputDevList.detailInfo, sizeof(InputDeviceInfo), detailInfo.get(), 309094332d3Sopenharmony_ci sizeof(InputDeviceInfo)) != EOK) { 310094332d3Sopenharmony_ci HDF_LOGE("%{public}s: memcpy_s failed, line: %{public}d", __func__, __LINE__); 311094332d3Sopenharmony_ci return; 312094332d3Sopenharmony_ci } 313094332d3Sopenharmony_ci inputDevList_.insert_or_assign(devIndex_, inputDevList); 314094332d3Sopenharmony_ci devIndex_ += 1; 315094332d3Sopenharmony_ci } 316094332d3Sopenharmony_ci} 317094332d3Sopenharmony_ci 318094332d3Sopenharmony_ciint32_t InputDeviceManager::DoInputDeviceAction(void) 319094332d3Sopenharmony_ci{ 320094332d3Sopenharmony_ci struct input_event evtBuffer[EVENT_BUFFER_SIZE] {}; 321094332d3Sopenharmony_ci int32_t result = 0; 322094332d3Sopenharmony_ci 323094332d3Sopenharmony_ci mEpollId_ = epoll_create1(EPOLL_CLOEXEC); 324094332d3Sopenharmony_ci if (mEpollId_ == INPUT_FAILURE) { 325094332d3Sopenharmony_ci HDF_LOGE("%{public}s: epoll create failed", __func__); 326094332d3Sopenharmony_ci return mEpollId_; 327094332d3Sopenharmony_ci } 328094332d3Sopenharmony_ci mInotifyId_ = inotify_init(); 329094332d3Sopenharmony_ci result = inotify_add_watch(mInotifyId_, devPath_.c_str(), IN_DELETE | IN_CREATE); 330094332d3Sopenharmony_ci if (result == INPUT_FAILURE) { 331094332d3Sopenharmony_ci HDF_LOGE("%{public}s: add file watch failed", __func__); 332094332d3Sopenharmony_ci return result; 333094332d3Sopenharmony_ci } 334094332d3Sopenharmony_ci AddToEpoll(mEpollId_, mInotifyId_); 335094332d3Sopenharmony_ci while (true) { 336094332d3Sopenharmony_ci result = epoll_wait(mEpollId_, epollEventList_, EPOLL_MAX_EVENTS, EPOLL_WAIT_TIMEOUT); 337094332d3Sopenharmony_ci if (result <= 0) { 338094332d3Sopenharmony_ci continue; 339094332d3Sopenharmony_ci } 340094332d3Sopenharmony_ci for (int32_t i = 0; i < result; i++) { 341094332d3Sopenharmony_ci if (epollEventList_[i].data.fd != mInotifyId_) { 342094332d3Sopenharmony_ci DoRead(epollEventList_[i].data.fd, evtBuffer, EVENT_BUFFER_SIZE); 343094332d3Sopenharmony_ci continue; 344094332d3Sopenharmony_ci } 345094332d3Sopenharmony_ci if (INPUT_FAILURE == InotifyEventHandler(mEpollId_, mInotifyId_)) { 346094332d3Sopenharmony_ci HDF_LOGE("%{public}s: inotify handler failed", __func__); 347094332d3Sopenharmony_ci return INPUT_FAILURE; 348094332d3Sopenharmony_ci } 349094332d3Sopenharmony_ci } 350094332d3Sopenharmony_ci } 351094332d3Sopenharmony_ci return INPUT_SUCCESS; 352094332d3Sopenharmony_ci} 353094332d3Sopenharmony_ci 354094332d3Sopenharmony_civoid InputDeviceManager::DeleteDevListNode(int index) 355094332d3Sopenharmony_ci{ 356094332d3Sopenharmony_ci for (auto it = inputDevList_.begin(); it != inputDevList_.end();) { 357094332d3Sopenharmony_ci if (it->first == (uint32_t)index) { 358094332d3Sopenharmony_ci it = inputDevList_.erase(it); 359094332d3Sopenharmony_ci if (devIndex_ < 1 || devIndex_ > DEV_INDEX_MAX) { 360094332d3Sopenharmony_ci return; 361094332d3Sopenharmony_ci } 362094332d3Sopenharmony_ci devIndex_ -= 1; 363094332d3Sopenharmony_ci } else { 364094332d3Sopenharmony_ci ++it; 365094332d3Sopenharmony_ci } 366094332d3Sopenharmony_ci } 367094332d3Sopenharmony_ci return; 368094332d3Sopenharmony_ci} 369094332d3Sopenharmony_ci 370094332d3Sopenharmony_ciint32_t InputDeviceManager::AddDeviceNodeToList( 371094332d3Sopenharmony_ci int32_t &epollFd, int32_t &fd, string devPath, std::shared_ptr<InputDeviceInfo> &detailInfo) 372094332d3Sopenharmony_ci{ 373094332d3Sopenharmony_ci if (epollFd < 0 || fd < 0) { 374094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param invalid, %{public}d", __func__, __LINE__); 375094332d3Sopenharmony_ci return INPUT_FAILURE; 376094332d3Sopenharmony_ci } 377094332d3Sopenharmony_ci InputDevListNode inputDevList {}; 378094332d3Sopenharmony_ci inputDevList.index = devIndex_; 379094332d3Sopenharmony_ci inputDevList.status = INPUT_DEVICE_STATUS_OPENED; 380094332d3Sopenharmony_ci inputDevList.fd = fd; 381094332d3Sopenharmony_ci detailInfo->devIndex = devIndex_; 382094332d3Sopenharmony_ci if (memcpy_s(inputDevList.devPathNode, devPath.length(), devPath.c_str(), devPath.length()) != EOK || 383094332d3Sopenharmony_ci memcpy_s(&inputDevList.detailInfo, sizeof(InputDeviceInfo), detailInfo.get(), 384094332d3Sopenharmony_ci sizeof(InputDeviceInfo)) != EOK) { 385094332d3Sopenharmony_ci HDF_LOGE("%{public}s: memcpy_s failed, line: %{public}d", __func__, __LINE__); 386094332d3Sopenharmony_ci return INPUT_FAILURE; 387094332d3Sopenharmony_ci } 388094332d3Sopenharmony_ci inputDevList_.insert_or_assign(devIndex_, inputDevList); 389094332d3Sopenharmony_ci devIndex_ += 1; 390094332d3Sopenharmony_ci if (AddToEpoll(epollFd, inputDevList.fd) != INPUT_SUCCESS) { 391094332d3Sopenharmony_ci HDF_LOGE("%{public}s: add to epoll failed, line: %{public}d", __func__, __LINE__); 392094332d3Sopenharmony_ci DeleteDevListNode(devIndex_); 393094332d3Sopenharmony_ci return INPUT_FAILURE; 394094332d3Sopenharmony_ci } 395094332d3Sopenharmony_ci return INPUT_SUCCESS; 396094332d3Sopenharmony_ci} 397094332d3Sopenharmony_ci 398094332d3Sopenharmony_civoid InputDeviceManager::DoWithEventDeviceAdd(int32_t &epollFd, int32_t &fd, string devPath) 399094332d3Sopenharmony_ci{ 400094332d3Sopenharmony_ci bool findDeviceFlag = false; 401094332d3Sopenharmony_ci uint32_t type {}; 402094332d3Sopenharmony_ci uint32_t index {}; 403094332d3Sopenharmony_ci uint32_t status {}; 404094332d3Sopenharmony_ci 405094332d3Sopenharmony_ci std::shared_ptr<InputDeviceInfo> detailInfo = std::make_shared<InputDeviceInfo>(); 406094332d3Sopenharmony_ci (void)memset_s(detailInfo.get(), sizeof(InputDeviceInfo), 0, sizeof(InputDeviceInfo)); 407094332d3Sopenharmony_ci (void)GetInputDeviceInfo(fd, detailInfo.get()); 408094332d3Sopenharmony_ci auto sDevName = string(detailInfo->attrSet.devName); 409094332d3Sopenharmony_ci for (auto it = inputDevList_.begin(); it != inputDevList_.end();) { 410094332d3Sopenharmony_ci if (string(it->second.detailInfo.attrSet.devName) == sDevName) { 411094332d3Sopenharmony_ci it->second.fd = fd; 412094332d3Sopenharmony_ci it->second.status = INPUT_DEVICE_STATUS_OPENED; 413094332d3Sopenharmony_ci findDeviceFlag = true; 414094332d3Sopenharmony_ci index = it->first; 415094332d3Sopenharmony_ci break; 416094332d3Sopenharmony_ci } else { 417094332d3Sopenharmony_ci ++it; 418094332d3Sopenharmony_ci } 419094332d3Sopenharmony_ci } 420094332d3Sopenharmony_ci if (sDevName.find("Keyboard") != std::string::npos) { 421094332d3Sopenharmony_ci detailInfo->devType = INDEV_TYPE_KEYBOARD; 422094332d3Sopenharmony_ci } 423094332d3Sopenharmony_ci if (sDevName.find("Mouse") != std::string::npos) { 424094332d3Sopenharmony_ci detailInfo->devType = INDEV_TYPE_MOUSE; 425094332d3Sopenharmony_ci } 426094332d3Sopenharmony_ci type = detailInfo->devType; 427094332d3Sopenharmony_ci if (!findDeviceFlag) { 428094332d3Sopenharmony_ci if (AddDeviceNodeToList(epollFd, fd, devPath, detailInfo) != INPUT_SUCCESS) { 429094332d3Sopenharmony_ci HDF_LOGE("%{public}s: add device node failed, line: %{public}d", __func__, __LINE__); 430094332d3Sopenharmony_ci return; 431094332d3Sopenharmony_ci } 432094332d3Sopenharmony_ci } 433094332d3Sopenharmony_ci status = INPUT_DEVICE_STATUS_OPENED; 434094332d3Sopenharmony_ci SendHotPlugEvent(type, index, status); 435094332d3Sopenharmony_ci} 436094332d3Sopenharmony_ci 437094332d3Sopenharmony_civoid InputDeviceManager::SendHotPlugEvent(uint32_t &type, uint32_t &index, uint32_t status) 438094332d3Sopenharmony_ci{ 439094332d3Sopenharmony_ci // hot plug evnets happened 440094332d3Sopenharmony_ci InputHotPlugEvent *evtPlusPkg = (InputHotPlugEvent *)OsalMemAlloc(sizeof(InputHotPlugEvent)); 441094332d3Sopenharmony_ci if (evtPlusPkg == nullptr) { 442094332d3Sopenharmony_ci HDF_LOGE("%{public}s: OsalMemAlloc failed", __func__); 443094332d3Sopenharmony_ci return; 444094332d3Sopenharmony_ci } 445094332d3Sopenharmony_ci 446094332d3Sopenharmony_ci evtPlusPkg->devType = type; 447094332d3Sopenharmony_ci evtPlusPkg->devIndex = index; 448094332d3Sopenharmony_ci evtPlusPkg->status = status; 449094332d3Sopenharmony_ci 450094332d3Sopenharmony_ci if (reportHotPlugEventCallback_ != nullptr) { 451094332d3Sopenharmony_ci HDF_LOGD("devType: %{public}u devIndex: %{public}u status: %{public}u", type, index, status); 452094332d3Sopenharmony_ci reportHotPlugEventCallback_->HotPlugCallback(evtPlusPkg); 453094332d3Sopenharmony_ci } 454094332d3Sopenharmony_ci 455094332d3Sopenharmony_ci OsalMemFree(evtPlusPkg); 456094332d3Sopenharmony_ci evtPlusPkg = nullptr; 457094332d3Sopenharmony_ci} 458094332d3Sopenharmony_ci 459094332d3Sopenharmony_civoid InputDeviceManager::DoWithEventDeviceDel(int32_t &epollFd, uint32_t &index) 460094332d3Sopenharmony_ci{ 461094332d3Sopenharmony_ci uint32_t type {}; 462094332d3Sopenharmony_ci uint32_t devIndex {}; 463094332d3Sopenharmony_ci uint32_t status {}; 464094332d3Sopenharmony_ci 465094332d3Sopenharmony_ci HDF_LOGD("%{public}s: index: %{public}d fd: %{public}d devName: %{public}s", __func__, 466094332d3Sopenharmony_ci index, inputDevList_[index].fd, inputDevList_[index].detailInfo.attrSet.devName); 467094332d3Sopenharmony_ci 468094332d3Sopenharmony_ci // hot plug evnets happened 469094332d3Sopenharmony_ci auto sDevName = string(inputDevList_[index].detailInfo.attrSet.devName); 470094332d3Sopenharmony_ci if (sDevName.find("Keyboard") != std::string::npos) { 471094332d3Sopenharmony_ci type = INDEV_TYPE_KEYBOARD; 472094332d3Sopenharmony_ci } 473094332d3Sopenharmony_ci if (sDevName.find("Mouse") != std::string::npos) { 474094332d3Sopenharmony_ci type = INDEV_TYPE_MOUSE; 475094332d3Sopenharmony_ci } 476094332d3Sopenharmony_ci auto ret = FindIndexFromDevName(sDevName, &devIndex); 477094332d3Sopenharmony_ci if (ret != INPUT_SUCCESS) { 478094332d3Sopenharmony_ci HDF_LOGE("%{public}s: no found device maybe it has been removed", __func__); 479094332d3Sopenharmony_ci SendHotPlugEvent(type, devIndex_, status); 480094332d3Sopenharmony_ci return; 481094332d3Sopenharmony_ci } 482094332d3Sopenharmony_ci status = INPUT_DEVICE_STATUS_CLOSED; 483094332d3Sopenharmony_ci SendHotPlugEvent(type, devIndex, status); 484094332d3Sopenharmony_ci CloseInputDevice(inputDevList_[index].devPathNode); 485094332d3Sopenharmony_ci DeleteDevListNode(index); 486094332d3Sopenharmony_ci} 487094332d3Sopenharmony_ci 488094332d3Sopenharmony_ciint32_t InputDeviceManager::InotifyEventHandler(int32_t epollFd, int32_t notifyFd) 489094332d3Sopenharmony_ci{ 490094332d3Sopenharmony_ci char InfoBuf[BUFFER_SIZE]; 491094332d3Sopenharmony_ci struct inotify_event *event {}; 492094332d3Sopenharmony_ci char nodeRealPath[PATH_MAX + 1] = { '\0' }; 493094332d3Sopenharmony_ci char *p {}; 494094332d3Sopenharmony_ci int32_t tmpFd {}; 495094332d3Sopenharmony_ci 496094332d3Sopenharmony_ci (void)memset_s(InfoBuf, BUFFER_SIZE, 0, BUFFER_SIZE); 497094332d3Sopenharmony_ci int32_t result = read(notifyFd, InfoBuf, BUFFER_SIZE); 498094332d3Sopenharmony_ci for (p = InfoBuf; p < InfoBuf + result;) { 499094332d3Sopenharmony_ci event = (struct inotify_event *)(p); 500094332d3Sopenharmony_ci auto nodePath = devPath_ + "/" + string(event->name); 501094332d3Sopenharmony_ci if (event->mask & IN_CREATE) { 502094332d3Sopenharmony_ci if (realpath(nodePath.c_str(), nodeRealPath) == nullptr) { 503094332d3Sopenharmony_ci HDF_LOGE("%{public}s: The absolute path does not exist.", __func__); 504094332d3Sopenharmony_ci return INPUT_FAILURE; 505094332d3Sopenharmony_ci } 506094332d3Sopenharmony_ci tmpFd = open(nodeRealPath, O_RDWR); 507094332d3Sopenharmony_ci if (tmpFd == INPUT_FAILURE) { 508094332d3Sopenharmony_ci HDF_LOGE("%{public}s: open file failure: %{public}s", __func__, nodeRealPath); 509094332d3Sopenharmony_ci return INPUT_FAILURE; 510094332d3Sopenharmony_ci } 511094332d3Sopenharmony_ci if (nodePath.find("event") == std::string::npos) { 512094332d3Sopenharmony_ci break; 513094332d3Sopenharmony_ci } 514094332d3Sopenharmony_ci DoWithEventDeviceAdd(epollFd, tmpFd, nodePath); 515094332d3Sopenharmony_ci } else if (event->mask & IN_DELETE) { 516094332d3Sopenharmony_ci for (auto &inputDev : inputDevList_) { 517094332d3Sopenharmony_ci if (!strcmp(inputDev.second.devPathNode, nodePath.c_str())) { 518094332d3Sopenharmony_ci DoWithEventDeviceDel(epollFd, inputDev.second.index); 519094332d3Sopenharmony_ci break; 520094332d3Sopenharmony_ci } 521094332d3Sopenharmony_ci } 522094332d3Sopenharmony_ci } else { 523094332d3Sopenharmony_ci // do nothing 524094332d3Sopenharmony_ci HDF_LOGI("%{public}s: others actions has done", __func__); 525094332d3Sopenharmony_ci } 526094332d3Sopenharmony_ci p += sizeof(struct inotify_event) + event->len; 527094332d3Sopenharmony_ci } 528094332d3Sopenharmony_ci return 0; 529094332d3Sopenharmony_ci} 530094332d3Sopenharmony_ci 531094332d3Sopenharmony_ciint32_t InputDeviceManager::AddToEpoll(int32_t epollFd, int32_t fileFd) 532094332d3Sopenharmony_ci{ 533094332d3Sopenharmony_ci int32_t result {0}; 534094332d3Sopenharmony_ci struct epoll_event eventItem {}; 535094332d3Sopenharmony_ci 536094332d3Sopenharmony_ci (void)memset_s(&eventItem, sizeof(eventItem), 0, sizeof(eventItem)); 537094332d3Sopenharmony_ci eventItem.events = EPOLLIN; 538094332d3Sopenharmony_ci eventItem.data.fd = fileFd; 539094332d3Sopenharmony_ci result = epoll_ctl(epollFd, EPOLL_CTL_ADD, fileFd, &eventItem); 540094332d3Sopenharmony_ci return result; 541094332d3Sopenharmony_ci} 542094332d3Sopenharmony_civoid InputDeviceManager::RemoveEpoll(int32_t epollFd, int32_t fileFd) 543094332d3Sopenharmony_ci{ 544094332d3Sopenharmony_ci epoll_ctl(epollFd, EPOLL_CTL_DEL, fileFd, nullptr); 545094332d3Sopenharmony_ci} 546094332d3Sopenharmony_ci 547094332d3Sopenharmony_ciint32_t InputDeviceManager::FindIndexFromFd(int32_t &fd, uint32_t *index) 548094332d3Sopenharmony_ci{ 549094332d3Sopenharmony_ci std::lock_guard<std::mutex> guard(lock_); 550094332d3Sopenharmony_ci for (const auto &inputDev : inputDevList_) { 551094332d3Sopenharmony_ci if (fd == inputDev.second.fd) { 552094332d3Sopenharmony_ci *index = inputDev.first; 553094332d3Sopenharmony_ci return INPUT_SUCCESS; 554094332d3Sopenharmony_ci } 555094332d3Sopenharmony_ci } 556094332d3Sopenharmony_ci return INPUT_FAILURE; 557094332d3Sopenharmony_ci} 558094332d3Sopenharmony_ci 559094332d3Sopenharmony_ciint32_t InputDeviceManager::FindIndexFromDevName(string devName, uint32_t *index) 560094332d3Sopenharmony_ci{ 561094332d3Sopenharmony_ci std::lock_guard<std::mutex> guard(lock_); 562094332d3Sopenharmony_ci for (const auto &inputDev : inputDevList_) { 563094332d3Sopenharmony_ci if (!strcmp(devName.c_str(), inputDev.second.detailInfo.attrSet.devName)) { 564094332d3Sopenharmony_ci *index = inputDev.first; 565094332d3Sopenharmony_ci return INPUT_SUCCESS; 566094332d3Sopenharmony_ci } 567094332d3Sopenharmony_ci } 568094332d3Sopenharmony_ci return INPUT_FAILURE; 569094332d3Sopenharmony_ci} 570094332d3Sopenharmony_ci 571094332d3Sopenharmony_ci// InputManager 572094332d3Sopenharmony_ciRetStatus InputDeviceManager::ScanDevice(InputDevDesc *staArr, uint32_t arrLen) 573094332d3Sopenharmony_ci{ 574094332d3Sopenharmony_ci if (staArr == nullptr) { 575094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is null", __func__); 576094332d3Sopenharmony_ci return INPUT_NULL_PTR; 577094332d3Sopenharmony_ci } 578094332d3Sopenharmony_ci 579094332d3Sopenharmony_ci auto scanCount = (arrLen >= inputDevList_.size() ? inputDevList_.size() : arrLen); 580094332d3Sopenharmony_ci if (inputDevList_.size() == 0) { 581094332d3Sopenharmony_ci HDF_LOGE("%{public}s: inputDevList_.size is 0", __func__); 582094332d3Sopenharmony_ci return INPUT_FAILURE; 583094332d3Sopenharmony_ci } 584094332d3Sopenharmony_ci 585094332d3Sopenharmony_ci for (size_t i = 0; i <= scanCount; i++) { 586094332d3Sopenharmony_ci (staArr + i)->devIndex = inputDevList_[i].index; 587094332d3Sopenharmony_ci (staArr + i)->devType = inputDevList_[i].detailInfo.devType; 588094332d3Sopenharmony_ci } 589094332d3Sopenharmony_ci 590094332d3Sopenharmony_ci return INPUT_SUCCESS; 591094332d3Sopenharmony_ci} 592094332d3Sopenharmony_ci 593094332d3Sopenharmony_ciRetStatus InputDeviceManager::OpenDevice(uint32_t deviceIndex) 594094332d3Sopenharmony_ci{ 595094332d3Sopenharmony_ci std::lock_guard<std::mutex> guard(lock_); 596094332d3Sopenharmony_ci auto ret = INPUT_FAILURE; 597094332d3Sopenharmony_ci 598094332d3Sopenharmony_ci if (deviceIndex >= inputDevList_.size()) { 599094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 600094332d3Sopenharmony_ci return ret; 601094332d3Sopenharmony_ci } 602094332d3Sopenharmony_ci auto searchIndex = inputDevList_.find(deviceIndex); 603094332d3Sopenharmony_ci if (searchIndex != inputDevList_.end()) { 604094332d3Sopenharmony_ci if (searchIndex->second.status != INPUT_DEVICE_STATUS_OPENED) { 605094332d3Sopenharmony_ci auto openRet = OpenInputDevice(searchIndex->second.devPathNode); 606094332d3Sopenharmony_ci if (openRet > 0) { 607094332d3Sopenharmony_ci AddToEpoll(mEpollId_, openRet); 608094332d3Sopenharmony_ci ret = INPUT_SUCCESS; 609094332d3Sopenharmony_ci } else { 610094332d3Sopenharmony_ci HDF_LOGE("%{public}s: open error: %{public}d errormsg: %{public}s", 611094332d3Sopenharmony_ci __func__, openRet, strerror(errno)); 612094332d3Sopenharmony_ci return ret; 613094332d3Sopenharmony_ci } 614094332d3Sopenharmony_ci searchIndex->second.fd = openRet; 615094332d3Sopenharmony_ci } else { 616094332d3Sopenharmony_ci HDF_LOGD("%{public}s: open devPathNoth: %{public}s fd: %{public}d", 617094332d3Sopenharmony_ci __func__, searchIndex->second.devPathNode, searchIndex->second.fd); 618094332d3Sopenharmony_ci HDF_LOGD("%{public}s: open devPathNoth: %{public}s status: %{public}d index: %{public}d", 619094332d3Sopenharmony_ci __func__, searchIndex->second.devPathNode, searchIndex->second.status, searchIndex->first); 620094332d3Sopenharmony_ci AddToEpoll(mEpollId_, searchIndex->second.fd); 621094332d3Sopenharmony_ci ret = INPUT_SUCCESS; 622094332d3Sopenharmony_ci } 623094332d3Sopenharmony_ci } 624094332d3Sopenharmony_ci for (auto &e : inputDevList_) { 625094332d3Sopenharmony_ci dumpInfoList(e.second); 626094332d3Sopenharmony_ci } 627094332d3Sopenharmony_ci return ret; 628094332d3Sopenharmony_ci} 629094332d3Sopenharmony_ci 630094332d3Sopenharmony_ciRetStatus InputDeviceManager::CloseDevice(uint32_t deviceIndex) 631094332d3Sopenharmony_ci{ 632094332d3Sopenharmony_ci std::lock_guard<std::mutex> guard(lock_); 633094332d3Sopenharmony_ci auto ret = INPUT_FAILURE; 634094332d3Sopenharmony_ci 635094332d3Sopenharmony_ci if (deviceIndex >= inputDevList_.size()) { 636094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 637094332d3Sopenharmony_ci return ret; 638094332d3Sopenharmony_ci } 639094332d3Sopenharmony_ci auto searchIndex = inputDevList_.find(deviceIndex); 640094332d3Sopenharmony_ci if (searchIndex != inputDevList_.end()) { 641094332d3Sopenharmony_ci ret = CloseInputDevice(searchIndex->second.devPathNode); 642094332d3Sopenharmony_ci } 643094332d3Sopenharmony_ci HDF_LOGD("%{public}s: close devIndex: %{public}u ret: %{public}d inputDevList_ size:%{public}lu ", 644094332d3Sopenharmony_ci __func__, deviceIndex, ret, inputDevList_.size()); 645094332d3Sopenharmony_ci return ret; 646094332d3Sopenharmony_ci} 647094332d3Sopenharmony_ci 648094332d3Sopenharmony_ciint32_t InputDeviceManager::GetDevice(int32_t deviceIndex, InputDeviceInfo **devInfo) 649094332d3Sopenharmony_ci{ 650094332d3Sopenharmony_ci std::lock_guard<std::mutex> guard(lock_); 651094332d3Sopenharmony_ci auto ret = INPUT_FAILURE; 652094332d3Sopenharmony_ci 653094332d3Sopenharmony_ci if (devInfo == nullptr || deviceIndex >= static_cast<int32_t>(inputDevList_.size()) || *devInfo != nullptr) { 654094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 655094332d3Sopenharmony_ci return ret; 656094332d3Sopenharmony_ci } 657094332d3Sopenharmony_ci auto it = inputDevList_.find(deviceIndex); 658094332d3Sopenharmony_ci if (it != inputDevList_.end()) { 659094332d3Sopenharmony_ci int inputDeviceInfoSize = sizeof(InputDeviceInfo); 660094332d3Sopenharmony_ci *devInfo = reinterpret_cast<InputDeviceInfo *>(OsalMemAlloc(inputDeviceInfoSize)); 661094332d3Sopenharmony_ci if (*devInfo == nullptr) { 662094332d3Sopenharmony_ci HDF_LOGE("%{public}s: %{public}d OsalMemAlloc failed", __func__, __LINE__); 663094332d3Sopenharmony_ci return ret; 664094332d3Sopenharmony_ci } 665094332d3Sopenharmony_ci if (memcpy_s(*devInfo, inputDeviceInfoSize, &it->second.detailInfo, inputDeviceInfoSize) != EOK) { 666094332d3Sopenharmony_ci OsalMemFree(*devInfo); 667094332d3Sopenharmony_ci HDF_LOGE("%{public}s: memcpy_s failed, line: %{public}d", __func__, __LINE__); 668094332d3Sopenharmony_ci return ret; 669094332d3Sopenharmony_ci } 670094332d3Sopenharmony_ci ret = INPUT_SUCCESS; 671094332d3Sopenharmony_ci } 672094332d3Sopenharmony_ci HDF_LOGD("%{public}s: devIndex: %{public}d ret: %{public}d", __func__, deviceIndex, ret); 673094332d3Sopenharmony_ci return ret; 674094332d3Sopenharmony_ci} 675094332d3Sopenharmony_ci 676094332d3Sopenharmony_ciint32_t InputDeviceManager::GetDeviceList(uint32_t *devNum, InputDeviceInfo **deviceList, uint32_t size) 677094332d3Sopenharmony_ci{ 678094332d3Sopenharmony_ci std::lock_guard<std::mutex> guard(lock_); 679094332d3Sopenharmony_ci auto ret = INPUT_FAILURE; 680094332d3Sopenharmony_ci 681094332d3Sopenharmony_ci auto scanCount = (size >= inputDevList_.size() ? inputDevList_.size() : size); 682094332d3Sopenharmony_ci if ((devNum == nullptr) || (deviceList == nullptr) || inputDevList_.size() == 0 || *deviceList != nullptr) { 683094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 684094332d3Sopenharmony_ci return ret; 685094332d3Sopenharmony_ci } 686094332d3Sopenharmony_ci 687094332d3Sopenharmony_ci int inputDeviceInfoSize = sizeof(InputDeviceInfo); 688094332d3Sopenharmony_ci *deviceList = reinterpret_cast<InputDeviceInfo *>(OsalMemAlloc(inputDeviceInfoSize * scanCount)); 689094332d3Sopenharmony_ci if (*deviceList == nullptr) { 690094332d3Sopenharmony_ci HDF_LOGE("%{public}s: %{public}d OsalMemAlloc failed", __func__, __LINE__); 691094332d3Sopenharmony_ci return ret; 692094332d3Sopenharmony_ci } 693094332d3Sopenharmony_ci for (size_t i = 0; i < scanCount; i++) { 694094332d3Sopenharmony_ci if (memcpy_s((*deviceList) + i, inputDeviceInfoSize, &inputDevList_[i].detailInfo, inputDeviceInfoSize) != 695094332d3Sopenharmony_ci EOK) { 696094332d3Sopenharmony_ci OsalMemFree(*deviceList); 697094332d3Sopenharmony_ci HDF_LOGE("%{public}s: memcpy_s failed, line: %{public}d", __func__, __LINE__); 698094332d3Sopenharmony_ci return ret; 699094332d3Sopenharmony_ci } 700094332d3Sopenharmony_ci } 701094332d3Sopenharmony_ci *devNum = inputDevList_.size(); 702094332d3Sopenharmony_ci ret = INPUT_SUCCESS; 703094332d3Sopenharmony_ci HDF_LOGD("%{public}s: devNum: %{public}u devIndex_: %{public}d", __func__, *devNum, devIndex_); 704094332d3Sopenharmony_ci 705094332d3Sopenharmony_ci return ret; 706094332d3Sopenharmony_ci} 707094332d3Sopenharmony_ci 708094332d3Sopenharmony_ci// InputController 709094332d3Sopenharmony_ciRetStatus InputDeviceManager::SetPowerStatus(uint32_t devIndex, uint32_t status) 710094332d3Sopenharmony_ci{ 711094332d3Sopenharmony_ci RetStatus rc = INPUT_SUCCESS; 712094332d3Sopenharmony_ci if ((devIndex >= inputDevList_.size()) || (status >= INPUT_POWER_STATUS_UNKNOWN)) { 713094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 714094332d3Sopenharmony_ci return INPUT_FAILURE; 715094332d3Sopenharmony_ci } 716094332d3Sopenharmony_ci return rc; 717094332d3Sopenharmony_ci} 718094332d3Sopenharmony_ci 719094332d3Sopenharmony_ciRetStatus InputDeviceManager::GetPowerStatus(uint32_t devIndex, uint32_t *status) 720094332d3Sopenharmony_ci{ 721094332d3Sopenharmony_ci RetStatus rc = INPUT_SUCCESS; 722094332d3Sopenharmony_ci if ((devIndex >= inputDevList_.size()) || (status == nullptr)) { 723094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 724094332d3Sopenharmony_ci return INPUT_FAILURE; 725094332d3Sopenharmony_ci } 726094332d3Sopenharmony_ci return rc; 727094332d3Sopenharmony_ci} 728094332d3Sopenharmony_ci 729094332d3Sopenharmony_ciRetStatus InputDeviceManager::GetDeviceType(uint32_t devIndex, uint32_t *deviceType) 730094332d3Sopenharmony_ci{ 731094332d3Sopenharmony_ci RetStatus rc = INPUT_SUCCESS; 732094332d3Sopenharmony_ci if ((devIndex >= inputDevList_.size()) || (deviceType == nullptr)) { 733094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 734094332d3Sopenharmony_ci return INPUT_FAILURE; 735094332d3Sopenharmony_ci } 736094332d3Sopenharmony_ci 737094332d3Sopenharmony_ci *deviceType = inputDevList_[devIndex].detailInfo.devType; 738094332d3Sopenharmony_ci HDF_LOGI("%{public}s: devType: %{public}u", __func__, *deviceType); 739094332d3Sopenharmony_ci return rc; 740094332d3Sopenharmony_ci} 741094332d3Sopenharmony_ci 742094332d3Sopenharmony_ciRetStatus InputDeviceManager::GetChipInfo(uint32_t devIndex, char *chipInfo, uint32_t length) 743094332d3Sopenharmony_ci{ 744094332d3Sopenharmony_ci RetStatus rc = INPUT_SUCCESS; 745094332d3Sopenharmony_ci if ((devIndex >= inputDevList_.size()) || (chipInfo == nullptr)) { 746094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 747094332d3Sopenharmony_ci return INPUT_FAILURE; 748094332d3Sopenharmony_ci } 749094332d3Sopenharmony_ci 750094332d3Sopenharmony_ci if (memcpy_s(chipInfo, length, inputDevList_[devIndex].detailInfo.chipInfo, length) != EOK) { 751094332d3Sopenharmony_ci HDF_LOGE("%{public}s: memcpy_s failed, line: %{public}d", __func__, __LINE__); 752094332d3Sopenharmony_ci rc = INPUT_FAILURE; 753094332d3Sopenharmony_ci } 754094332d3Sopenharmony_ci HDF_LOGI("%{public}s: chipInfo: %{public}s", __func__, chipInfo); 755094332d3Sopenharmony_ci return rc; 756094332d3Sopenharmony_ci} 757094332d3Sopenharmony_ci 758094332d3Sopenharmony_ciRetStatus InputDeviceManager::GetVendorName(uint32_t devIndex, char *vendorName, uint32_t length) 759094332d3Sopenharmony_ci{ 760094332d3Sopenharmony_ci RetStatus rc = INPUT_SUCCESS; 761094332d3Sopenharmony_ci if ((devIndex >= inputDevList_.size()) || (vendorName == nullptr)) { 762094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 763094332d3Sopenharmony_ci return INPUT_FAILURE; 764094332d3Sopenharmony_ci } 765094332d3Sopenharmony_ci 766094332d3Sopenharmony_ci if (memcpy_s(vendorName, length, inputDevList_[devIndex].detailInfo.vendorName, length) != EOK) { 767094332d3Sopenharmony_ci HDF_LOGE("%{public}s: memcpy_s failed, line: %{public}d", __func__, __LINE__); 768094332d3Sopenharmony_ci rc = INPUT_FAILURE; 769094332d3Sopenharmony_ci } 770094332d3Sopenharmony_ci HDF_LOGI("%{public}s: vendorName: %{public}s", __func__, vendorName); 771094332d3Sopenharmony_ci return rc; 772094332d3Sopenharmony_ci} 773094332d3Sopenharmony_ci 774094332d3Sopenharmony_ciRetStatus InputDeviceManager::GetChipName(uint32_t devIndex, char *chipName, uint32_t length) 775094332d3Sopenharmony_ci{ 776094332d3Sopenharmony_ci RetStatus rc = INPUT_SUCCESS; 777094332d3Sopenharmony_ci if ((devIndex >= inputDevList_.size()) || (chipName == nullptr)) { 778094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 779094332d3Sopenharmony_ci return INPUT_FAILURE; 780094332d3Sopenharmony_ci } 781094332d3Sopenharmony_ci 782094332d3Sopenharmony_ci if (memcpy_s(chipName, length, inputDevList_[devIndex].detailInfo.chipName, length) != EOK) { 783094332d3Sopenharmony_ci HDF_LOGE("%{public}s: memcpy_s failed, line: %{public}d", __func__, __LINE__); 784094332d3Sopenharmony_ci rc = INPUT_FAILURE; 785094332d3Sopenharmony_ci } 786094332d3Sopenharmony_ci HDF_LOGI("%{public}s: chipName: %{public}s", __func__, chipName); 787094332d3Sopenharmony_ci return rc; 788094332d3Sopenharmony_ci} 789094332d3Sopenharmony_ci 790094332d3Sopenharmony_ciRetStatus InputDeviceManager::SetGestureMode(uint32_t devIndex, uint32_t gestureMode) 791094332d3Sopenharmony_ci{ 792094332d3Sopenharmony_ci RetStatus rc = INPUT_SUCCESS; 793094332d3Sopenharmony_ci if ((devIndex >= inputDevList_.size())) { 794094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 795094332d3Sopenharmony_ci return INPUT_FAILURE; 796094332d3Sopenharmony_ci } 797094332d3Sopenharmony_ci return rc; 798094332d3Sopenharmony_ci} 799094332d3Sopenharmony_ci 800094332d3Sopenharmony_ciRetStatus InputDeviceManager::RunCapacitanceTest(uint32_t devIndex, uint32_t testType, char *result, uint32_t length) 801094332d3Sopenharmony_ci{ 802094332d3Sopenharmony_ci RetStatus rc = INPUT_SUCCESS; 803094332d3Sopenharmony_ci if ((devIndex >= inputDevList_.size()) || (testType >= TEST_TYPE_UNKNOWN) || 804094332d3Sopenharmony_ci (result == nullptr) || (length < SELF_TEST_RESULT_LEN)) { 805094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 806094332d3Sopenharmony_ci return INPUT_FAILURE; 807094332d3Sopenharmony_ci } 808094332d3Sopenharmony_ci return rc; 809094332d3Sopenharmony_ci} 810094332d3Sopenharmony_ci 811094332d3Sopenharmony_ciRetStatus InputDeviceManager::RunExtraCommand(uint32_t devIndex, InputExtraCmd *cmd) 812094332d3Sopenharmony_ci{ 813094332d3Sopenharmony_ci RetStatus rc = INPUT_SUCCESS; 814094332d3Sopenharmony_ci if ((devIndex >= inputDevList_.size()) || (cmd == nullptr) || (cmd->cmdCode == nullptr || 815094332d3Sopenharmony_ci (cmd->cmdValue == nullptr))) { 816094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 817094332d3Sopenharmony_ci return INPUT_FAILURE; 818094332d3Sopenharmony_ci } 819094332d3Sopenharmony_ci return rc; 820094332d3Sopenharmony_ci} 821094332d3Sopenharmony_ci 822094332d3Sopenharmony_ci// InputReporter 823094332d3Sopenharmony_ciRetStatus InputDeviceManager::RegisterReportCallback(uint32_t devIndex, InputEventCb *callback) 824094332d3Sopenharmony_ci{ 825094332d3Sopenharmony_ci RetStatus rc = INPUT_SUCCESS; 826094332d3Sopenharmony_ci if ((devIndex >= inputDevList_.size()) || (callback == nullptr) || (callback->EventPkgCallback == nullptr)) { 827094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 828094332d3Sopenharmony_ci return INPUT_FAILURE; 829094332d3Sopenharmony_ci } 830094332d3Sopenharmony_ci std::lock_guard<std::mutex> guard(reportEventPkgCallBackLock_); 831094332d3Sopenharmony_ci reportEventPkgCallback_[devIndex] = callback; 832094332d3Sopenharmony_ci return rc; 833094332d3Sopenharmony_ci} 834094332d3Sopenharmony_ci 835094332d3Sopenharmony_ciRetStatus InputDeviceManager::UnregisterReportCallback(uint32_t devIndex) 836094332d3Sopenharmony_ci{ 837094332d3Sopenharmony_ci HDF_LOGI("%{public}s: %{public}d dev is unregister", __func__, devIndex); 838094332d3Sopenharmony_ci RetStatus rc = INPUT_SUCCESS; 839094332d3Sopenharmony_ci if (devIndex >= inputDevList_.size()) { 840094332d3Sopenharmony_ci HDF_LOGE("%{public}s: param is wrong", __func__); 841094332d3Sopenharmony_ci return INPUT_FAILURE; 842094332d3Sopenharmony_ci } 843094332d3Sopenharmony_ci std::lock_guard<std::mutex> guard(reportEventPkgCallBackLock_); 844094332d3Sopenharmony_ci reportEventPkgCallback_[devIndex] = nullptr; 845094332d3Sopenharmony_ci return rc; 846094332d3Sopenharmony_ci} 847094332d3Sopenharmony_ci 848094332d3Sopenharmony_ciRetStatus InputDeviceManager::RegisterHotPlugCallback(InputHostCb *callback) 849094332d3Sopenharmony_ci{ 850094332d3Sopenharmony_ci RetStatus rc = INPUT_SUCCESS; 851094332d3Sopenharmony_ci reportHotPlugEventCallback_ = callback; 852094332d3Sopenharmony_ci HDF_LOGI("%{public}s: called line %{public}d ret %{public}d", __func__, __LINE__, rc); 853094332d3Sopenharmony_ci return rc; 854094332d3Sopenharmony_ci} 855094332d3Sopenharmony_ci 856094332d3Sopenharmony_ciRetStatus InputDeviceManager::UnregisterHotPlugCallback(void) 857094332d3Sopenharmony_ci{ 858094332d3Sopenharmony_ci RetStatus rc = INPUT_SUCCESS; 859094332d3Sopenharmony_ci reportHotPlugEventCallback_ = nullptr; 860094332d3Sopenharmony_ci HDF_LOGI("%{public}s: called line %{public}d ret:%{public}d", __func__, __LINE__, rc); 861094332d3Sopenharmony_ci return rc; 862094332d3Sopenharmony_ci} 863094332d3Sopenharmony_ci 864094332d3Sopenharmony_civoid InputDeviceManager::WorkerThread() 865094332d3Sopenharmony_ci{ 866094332d3Sopenharmony_ci HDF_LOGI("%{public}s: called line %{public}d ", __func__, __LINE__); 867094332d3Sopenharmony_ci std::future<void> fuResult = std::async(std::launch::async, [this]() { 868094332d3Sopenharmony_ci DoInputDeviceAction(); 869094332d3Sopenharmony_ci return; 870094332d3Sopenharmony_ci }); 871094332d3Sopenharmony_ci fuResult.get(); 872094332d3Sopenharmony_ci} 873094332d3Sopenharmony_ci} 874094332d3Sopenharmony_ci} 875