1 /*
2 * Copyright (c) 2021 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 #include "input_manager.h"
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19 #include <limits.h>
20 #include <fcntl.h>
21 #include <malloc.h>
22 #include <sys/ioctl.h>
23 #include <securec.h>
24 #include "hdf_io_service_if.h"
25 #include "input_common.h"
26
27 #define TOUCH_INDEX 1
28 #define PLACEHOLDER_LENGTH 2
29 #define PLACEHOLDER_LIMIT 10
30
31 static InputDevManager *g_devManager;
32 int32_t InstanceReporterHdi(InputReporter **hdi);
33 int32_t InstanceControllerHdi(InputController **hdi);
34 int32_t UpdateDevFullInfo(uint32_t devIndex);
35
GetDevManager(void)36 InputDevManager *GetDevManager(void)
37 {
38 return g_devManager;
39 }
40
GetInputDevice(uint32_t devIndex,DeviceInfo ** devInfo)41 static int32_t GetInputDevice(uint32_t devIndex, DeviceInfo **devInfo)
42 {
43 int32_t ret;
44 DeviceInfoNode *pos = NULL;
45 DeviceInfoNode *next = NULL;
46 InputDevManager *manager = NULL;
47
48 if (devIndex >= MAX_INPUT_DEV_NUM || devInfo == NULL) {
49 HDF_LOGE("%s: invalid param", __func__);
50 return INPUT_INVALID_PARAM;
51 }
52
53 ret = UpdateDevFullInfo(devIndex);
54 if (ret != INPUT_SUCCESS) {
55 HDF_LOGE("%s: update dev info failed", __func__);
56 return ret;
57 }
58
59 GET_MANAGER_CHECK_RETURN(manager);
60
61 pthread_mutex_lock(&manager->mutex);
62 DLIST_FOR_EACH_ENTRY_SAFE(pos, next, &manager->devList, DeviceInfoNode, node) {
63 if (pos->payload.devIndex != devIndex) {
64 continue;
65 }
66 *devInfo = &pos->payload;
67 pthread_mutex_unlock(&manager->mutex);
68 HDF_LOGI("%s: device%u get dev info succ", __func__, devIndex);
69 return INPUT_SUCCESS;
70 }
71
72 pthread_mutex_unlock(&manager->mutex);
73 HDF_LOGE("%s: device%u doesn't exist, can't get device info", __func__, devIndex);
74 return INPUT_FAILURE;
75 }
76
GetInputDeviceList(uint32_t * devNum,DeviceInfo ** deviceList,uint32_t size)77 static int32_t GetInputDeviceList(uint32_t *devNum, DeviceInfo **deviceList, uint32_t size)
78 {
79 DeviceInfoNode *pos = NULL;
80 DeviceInfoNode *next = NULL;
81 InputDevManager *manager = NULL;
82 uint32_t tempSize = 0;
83 DeviceInfo **tempList = NULL;
84
85 if (devNum == NULL || deviceList == NULL) {
86 HDF_LOGE("%s: invalid param", __func__);
87 return INPUT_INVALID_PARAM;
88 }
89 tempList = deviceList;
90 GET_MANAGER_CHECK_RETURN(manager);
91
92 pthread_mutex_lock(&manager->mutex);
93 DLIST_FOR_EACH_ENTRY_SAFE(pos, next, &manager->devList, DeviceInfoNode, node) {
94 if (tempSize >= size) {
95 *devNum = manager->attachedDevNum;
96 pthread_mutex_unlock(&manager->mutex);
97 HDF_LOGE("%s: size is not enough, size = %u, devNum = %u", __func__,
98 size, *devNum);
99 return INPUT_FAILURE;
100 }
101 *tempList = &pos->payload;
102 tempList++;
103 tempSize++;
104 }
105 *devNum = manager->attachedDevNum;
106 pthread_mutex_unlock(&manager->mutex);
107 return INPUT_SUCCESS;
108 }
109
CloseInputDevice(uint32_t devIndex)110 static int32_t CloseInputDevice(uint32_t devIndex)
111 {
112 DeviceInfoNode *pos = NULL;
113 DeviceInfoNode *next = NULL;
114 InputDevManager *manager = NULL;
115
116 GET_MANAGER_CHECK_RETURN(manager);
117
118 pthread_mutex_lock(&manager->mutex);
119 DLIST_FOR_EACH_ENTRY_SAFE(pos, next, &manager->devList, DeviceInfoNode, node) {
120 if (pos->payload.devIndex != devIndex) {
121 continue;
122 }
123 HdfIoServiceRecycle(pos->service);
124 DListRemove(&pos->node);
125 free(pos);
126 manager->attachedDevNum--;
127 pthread_mutex_unlock(&manager->mutex);
128 return INPUT_SUCCESS;
129 }
130
131 pthread_mutex_unlock(&manager->mutex);
132 HDF_LOGE("%s: device%u doesn't exist", __func__, devIndex);
133 return INPUT_FAILURE;
134 }
135
AddService(uint32_t index,const struct HdfIoService * service)136 static int32_t AddService(uint32_t index, const struct HdfIoService *service)
137 {
138 InputDevManager *manager = NULL;
139 DeviceInfoNode *device = NULL;
140
141 GET_MANAGER_CHECK_RETURN(manager);
142 device = (DeviceInfoNode *)malloc(sizeof(DeviceInfoNode));
143 if (device == NULL) {
144 HDF_LOGE("%s: malloc fail", __func__);
145 return INPUT_NOMEM;
146 }
147 (void)memset_s(device, sizeof(DeviceInfoNode), 0, sizeof(DeviceInfoNode));
148
149 device->payload.devIndex = index;
150 device->service = (struct HdfIoService *)service;
151 pthread_mutex_lock(&manager->mutex);
152 DListInsertTail(&device->node, &manager->devList);
153 manager->attachedDevNum++;
154 pthread_mutex_unlock(&manager->mutex);
155 return INPUT_SUCCESS;
156 }
157
CheckIndex(uint32_t devIndex)158 static int32_t CheckIndex(uint32_t devIndex)
159 {
160 DeviceInfoNode *pos = NULL;
161 DeviceInfoNode *next = NULL;
162 InputDevManager *manager = NULL;
163
164 if (devIndex >= MAX_INPUT_DEV_NUM) {
165 HDF_LOGE("%s: invalid param", __func__);
166 return INPUT_INVALID_PARAM;
167 }
168
169 GET_MANAGER_CHECK_RETURN(manager);
170 pthread_mutex_lock(&manager->mutex);
171 DLIST_FOR_EACH_ENTRY_SAFE(pos, next, &manager->devList, DeviceInfoNode, node) {
172 if (pos->payload.devIndex == devIndex) {
173 pthread_mutex_unlock(&manager->mutex);
174 HDF_LOGE("%s: the device%u has existed", __func__, devIndex);
175 return INPUT_FAILURE;
176 }
177 }
178 pthread_mutex_unlock(&manager->mutex);
179 return INPUT_SUCCESS;
180 }
181
OpenInputDevice(uint32_t devIndex)182 static int32_t OpenInputDevice(uint32_t devIndex)
183 {
184 int32_t ret;
185 int32_t len;
186 struct HdfIoService *service = NULL;
187 char serviceName[SERVICE_NAME_LEN] = {0};
188
189 if (CheckIndex(devIndex) != INPUT_SUCCESS) {
190 return INPUT_FAILURE;
191 }
192
193 len = (devIndex < PLACEHOLDER_LIMIT) ? 1 : PLACEHOLDER_LENGTH;
194 ret = snprintf_s(serviceName, SERVICE_NAME_LEN, strlen("hdf_input_event") + len, "%s%u",
195 "hdf_input_event", devIndex);
196 if (ret == -1) {
197 HDF_LOGE("%s: snprintf_s fail", __func__);
198 return INPUT_FAILURE;
199 }
200
201 service = HdfIoServiceBind(serviceName);
202 if (service == NULL) {
203 HDF_LOGE("%s: fail to get io service: %s", __func__, serviceName);
204 return INPUT_NULL_PTR;
205 }
206
207 if (AddService(devIndex, service) < 0) {
208 HDF_LOGE("%s: add device%d failed", __func__, devIndex);
209 HdfIoServiceRecycle(service);
210 return INPUT_FAILURE;
211 }
212
213 HDF_LOGI("%s: open dev%u succ, service name = %s", __func__, devIndex, serviceName);
214 return INPUT_SUCCESS;
215 }
216
ScanInputDevice(DevDesc * staArr,uint32_t arrLen)217 static int32_t ScanInputDevice(DevDesc *staArr, uint32_t arrLen)
218 {
219 InputDevManager *manager = NULL;
220 struct HdfIoService *service = NULL;
221 struct HdfSBuf *reply = NULL;
222 char *data = {0};
223 uint32_t count = 0;
224 uint32_t replayDataSize = 0;
225 int32_t ret;
226
227 GET_MANAGER_CHECK_RETURN(manager);
228 pthread_mutex_lock(&manager->mutex);
229 if (manager->hostDev.service == NULL) {
230 manager->hostDev.service = HdfIoServiceBind(DEV_MANAGER_SERVICE_NAME);
231 }
232 service = manager->hostDev.service;
233 pthread_mutex_unlock(&manager->mutex);
234
235 if (service == NULL) {
236 HDF_LOGE("%s: HdfIoServiceBind failed", __func__);
237 return INPUT_FAILURE;
238 }
239 reply = HdfSbufObtainDefaultSize();
240 if (reply == NULL) {
241 HDF_LOGE("%s: fail to obtain sbuf data", __func__);
242 return INPUT_FAILURE;
243 }
244
245 ret = service->dispatcher->Dispatch(&service->object, 0, NULL, reply);
246 if (ret != INPUT_SUCCESS) {
247 HDF_LOGE("%s: dispatch fail", __func__);
248 HdfSbufRecycle(reply);
249 return INPUT_FAILURE;
250 }
251
252 while (count < arrLen) {
253 if (!HdfSbufReadBuffer(reply, (const void **)(&data), &replayDataSize) ||
254 replayDataSize != sizeof(DevDesc)) {
255 HDF_LOGE("%s: sbuf read failed", __func__);
256 break;
257 }
258 if (memcpy_s(&staArr[count], sizeof(DevDesc), data, replayDataSize) != EOK) {
259 HDF_LOGE("%s: memcpy failed, line: %d", __func__, __LINE__);
260 HdfSbufRecycle(reply);
261 return INPUT_FAILURE;
262 }
263 HDF_LOGI("%s: type = %d, id =%d", __func__, staArr[count].devType, staArr[count].devIndex);
264 count++;
265 }
266 HdfSbufRecycle(reply);
267 return INPUT_SUCCESS;
268 }
269
InstanceManagerHdi(InputManager ** manager)270 static int32_t InstanceManagerHdi(InputManager **manager)
271 {
272 InputManager *managerHdi = (InputManager *)malloc(sizeof(InputManager));
273 if (managerHdi == NULL) {
274 HDF_LOGE("%s: malloc fail", __func__);
275 return INPUT_NOMEM;
276 }
277
278 (void)memset_s(managerHdi, sizeof(InputManager), 0, sizeof(InputManager));
279
280 managerHdi->ScanInputDevice = ScanInputDevice;
281 managerHdi->OpenInputDevice = OpenInputDevice;
282 managerHdi->CloseInputDevice = CloseInputDevice;
283 managerHdi->GetInputDevice = GetInputDevice;
284 managerHdi->GetInputDeviceList = GetInputDeviceList;
285 *manager = managerHdi;
286 return INPUT_SUCCESS;
287 }
288
InitDevManager(void)289 static int32_t InitDevManager(void)
290 {
291 InputDevManager *manager = (InputDevManager *)malloc(sizeof(InputDevManager));
292 if (manager == NULL) {
293 HDF_LOGE("%s: malloc fail", __func__);
294 return INPUT_NOMEM;
295 }
296
297 (void)memset_s(manager, sizeof(InputDevManager), 0, sizeof(InputDevManager));
298 DListHeadInit(&manager->devList);
299 pthread_mutex_init(&manager->mutex, NULL);
300 manager->attachedDevNum = 0;
301 manager->evtCallbackNum = 0;
302 g_devManager = manager;
303 return INPUT_SUCCESS;
304 }
305
FreeInputHdi(IInputInterface * hdi)306 static void FreeInputHdi(IInputInterface *hdi)
307 {
308 if (hdi->iInputManager != NULL) {
309 free(hdi->iInputManager);
310 hdi->iInputManager = NULL;
311 }
312
313 if (hdi->iInputController != NULL) {
314 free(hdi->iInputController);
315 hdi->iInputController = NULL;
316 }
317
318 if (hdi->iInputReporter != NULL) {
319 free(hdi->iInputReporter);
320 hdi->iInputReporter = NULL;
321 }
322 free(hdi);
323 }
324
InstanceInputHdi(void)325 static IInputInterface *InstanceInputHdi(void)
326 {
327 int32_t ret;
328 IInputInterface *hdi = (IInputInterface *)malloc(sizeof(IInputInterface));
329 if (hdi == NULL) {
330 HDF_LOGE("%s: malloc fail", __func__);
331 return NULL;
332 }
333 (void)memset_s(hdi, sizeof(IInputInterface), 0, sizeof(IInputInterface));
334
335 ret = InstanceManagerHdi(&hdi->iInputManager);
336 if (ret != INPUT_SUCCESS) {
337 FreeInputHdi(hdi);
338 return NULL;
339 }
340
341 ret = InstanceControllerHdi(&hdi->iInputController);
342 if (ret != INPUT_SUCCESS) {
343 FreeInputHdi(hdi);
344 return NULL;
345 }
346
347 ret = InstanceReporterHdi(&hdi->iInputReporter);
348 if (ret != INPUT_SUCCESS) {
349 FreeInputHdi(hdi);
350 return NULL;
351 }
352 return hdi;
353 }
354
GetInputInterface(IInputInterface ** inputInterface)355 int32_t GetInputInterface(IInputInterface **inputInterface)
356 {
357 int32_t ret;
358 IInputInterface *inputHdi = NULL;
359
360 if (inputInterface == NULL) {
361 HDF_LOGE("%s: parameter is null", __func__);
362 return INPUT_INVALID_PARAM;
363 }
364
365 inputHdi = InstanceInputHdi();
366 if (inputHdi == NULL) {
367 HDF_LOGE("%s: failed to instance hdi", __func__);
368 return INPUT_NULL_PTR;
369 }
370
371 ret = InitDevManager();
372 if (ret != INPUT_SUCCESS) {
373 HDF_LOGE("%s: failed to initialize manager", __func__);
374 FreeInputHdi(inputHdi);
375 return INPUT_FAILURE;
376 }
377
378 *inputInterface = inputHdi;
379 HDF_LOGI("%s: exit succ", __func__);
380 return INPUT_SUCCESS;
381 }
382
FreeDevManager(InputDevManager * manager)383 static void FreeDevManager(InputDevManager *manager)
384 {
385 (void)HdfDeviceUnregisterEventListener(manager->hostDev.service, manager->hostDev.listener);
386 if (manager->hostDev.listener != NULL) {
387 free(manager->hostDev.listener);
388 manager->hostDev.listener = NULL;
389 manager->hostDev.hostCb = NULL;
390 }
391 (void)HdfIoServiceRecycle(manager->hostDev.service);
392 pthread_mutex_unlock(&manager->mutex);
393 pthread_mutex_destroy(&manager->mutex);
394 free(manager);
395 g_devManager = NULL;
396 }
397
ReleaseInputInterface(IInputInterface * inputInterface)398 void ReleaseInputInterface(IInputInterface *inputInterface)
399 {
400 DeviceInfoNode *pos = NULL;
401 DeviceInfoNode *next = NULL;
402 InputDevManager *manager = NULL;
403
404 if (inputInterface == NULL) {
405 return;
406 }
407 FreeInputHdi(inputInterface);
408 inputInterface = NULL;
409
410 if (g_devManager == NULL) {
411 return;
412 }
413 manager = g_devManager;
414 pthread_mutex_lock(&manager->mutex);
415 DLIST_FOR_EACH_ENTRY_SAFE(pos, next, &manager->devList, DeviceInfoNode, node) {
416 (void)HdfDeviceUnregisterEventListener(pos->service, pos->listener);
417 if (pos->listener != NULL) {
418 free(pos->listener);
419 pos->listener = NULL;
420 pos->eventCb = NULL;
421 }
422 (void)HdfIoServiceRecycle(pos->service);
423 DListRemove(&pos->node);
424 free(pos);
425 }
426 FreeDevManager(manager);
427 }