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