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