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_hid_adapter.h"
10 #include <securec.h>
11 #include "event_hub.h"
12 #include "hdf_device_desc.h"
13 #include "hdf_log.h"
14 #include "osal_mem.h"
15 #include "osal_timer.h"
16
17 #ifdef CONFIG_DFX_ZEROHUNG
18 #include <dfx/hung_wp_screen.h>
19 #endif
20
21 #define TIMER_INTERVAL 500
22 #define REPEAT_VALUE 2
23 #define MEMCPY_CHECK_RETURN(ret) do { \
24 if ((ret) != 0) { \
25 HDF_LOGE("%s: memcpy failed, line %d", __func__, __LINE__); \
26 return; \
27 } \
28 } while (0)
29
30 InputDevice *cachedHid[MAX_INPUT_DEV_NUM];
31 HidInfo *g_cachedInfo[MAX_INPUT_DEV_NUM];
32
33 uint32_t g_kbdcode = 0;
34 OsalTimer g_timer;
35
InputDriverLoaded(void)36 static bool InputDriverLoaded(void)
37 {
38 InputManager* g_inputManager = GetInputManager();
39 if ((g_inputManager != NULL) && (g_inputManager->initialized != false)) {
40 return true;
41 }
42 return false;
43 }
44
HaveHidCache(void)45 static bool HaveHidCache(void)
46 {
47 if (cachedHid[0] == NULL) {
48 return false;
49 }
50 return true;
51 }
52
LoadCachedHid(void)53 static void LoadCachedHid(void)
54 {
55 HDF_LOGI("%s: start", __func__);
56 int32_t i = 0;
57 int32_t ret;
58 static bool repeatLoadCache = false;
59 if (repeatLoadCache) {
60 HDF_LOGE("%s: no need repeat load cache", __func__);
61 return;
62 }
63 repeatLoadCache = true;
64 if (!HaveHidCache()) {
65 HDF_LOGI("%s: exit", __func__);
66 return;
67 }
68 while (i < MAX_INPUT_DEV_NUM && cachedHid[i] != NULL) {
69 ret = RegisterInputDevice(cachedHid[i]);
70 if (ret != HDF_SUCCESS) {
71 HDF_LOGE("%s: add %s failed", __func__, cachedHid[i]->devName);
72 }
73 cachedHid[i] = NULL;
74 i++;
75 }
76 }
77
cachedPosId(void)78 static int cachedPosId(void)
79 {
80 int32_t id = 0;
81 while (id < MAX_INPUT_DEV_NUM) {
82 if (g_cachedInfo[id] == NULL) {
83 return id;
84 }
85 id++;
86 }
87 return HDF_FAILURE;
88 }
89
SendInfoToHdf(HidInfo * info)90 void SendInfoToHdf(HidInfo *info)
91 {
92 int ret;
93 int32_t id = cachedPosId();
94 if (id == HDF_FAILURE) {
95 HDF_LOGE("%s: cached hid info failed", __func__);
96 return;
97 }
98 g_cachedInfo[id] = (HidInfo *)OsalMemAlloc(sizeof(HidInfo));
99 if (g_cachedInfo[id] == NULL) {
100 HDF_LOGE("%s: malloc failed", __func__);
101 return;
102 }
103 ret = memcpy_s(g_cachedInfo[id], sizeof(HidInfo), info, sizeof(HidInfo));
104 if (ret != 0) {
105 HDF_LOGE("%s: memcpy failed", __func__);
106 OsalMemFree(g_cachedInfo[id]);
107 g_cachedInfo[id] = NULL;
108 return;
109 }
110 }
111
FreeCachedInfo(void)112 static void FreeCachedInfo(void)
113 {
114 int32_t id = 0;
115 while (id < MAX_INPUT_DEV_NUM) {
116 if (g_cachedInfo[id] != NULL) {
117 OsalMemFree(g_cachedInfo[id]);
118 g_cachedInfo[id] = NULL;
119 }
120 id++;
121 }
122 }
123
SetInputDevAbsAttr(InputDevice * inputDev,const HidInfo * info)124 static int32_t SetInputDevAbsAttr(InputDevice *inputDev, const HidInfo *info)
125 {
126 int32_t ret;
127 int i;
128 for (i = 0; i < BITS_TO_LONG(ABS_CNT); i++) {
129 if (inputDev->abilitySet.absCode[i] != 0) {
130 ret = memcpy_s(inputDev->attrSet.axisInfo, sizeof(AbsAttr) * ABS_CNT,
131 info->axisInfo, sizeof(AbsAttr) * ABS_CNT);
132 return ret;
133 }
134 }
135 return HDF_SUCCESS;
136 }
137
GetInfoFromCache(InputDevice * inputDev,const HidInfo * info)138 static void GetInfoFromCache(InputDevice *inputDev, const HidInfo *info)
139 {
140 uint32_t len;
141 int32_t ret;
142
143 len = sizeof(unsigned long);
144 ret = memcpy_s(inputDev->abilitySet.devProp, len * BITS_TO_LONG(INPUT_PROP_CNT),
145 info->devProp, len * BITS_TO_LONG(INPUT_PROP_CNT));
146 MEMCPY_CHECK_RETURN(ret);
147 ret = memcpy_s(inputDev->abilitySet.eventType, len * BITS_TO_LONG(EV_CNT),
148 info->eventType, len * BITS_TO_LONG(EV_CNT));
149 MEMCPY_CHECK_RETURN(ret);
150 ret = memcpy_s(inputDev->abilitySet.absCode, len * BITS_TO_LONG(ABS_CNT),
151 info->absCode, len * BITS_TO_LONG(ABS_CNT));
152 MEMCPY_CHECK_RETURN(ret);
153 ret = memcpy_s(inputDev->abilitySet.relCode, len * BITS_TO_LONG(REL_CNT),
154 info->relCode, len * BITS_TO_LONG(REL_CNT));
155 MEMCPY_CHECK_RETURN(ret);
156 ret = memcpy_s(inputDev->abilitySet.keyCode, len * BITS_TO_LONG(KEY_CNT),
157 info->keyCode, len * BITS_TO_LONG(KEY_CNT));
158 MEMCPY_CHECK_RETURN(ret);
159 ret = memcpy_s(inputDev->abilitySet.ledCode, len * BITS_TO_LONG(LED_CNT),
160 info->ledCode, len * BITS_TO_LONG(LED_CNT));
161 MEMCPY_CHECK_RETURN(ret);
162 ret = memcpy_s(inputDev->abilitySet.miscCode, len * BITS_TO_LONG(MSC_CNT),
163 info->miscCode, len * BITS_TO_LONG(MSC_CNT));
164 MEMCPY_CHECK_RETURN(ret);
165 ret = memcpy_s(inputDev->abilitySet.soundCode, len * BITS_TO_LONG(SND_CNT),
166 info->soundCode, len * BITS_TO_LONG(SND_CNT));
167 MEMCPY_CHECK_RETURN(ret);
168 ret = memcpy_s(inputDev->abilitySet.forceCode, len * BITS_TO_LONG(FF_CNT),
169 info->forceCode, len * BITS_TO_LONG(FF_CNT));
170 MEMCPY_CHECK_RETURN(ret);
171 ret = memcpy_s(inputDev->abilitySet.switchCode, len * BITS_TO_LONG(SW_CNT),
172 info->switchCode, len * BITS_TO_LONG(SW_CNT));
173 MEMCPY_CHECK_RETURN(ret);
174 ret = SetInputDevAbsAttr(inputDev, info);
175 MEMCPY_CHECK_RETURN(ret);
176 inputDev->attrSet.id.busType = info->bustype;
177 inputDev->attrSet.id.vendor = info->vendor;
178 inputDev->attrSet.id.product = info->product;
179 inputDev->attrSet.id.version = info->version;
180 }
181
SetInputDevAbility(InputDevice * inputDev)182 static void SetInputDevAbility(InputDevice *inputDev)
183 {
184 HidInfo *info = NULL;
185 int32_t id = 0;
186
187 while (id < MAX_INPUT_DEV_NUM) {
188 if (g_cachedInfo[id] != NULL && !strcmp(inputDev->devName, g_cachedInfo[id]->devName)) {
189 info = g_cachedInfo[id];
190 break;
191 }
192 id++;
193 }
194 if (id == MAX_INPUT_DEV_NUM || info == NULL) {
195 HDF_LOGE("%s: match cached info failed", __func__);
196 return;
197 }
198
199 GetInfoFromCache(inputDev, info);
200 FreeCachedInfo();
201 }
202
HidConstructInputDev(HidInfo * info)203 static InputDevice* HidConstructInputDev(HidInfo *info)
204 {
205 InputDevice *inputDev = (InputDevice *)OsalMemAlloc(sizeof(InputDevice));
206 if (inputDev == NULL) {
207 HDF_LOGE("%s: instance input device failed", __func__);
208 return NULL;
209 }
210 (void)memset_s(inputDev, sizeof(InputDevice), 0, sizeof(InputDevice));
211
212 inputDev->devType = info->devType;
213 inputDev->devName = info->devName;
214 SetInputDevAbility(inputDev);
215
216 return inputDev;
217 }
218
DoRegisterInputDev(InputDevice * inputDev)219 static void DoRegisterInputDev(InputDevice* inputDev)
220 {
221 int32_t ret;
222 ret = RegisterInputDevice(inputDev);
223 if (ret != HDF_SUCCESS) {
224 OsalMemFree(inputDev);
225 return;
226 }
227 }
228
CacheHid(InputDevice * inputDev)229 static void CacheHid(InputDevice* inputDev)
230 {
231 HDF_LOGI("%s: Cache hid device", __func__);
232 int32_t i = 0;
233 while ((i < MAX_INPUT_DEV_NUM) && (cachedHid[i] != NULL)) {
234 i++;
235 }
236 if (i < MAX_INPUT_DEV_NUM) {
237 cachedHid[i] = inputDev;
238 return;
239 } else {
240 HDF_LOGE("%s: cached hid device failed", __func__);
241 }
242 }
243
HidRegisterHdfInputDev(HidInfo * info)244 void* HidRegisterHdfInputDev(HidInfo *info)
245 {
246 InputDevice* inputDev = HidConstructInputDev(info);
247 if (inputDev == NULL) {
248 HDF_LOGE("%s: hid construct input Dev failed", __func__);
249 return NULL;
250 }
251
252 HDF_LOGI("%s: enter devName=%s, devType=%u", __func__, info->devName, info->devType);
253 if (InputDriverLoaded()) {
254 LoadCachedHid();
255 DoRegisterInputDev(inputDev);
256 } else {
257 CacheHid(inputDev);
258 }
259 return inputDev;
260 }
261
HidUnregisterHdfInputDev(const void * inputDev)262 void HidUnregisterHdfInputDev(const void *inputDev)
263 {
264 if (inputDev == NULL) {
265 HDF_LOGE("%s: inputDev is null", __func__);
266 return;
267 }
268 UnregisterInputDevice((InputDevice *)inputDev);
269 }
270
TimerFunc(uintptr_t arg)271 static void TimerFunc(uintptr_t arg)
272 {
273 InputDevice *device = (InputDevice *)arg;
274 PushOnePackage(device, EV_KEY, g_kbdcode, REPEAT_VALUE);
275 PushOnePackage(device, 0, 0, SYN_CONFIG);
276 }
277
RepateEvent(const InputDevice * device)278 static void RepateEvent(const InputDevice *device)
279 {
280 int32_t ret;
281 static int32_t flag = 0;
282 if (flag == 1) {
283 (void)OsalTimerDelete(&g_timer);
284 }
285
286 ret = OsalTimerCreate(&g_timer, TIMER_INTERVAL, TimerFunc, (uintptr_t)device);
287 if (ret != HDF_SUCCESS) {
288 HDF_LOGE("%s: create timer failed, ret = %d", __func__, ret);
289 return;
290 }
291 ret = OsalTimerStartLoop(&g_timer);
292 if (ret != HDF_SUCCESS) {
293 HDF_LOGE("%s: start timer failed, ret = %d", __func__, ret);
294 return;
295 }
296 flag = 1;
297 }
298
HidReportEvent(const void * inputDev,uint32_t type,uint32_t code,int32_t value)299 void HidReportEvent(const void *inputDev, uint32_t type, uint32_t code, int32_t value)
300 {
301 bool loaded = InputDriverLoaded();
302 if (!loaded) {
303 HDF_LOGD("%s: device not loaded", __func__);
304 return;
305 }
306 #ifdef CONFIG_DFX_ZEROHUNG
307 if (type == EV_KEY && code == KEY_POWER)
308 hung_wp_screen_powerkey_ncb(value);
309 #endif
310 InputDevice *device = (InputDevice *)inputDev;
311 PushOnePackage(device, type, code, value);
312 if (type == EV_KEY && KEY_RESERVED < code && code < KEY_MAX && value == 0 && code == g_kbdcode) {
313 OsalTimerDelete(&g_timer);
314 g_kbdcode = 0;
315 }
316 if (type == EV_KEY && KEY_RESERVED < code && code < KEY_MAX && value == 1 &&
317 device->devType == INDEV_TYPE_KEYBOARD) {
318 g_kbdcode = code;
319 RepateEvent(device);
320 }
321 }
322
HdfHIDDriverInit(struct HdfDeviceObject * device)323 static int32_t HdfHIDDriverInit(struct HdfDeviceObject *device)
324 {
325 HDF_LOGI("%s: Hid adapter init", __func__);
326 (void)device;
327 LoadCachedHid();
328 return HDF_SUCCESS;
329 }
330
HidGetDevType(InputDevice * inputDev,struct HdfSBuf * reply)331 static int32_t HidGetDevType(InputDevice *inputDev, struct HdfSBuf *reply)
332 {
333 uint32_t devType = inputDev->devType;
334 HDF_LOGI("%s: enter, devType is %u", __func__, devType);
335 bool ret = HdfSbufWriteUint32(reply, devType);
336 if (!ret) {
337 HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__);
338 return HDF_FAILURE;
339 }
340 return HDF_SUCCESS;
341 }
342
HidGetDeviceStrInfo(InputDevice * inputDev,int32_t cmd,struct HdfSBuf * reply)343 static int32_t HidGetDeviceStrInfo(InputDevice *inputDev, int32_t cmd, struct HdfSBuf *reply)
344 {
345 const char *info = NULL;
346 if (inputDev == NULL) {
347 HDF_LOGE("%s: parameter invalid", __func__);
348 return HDF_ERR_INVALID_PARAM;
349 }
350
351 switch (cmd) {
352 case GET_CHIP_NAME:
353 info = "null";
354 break;
355 case GET_VENDOR_NAME:
356 info = "null";
357 break;
358 case GET_CHIP_INFO:
359 info = "null";
360 break;
361 default:
362 info = NULL;
363 break;
364 }
365
366 bool ret = HdfSbufWriteString(reply, info);
367 if (!ret) {
368 HDF_LOGE("%s: HdfSbufWriteUint32 failed", __func__);
369 return HDF_FAILURE;
370 }
371 HDF_LOGI("%s: cmd is %d, the info is %s", __func__, cmd, info);
372 return HDF_SUCCESS;
373 }
374
HidGetDeviceAttr(InputDevice * inputDev,struct HdfSBuf * reply)375 static int32_t HidGetDeviceAttr(InputDevice *inputDev, struct HdfSBuf *reply)
376 {
377 int32_t ret;
378 if (inputDev == NULL) {
379 return HDF_FAILURE;
380 }
381
382 ret = strncpy_s(inputDev->attrSet.devName, DEV_NAME_LEN, inputDev->devName, strlen(inputDev->devName));
383 if (ret != 0) {
384 HDF_LOGE("%s: copy name from inputDev failed, ret = %d", __func__, ret);
385 return HDF_FAILURE;
386 }
387
388 if (!HdfSbufWriteBuffer(reply, &inputDev->attrSet, sizeof(DevAttr))) {
389 HDF_LOGE("%s: sbuf write dev attr failed", __func__);
390 return HDF_FAILURE;
391 }
392
393 return HDF_SUCCESS;
394 }
395
HidGetDeviceAbility(InputDevice * inputDev,struct HdfSBuf * reply)396 static int32_t HidGetDeviceAbility(InputDevice *inputDev, struct HdfSBuf *reply)
397 {
398 if (inputDev == NULL) {
399 return HDF_FAILURE;
400 }
401
402 if (!HdfSbufWriteBuffer(reply, &inputDev->abilitySet, sizeof(DevAbility))) {
403 HDF_LOGE("%s: sbuf write dev ability failed", __func__);
404 return HDF_FAILURE;
405 }
406
407 return HDF_SUCCESS;
408 }
409
HdfHIDDispatch(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)410 static int32_t HdfHIDDispatch(struct HdfDeviceIoClient *client, int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
411 {
412 (void)cmd;
413 int32_t ret;
414 InputDevice *inputDev = NULL;
415 if (client == NULL || data == NULL || reply == NULL) {
416 HDF_LOGE("%s: param is null", __func__);
417 return HDF_FAILURE;
418 }
419
420 inputDev = (InputDevice *)client->device->priv;
421 if (inputDev == NULL) {
422 HDF_LOGE("%s: inputDev is null", __func__);
423 return HDF_FAILURE;
424 }
425
426 HDF_LOGI("%s: cmd = %d", __func__, cmd);
427 switch (cmd) {
428 case GET_DEV_TYPE:
429 ret = HidGetDevType(inputDev, reply);
430 break;
431 case GET_CHIP_NAME:
432 case GET_VENDOR_NAME:
433 case GET_CHIP_INFO:
434 ret = HidGetDeviceStrInfo(inputDev, cmd, reply);
435 break;
436 case GET_DEV_ATTR:
437 ret = HidGetDeviceAttr(inputDev, reply);
438 break;
439 case GET_DEV_ABILITY:
440 ret = HidGetDeviceAbility(inputDev, reply);
441 break;
442 default:
443 ret = HDF_SUCCESS;
444 HDF_LOGE("%s: cmd unknown, cmd = 0x%x", __func__, cmd);
445 break;
446 }
447 return ret;
448 }
449
HdfHIDDriverBind(struct HdfDeviceObject * device)450 static int32_t HdfHIDDriverBind(struct HdfDeviceObject *device)
451 {
452 if (device == NULL) {
453 return HDF_ERR_INVALID_PARAM;
454 }
455 static struct IDeviceIoService hidService = {
456 .Dispatch = HdfHIDDispatch,
457 };
458 device->service = &hidService;
459 return HDF_SUCCESS;
460 }
461
HdfHIDDriverRelease(struct HdfDeviceObject * device)462 static void HdfHIDDriverRelease(struct HdfDeviceObject *device)
463 {
464 FreeCachedInfo();
465 if (device == NULL) {
466 HDF_LOGE("%s: device is null", __func__);
467 return;
468 }
469 }
470
471 struct HdfDriverEntry g_hdfHIDEntry = {
472 .moduleVersion = 1,
473 .moduleName = "HDF_HID",
474 .Bind = HdfHIDDriverBind,
475 .Init = HdfHIDDriverInit,
476 .Release = HdfHIDDriverRelease,
477 };
478
479 HDF_INIT(g_hdfHIDEntry);
480