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