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 #ifndef INPUT_DEVICE_MANAGER_H
17 #define INPUT_DEVICE_MANAGER_H
18 
19 #include <functional>
20 #include <linux/input.h>
21 #include <list>
22 #include <map>
23 #include <mutex>
24 #include <pthread.h>
25 #include <sys/epoll.h>
26 #include <thread>
27 #include <unistd.h>
28 #include <vector>
29 #include "hdf_log.h"
30 #include "input_manager.h"
31 
32 namespace OHOS {
33 namespace Input {
34 using namespace std;
35 #define EPOLL_WAIT_TIMEOUT  (-1)
36 #define DEVICE_INFO_SIZE    (64)
37 #define EPOLL_MAX_EVENTS    (32)
38 #define MAX_SUPPORT_DEVS    (32)
39 #define BUFFER_SIZE         (1024)
40 #define ARRAY_LENGTH        (128)
41 #define NAME_LENGTH         (128)
42 #define EVENT_BUFFER_SIZE   (512)
43 #define MS_THOUSAND         (1000)
44 
45 enum InputDeviceStatus {
46     INPUT_DEVICE_STATUS_OPENED = 1,
47     INPUT_DEVICE_STATUS_CLOSED,
48     INPUT_DEVICE_STATUS_UNKNOWN
49 };
50 
51 // manager the device node list
52 typedef struct {
53     uint32_t index;
54     uint32_t status;
55     int32_t fd;
56     char devPathNode[DEV_NAME_LEN];
57     InputDeviceInfo detailInfo;
58 } InputDevListNode;
59 
60 class InputDeviceManager {
61 public:
62     InputDeviceManager() = default;
~InputDeviceManager()63     virtual ~InputDeviceManager()
64     {
65         inputDevList_.clear();
66         reportEventPkgCallback_.clear();
67     };
68     InputDeviceManager(const InputDeviceManager &other) = delete;
69     InputDeviceManager(InputDeviceManager &&other) = delete;
70     InputDeviceManager &operator=(const InputDeviceManager &other) = delete;
71     InputDeviceManager &operator=(InputDeviceManager &&other) = delete;
72     void Init(void);
73     vector<string> GetFiles(string path);
74     void DoRead(int32_t fd, struct input_event *event, size_t size);
75     int32_t OpenInputDevice(string devPath);
76     RetStatus CloseInputDevice(string devPath);
77     int32_t GetInputDeviceInfo(int32_t fd, InputDeviceInfo *detailInfo);
78     void GetInputDeviceInfoList();
79     int32_t DoInputDeviceAction(void);
80     int32_t InotifyEventHandler(int32_t epollFd, int32_t notifyFd);
81     void RemoveEpoll(int32_t epollFd, int32_t fileFd);
82     int32_t AddToEpoll(int32_t epollFd, int32_t fileFd);
83     void WorkerThread();
84     int32_t FindIndexFromFd(int32_t &fd, uint32_t *index);
85     int32_t FindIndexFromDevName(string devName, uint32_t *index);
86     void DoWithEventDeviceAdd(int32_t &epollFd, int32_t &fd, string devPath);
87     void SendHotPlugEvent(uint32_t &type, uint32_t &index, uint32_t status);
88     void DoWithEventDeviceDel(int32_t &epollFd, uint32_t &index);
89     void ReportEventPkg(int32_t iFd, InputEventPackage **iEvtPkg, size_t iCount);
90     // InputManager
91     RetStatus ScanDevice(InputDevDesc *staArr, uint32_t arrLen);
92     RetStatus OpenDevice(uint32_t deviceIndex);
93     RetStatus CloseDevice(uint32_t deviceIndex);
94     int32_t GetDevice(int32_t deviceIndex, InputDeviceInfo **devInfo);
95     int32_t GetDeviceList(uint32_t *devNum, InputDeviceInfo **deviceList, uint32_t size);
96     // InputController
97     RetStatus SetPowerStatus(uint32_t devIndex, uint32_t status);
98     RetStatus GetPowerStatus(uint32_t devIndex, uint32_t *status);
99     RetStatus GetDeviceType(uint32_t devIndex, uint32_t *deviceType);
100     RetStatus GetChipInfo(uint32_t devIndex, char *chipInfo, uint32_t length);
101     RetStatus GetVendorName(uint32_t devIndex, char *vendorName, uint32_t length);
102     RetStatus GetChipName(uint32_t devIndex, char *chipName, uint32_t length);
103     RetStatus SetGestureMode(uint32_t devIndex, uint32_t gestureMode);
104     RetStatus RunCapacitanceTest(uint32_t devIndex, uint32_t testType, char *result, uint32_t length);
105     RetStatus RunExtraCommand(uint32_t devIndex, InputExtraCmd *cmd);
106     // InputReporter
107     RetStatus RegisterReportCallback(uint32_t devIndex, InputEventCb *callback);
108     RetStatus UnregisterReportCallback(uint32_t devIndex);
109     RetStatus RegisterHotPlugCallback(InputHostCb *callback);
110     RetStatus UnregisterHotPlugCallback(void);
dumpInfoList(InputDevListNode in)111     void dumpInfoList(InputDevListNode in)
112     {
113         HDF_LOGD("%{public}s index: %{public}u state:%{public}u fd:%{public}d devPathNode:%{public}s", __func__,
114                  in.index, in.status, in.fd, in.devPathNode);
115         HDF_LOGD("devIndex: %{public}u devType:%{public}u chipInfo:%{public}s "
116                  "vendorName: %{public}s chipName: %{public}s attrSet.devName: %s "
117                  "attrSet.id.busType: %{public}u attrSet.id.vendor: %{public}u "
118                  "attrSet.id.product: %{public}u attrSet.id.version: %{public}u ",
119                  in.detailInfo.devIndex, in.detailInfo.devType,
120                  in.detailInfo.chipInfo, in.detailInfo.vendorName,
121                  in.detailInfo.chipName, in.detailInfo.attrSet.devName,
122                  in.detailInfo.attrSet.id.busType, in.detailInfo.attrSet.id.vendor,
123                  in.detailInfo.attrSet.id.product, in.detailInfo.attrSet.id.version);
124         for (int32_t i = 0; i < ABS_CNT; i++) {
125             HDF_LOGD("attrSet.axisInfo.axis: %{public}d attrSet.axisInfo.min: %{public}d "
126                      "attrSet.axisInfo.max: %{public}d attrSet.axisInfo.fuzz: %{public}d "
127                      "attrSet.axisInfo.flat: %{public}d attrSet.axisInfo.range: %{public}d ",
128                      in.detailInfo.attrSet.axisInfo[i].axis, in.detailInfo.attrSet.axisInfo[i].flat,
129                      in.detailInfo.attrSet.axisInfo[i].fuzz, in.detailInfo.attrSet.axisInfo[i].max,
130                      in.detailInfo.attrSet.axisInfo[i].min, in.detailInfo.attrSet.axisInfo[i].range);
131         }
132     }
133 private:
134     void DeleteDevListNode(int index);
135     int32_t AddDeviceNodeToList(
136         int32_t &epollFd, int32_t &fd, string devPath, std::shared_ptr<InputDeviceInfo> &detailInfo);
137     int32_t GetCurDevIndex();
138     void LoadInputDevices(std::vector<std::string> &flist);
139     void ReloadInputDevices(std::vector<std::string> flist);
140     int32_t CreateInputDevListNode(InputDevListNode &inputDevNode, std::string &fileName);
141 
142     mutable std::mutex lock_;
143     std::mutex reportEventPkgCallBackLock_;
144     std::map<uint32_t, InputDevListNode> inputDevList_;
145     struct epoll_event epollEventList_[EPOLL_MAX_EVENTS] {};
146     std::string devPath_ {"/dev/input"};
147     uint32_t devIndex_ {1};
148     std::map<int32_t, InputEventCb*> reportEventPkgCallback_;
149     InputHostCb *reportHotPlugEventCallback_ = nullptr;
150     std::thread thread_ {};
151     int32_t mEpollId_ {0};
152     int32_t mInotifyId_ {0};
153 };
154 }
155 }
156 #endif // INPUT_DEVICE_MANAGER_H
157