1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "hdf_input_device_manager.h"
10 #include <securec.h>
11 #include "event_hub.h"
12 #include "hdf_base.h"
13 #include "hdf_device_object.h"
14 #include "hdf_log.h"
15 #include "osal_mem.h"
16 
17 #define NODE_MODE            0660
18 #define SERVICE_NAME_LEN     24
19 #define QUEUE_NAME_LEN       18
20 #define INPUT_DEV_EXIST      1
21 #define INPUT_DEV_NOT_EXIST  0
22 #define INPUTDEV_FIRST_ID    2
23 #define FILLER_FLAG          1
24 #define PLACEHOLDER_LENGTH   2
25 #define PLACEHOLDER_LIMIT    10
26 
27 static InputManager *g_inputManager;
28 
GetInputManager(void)29 InputManager* GetInputManager(void)
30 {
31     return g_inputManager;
32 }
33 
IsHidDevice(InputDevice * inputDev)34 static bool IsHidDevice(InputDevice *inputDev)
35 {
36     if ((inputDev->devType > INDEV_TYPE_HID_BEGIN_POS) && (inputDev->devType < INDEV_TYPE_UNKNOWN)) {
37         return true;
38 #ifdef CONFIG_ARCH_ROCKCHIP
39     } else if (strncmp(inputDev->devName, "hid-powerkey", strlen("hid-powerkey")) == 0) {
40         return true;
41 #endif
42     }
43     return false;
44 }
45 
HidRegisterHdfDevice(InputDevice * inputDev)46 static struct HdfDeviceObject *HidRegisterHdfDevice(InputDevice *inputDev)
47 {
48     char svcName[SERVICE_NAME_LEN] = {0};
49     const char *moduleName = "HDF_HID";
50     struct HdfDeviceObject *hdfDev = NULL;
51 
52     int32_t len = (inputDev->devId < PLACEHOLDER_LIMIT) ? 1 : PLACEHOLDER_LENGTH;
53     int32_t ret = snprintf_s(svcName, SERVICE_NAME_LEN, strlen("hdf_input_event") + len, "%s%u",
54         "hdf_input_event", inputDev->devId);
55     if (ret < 0) {
56         HDF_LOGE("%s: snprintf_s failed", __func__);
57         return NULL;
58     }
59 
60     hdfDev = HdfDeviceObjectAlloc(g_inputManager->hdfDevObj, moduleName);
61     if (hdfDev == NULL) {
62         HDF_LOGE("%s: failed to alloc device object", __func__);
63         return NULL;
64     }
65     ret = HdfDeviceObjectRegister(hdfDev);
66     if (ret != HDF_SUCCESS) {
67         HDF_LOGE("%s: failed to register device %s", __func__, moduleName);
68         HdfDeviceObjectRelease(hdfDev);
69         return NULL;
70     }
71     ret = HdfDeviceObjectPublishService(hdfDev, svcName, SERVICE_POLICY_CAPACITY, 0664); // 0664:permission setting
72     if (ret != HDF_SUCCESS) {
73         HDF_LOGE("%s: failed to register device %s", __func__, moduleName);
74         HdfDeviceObjectRelease(hdfDev);
75         return NULL;
76     }
77     inputDev->hdfDevObj = hdfDev;
78     HDF_LOGI("%s: svcName is %s, devName = %s", __func__, svcName, inputDev->devName);
79     return hdfDev;
80 }
81 
HotPlugNotify(const InputDevice * inputDev,uint32_t status)82 static void HotPlugNotify(const InputDevice *inputDev, uint32_t status)
83 {
84     HotPlugEvent event = {0};
85     int32_t ret;
86 
87     if (inputDev->eventBuf == NULL) {
88         HDF_LOGE("%s: event buffer is null", __func__);
89         return;
90     }
91 
92     event.devId = inputDev->devId;
93     event.devType = inputDev->devType;
94     event.status = status;
95 
96     if (!HdfSbufWriteBuffer(inputDev->eventBuf, &event, sizeof(HotPlugEvent))) {
97         HDF_LOGE("%s: write buffer failed", __func__);
98         HdfSbufFlush(inputDev->eventBuf);
99         return;
100     }
101     ret = HdfDeviceSendEvent(g_inputManager->hdfDevObj, 0, inputDev->eventBuf);
102     if (ret != HDF_SUCCESS) {
103         HDF_LOGE("%s: send event failed", __func__);
104     }
105     HdfSbufFlush(inputDev->eventBuf);
106 }
107 
CreateDeviceNode(InputDevice * inputDev)108 static int32_t CreateDeviceNode(InputDevice *inputDev)
109 {
110     if (IsHidDevice(inputDev)) {
111         HDF_LOGI("%s: prepare to register hdf device", __func__);
112         inputDev->hdfDevObj = HidRegisterHdfDevice(inputDev);
113         if (inputDev->hdfDevObj == NULL) {
114             return HDF_DEV_ERR_NO_DEVICE;
115         }
116         inputDev->hdfDevObj->priv = (void *)inputDev;
117     }
118 
119     HDF_LOGI("%s: create node succ, devId is %d ", __func__, inputDev->devId);
120     return HDF_SUCCESS;
121 }
122 
DeleteDeviceNode(InputDevice * inputDev)123 static void DeleteDeviceNode(InputDevice *inputDev)
124 {
125     if (IsHidDevice(inputDev)) {
126         HDF_LOGI("remove input device: hdf_input_event%u", inputDev->devId);
127         HdfDeviceObjectRelease(inputDev->hdfDevObj);
128     }
129 
130     HDF_LOGI("%s: delete node succ, devId is %d", __func__, inputDev->devId);
131 }
132 
AddInputDevice(InputDevice * inputDev)133 static void AddInputDevice(InputDevice *inputDev)
134 {
135     InputDevice *tmpDev = NULL;
136     if (g_inputManager->inputDevList == NULL) {
137         g_inputManager->inputDevList = inputDev;
138         (g_inputManager->inputDevList)->next = NULL;
139     } else {
140         tmpDev = g_inputManager->inputDevList;
141         while (tmpDev != NULL) {
142             if (tmpDev->next == NULL) {
143                 tmpDev->next = inputDev;
144                 inputDev->next = NULL;
145                 break;
146             }
147             tmpDev = tmpDev->next;
148         }
149     }
150     g_inputManager->devCount++;
151     HotPlugNotify(inputDev, ONLINE);
152 }
153 
CheckInputDevice(InputDevice * inputDev)154 static int32_t CheckInputDevice(InputDevice *inputDev)
155 {
156     InputDevice *tmpDev = NULL;
157     if (g_inputManager->inputDevList == NULL) {
158         return HDF_SUCCESS;
159     } else {
160         tmpDev = g_inputManager->inputDevList;
161         while (tmpDev != NULL) {
162             if (tmpDev->devId == inputDev->devId) {
163                 HDF_LOGE("%s: device%d registered", __func__, inputDev->devId);
164                 return INPUT_DEV_EXIST;
165             }
166             tmpDev = tmpDev->next;
167         }
168     }
169     return INPUT_DEV_NOT_EXIST;
170 }
171 
DeleteInputDevice(InputDevice * inputDev)172 static int32_t DeleteInputDevice(InputDevice *inputDev)
173 {
174     if (g_inputManager->inputDevList == NULL) {
175         return HDF_FAILURE;
176     } else {
177         if ((g_inputManager->inputDevList)->devId == inputDev->devId) {
178             g_inputManager->inputDevList = g_inputManager->inputDevList->next;
179             goto EXIT;
180         }
181 
182         InputDevice *preNode = g_inputManager->inputDevList;
183         InputDevice *tmpDev = preNode->next;
184         while (tmpDev != NULL) {
185             if (tmpDev->devId == inputDev->devId) {
186                 preNode->next = tmpDev->next;
187                 goto EXIT;
188             }
189             preNode = tmpDev;
190             tmpDev = tmpDev->next;
191         }
192         HDF_LOGE("%s: device%d not exist", __func__, inputDev->devId);
193         return HDF_FAILURE;
194     }
195 
196 EXIT:
197     g_inputManager->devCount--;
198     HotPlugNotify(inputDev, OFFLINE);
199     return HDF_SUCCESS;
200 }
201 
202 #define DEFAULT_TOUCH_BUF_PKG_NUM      50
203 #define DEFAULT_KEY_BUF_PKG_NUM        10
204 #define DEFAULT_MOUSE_BUF_PKG_NUM      30
205 #define DEFAULT_KEYBOARD_BUF_PKG_NUM   20
206 #define DEFAULT_CROWN_BUF_PKG_NUM      20
207 #define DEFAULT_ENCODER_BUF_PKG_NUM    20
208 #define DEFAULT_ROCKER_BUF_PKG_NUM     40
209 #define DEFAULT_TRACKBALL_BUF_PKG_NUM  30
210 
AllocPackageBuffer(InputDevice * inputDev)211 static int32_t AllocPackageBuffer(InputDevice *inputDev)
212 {
213     uint16_t pkgNum;
214     switch (inputDev->devType) {
215         case INDEV_TYPE_TOUCH:
216             pkgNum = DEFAULT_TOUCH_BUF_PKG_NUM;
217             break;
218         case INDEV_TYPE_KEY:
219             pkgNum = DEFAULT_KEY_BUF_PKG_NUM;
220             break;
221         case INDEV_TYPE_MOUSE:
222             pkgNum = DEFAULT_MOUSE_BUF_PKG_NUM;
223             break;
224         case INDEV_TYPE_KEYBOARD:
225             pkgNum = DEFAULT_KEYBOARD_BUF_PKG_NUM;
226             break;
227         case INDEV_TYPE_CROWN:
228             pkgNum = DEFAULT_CROWN_BUF_PKG_NUM;
229             break;
230         case INDEV_TYPE_ENCODER:
231             pkgNum = DEFAULT_ENCODER_BUF_PKG_NUM;
232             break;
233         case INDEV_TYPE_ROCKER:
234             pkgNum = DEFAULT_ROCKER_BUF_PKG_NUM;
235             break;
236         case INDEV_TYPE_TRACKBALL:
237             pkgNum = DEFAULT_TRACKBALL_BUF_PKG_NUM;
238             break;
239         default:
240             HDF_LOGE("%s: devType not exist", __func__);
241             return HDF_FAILURE;
242     }
243     inputDev->pkgBuf = HdfSbufObtain(sizeof(EventPackage) * pkgNum);
244     if (inputDev->pkgBuf == NULL) {
245         HDF_LOGE("%s: malloc sbuf failed", __func__);
246         return HDF_ERR_MALLOC_FAIL;
247     }
248     inputDev->eventBuf = HdfSbufObtain(sizeof(HotPlugEvent));
249     if (inputDev->eventBuf == NULL) {
250         HDF_LOGE("%s: malloc sbuf failed", __func__);
251         return HDF_ERR_MALLOC_FAIL;
252     }
253     inputDev->pkgNum = pkgNum;
254     return HDF_SUCCESS;
255 }
256 
AllocDeviceID(InputDevice * inputDev)257 static int32_t AllocDeviceID(InputDevice *inputDev)
258 {
259     InputDevice *tmpDev = g_inputManager->inputDevList;
260     uint32_t idList[MAX_INPUT_DEV_NUM + 1];
261     uint32_t id;
262     int32_t ret;
263     ret = memset_s(idList, (MAX_INPUT_DEV_NUM + 1) * sizeof(uint32_t), 0,
264                    (MAX_INPUT_DEV_NUM + 1) * sizeof(uint32_t));
265     if (ret != 0) {
266         HDF_LOGE("%s: memset_s is failed", __func__);
267         return HDF_FAILURE;
268     }
269     while (tmpDev != NULL) {
270         if (idList[tmpDev->devId] == 0) {
271             idList[tmpDev->devId] = FILLER_FLAG;
272         }
273         tmpDev = tmpDev->next;
274     }
275 
276     if (inputDev->devType == INDEV_TYPE_TOUCH) {
277         inputDev->devId = 1;
278         return HDF_SUCCESS;
279     }
280     for (id = INPUTDEV_FIRST_ID; id < MAX_INPUT_DEV_NUM + 1; id++) {
281         if (idList[id] == 0) {
282             inputDev->devId = id;
283             return HDF_SUCCESS;
284         }
285     }
286     HDF_LOGE("%s: alloc device id failed", __func__);
287     return HDF_FAILURE;
288 }
289 
290 #ifndef __LITEOS_M__
InitEventWorkQueue(InputDevice * inputDev)291 static int32_t InitEventWorkQueue(InputDevice *inputDev)
292 {
293     char queueName[QUEUE_NAME_LEN] = {0};
294 
295     int32_t len = (inputDev->devId < PLACEHOLDER_LIMIT) ? 1 : PLACEHOLDER_LENGTH;
296     int32_t ret = snprintf_s(queueName, QUEUE_NAME_LEN, strlen("hdf_event") + len + strlen("_queue"), "%s%u%s",
297         "hdf_event", inputDev->devId, "_queue");
298     if (ret < 0) {
299         HDF_LOGE("%s: snprintf_s failed", __func__);
300         return HDF_FAILURE;
301     }
302     if (HdfWorkQueueInit(&inputDev->eventWorkQueue, queueName) != HDF_SUCCESS) {
303         HDF_LOGE("%s: device %s init work queue failed", __func__, inputDev->devName);
304         return HDF_FAILURE;
305     }
306     if (HdfWorkInit(&inputDev->eventWork, EventQueueWorkEntry, inputDev) != HDF_SUCCESS) {
307         HDF_LOGE("%s: create event thread failed", __func__);
308         return HDF_FAILURE;
309     }
310     return HDF_SUCCESS;
311 }
312 #endif // __LITEOS_M__
313 
RegisterInputDevice(InputDevice * inputDev)314 int32_t RegisterInputDevice(InputDevice *inputDev)
315 {
316     int32_t ret;
317 
318     HDF_LOGI("%s: enter", __func__);
319     if (inputDev == NULL) {
320         HDF_LOGE("%s: inputdev is null", __func__);
321         return HDF_ERR_INVALID_PARAM;
322     }
323 
324     if ((g_inputManager == NULL) || (g_inputManager->initialized == false)) {
325         HDF_LOGE("%s: dev manager is null or initialized failed", __func__);
326         return HDF_FAILURE;
327     }
328     HDF_LOGI("%s: enter devName=%s, devType=%u", __func__, inputDev->devName, inputDev->devType);
329 
330     OsalMutexLock(&g_inputManager->mutex);
331     ret = AllocDeviceID(inputDev);
332     if (ret != HDF_SUCCESS) {
333         goto EXIT;
334     }
335     ret = CreateDeviceNode(inputDev);
336     if (ret != HDF_SUCCESS) {
337         goto EXIT1;
338     }
339 
340     ret = AllocPackageBuffer(inputDev);
341     if (ret != HDF_SUCCESS) {
342         goto EXIT1;
343     }
344 #ifndef __LITEOS_M__
345     ret = InitEventWorkQueue(inputDev);
346     if (ret != HDF_SUCCESS) {
347         goto EXIT1;
348     }
349 #endif // __LITEOS_M__
350     AddInputDevice(inputDev);
351     OsalMutexUnlock(&g_inputManager->mutex);
352     HDF_LOGI("%s: exit succ, devCount is %d", __func__, g_inputManager->devCount);
353     return HDF_SUCCESS;
354 
355 EXIT1:
356     DeleteDeviceNode(inputDev);
357 EXIT:
358     OsalMutexUnlock(&g_inputManager->mutex);
359     return ret;
360 }
361 
UnregisterInputDevice(InputDevice * inputDev)362 void UnregisterInputDevice(InputDevice *inputDev)
363 {
364     int32_t ret;
365     HDF_LOGI("%s: enter", __func__);
366     if (inputDev == NULL) {
367         HDF_LOGE("%s: inputdev is null", __func__);
368         return;
369     }
370 
371     if ((g_inputManager == NULL) || (g_inputManager->initialized == false)) {
372         HDF_LOGE("%s: dev manager is null or initialized failed", __func__);
373         return;
374     }
375 
376     OsalMutexLock(&g_inputManager->mutex);
377     if (CheckInputDevice(inputDev) == INPUT_DEV_NOT_EXIST) {
378         HDF_LOGE("%s: dev%d not exist", __func__, inputDev->devId);
379         goto EXIT;
380     }
381 
382     DeleteDeviceNode(inputDev);
383     HdfSbufRecycle(inputDev->pkgBuf);
384     inputDev->pkgBuf = NULL;
385     ret = DeleteInputDevice(inputDev);
386     if (ret != HDF_SUCCESS) {
387         goto EXIT;
388     }
389     HdfSbufRecycle(inputDev->eventBuf);
390     inputDev->eventBuf = NULL;
391 #ifndef __LITEOS_M__
392     HdfWorkQueueDestroy(&inputDev->eventWorkQueue);
393     HdfWorkDestroy(&inputDev->eventWork);
394 #endif // __LITEOS_M__
395     OsalMemFree(inputDev);
396     inputDev = NULL;
397     OsalMutexUnlock(&g_inputManager->mutex);
398     HDF_LOGI("%s: exit succ, devCount is %d", __func__, g_inputManager->devCount);
399     return;
400 
401 EXIT:
402     OsalMutexUnlock(&g_inputManager->mutex);
403     return;
404 }
405 
GetDeviceCount(void)406 static uint32_t GetDeviceCount(void)
407 {
408     HDF_LOGI("%s: devCount = %d", __func__, g_inputManager->devCount);
409     return g_inputManager->devCount;
410 }
411 
ScanAllDev(struct HdfSBuf * reply)412 static int32_t ScanAllDev(struct HdfSBuf *reply)
413 {
414     DevDesc sta;
415     InputDevice *tmpDev = g_inputManager->inputDevList;
416     while (tmpDev != NULL) {
417         sta.devType = tmpDev->devType;
418         sta.devId = tmpDev->devId;
419 
420         if (!HdfSbufWriteBuffer(reply, &sta, sizeof(DevDesc))) {
421             HDF_LOGE("%s: HdfSbufWriteBuffer failed", __func__);
422             return HDF_FAILURE;
423         }
424         tmpDev = tmpDev->next;
425     }
426     HdfSbufWriteBuffer(reply, NULL, 0); // end flag
427     return HDF_SUCCESS;
428 }
429 
ScanDevice(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)430 static int32_t ScanDevice(struct HdfDeviceIoClient *client, int32_t cmd,
431     struct HdfSBuf *data, struct HdfSBuf *reply)
432 {
433     (void)cmd;
434     int32_t ret;
435     if ((client == NULL) || (data == NULL) || (reply == NULL)) {
436         HDF_LOGE("%s: param is null", __func__);
437         return HDF_FAILURE;
438     }
439     ret = ScanAllDev(reply);
440     if (ret != HDF_SUCCESS) {
441         HDF_LOGE("%s: scan all dev failed", __func__);
442     }
443     return ret;
444 }
445 
HdfInputManagerBind(struct HdfDeviceObject * device)446 static int32_t HdfInputManagerBind(struct HdfDeviceObject *device)
447 {
448     if (device == NULL) {
449         HDF_LOGE("%s: device is null", __func__);
450         return HDF_ERR_INVALID_PARAM;
451     }
452 
453     static IInputManagerService managerService = {
454         .getDeviceCount = GetDeviceCount,
455         .ioService.Dispatch = ScanDevice,
456     };
457 
458     device->service = &managerService.ioService;
459     return HDF_SUCCESS;
460 }
461 
InputManagerInstance(void)462 static InputManager *InputManagerInstance(void)
463 {
464     InputManager *manager = (InputManager *)OsalMemAlloc(sizeof(InputManager));
465     if (manager == NULL) {
466         HDF_LOGE("%s: instance input manager failed", __func__);
467         return NULL;
468     }
469     (void)memset_s(manager, sizeof(InputManager), 0, sizeof(InputManager));
470     return manager;
471 }
472 
HdfInputManagerInit(struct HdfDeviceObject * device)473 static int32_t HdfInputManagerInit(struct HdfDeviceObject *device)
474 {
475     HDF_LOGI("%s: enter", __func__);
476     if (device == NULL) {
477         HDF_LOGE("%s: device is null", __func__);
478         return HDF_ERR_INVALID_PARAM;
479     }
480 
481     g_inputManager = InputManagerInstance();
482     if (g_inputManager == NULL) {
483         return HDF_ERR_MALLOC_FAIL;
484     }
485 
486     if (OsalMutexInit(&g_inputManager->mutex) != HDF_SUCCESS) {
487         HDF_LOGE("%s: mutex init failed", __func__);
488         OsalMemFree(g_inputManager);
489         g_inputManager = NULL;
490         return HDF_FAILURE;
491     }
492 
493     if (OsalSpinInit(&g_inputManager->lock) != HDF_SUCCESS) {
494         HDF_LOGE("%s: spin lock init failed", __func__);
495         OsalMemFree(g_inputManager);
496         g_inputManager = NULL;
497         return HDF_FAILURE;
498     }
499     g_inputManager->initialized = true;
500     g_inputManager->hdfDevObj = device;
501     HDF_LOGI("%s: exit succ", __func__);
502     return HDF_SUCCESS;
503 }
504 
HdfInputManagerRelease(struct HdfDeviceObject * device)505 static void HdfInputManagerRelease(struct HdfDeviceObject *device)
506 {
507     if (device == NULL) {
508         HDF_LOGE("%s: device is null", __func__);
509         return;
510     }
511     if (g_inputManager != NULL) {
512         OsalMutexDestroy(&g_inputManager->mutex);
513         OsalSpinDestroy(&g_inputManager->lock);
514         OsalMemFree(g_inputManager);
515         g_inputManager = NULL;
516     }
517 }
518 
519 struct HdfDriverEntry g_hdfInputEntry = {
520     .moduleVersion = 1,
521     .moduleName = "HDF_INPUT_MANAGER",
522     .Bind = HdfInputManagerBind,
523     .Init = HdfInputManagerInit,
524     .Release = HdfInputManagerRelease,
525 };
526 
527 HDF_INIT(g_hdfInputEntry);
528