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 
40 namespace OHOS {
41 namespace Input {
42 using namespace std;
43 constexpr uint32_t DEV_INDEX_MAX = 32;
Init()44 void 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 
FreeEventPkgs(InputEventPackage **eventPkgs, size_t count)60 static 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
GetFiles(string path)72 vector<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 
ReportEventPkg(int32_t iFd, InputEventPackage **iEvtPkg, size_t iCount)99 void 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 
CheckReadResult(int32_t readResult)116 int32_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
DoRead(int32_t fd, struct input_event *event, size_t size)136 void 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
OpenInputDevice(string devPath)175 int32_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
CloseInputDevice(string devPath)193 RetStatus 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 
GetInputDeviceInfo(int32_t fd, InputDeviceInfo *detailInfo)211 int32_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 
GetInputDeviceTypeInfo(const string &devName)256 uint32_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 
GetInputDeviceInfoList(int32_t epollFd)275 void 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 
DoInputDeviceAction(void)318 int32_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 
DeleteDevListNode(int index)354 void 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 
AddDeviceNodeToList( int32_t &epollFd, int32_t &fd, string devPath, std::shared_ptr<InputDeviceInfo> &detailInfo)370 int32_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 
DoWithEventDeviceAdd(int32_t &epollFd, int32_t &fd, string devPath)398 void 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 
SendHotPlugEvent(uint32_t &type, uint32_t &index, uint32_t status)437 void 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 
DoWithEventDeviceDel(int32_t &epollFd, uint32_t &index)459 void 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 
InotifyEventHandler(int32_t epollFd, int32_t notifyFd)488 int32_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 
AddToEpoll(int32_t epollFd, int32_t fileFd)531 int32_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 }
RemoveEpoll(int32_t epollFd, int32_t fileFd)542 void InputDeviceManager::RemoveEpoll(int32_t epollFd, int32_t fileFd)
543 {
544     epoll_ctl(epollFd, EPOLL_CTL_DEL, fileFd, nullptr);
545 }
546 
FindIndexFromFd(int32_t &fd, uint32_t *index)547 int32_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 
FindIndexFromDevName(string devName, uint32_t *index)559 int32_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
ScanDevice(InputDevDesc *staArr, uint32_t arrLen)572 RetStatus 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 
OpenDevice(uint32_t deviceIndex)593 RetStatus 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 
CloseDevice(uint32_t deviceIndex)630 RetStatus 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 
GetDevice(int32_t deviceIndex, InputDeviceInfo **devInfo)648 int32_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 
GetDeviceList(uint32_t *devNum, InputDeviceInfo **deviceList, uint32_t size)676 int32_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
SetPowerStatus(uint32_t devIndex, uint32_t status)709 RetStatus 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 
GetPowerStatus(uint32_t devIndex, uint32_t *status)719 RetStatus 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 
GetDeviceType(uint32_t devIndex, uint32_t *deviceType)729 RetStatus 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 
GetChipInfo(uint32_t devIndex, char *chipInfo, uint32_t length)742 RetStatus 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 
GetVendorName(uint32_t devIndex, char *vendorName, uint32_t length)758 RetStatus 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 
GetChipName(uint32_t devIndex, char *chipName, uint32_t length)774 RetStatus 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 
SetGestureMode(uint32_t devIndex, uint32_t gestureMode)790 RetStatus 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 
RunCapacitanceTest(uint32_t devIndex, uint32_t testType, char *result, uint32_t length)800 RetStatus 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 
RunExtraCommand(uint32_t devIndex, InputExtraCmd *cmd)811 RetStatus 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
RegisterReportCallback(uint32_t devIndex, InputEventCb *callback)823 RetStatus 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 
UnregisterReportCallback(uint32_t devIndex)835 RetStatus 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 
RegisterHotPlugCallback(InputHostCb *callback)848 RetStatus 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 
UnregisterHotPlugCallback(void)856 RetStatus 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 
WorkerThread()864 void 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