tizen 2.3.1 release
[framework/system/libfeedback.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 #include <vconf.h>
24
25 #include "feedback.h"
26 #include "common.h"
27 #include "log.h"
28 #include "devices.h"
29
30 #ifndef API
31 #define API __attribute__ ((visibility("default")))
32 #endif
33
34 int callstatus;
35 int alert_callstatus;
36
37 static bool binit;
38
39 static void feedback_callstatus_cb(keynode_t *key, void* data)
40 {
41         callstatus = vconf_keynode_get_int(key);
42 }
43
44 static void feedback_alertstatus_cb(keynode_t *key, void* data)
45 {
46         alert_callstatus = vconf_keynode_get_int(key);
47 }
48
49 static feedback_pattern_e get_alert_on_call_key(feedback_pattern_e pattern)
50 {
51         switch(pattern) {
52         case FEEDBACK_PATTERN_MESSAGE:
53         case FEEDBACK_PATTERN_EMAIL:
54         case FEEDBACK_PATTERN_WAKEUP:
55         case FEEDBACK_PATTERN_SCHEDULE:
56         case FEEDBACK_PATTERN_TIMER:
57         case FEEDBACK_PATTERN_GENERAL:
58         case FEEDBACK_PATTERN_CHARGERCONN:
59         case FEEDBACK_PATTERN_CHARGING_ERROR:
60         case FEEDBACK_PATTERN_FULLCHARGED:
61         case FEEDBACK_PATTERN_LOWBATT:
62                 return (feedback_pattern_e)(pattern+1);
63         default:
64                 break;
65         }
66
67         return pattern;
68 }
69
70 static void __DESTRUCTOR__ module_exit(void)
71 {
72         if (!binit)
73                 return;
74
75         vconf_ignore_key_changed(VCONFKEY_CALL_STATE, feedback_callstatus_cb);
76         vconf_ignore_key_changed(VCONFKEY_CISSAPPL_ALERT_ON_CALL_INT, feedback_alertstatus_cb);
77
78         /* deinitialize device */
79         devices_exit();
80
81         binit = false;
82 }
83
84 API int feedback_initialize()
85 {
86         if (binit)
87                 return FEEDBACK_ERROR_NONE;
88
89         /* check call status */
90         if (vconf_get_int(VCONFKEY_CALL_STATE, &callstatus) < 0)
91                 _W("VCONFKEY_CALL_STATE ==> FAIL!!");
92
93
94         /* alert option on call */
95         if (vconf_get_int(VCONFKEY_CISSAPPL_ALERT_ON_CALL_INT, &alert_callstatus) < 0)
96                 _W("VCONFKEY_CISSAPPL_ON_CALL_INT ==> FAIL!!");
97
98         /* add watch for status value */
99         vconf_notify_key_changed(VCONFKEY_CALL_STATE, feedback_callstatus_cb, NULL);
100         vconf_notify_key_changed(VCONFKEY_CISSAPPL_ALERT_ON_CALL_INT, feedback_alertstatus_cb, NULL);
101
102         /* initialize device */
103         devices_init();
104
105         binit = true;
106         return FEEDBACK_ERROR_NONE;
107 }
108
109 API int feedback_deinitialize()
110 {
111         return FEEDBACK_ERROR_NONE;
112 }
113
114 API int feedback_play(feedback_pattern_e pattern)
115 {
116         /* check initialize */
117         if (!binit) {
118                 _E("Not initialized");
119                 return FEEDBACK_ERROR_NOT_INITIALIZED;
120         }
121
122         if (pattern < FEEDBACK_PATTERN_NONE || pattern >= FEEDBACK_PATTERN_END) {
123                 _E("Invalid parameter : pattern(%d)", pattern);
124                 return FEEDBACK_ERROR_INVALID_PARAMETER;
125         }
126
127         if (pattern == FEEDBACK_PATTERN_NONE) {
128                 _D("pattern is NONE");
129                 return FEEDBACK_ERROR_NONE;
130         }
131
132         /* in case of call connected or connecting */
133         if (callstatus != VCONFKEY_CALL_OFF) {
134                 pattern = get_alert_on_call_key(pattern);
135                 _D("Call status is connected or connecting. pattern changed : %s", str_pattern[pattern]);
136         }
137
138         /* play all device */
139         devices_play(pattern);
140
141         return FEEDBACK_ERROR_NONE;
142 }
143
144 API int feedback_play_type(feedback_type_e type, feedback_pattern_e pattern)
145 {
146         const struct device_ops *dev;
147         int err;
148
149         /* check initialize */
150         if (!binit) {
151                 _E("Not initialized");
152                 return FEEDBACK_ERROR_NOT_INITIALIZED;
153         }
154
155         if (type <= FEEDBACK_TYPE_NONE || type >= FEEDBACK_TYPE_END) {
156                 _E("Invalid parameter : type(%d)", type);
157                 return FEEDBACK_ERROR_INVALID_PARAMETER;
158         }
159
160         if (pattern < FEEDBACK_PATTERN_NONE || pattern >= FEEDBACK_PATTERN_END) {
161                 _E("Invalid parameter : pattern(%d)", pattern);
162                 return FEEDBACK_ERROR_INVALID_PARAMETER;
163         }
164
165         if (pattern == FEEDBACK_PATTERN_NONE) {
166                 _D("pattern is NONE");
167                 return FEEDBACK_ERROR_NONE;
168         }
169
170         /* in case of call connected or connecting */
171         if (callstatus != VCONFKEY_CALL_OFF) {
172                 pattern = get_alert_on_call_key(pattern);
173                 _D("Call status is connected or connecting. pattern changed : %s", str_pattern[pattern]);
174         }
175
176         /* should play led regardless of sound or vibration */
177         dev = find_device(FEEDBACK_TYPE_LED);
178         if (dev) {
179                 err = dev->play(pattern);
180                 if (err < 0)
181                         _E("feedback_play_led is failed");
182         }
183
184         if (type == FEEDBACK_TYPE_LED)
185                 return FEEDBACK_ERROR_NONE;
186
187         /* play proper device */
188         dev = find_device(type);
189         if (dev) {
190                 err = dev->play(pattern);
191                 if (err < 0)
192                         _E("fail to play sound");
193         }
194
195         return FEEDBACK_ERROR_NONE;
196 }
197
198 API int feedback_play_type_by_name(char *type, char *pattern)
199 {
200         feedback_type_e etype;
201         feedback_pattern_e epattern;
202
203         if (!type || !pattern) {
204                 _E("Invalid parameter : type(%x), pattern(%x)", type, pattern);
205                 return FEEDBACK_ERROR_INVALID_PARAMETER;
206         }
207
208         for (etype = FEEDBACK_TYPE_NONE; etype < FEEDBACK_TYPE_END; ++etype) {
209                 if (!strncmp(type, str_type[etype], strlen(type)))
210                         break;
211         }
212
213         if (etype == FEEDBACK_TYPE_END) {
214                 _E("Invalid parameter : type(%s)", type);
215                 return FEEDBACK_ERROR_INVALID_PARAMETER;
216         }
217
218         for (epattern = 0; epattern < FEEDBACK_PATTERN_END; ++epattern) {
219                 if (!strncmp(pattern, str_pattern[epattern], strlen(pattern)))
220                         break;
221         }
222
223         if (epattern == FEEDBACK_PATTERN_END) {
224                 _E("Invalid parameter : pattern(%d)", pattern);
225                 return FEEDBACK_ERROR_INVALID_PARAMETER;
226         }
227
228         return feedback_play_type(etype, epattern);
229 }
230
231 API int feedback_stop(void)
232 {
233         /* check initialize */
234         if (!binit) {
235                 _E("Not initialized");
236                 return FEEDBACK_ERROR_NOT_INITIALIZED;
237         }
238
239         /* stop all device */
240         devices_stop();
241
242         return FEEDBACK_ERROR_NONE;
243 }
244
245 API int feedback_get_resource_path(feedback_type_e type, feedback_pattern_e pattern, char** path)
246 {
247         const struct device_ops *dev;
248         char buf[PATH_MAX] = {0,};
249         int err;
250
251         if (path == NULL) {
252                 _E("Invalid parameter : path(NULL)");
253                 return FEEDBACK_ERROR_INVALID_PARAMETER;
254         }
255
256         if (type <= FEEDBACK_TYPE_NONE || type >= FEEDBACK_TYPE_END) {
257                 _E("Invalid parameter : type(%d)", type);
258                 return FEEDBACK_ERROR_INVALID_PARAMETER;
259         }
260
261         if (pattern <= FEEDBACK_PATTERN_NONE || pattern >= FEEDBACK_PATTERN_END) {
262                 _E("Invalid parameter : pattern(%d)", pattern);
263                 return FEEDBACK_ERROR_INVALID_PARAMETER;
264         }
265
266         /* proper device get path */
267         dev = find_device(type);
268         if (dev) {
269                 err = dev->get_path(pattern, buf, sizeof(buf));
270                 if (err < 0)
271                         return FEEDBACK_ERROR_OPERATION_FAILED;
272         }
273
274         *path = strdup(buf);
275         return FEEDBACK_ERROR_NONE;
276 }
277
278 API int feedback_set_resource_path(feedback_type_e type, feedback_pattern_e pattern, char *path)
279 {
280         const struct device_ops *dev;
281         int err;
282
283         if (type <= FEEDBACK_TYPE_NONE || type >= FEEDBACK_TYPE_END) {
284                 _E("Invalid parameter : type(%d)", type);
285                 return FEEDBACK_ERROR_INVALID_PARAMETER;
286         }
287
288         if (pattern <= FEEDBACK_PATTERN_NONE || pattern >= FEEDBACK_PATTERN_END) {
289                 _E("Invalid parameter : pattern(%d)", pattern);
290                 return FEEDBACK_ERROR_INVALID_PARAMETER;
291         }
292
293         /* proper device set path */
294         dev = find_device(type);
295         if (dev) {
296                 err = dev->set_path(pattern, path);
297                 if (err < 0)
298                         return FEEDBACK_ERROR_OPERATION_FAILED;
299         }
300
301         return FEEDBACK_ERROR_NONE;
302 }