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