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