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