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
16 #include "vibrator_controller.h"
17 #include <securec.h>
18 #include "hdf_base.h"
19 #include "hdf_log.h"
20 #include "vibrator_if.h"
21
22 #define HDF_LOG_TAG vibrator_controller_c
23 #define EFFECT_SUN 64
24 #define VIBRATOR_SERVICE_NAME "hdf_misc_vibrator"
25
GetVibratorDevicePriv(void)26 static struct VibratorDevice *GetVibratorDevicePriv(void)
27 {
28 static struct VibratorDevice vibratorDeviceData = {
29 .initState = false,
30 .ioService = NULL,
31 };
32
33 return &vibratorDeviceData;
34 }
35
StartOnce(uint32_t duration)36 static int32_t StartOnce(uint32_t duration)
37 {
38 struct VibratorDevice *priv = GetVibratorDevicePriv();
39
40 if (duration == 0) {
41 HDF_LOGE("%s:invalid duration para", __func__);
42 return HDF_ERR_INVALID_PARAM;
43 }
44
45 (void)OsalMutexLock(&priv->mutex);
46 struct HdfSBuf *msg = HdfSBufObtainDefaultSize();
47 if (msg == NULL) {
48 HDF_LOGE("%s: get sbuf failed", __func__);
49 (void)OsalMutexUnlock(&priv->mutex);
50 return HDF_FAILURE;
51 }
52
53 if (!HdfSbufWriteUint32(msg, duration)) {
54 HDF_LOGE("%s: write duration failed", __func__);
55 HdfSBufRecycle(msg);
56 (void)OsalMutexUnlock(&priv->mutex);
57 return HDF_FAILURE;
58 }
59
60 if (priv->ioService == NULL || priv->ioService->dispatcher == NULL ||
61 priv->ioService->dispatcher->Dispatch == NULL) {
62 HDF_LOGE("%s: para invalid", __func__);
63 HdfSBufRecycle(msg);
64 (void)OsalMutexUnlock(&priv->mutex);
65 return HDF_FAILURE;
66 }
67
68 int32_t ret = priv->ioService->dispatcher->Dispatch(&priv->ioService->object, VIBRATOR_IO_START_ONCE, msg, NULL);
69 if (ret != HDF_SUCCESS) {
70 HDF_LOGE("%s: dispatcher duration failed", __func__);
71 HdfSBufRecycle(msg);
72 (void)OsalMutexUnlock(&priv->mutex);
73 return ret;
74 }
75
76 HdfSBufRecycle(msg);
77 (void)OsalMutexUnlock(&priv->mutex);
78
79 return HDF_SUCCESS;
80 }
81
CovertVibratorEffectName(char * effectName,int32_t len)82 static int32_t CovertVibratorEffectName(char *effectName, int32_t len)
83 {
84 for (int i = 0; i < len; i++) {
85 if (effectName[i] == '.') {
86 effectName[i] = '_';
87 }
88 }
89 return HDF_SUCCESS;
90 }
91
Start(const char * effect)92 static int32_t Start(const char *effect)
93 {
94 struct VibratorDevice *priv = GetVibratorDevicePriv();
95 char effectName[EFFECT_SUN];
96
97 if (effect == NULL) {
98 HDF_LOGE("%s: start vibrator effect type invalid", __func__);
99 return HDF_ERR_INVALID_PARAM;
100 }
101
102 if (strcpy_s(&effectName[0], EFFECT_SUN, effect) != HDF_SUCCESS) {
103 HDF_LOGE("%s: failed to copy string", __func__);
104 return HDF_FAILURE;
105 }
106
107 int32_t effectRet = CovertVibratorEffectName(effectName, EFFECT_SUN);
108 if (effectRet == HDF_FAILURE) {
109 HDF_LOGE("%s: covert effectName failed", __func__);
110 return HDF_FAILURE;
111 }
112
113 (void)OsalMutexLock(&priv->mutex);
114 struct HdfSBuf *msg = HdfSBufObtainDefaultSize();
115 if (msg == NULL) {
116 HDF_LOGE("%s: get sbuf failed", __func__);
117 HdfSBufRecycle(msg);
118 (void)OsalMutexUnlock(&priv->mutex);
119 return HDF_FAILURE;
120 }
121
122 if (priv->ioService == NULL || priv->ioService->dispatcher == NULL ||
123 priv->ioService->dispatcher->Dispatch == NULL) {
124 HDF_LOGE("%s: para invalid", __func__);
125 HdfSBufRecycle(msg);
126 (void)OsalMutexUnlock(&priv->mutex);
127 return HDF_FAILURE;
128 }
129
130 if (!HdfSbufWriteString(msg, effectName)) {
131 HDF_LOGE("%s: write effectName failed", __func__);
132 HdfSBufRecycle(msg);
133 (void)OsalMutexUnlock(&priv->mutex);
134 return HDF_FAILURE;
135 }
136
137 int32_t ret = priv->ioService->dispatcher->Dispatch(&priv->ioService->object, VIBRATOR_IO_START_EFFECT, msg, NULL);
138 if (ret != HDF_SUCCESS) {
139 HDF_LOGE("%s: dispatcher effect failed", __func__);
140 HdfSBufRecycle(msg);
141 (void)OsalMutexUnlock(&priv->mutex);
142 return ret;
143 }
144
145 HdfSBufRecycle(msg);
146 (void)OsalMutexUnlock(&priv->mutex);
147
148 return HDF_SUCCESS;
149 }
150
Stop(enum VibratorMode mode)151 static int32_t Stop(enum VibratorMode mode)
152 {
153 struct VibratorDevice *priv = GetVibratorDevicePriv();
154
155 (void)OsalMutexLock(&priv->mutex);
156 struct HdfSBuf *msg = HdfSBufObtainDefaultSize();
157 if (msg == NULL) {
158 HDF_LOGE("%s: get sbuf failed", __func__);
159 (void)OsalMutexUnlock(&priv->mutex);
160 return HDF_FAILURE;
161 }
162
163 if (priv->ioService == NULL || priv->ioService->dispatcher == NULL ||
164 priv->ioService->dispatcher->Dispatch == NULL) {
165 HDF_LOGE("%s: para invalid", __func__);
166 HdfSBufRecycle(msg);
167 (void)OsalMutexUnlock(&priv->mutex);
168 return HDF_FAILURE;
169 }
170
171 if (!HdfSbufWriteInt32(msg, mode)) {
172 HDF_LOGE("%s: write mode failed", __func__);
173 HdfSBufRecycle(msg);
174 (void)OsalMutexUnlock(&priv->mutex);
175 return HDF_FAILURE;
176 }
177
178 int32_t ret = priv->ioService->dispatcher->Dispatch(&priv->ioService->object, VIBRATOR_IO_STOP, msg, NULL);
179 if (ret != HDF_SUCCESS) {
180 HDF_LOGE("%s: dispatcher stop failed", __func__);
181 HdfSBufRecycle(msg);
182 (void)OsalMutexUnlock(&priv->mutex);
183 return ret;
184 }
185
186 HdfSBufRecycle(msg);
187 (void)OsalMutexUnlock(&priv->mutex);
188
189 return HDF_SUCCESS;
190 }
191
NewVibratorInterfaceInstance(void)192 const struct VibratorInterface *NewVibratorInterfaceInstance(void)
193 {
194 static struct VibratorInterface vibratorDevInstance;
195 struct VibratorDevice *priv = GetVibratorDevicePriv();
196
197 if (priv->initState) {
198 return &vibratorDevInstance;
199 }
200
201 OsalMutexInit(&priv->mutex);
202 vibratorDevInstance.Start = Start;
203 vibratorDevInstance.StartOnce = StartOnce;
204 vibratorDevInstance.Stop = Stop;
205
206 priv->ioService = HdfIoServiceBind(VIBRATOR_SERVICE_NAME);
207 if (priv->ioService == NULL) {
208 HDF_LOGE("%s: get vibrator ioService failed", __func__);
209 OsalMutexDestroy(&priv->mutex);
210 return NULL;
211 }
212
213 priv->initState = true;
214 HDF_LOGD("get vibrator devInstance success");
215 return &vibratorDevInstance;
216 }
217
FreeVibratorInterfaceInstance(void)218 int32_t FreeVibratorInterfaceInstance(void)
219 {
220 struct VibratorDevice *priv = GetVibratorDevicePriv();
221
222 if (!priv->initState) {
223 HDF_LOGD("%s: vibrator instance had released", __func__);
224 return HDF_SUCCESS;
225 }
226
227 if (priv->ioService != NULL) {
228 HdfIoServiceRecycle(priv->ioService);
229 }
230
231 OsalMutexDestroy(&priv->mutex);
232
233 return HDF_SUCCESS;
234 }