• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }