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