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