3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Licensed under the Apache License, Version 2.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
25 #include "feedback-internal.h"
32 #define API __attribute__ ((visibility("default")))
35 static unsigned int init_cnt;
36 static pthread_mutex_t fmutex = PTHREAD_MUTEX_INITIALIZER;
38 //LCOV_EXCL_START Not called Callback
39 static int restart_callback()
41 const struct device_ops *dev;
43 dev = find_device(FEEDBACK_TYPE_VIBRATION);
45 _E("Not supported device : type(FEEDBACK_TYPE_VIBRATION)"); //LCOV_EXCL_LINE
54 API int feedback_initialize(void)
58 pthread_mutex_lock(&fmutex);
60 _E("there is no valid profile module."); //LCOV_EXCL_LINE
61 pthread_mutex_unlock(&fmutex);
62 return FEEDBACK_ERROR_NOT_SUPPORTED; //LCOV_EXCL_LINE System Error
66 pthread_mutex_unlock(&fmutex);
67 return FEEDBACK_ERROR_NONE;
70 ret = register_signal_handler(restart_callback);
72 _E("Fail to register signal handler: %d", ret); //LCOV_EXCL_LINE System Error
74 /* initialize device */
77 /* initialize profile feature */
81 pthread_mutex_unlock(&fmutex);
82 return FEEDBACK_ERROR_NONE;
85 API int feedback_deinitialize(void)
89 pthread_mutex_lock(&fmutex);
91 pthread_mutex_unlock(&fmutex);
92 return FEEDBACK_ERROR_NOT_INITIALIZED;
96 pthread_mutex_unlock(&fmutex);
97 return FEEDBACK_ERROR_NONE;
100 ret = unregister_signal_handler(restart_callback);
102 _E("Fail to unregister signal handler: %d", ret); //LCOV_EXCL_LINE System Error
104 /* deinitialize device */
107 /* deinitialize profile feature */
111 pthread_mutex_unlock(&fmutex);
112 return FEEDBACK_ERROR_NONE;
115 API int feedback_play(feedback_pattern_e pattern)
121 /* check initialize */
122 pthread_mutex_lock(&fmutex);
124 _E("Not initialized"); //LCOV_EXCL_LINE
125 pthread_mutex_unlock(&fmutex);
126 return FEEDBACK_ERROR_NOT_INITIALIZED;
128 pthread_mutex_unlock(&fmutex);
130 if (pattern <= FEEDBACK_PATTERN_NONE ||
131 pattern >= profile->max_pattern) {
132 _E("Invalid parameter : pattern(%d)", pattern);
133 return FEEDBACK_ERROR_INVALID_PARAMETER;
136 /* if you need to switch pattern */
137 if (profile->get_switched_pattern) {
138 result = profile->get_switched_pattern(pattern, &switched);
140 _W("pattern is changed : (%s) -> (%s)", //LCOV_EXCL_LINE
141 profile->str_pattern(pattern), profile->str_pattern(switched));
146 /* play all device */
147 err = devices_play(pattern);
149 * devices_play() returns error even if all devices are failed.
150 * It means if to play anything is successful,
151 * this function regards as success.
154 return FEEDBACK_ERROR_NOT_SUPPORTED;
156 return FEEDBACK_ERROR_OPERATION_FAILED;
158 return FEEDBACK_ERROR_NONE;
161 API int feedback_play_type(feedback_type_e type, feedback_pattern_e pattern)
163 const struct device_ops *dev;
168 /* check initialize */
169 pthread_mutex_lock(&fmutex);
171 _E("Not initialized"); //LCOV_EXCL_LINE
172 pthread_mutex_unlock(&fmutex);
173 return FEEDBACK_ERROR_NOT_INITIALIZED;
175 pthread_mutex_unlock(&fmutex);
177 if (type <= FEEDBACK_TYPE_NONE ||
178 type >= profile->max_type) {
179 _E("Invalid parameter : type(%d)", type);
180 return FEEDBACK_ERROR_INVALID_PARAMETER;
183 if (pattern <= FEEDBACK_PATTERN_NONE ||
184 pattern >= profile->max_pattern) {
185 _E("Invalid parameter : pattern(%d)", pattern);
186 return FEEDBACK_ERROR_INVALID_PARAMETER;
189 /* if you need to switch pattern */
190 if (profile->get_switched_pattern) {
191 result = profile->get_switched_pattern(pattern, &switched);
193 _W("pattern is changed : (%s) -> (%s)", //LCOV_EXCL_LINE
194 profile->str_pattern(pattern), profile->str_pattern(switched));
199 /* play proper device */
200 dev = find_device(type);
202 _E("Not supported device : type(%s)", profile->str_type[type]); //LCOV_EXCL_LINE
203 return FEEDBACK_ERROR_NOT_SUPPORTED;
206 err = dev->play(pattern);
208 return FEEDBACK_ERROR_NOT_SUPPORTED;
209 else if (err == -ECOMM || err == -EACCES)
210 return FEEDBACK_ERROR_PERMISSION_DENIED;
212 return FEEDBACK_ERROR_OPERATION_FAILED;
214 return FEEDBACK_ERROR_NONE;
217 API int feedback_stop(void)
221 /* check initialize */
222 pthread_mutex_lock(&fmutex);
224 _E("Not initialized"); //LCOV_EXCL_LINE
225 pthread_mutex_unlock(&fmutex);
226 return FEEDBACK_ERROR_NOT_INITIALIZED;
228 pthread_mutex_unlock(&fmutex);
230 /* stop all device */
231 err = devices_stop();
233 return FEEDBACK_ERROR_NOT_SUPPORTED;
234 else if (err == -ECOMM || err == -EACCES)
235 return FEEDBACK_ERROR_PERMISSION_DENIED;
237 return FEEDBACK_ERROR_OPERATION_FAILED;
239 return FEEDBACK_ERROR_NONE;
242 API int feedback_is_supported_pattern(feedback_type_e type, feedback_pattern_e pattern, bool *status)
244 const struct device_ops *dev;
250 /* check initialize */
251 pthread_mutex_lock(&fmutex);
253 _E("Not initialized"); //LCOV_EXCL_LINE
254 pthread_mutex_unlock(&fmutex);
255 return FEEDBACK_ERROR_NOT_INITIALIZED;
257 pthread_mutex_unlock(&fmutex);
260 _E("Invalid parameter : status(NULL)");
261 return FEEDBACK_ERROR_INVALID_PARAMETER;
264 if (type <= FEEDBACK_TYPE_NONE ||
265 type >= profile->max_type) {
266 _E("Invalid parameter : type(%d)", type);
267 return FEEDBACK_ERROR_INVALID_PARAMETER;
270 if (pattern <= FEEDBACK_PATTERN_NONE ||
271 pattern >= profile->max_pattern) {
272 _E("Invalid parameter : pattern(%d)", pattern);
273 return FEEDBACK_ERROR_INVALID_PARAMETER;
276 /* if you need to switch pattern */
277 if (profile->get_switched_pattern) {
278 result = profile->get_switched_pattern(pattern, &switched);
280 _W("pattern is changed : (%s) -> (%s)", //LCOV_EXCL_LINE
281 profile->str_pattern(pattern), profile->str_pattern(switched));
286 /* play proper device */
287 dev = find_device(type);
289 _E("Not supported device : type(%s)", profile->str_type[type]); //LCOV_EXCL_LINE
290 return FEEDBACK_ERROR_NOT_SUPPORTED;
293 err = dev->is_supported(pattern, &supported);
295 return FEEDBACK_ERROR_NOT_SUPPORTED; //LCOV_EXCL_LINE System Error
296 else if (err == -ECOMM || err == -EACCES)
297 return FEEDBACK_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE System Error
299 _E("fail to invoke is_supported() : pattern(%d)", pattern); //LCOV_EXCL_LINE
300 return FEEDBACK_ERROR_OPERATION_FAILED;
305 return FEEDBACK_ERROR_NONE;
309 API int feedback_play_type_by_name(char *type, char *pattern)
311 feedback_type_e etype;
312 feedback_pattern_e epattern;
316 if (!type || !pattern) {
317 _E("Invalid parameter : type(%s), pattern(%s)", type, pattern);
318 return FEEDBACK_ERROR_INVALID_PARAMETER;
321 type_max = profile->max_type;
322 for (etype = 0; etype < type_max; ++etype) {
323 if (!strncmp(type, profile->str_type[etype], strlen(type)))
327 if (etype == type_max) {
328 _E("Invalid parameter : type(%s)", type);
329 return FEEDBACK_ERROR_INVALID_PARAMETER;
332 pattern_max = profile->max_pattern;
333 for (epattern = 0; epattern < pattern_max; ++epattern) {
334 if (!strncmp(pattern, profile->str_pattern(epattern), strlen(pattern)))
338 if (epattern == pattern_max) {
339 _E("Invalid parameter : pattern(%s)", pattern);
340 return FEEDBACK_ERROR_INVALID_PARAMETER;
343 return feedback_play_type(etype, epattern);
346 API int feedback_play_internal(feedback_pattern_internal_e pattern)
352 /* check initialize */
353 pthread_mutex_lock(&fmutex);
355 _E("Not initialized"); //LCOV_EXCL_LINE
356 pthread_mutex_unlock(&fmutex);
357 return FEEDBACK_ERROR_NOT_INITIALIZED;
359 pthread_mutex_unlock(&fmutex);
361 if (pattern <= FEEDBACK_PATTERN_INTERNAL_NONE ||
362 pattern >= profile->max_pattern) {
363 _E("Invalid parameter : pattern(%d)", pattern);
364 return FEEDBACK_ERROR_INVALID_PARAMETER;
367 /* if you need to switch pattern */
368 if (profile->get_switched_pattern) {
369 result = profile->get_switched_pattern(pattern, &switched);
371 _W("pattern is changed : (%s) -> (%s)", //LCOV_EXCL_LINE
372 profile->str_pattern(pattern), profile->str_pattern(switched));
377 /* play all device */
378 err = devices_play(pattern);
380 * devices_play() returns error even if all devices are failed.
381 * It means if to play anything is successful,
382 * this function regards as success.
385 return FEEDBACK_ERROR_NOT_SUPPORTED;
387 return FEEDBACK_ERROR_OPERATION_FAILED;
389 return FEEDBACK_ERROR_NONE;
392 API int feedback_play_type_internal(feedback_type_e type, feedback_pattern_internal_e pattern)
394 const struct device_ops *dev;
399 /* check initialize */
400 pthread_mutex_lock(&fmutex);
402 _E("Not initialized"); //LCOV_EXCL_LINE
403 pthread_mutex_unlock(&fmutex);
404 return FEEDBACK_ERROR_NOT_INITIALIZED;
406 pthread_mutex_unlock(&fmutex);
408 if (type <= FEEDBACK_TYPE_NONE ||
409 type >= profile->max_type) {
410 _E("Invalid parameter : type(%d)", type);
411 return FEEDBACK_ERROR_INVALID_PARAMETER;
414 if (pattern <= FEEDBACK_PATTERN_INTERNAL_NONE ||
415 pattern >= profile->max_pattern) {
416 _E("Invalid parameter : pattern(%d)", pattern);
417 return FEEDBACK_ERROR_INVALID_PARAMETER;
420 /* if you need to switch pattern */
421 if (profile->get_switched_pattern) {
422 result = profile->get_switched_pattern(pattern, &switched);
424 _W("pattern is changed : (%s) -> (%s)", //LCOV_EXCL_LINE
425 profile->str_pattern(pattern), profile->str_pattern(switched));
430 /* play proper device */
431 dev = find_device(type);
433 _E("Not supported device : type(%s)", profile->str_type[type]); //LCOV_EXCL_LINE
434 return FEEDBACK_ERROR_NOT_SUPPORTED;
437 err = dev->play(pattern);
439 return FEEDBACK_ERROR_NOT_SUPPORTED;
440 else if (err == -ECOMM || err == -EACCES)
441 return FEEDBACK_ERROR_PERMISSION_DENIED;
443 return FEEDBACK_ERROR_OPERATION_FAILED;
445 return FEEDBACK_ERROR_NONE;
448 API int feedback_get_resource_path(feedback_type_e type, feedback_pattern_e pattern, char** path)
450 const struct device_ops *dev;
451 char buf[PATH_MAX] = {0,};
455 _E("Invalid parameter : path(NULL)");
456 return FEEDBACK_ERROR_INVALID_PARAMETER;
459 if (type <= FEEDBACK_TYPE_NONE ||
460 type >= profile->max_type) {
461 _E("Invalid parameter : type(%d)", type);
462 return FEEDBACK_ERROR_INVALID_PARAMETER;
465 if (type == FEEDBACK_TYPE_VIBRATION)
466 return FEEDBACK_ERROR_INVALID_PARAMETER;
468 if (pattern <= FEEDBACK_PATTERN_NONE ||
469 pattern >= profile->max_pattern) {
470 _E("Invalid parameter : pattern(%d)", pattern);
471 return FEEDBACK_ERROR_INVALID_PARAMETER;
474 /* proper device get path */
475 dev = find_device(type);
477 err = dev->get_path(pattern, buf, sizeof(buf));
479 return FEEDBACK_ERROR_OPERATION_FAILED;
483 return FEEDBACK_ERROR_NONE;
486 API int feedback_set_resource_path(feedback_type_e type, feedback_pattern_e pattern, char *path)
488 const struct device_ops *dev;
491 if (type <= FEEDBACK_TYPE_NONE ||
492 type >= profile->max_type) {
493 _E("Invalid parameter : type(%d)", type);
494 return FEEDBACK_ERROR_INVALID_PARAMETER;
497 if (pattern <= FEEDBACK_PATTERN_NONE ||
498 pattern >= profile->max_pattern) {
499 _E("Invalid parameter : pattern(%d)", pattern);
500 return FEEDBACK_ERROR_INVALID_PARAMETER;
503 if (type == FEEDBACK_TYPE_VIBRATION) {
504 _E("Not supported type"); //LCOV_EXCL_LINE
505 return FEEDBACK_ERROR_INVALID_PARAMETER;
508 /* proper device set path */
509 dev = find_device(type);
511 err = dev->set_path(pattern, path);
513 return FEEDBACK_ERROR_OPERATION_FAILED;
516 return FEEDBACK_ERROR_NONE;