libfeedback: Fix wrong return value on feedback_stop().
[platform/core/system/libsvi.git] / src / feedback.c
1 /*
2  * libfeedback
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
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
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17
18
19 #include <stdio.h>
20 #include <stdbool.h>
21 #include <string.h>
22 #include <limits.h>
23
24 #include "feedback.h"
25 #include "profiles.h"
26 #include "devices.h"
27 #include "log.h"
28
29 #ifndef API
30 #define API __attribute__ ((visibility("default")))
31 #endif
32
33 static bool binit;
34
35 API int feedback_initialize(void)
36 {
37         if (binit)
38                 return FEEDBACK_ERROR_NONE;
39
40         if (!profile) {
41                 _E("there is no valid profile module.");
42                 return FEEDBACK_ERROR_NOT_SUPPORTED;
43         }
44
45         /* initialize device */
46         devices_init();
47
48         /* initialize profile feature */
49         if (profile->init)
50                 profile->init();
51
52         binit = true;
53         return FEEDBACK_ERROR_NONE;
54 }
55
56 API int feedback_deinitialize(void)
57 {
58         if (!binit)
59                 return FEEDBACK_ERROR_NOT_INITIALIZED;
60
61         /* deinitialize device */
62         devices_exit();
63
64         /* deinitialize profile feature */
65         if (profile->exit)
66                 profile->exit();
67
68         binit = false;
69         return FEEDBACK_ERROR_NONE;
70 }
71
72 API int feedback_play(feedback_pattern_e pattern)
73 {
74         int err;
75         bool result;
76         int switched;
77
78         /* check initialize */
79         if (!binit) {
80                 _E("Not initialized");
81                 return FEEDBACK_ERROR_NOT_INITIALIZED;
82         }
83
84         if (pattern <= FEEDBACK_PATTERN_NONE ||
85             pattern >= profile->max_pattern) {
86                 _E("Invalid parameter : pattern(%d)", pattern);
87                 return FEEDBACK_ERROR_INVALID_PARAMETER;
88         }
89
90         /* if you need to switch pattern */
91         if (profile->get_switched_pattern) {
92                 result = profile->get_switched_pattern(pattern, &switched);
93                 if (result) {
94                         _W("pattern is changed : (%s) -> (%s)",
95                                         profile->str_pattern[pattern], profile->str_pattern[switched]);
96                         pattern = switched;
97                 }
98         }
99
100         /* play all device */
101         err = devices_play(pattern);
102         /**
103          * devices_play() returns error even if all devices are failed.
104          * It means if to play anything is successful,
105          * this function regards as success.
106          */
107         if (err == -ENOTSUP)
108                 return FEEDBACK_ERROR_NOT_SUPPORTED;
109         else if (err < 0)
110                 return FEEDBACK_ERROR_OPERATION_FAILED;
111
112         return FEEDBACK_ERROR_NONE;
113 }
114
115 API int feedback_play_type(feedback_type_e type, feedback_pattern_e pattern)
116 {
117         const struct device_ops *dev;
118         int err;
119         bool result;
120         int switched;
121
122         /* check initialize */
123         if (!binit) {
124                 _E("Not initialized");
125                 return FEEDBACK_ERROR_NOT_INITIALIZED;
126         }
127
128         if (type <= FEEDBACK_TYPE_NONE ||
129             type >= profile->max_type) {
130                 _E("Invalid parameter : type(%d)", type);
131                 return FEEDBACK_ERROR_INVALID_PARAMETER;
132         }
133
134         if (pattern <= FEEDBACK_PATTERN_NONE ||
135             pattern >= profile->max_pattern) {
136                 _E("Invalid parameter : pattern(%d)", pattern);
137                 return FEEDBACK_ERROR_INVALID_PARAMETER;
138         }
139
140         /* if you need to switch pattern */
141         if (profile->get_switched_pattern) {
142                 result = profile->get_switched_pattern(pattern, &switched);
143                 if (result) {
144                         _W("pattern is changed : (%s) -> (%s)",
145                                         profile->str_pattern[pattern], profile->str_pattern[switched]);
146                         pattern = switched;
147                 }
148         }
149
150         /* play proper device */
151         dev = find_device(type);
152         if (!dev) {
153                 _E("Not supported device : type(%s)", profile->str_type[type]);
154                 return FEEDBACK_ERROR_NOT_SUPPORTED;
155         }
156
157         err = dev->play(pattern);
158         if (err == -ENOTSUP)
159                 return FEEDBACK_ERROR_NOT_SUPPORTED;
160         else if (err == -ECOMM)
161                 return FEEDBACK_ERROR_PERMISSION_DENIED;
162         else
163                 return FEEDBACK_ERROR_OPERATION_FAILED;
164
165         return FEEDBACK_ERROR_NONE;
166 }
167
168 API int feedback_stop(void)
169 {
170         int err;
171
172         /* check initialize */
173         if (!binit) {
174                 _E("Not initialized");
175                 return FEEDBACK_ERROR_NOT_INITIALIZED;
176         }
177
178         /* stop all device */
179         err = devices_stop();
180         if (err == -ENOTSUP)
181                 return FEEDBACK_ERROR_NOT_SUPPORTED;
182         else if (err == -ECOMM)
183                 return FEEDBACK_ERROR_PERMISSION_DENIED;
184         else if (err < 0)
185                 return FEEDBACK_ERROR_OPERATION_FAILED;
186
187         return FEEDBACK_ERROR_NONE;
188 }
189
190 API int feedback_is_supported_pattern(feedback_type_e type, feedback_pattern_e pattern, bool *status)
191 {
192         const struct device_ops *dev;
193         bool supported;
194         int err;
195         bool result;
196         int switched;
197
198         /* check initialize */
199         if (!binit) {
200                 _E("Not initialized");
201                 return FEEDBACK_ERROR_NOT_INITIALIZED;
202         }
203
204         if (!status) {
205                 _E("Invalid parameter : status(NULL)");
206                 return FEEDBACK_ERROR_INVALID_PARAMETER;
207         }
208
209         if (type <= FEEDBACK_TYPE_NONE ||
210             type >= profile->max_type) {
211                 _E("Invalid parameter : type(%d)", type);
212                 return FEEDBACK_ERROR_INVALID_PARAMETER;
213         }
214
215         if (pattern <= FEEDBACK_PATTERN_NONE ||
216             pattern >= profile->max_pattern) {
217                 _E("Invalid parameter : pattern(%d)", pattern);
218                 return FEEDBACK_ERROR_INVALID_PARAMETER;
219         }
220
221         /* if you need to switch pattern */
222         if (profile->get_switched_pattern) {
223                 result = profile->get_switched_pattern(pattern, &switched);
224                 if (result) {
225                         _W("pattern is changed : (%s) -> (%s)",
226                                         profile->str_pattern[pattern], profile->str_pattern[switched]);
227                         pattern = switched;
228                 }
229         }
230
231         /* play proper device */
232         dev = find_device(type);
233         if (!dev) {
234                 _E("Not supported device : type(%s)", profile->str_type[type]);
235                 return FEEDBACK_ERROR_NOT_SUPPORTED;
236         }
237
238         err = dev->is_supported(pattern, &supported);
239         if (err < 0) {
240                 _E("fail to invoke is_supported() : pattern(%s)", profile->str_pattern[pattern]);
241                 return FEEDBACK_ERROR_OPERATION_FAILED;
242         }
243
244         return FEEDBACK_ERROR_NONE;
245 }
246
247 /* Internal APIs */
248 API int feedback_play_type_by_name(char *type, char *pattern)
249 {
250         feedback_type_e etype;
251         feedback_pattern_e epattern;
252         int type_max;
253         int pattern_max;
254
255         if (!type || !pattern) {
256                 _E("Invalid parameter : type(%x), pattern(%x)", type, pattern);
257                 return FEEDBACK_ERROR_INVALID_PARAMETER;
258         }
259
260         type_max = profile->max_type;
261         for (etype = 0; etype < type_max; ++etype) {
262                 if (!strncmp(type, profile->str_type[etype], strlen(type)))
263                         break;
264         }
265
266         if (etype == type_max) {
267                 _E("Invalid parameter : type(%s)", type);
268                 return FEEDBACK_ERROR_INVALID_PARAMETER;
269         }
270
271         pattern_max = profile->max_pattern;
272         for (epattern = 0; epattern < pattern_max; ++epattern) {
273                 if (!strncmp(pattern, profile->str_pattern[epattern], strlen(pattern)))
274                         break;
275         }
276
277         if (epattern == pattern_max) {
278                 _E("Invalid parameter : pattern(%d)", pattern);
279                 return FEEDBACK_ERROR_INVALID_PARAMETER;
280         }
281
282         return feedback_play_type(etype, epattern);
283 }
284
285 API int feedback_get_resource_path(feedback_type_e type, feedback_pattern_e pattern, char** path)
286 {
287         const struct device_ops *dev;
288         char buf[PATH_MAX] = {0,};
289         int err;
290
291         if (path == NULL) {
292                 _E("Invalid parameter : path(NULL)");
293                 return FEEDBACK_ERROR_INVALID_PARAMETER;
294         }
295
296         if (type <= FEEDBACK_TYPE_NONE ||
297             type >= profile->max_type) {
298                 _E("Invalid parameter : type(%d)", type);
299                 return FEEDBACK_ERROR_INVALID_PARAMETER;
300         }
301
302         if (pattern <= FEEDBACK_PATTERN_NONE ||
303             pattern >= profile->max_pattern) {
304                 _E("Invalid parameter : pattern(%d)", pattern);
305                 return FEEDBACK_ERROR_INVALID_PARAMETER;
306         }
307
308         /* proper device get path */
309         dev = find_device(type);
310         if (dev) {
311                 err = dev->get_path(pattern, buf, sizeof(buf));
312                 if (err < 0)
313                         return FEEDBACK_ERROR_OPERATION_FAILED;
314         }
315
316         *path = strdup(buf);
317         return FEEDBACK_ERROR_NONE;
318 }
319
320 API int feedback_set_resource_path(feedback_type_e type, feedback_pattern_e pattern, char *path)
321 {
322         const struct device_ops *dev;
323         int err;
324
325         if (type <= FEEDBACK_TYPE_NONE ||
326             type >= profile->max_type) {
327                 _E("Invalid parameter : type(%d)", type);
328                 return FEEDBACK_ERROR_INVALID_PARAMETER;
329         }
330
331         if (pattern <= FEEDBACK_PATTERN_NONE ||
332             pattern >= profile->max_pattern) {
333                 _E("Invalid parameter : pattern(%d)", pattern);
334                 return FEEDBACK_ERROR_INVALID_PARAMETER;
335         }
336
337         /* proper device set path */
338         dev = find_device(type);
339         if (dev) {
340                 err = dev->set_path(pattern, path);
341                 if (err < 0)
342                         return FEEDBACK_ERROR_OPERATION_FAILED;
343         }
344
345         return FEEDBACK_ERROR_NONE;
346 }