1 /*
2 * Copyright (c) 2021-2023 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 "osal_mem.h"
21
22 #define HDF_LOG_TAG uhdf_vibrator_service
23 #define EFFECT_SUN 64
24 #define EFFECT_DURATION 2000
25 #define VIBRATOR_SERVICE_NAME "hdf_misc_vibrator"
26
GetVibratorDevicePriv(void)27 static struct VibratorDevice *GetVibratorDevicePriv(void)
28 {
29 static struct VibratorDevice vibratorDeviceData = {
30 .initState = false,
31 .ioService = NULL,
32 };
33
34 return &vibratorDeviceData;
35 }
36
SendVibratorMsg(uint32_t cmd,struct HdfSBuf * msg,struct HdfSBuf * reply)37 static int32_t SendVibratorMsg(uint32_t cmd, struct HdfSBuf *msg, struct HdfSBuf *reply)
38 {
39 struct VibratorDevice *priv = GetVibratorDevicePriv();
40
41 if (priv->ioService == NULL || priv->ioService->dispatcher == NULL ||
42 priv->ioService->dispatcher->Dispatch == NULL) {
43 HDF_LOGE("%s: para invalid", __func__);
44 return HDF_FAILURE;
45 }
46
47 int32_t ret = priv->ioService->dispatcher->Dispatch(&priv->ioService->object, cmd, msg, reply);
48 if (ret != HDF_SUCCESS) {
49 HDF_LOGE("%{public}s: Vibrator dispatch failed", __func__);
50 return ret;
51 }
52
53 return HDF_SUCCESS;
54 }
55
ReadVibratorInfo(struct HdfSBuf * reply,struct VibratorDevice * priv)56 static int32_t ReadVibratorInfo(struct HdfSBuf *reply, struct VibratorDevice *priv)
57 {
58 uint32_t len;
59 struct VibratorInfo *buf = NULL;
60
61 if (!HdfSbufReadBuffer(reply, (const void **)&buf, &len)) {
62 return HDF_FAILURE;
63 }
64
65 if (buf == NULL || len != sizeof(struct VibratorInfo)) {
66 HDF_LOGE("%{public}s: read size is error, len = %{public}d, size = %{public}zu\n",\
67 __func__, len, sizeof(struct VibratorInfo));
68 HdfSbufRecycle(reply);
69 return HDF_FAILURE;
70 }
71
72 if (memcpy_s(&priv->vibratorInfoEntry, sizeof(priv->vibratorInfoEntry), buf, sizeof(*buf)) != EOK) {
73 HDF_LOGE("%s: Memcpy buf failed", __func__);
74 HdfSbufRecycle(reply);
75 return HDF_FAILURE;
76 }
77
78 return HDF_SUCCESS;
79 }
80
GetVibratorInfo(struct VibratorInfo ** vibratorInfo)81 static int32_t GetVibratorInfo(struct VibratorInfo **vibratorInfo)
82 {
83 int32_t ret;
84 if (vibratorInfo == NULL) {
85 HDF_LOGE("%s:line:%{public}d pointer is null and return ret", __func__, __LINE__);
86 return HDF_FAILURE;
87 }
88 struct VibratorDevice *priv = GetVibratorDevicePriv();
89
90 (void)OsalMutexLock(&priv->mutex);
91 struct HdfSBuf *reply = HdfSbufObtainDefaultSize();
92 if (reply == NULL) {
93 HDF_LOGE("%s: get sbuf failed", __func__);
94 (void)OsalMutexUnlock(&priv->mutex);
95 return HDF_FAILURE;
96 }
97
98 ret = SendVibratorMsg(VIBRATOR_IO_GET_INFO, NULL, reply);
99 if (ret != HDF_SUCCESS) {
100 HDF_LOGE("%{public}s: Vibrator send cmd failed, ret[%{public}d]", __func__, ret);
101 HdfSbufRecycle(reply);
102 (void)OsalMutexUnlock(&priv->mutex);
103 return ret;
104 }
105
106 if (ReadVibratorInfo(reply, priv) != HDF_SUCCESS) {
107 HdfSbufRecycle(reply);
108 (void)OsalMutexUnlock(&priv->mutex);
109 return HDF_FAILURE;
110 }
111
112 HdfSbufRecycle(reply);
113 (void)OsalMutexUnlock(&priv->mutex);
114
115 *vibratorInfo = &priv->vibratorInfoEntry;
116
117 return HDF_SUCCESS;
118 }
119
ValidityJudgment(uint32_t duration,uint16_t intensity,int16_t frequency)120 static int32_t ValidityJudgment(uint32_t duration, uint16_t intensity, int16_t frequency)
121 {
122 struct VibratorDevice *priv = GetVibratorDevicePriv();
123 if (duration == 0) {
124 HDF_LOGE("%s:invalid vibration period", __func__);
125 return VIBRATOR_NOT_PERIOD;
126 }
127
128 if ((priv->vibratorInfoEntry.isSupportIntensity == 0) || (intensity < priv->vibratorInfoEntry.intensityMinValue) ||
129 (intensity > priv->vibratorInfoEntry.intensityMaxValue)) {
130 HDF_LOGE("%s:intensity not supported", __func__);
131 return VIBRATOR_NOT_INTENSITY;
132 }
133
134 if ((priv->vibratorInfoEntry.isSupportFrequency == 0) || (frequency < priv->vibratorInfoEntry.frequencyMinValue) ||
135 (frequency > priv->vibratorInfoEntry.frequencyMaxValue)) {
136 HDF_LOGE("%s:frequency not supported", __func__);
137 return VIBRATOR_NOT_FREQUENCY;
138 }
139
140 return VIBRATOR_SUCCESS;
141 }
142
EnableVibratorModulation(uint32_t duration,uint16_t intensity,int16_t frequency)143 static int32_t EnableVibratorModulation(uint32_t duration, uint16_t intensity, int16_t frequency)
144 {
145 int32_t ret;
146 struct VibratorDevice *priv = GetVibratorDevicePriv();
147
148 ret = ValidityJudgment(duration, intensity, frequency);
149 if (ret != HDF_SUCCESS) {
150 HDF_LOGE("%{public}s: effect is false", __func__);
151 return ret;
152 }
153
154 (void)OsalMutexLock(&priv->mutex);
155 struct HdfSBuf *msg = HdfSbufObtainDefaultSize();
156 if (msg == NULL) {
157 HDF_LOGE("%{public}s: get sbuf failed", __func__);
158 (void)OsalMutexUnlock(&priv->mutex);
159 return HDF_FAILURE;
160 }
161
162 if (!HdfSbufWriteUint32(msg, duration)) {
163 HDF_LOGE("%{public}s: write duration failed.", __func__);
164 HdfSbufRecycle(msg);
165 (void)OsalMutexUnlock(&priv->mutex);
166 return HDF_FAILURE;
167 }
168
169 if (!HdfSbufWriteUint16(msg, intensity)) {
170 HDF_LOGE("%{public}s: write intensity failed.", __func__);
171 HdfSbufRecycle(msg);
172 (void)OsalMutexUnlock(&priv->mutex);
173 return HDF_FAILURE;
174 }
175
176 if (!HdfSbufWriteInt16(msg, frequency)) {
177 HDF_LOGE("%{public}s: write frequency failed.", __func__);
178 HdfSbufRecycle(msg);
179 (void)OsalMutexUnlock(&priv->mutex);
180 return HDF_FAILURE;
181 }
182 ret = SendVibratorMsg(VIBRATOR_IO_ENABLE_MODULATION_PARAMETER, msg, NULL);
183 if (ret != HDF_SUCCESS) {
184 HDF_LOGE("%{public}s: Vibrator send cmd failed, ret[%{public}d]", __func__, ret);
185 }
186 HdfSbufRecycle(msg);
187 (void)OsalMutexUnlock(&priv->mutex);
188
189 return ret;
190 }
191
StartOnce(uint32_t duration)192 static int32_t StartOnce(uint32_t duration)
193 {
194 int32_t ret;
195 struct VibratorDevice *priv = GetVibratorDevicePriv();
196
197 if (duration == 0) {
198 HDF_LOGE("%s:invalid duration para", __func__);
199 return HDF_ERR_INVALID_PARAM;
200 }
201
202 (void)OsalMutexLock(&priv->mutex);
203 struct HdfSBuf *msg = HdfSbufObtainDefaultSize();
204 if (msg == NULL) {
205 HDF_LOGE("%s: get sbuf failed", __func__);
206 (void)OsalMutexUnlock(&priv->mutex);
207 return HDF_FAILURE;
208 }
209
210 if (!HdfSbufWriteUint32(msg, duration)) {
211 HDF_LOGE("%s: write duration failed", __func__);
212 HdfSbufRecycle(msg);
213 (void)OsalMutexUnlock(&priv->mutex);
214 return HDF_FAILURE;
215 }
216
217 ret = SendVibratorMsg(VIBRATOR_IO_START_ONCE, msg, NULL);
218 if (ret != HDF_SUCCESS) {
219 HDF_LOGE("%{public}s: Vibrator send cmd failed, ret[%{public}d]", __func__, ret);
220 }
221 HdfSbufRecycle(msg);
222 (void)OsalMutexUnlock(&priv->mutex);
223
224 return ret;
225 }
226
Start(const char * effect)227 static int32_t Start(const char *effect)
228 {
229 int32_t ret;
230 struct VibratorDevice *priv = GetVibratorDevicePriv();
231
232 if (effect == NULL) {
233 HDF_LOGE("%s: start vibrator effect type invalid", __func__);
234 return HDF_ERR_INVALID_PARAM;
235 }
236
237 (void)OsalMutexLock(&priv->mutex);
238 struct HdfSBuf *msg = HdfSbufObtainDefaultSize();
239 if (msg == NULL) {
240 HDF_LOGE("%s: get sbuf failed", __func__);
241 HdfSbufRecycle(msg);
242 (void)OsalMutexUnlock(&priv->mutex);
243 return HDF_FAILURE;
244 }
245
246 if (!HdfSbufWriteString(msg, effect)) {
247 HDF_LOGE("%s: write effectName failed", __func__);
248 HdfSbufRecycle(msg);
249 (void)OsalMutexUnlock(&priv->mutex);
250 return HDF_FAILURE;
251 }
252
253 ret = SendVibratorMsg(VIBRATOR_IO_START_EFFECT, msg, NULL);
254 if (ret != HDF_SUCCESS) {
255 HDF_LOGE("%{public}s: Vibrator send cmd failed, ret[%{public}d]", __func__, ret);
256 }
257 HdfSbufRecycle(msg);
258 (void)OsalMutexUnlock(&priv->mutex);
259
260 return ret;
261 }
262
GetEffectInfo(const char * effect,struct EffectInfo * effectInfo)263 static int32_t GetEffectInfo(const char *effect, struct EffectInfo *effectInfo)
264 {
265 if (!strcmp(effect, "haptic.clock.timer")) {
266 effectInfo->isSupportEffect = true;
267 effectInfo->duration = EFFECT_DURATION;
268 } else {
269 HDF_LOGE("%s: effect not support", __func__);
270 effectInfo->isSupportEffect = false;
271 effectInfo->duration = 0;
272 }
273
274 return HDF_SUCCESS;
275 }
276
Stop(enum VibratorMode mode)277 static int32_t Stop(enum VibratorMode mode)
278 {
279 int32_t ret;
280 struct VibratorDevice *priv = GetVibratorDevicePriv();
281
282 (void)OsalMutexLock(&priv->mutex);
283 struct HdfSBuf *msg = HdfSbufObtainDefaultSize();
284 if (msg == NULL) {
285 HDF_LOGE("%s: get sbuf failed", __func__);
286 (void)OsalMutexUnlock(&priv->mutex);
287 return HDF_FAILURE;
288 }
289
290 if (!HdfSbufWriteInt32(msg, mode)) {
291 HDF_LOGE("%s: write mode failed", __func__);
292 HdfSbufRecycle(msg);
293 (void)OsalMutexUnlock(&priv->mutex);
294 return HDF_FAILURE;
295 }
296
297 ret = SendVibratorMsg(VIBRATOR_IO_STOP, msg, NULL);
298 if (ret != HDF_SUCCESS) {
299 HDF_LOGE("%{public}s: Vibrator send cmd failed, ret[%{public}d]", __func__, ret);
300 }
301 HdfSbufRecycle(msg);
302 (void)OsalMutexUnlock(&priv->mutex);
303
304 return ret;
305 }
306
NewVibratorInterfaceInstance(void)307 const struct VibratorInterface *NewVibratorInterfaceInstance(void)
308 {
309 static struct VibratorInterface vibratorDevInstance;
310 struct VibratorDevice *priv = GetVibratorDevicePriv();
311
312 if (priv->initState) {
313 return &vibratorDevInstance;
314 }
315
316 OsalMutexInit(&priv->mutex);
317 vibratorDevInstance.Start = Start;
318 vibratorDevInstance.StartOnce = StartOnce;
319 vibratorDevInstance.Stop = Stop;
320 vibratorDevInstance.GetVibratorInfo = GetVibratorInfo;
321 vibratorDevInstance.GetEffectInfo = GetEffectInfo;
322 vibratorDevInstance.EnableVibratorModulation = EnableVibratorModulation;
323
324 priv->ioService = HdfIoServiceBind(VIBRATOR_SERVICE_NAME);
325 if (priv->ioService == NULL) {
326 HDF_LOGE("%s: get vibrator ioService failed", __func__);
327 OsalMutexDestroy(&priv->mutex);
328 return NULL;
329 }
330
331 priv->initState = true;
332 HDF_LOGD("get vibrator devInstance success");
333 return &vibratorDevInstance;
334 }
335
FreeVibratorInterfaceInstance(void)336 int32_t FreeVibratorInterfaceInstance(void)
337 {
338 struct VibratorDevice *priv = GetVibratorDevicePriv();
339
340 if (!priv->initState) {
341 HDF_LOGD("%s: vibrator instance had released", __func__);
342 return HDF_SUCCESS;
343 }
344
345 if (priv->ioService != NULL) {
346 HdfIoServiceRecycle(priv->ioService);
347 }
348
349 OsalMutexDestroy(&priv->mutex);
350
351 return HDF_SUCCESS;
352 }