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