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_common.h"
16 #include <hdf_base.h>
17 #include <hdf_log.h>
18 #include <osal_mem.h>
19 #include <hdf_device_desc.h>
20 #include <stdlib.h>
21 #include <securec.h>
22
23 #define DEV_MANAGER_SERVICE_NAME "hdf_input_host"
24 #define SHELL_LEN 50
25 #define ONLINE 0
26
27 static InputDevManager *g_hotPlugManager;
28 static InputHostCb hotPlug;
29
HotPlugCallback(const HotPlugEvent * msg)30 static void HotPlugCallback(const HotPlugEvent *msg)
31 {
32 int32_t ret;
33 char shell[SHELL_LEN];
34 if (msg == NULL) {
35 HDF_LOGE("msg is null");
36 return;
37 }
38 if (msg->status == ONLINE) {
39 ret = sprintf_s(shell, SHELL_LEN, "chown system:system /dev/hdf_input_event%d", msg->devIndex);
40 if (ret < 0) {
41 HDF_LOGE("%s: sprintf shell cmd failed", __func__);
42 return;
43 }
44 system(shell);
45 }
46 }
47
HotPlugEventListenerCallback(struct HdfDevEventlistener * listener,struct HdfIoService * service,uint32_t id,struct HdfSBuf * data)48 static int32_t HotPlugEventListenerCallback(struct HdfDevEventlistener *listener,
49 struct HdfIoService *service, uint32_t id, struct HdfSBuf *data)
50 {
51 (void)listener;
52 (void)id;
53 uint32_t len = 0;
54 HotPlugEvent *event = NULL;
55 bool ret = false;
56
57 if (service == NULL || data == NULL) {
58 HDF_LOGE("%s: invalid param", __func__);
59 return INPUT_INVALID_PARAM;
60 }
61
62 ret = HdfSbufReadBuffer(data, (const void **)&event, &len);
63 if (!ret) {
64 HDF_LOGE("%s: read sbuf failed", __func__);
65 return INPUT_FAILURE;
66 }
67 g_hotPlugManager->hostDev.hostCb->HotPlugCallback((const HotPlugEvent *)event);
68
69 return INPUT_SUCCESS;
70 }
71
HotPlugEventListenerInstance(void)72 static struct HdfDevEventlistener *HotPlugEventListenerInstance(void)
73 {
74 int32_t ret;
75 struct HdfDevEventlistener *listener = (struct HdfDevEventlistener *)malloc(sizeof(struct HdfDevEventlistener));
76 if (listener == NULL) {
77 HDF_LOGE("%s: instance listener failed", __func__);
78 return NULL;
79 }
80
81 ret = memset_s(listener, sizeof(struct HdfDevEventlistener), 0, sizeof(struct HdfDevEventlistener));
82 if (ret != 0) {
83 HDF_LOGE("%s: memset failed, ret = %d", __func__, ret);
84 free(listener);
85 listener = NULL;
86 return NULL;
87 }
88 listener->onReceive = HotPlugEventListenerCallback;
89 return listener;
90 }
91
RegisterHotPlugCallback(InputHostCb * callback)92 static int32_t RegisterHotPlugCallback(InputHostCb *callback)
93 {
94 int32_t ret;
95 if ((callback == NULL) || (callback->HotPlugCallback == NULL)) {
96 HDF_LOGE("%s: invalid param", __func__);
97 return INPUT_INVALID_PARAM;
98 }
99
100 g_hotPlugManager = (InputDevManager *)malloc(sizeof(InputDevManager));
101 if (g_hotPlugManager == NULL) {
102 HDF_LOGE("%s: malloc fail", __func__);
103 return INPUT_NOMEM;
104 }
105
106 ret = memset_s(g_hotPlugManager, sizeof(InputDevManager), 0, sizeof(InputDevManager));
107 if (ret != 0) {
108 HDF_LOGE("%s: memset failed, ret = %d", __func__, ret);
109 goto EXIT;
110 }
111
112 g_hotPlugManager->hostDev.service = HdfIoServiceBind(DEV_MANAGER_SERVICE_NAME);
113 if (g_hotPlugManager->hostDev.service == NULL) {
114 HDF_LOGE("%s: bind service failed", __func__);
115 goto EXIT;
116 }
117
118 struct HdfDevEventlistener *listener = HotPlugEventListenerInstance();
119 if (listener == NULL) {
120 HDF_LOGE("%s: fail to instance listener", __func__);
121 goto EXIT;
122 }
123 if (HdfDeviceRegisterEventListener(g_hotPlugManager->hostDev.service, listener) != INPUT_SUCCESS) {
124 HDF_LOGE("%s: fail to register listener", __func__);
125 free(listener);
126 listener = NULL;
127 goto EXIT;
128 }
129 g_hotPlugManager->hostDev.hostCb = callback;
130 g_hotPlugManager->hostDev.listener = listener;
131 return INPUT_SUCCESS;
132 EXIT:
133 free(g_hotPlugManager);
134 g_hotPlugManager = NULL;
135 return INPUT_FAILURE;
136 }
137
138
HdfHotPlugDriverRelease(struct HdfDeviceObject * deviceObject)139 static void HdfHotPlugDriverRelease(struct HdfDeviceObject *deviceObject)
140 {
141 (void)deviceObject;
142 if (g_hotPlugManager == NULL) {
143 return;
144 }
145 if (g_hotPlugManager->hostDev.listener != NULL) {
146 free(g_hotPlugManager->hostDev.listener);
147 g_hotPlugManager->hostDev.listener = NULL;
148 }
149 if (g_hotPlugManager != NULL) {
150 free(g_hotPlugManager);
151 g_hotPlugManager = NULL;
152 }
153 }
154
HdfHotPlugDriverBind(struct HdfDeviceObject * deviceObject)155 static int HdfHotPlugDriverBind(struct HdfDeviceObject *deviceObject)
156 {
157 (void)deviceObject;
158 return HDF_SUCCESS;
159 }
160
HdfHotPlugDriverInit(struct HdfDeviceObject * deviceObject)161 static int HdfHotPlugDriverInit(struct HdfDeviceObject *deviceObject)
162 {
163 (void)deviceObject;
164 int32_t ret;
165
166 hotPlug.HotPlugCallback = HotPlugCallback;
167 ret = RegisterHotPlugCallback(&hotPlug);
168 if (ret != HDF_SUCCESS) {
169 HDF_LOGE("%s: register hot plug callback failed, ret = %d", __func__, ret);
170 return HDF_FAILURE;
171 }
172
173 return HDF_SUCCESS;
174 }
175
176 struct HdfDriverEntry g_inputuserHostDriverEntry = {
177 .moduleVersion = 1,
178 .moduleName = "libhdf_input_hotplug.z.so",
179 .Bind = HdfHotPlugDriverBind,
180 .Init = HdfHotPlugDriverInit,
181 .Release = HdfHotPlugDriverRelease,
182 };
183
184 HDF_INIT(g_inputuserHostDriverEntry);