patch tizen_2.0_build
[profile/ivi/libsvi.git] / svi.c
1 /*
2  *  libsvi
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Hyungdeuk Kim <hd3.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #define _GNU_SOURCE
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30
31 #include <mm_sound_private.h>
32 #include <vconf.h>
33 #include <devman_haptic.h>
34
35 #include <fcntl.h>
36 #include <errno.h>
37
38 #include "svi.h"
39 #include "svi-log.h"
40 #include "svi-file.h"
41
42 #define SVI_RETRY_CNT 1
43 #define MAX_FILE_PATH 512
44
45 #ifndef API
46 #define API __attribute__ ((visibility("default")))
47 #endif
48
49 #ifdef PERFORM_CHECK
50 static long long ms = 0;
51
52 #define MICROSECONDS(tv)        ((tv.tv_sec * 1000000ll) + tv.tv_usec)
53
54 #define ESTIMATE_PERFORMANCE() \
55         do { \
56                 struct timeval tv; \
57                 if (ms == 0) { \
58                         gettimeofday(&tv, NULL); \
59                         ms = MICROSECONDS(tv); \
60                         fprintf(stderr, "%s start time : %lld", __func__, ms); \
61                 } else { \
62                         gettimeofday(&tv, NULL); \
63                         fprintf(stderr, "%s elapsed time : %lld", __func__, MICROSECONDS(tv) - ms); \
64                         ms = 0; \
65                 } \
66         } while(0)
67 #else
68 #define ESTIMATE_PERFORMANCE()
69 #endif
70
71 static int soundon = -1;
72 static int vib_level = -1;
73 static int sndstatus = -1;
74 static int vibstatus = -1;
75
76 static void __svi_soundon_cb(keynode_t *key, void* data)
77 {
78         soundon = vconf_keynode_get_bool(key);
79         SVILOG("[[[[[[[[[[[[[[soundon changed!! new soundon => %d", soundon);
80         return;
81 }
82
83 static void __svi_vib_cb(keynode_t *key, void* data)
84 {
85         vib_level = vconf_keynode_get_int(key);
86
87         SVILOG("[[[[[[[[[[[[[[vib_level changed!! new vib_level => %d", vib_level);
88
89         return;
90 }
91
92 static void __svi_sndstatus_cb(keynode_t *key, void* data)
93 {
94         sndstatus = vconf_keynode_get_int(key);
95
96         SVILOG("[[[[[[[[[[[[[[sndstatus changed!! new sndstatus => %d", sndstatus);
97
98         return;
99 }
100
101 static void __svi_vibstatus_cb(keynode_t *key, void* data)
102 {
103         vibstatus = vconf_keynode_get_bool(key);
104
105         SVILOG("[[[[[[[[[[[[[[vibstatus changed!! new vibstatus => %d", vibstatus);
106
107         return;
108 }
109
110 static volume_type_t __svi_get_volume_type(sound_type sound_key)
111 {
112         volume_type_t type = VOLUME_TYPE_SYSTEM;
113
114         if (sound_key >= SVI_SND_OPERATION_POWERON && sound_key <= SVI_SND_OPERATION_SCRCAPTURE)
115                 type = VOLUME_TYPE_SYSTEM;
116         else
117                 type = VOLUME_TYPE_SYSTEM;
118
119         return type;
120 }
121
122 static int __svi_restore_default_file(int svi_type, int svi_enum)
123 {
124         vibration_type vib_enum_type = SVI_VIB_NONE;
125         sound_type snd_enum_type = SVI_SND_NONE;
126         const char* cur_path = NULL;
127         char default_path[MAX_FILE_PATH] = {0,};
128         char *temp = NULL;
129         struct stat buf;
130
131         if(svi_type <=SVI_TYPE_NONE || svi_type >= SVI_TYPE_END) {
132                 SVILOG("ERROR!! invalid svi_type(%d).", svi_type);
133                 return SVI_ERROR;
134         }
135
136         if (svi_type == SVI_TYPE_SND) {
137                 snd_enum_type = (sound_type)svi_enum;
138
139                 if (snd_enum_type <= SVI_SND_NONE || snd_enum_type >= SVI_SND_ENUM_END) {
140                         SVILOG("ERROR! invalid svi_enum(%d)", snd_enum_type);
141                         return SVI_ERROR;
142                 }
143
144                 cur_path = snd_file[snd_enum_type];
145         } else {
146                 vib_enum_type = (vibration_type)svi_enum;
147
148                 if (vib_enum_type <= SVI_VIB_NONE || vib_enum_type >= SVI_VIB_ENUM_END) {
149                         SVILOG("ERROR! invalid svi_enum(%d)", vib_enum_type);
150                         return SVI_ERROR;
151                 }
152
153                 cur_path = haptic_file[vib_enum_type];
154         }
155
156         if( (cur_path == NULL) || (strlen(cur_path) == 0) ) {
157                 SVILOG("ERROR! current path is invalid");
158                 return SVI_ERROR;
159         }
160
161         temp = strcat(default_path, SVI_ORIGIN_DATA_DIR);
162
163         strcat(temp, cur_path+strlen(SVI_DATA_DIR));
164
165         SVILOG("default_path : %s", default_path);
166
167         if(stat(default_path, &buf)) { /*check file existence*/
168                 SVILOG("ERROR!! default file for type(%d),enum(%d) is not presents", svi_type, svi_enum);
169                 return SVI_ERROR;
170         }
171
172         if(unlink(cur_path) < 0) {
173                 SVILOG("WARNING!! unlink(%s) error(%d)", cur_path, errno);
174         }
175
176         if(symlink(default_path, cur_path) < 0) {
177                 SVILOG("ERROR!! symlink(%s) error(%d)", default_path, errno);
178                 return SVI_ERROR;
179         }
180
181         return SVI_SUCCESS;
182 }
183
184 API int svi_init(int *handle)
185 {
186         int v_handle = 0;
187
188         /* Sound Init */
189         if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &soundon) < 0) {
190                 SVILOG("vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &soundon) ==> FAIL!!");
191                 return SVI_ERROR;
192         } else {
193                 SVILOG("vconf_get_int(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &soundon) ==> %d", soundon);
194         }
195
196         if (vconf_get_int(VCONFKEY_SOUND_STATUS, &sndstatus) < 0) {
197                 SVILOG("vconf_get_int(VCONFKEY_SOUND_STATUS, &sndstatus) ==> FAIL!!");
198                 return SVI_ERROR;
199         } else {
200                 SVILOG("vconf_get_int(VCONFKEY_SOUND_STATUS, &sndstatus) ==> %d", sndstatus);
201         }
202
203         /* Vibration Init */
204         v_handle = device_haptic_open( DEV_IDX_0 , 0x01); // new haptic lib.
205         if (v_handle < 0) {
206                 SVILOG("device_haptic_open(DEV_IDX_0) ==> FAIL!!");
207                 return SVI_ERROR;
208         } else {
209                 /* check vibration status */
210                 if (vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibstatus) < 0) {
211                         SVILOG("vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibstatus) ==> FAIL!!");
212                         return SVI_ERROR;
213                 } else {
214                         SVILOG("vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibstatus) ==> %d", vibstatus);
215                 }
216
217                 /* check vib_level */
218                 if (vconf_get_int(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, &vib_level) < 0) {
219                         SVILOG("vconf_get_int(VCONFKEY_SETAPPL_VIB_FEEDBACK_INT, &vib_level) ==> FAIL!!");
220                         return SVI_ERROR;
221                 } else {
222                         SVILOG("vconf_get_int(VCONFKEY_SETAPPL_VIB_FEEDBACK_INT, &vib_level) ==> %d", vib_level);
223                 }
224
225                 *handle = v_handle;
226         }
227
228         /* add watch for status value */
229         vconf_notify_key_changed(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, __svi_soundon_cb, NULL);
230         vconf_notify_key_changed(VCONFKEY_SOUND_STATUS, __svi_sndstatus_cb, NULL);
231         vconf_notify_key_changed(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, __svi_vibstatus_cb, NULL);
232         vconf_notify_key_changed(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, __svi_vib_cb, NULL);
233
234         return SVI_SUCCESS;
235 }
236
237 API int svi_fini(int handle)
238 {
239         vconf_ignore_key_changed(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, __svi_soundon_cb);
240         vconf_ignore_key_changed(VCONFKEY_SOUND_STATUS, __svi_sndstatus_cb);
241         vconf_ignore_key_changed(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, __svi_vibstatus_cb);
242         vconf_ignore_key_changed(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, __svi_vib_cb);
243
244         if (handle > 0) {
245                 if (device_haptic_close(handle) < 0) {
246                         return SVI_ERROR;
247                 } else {
248                         return SVI_SUCCESS;
249                 }
250         }
251
252         return SVI_ERROR;
253 }
254
255 API int svi_play_sound(int handle, sound_type sound_key)
256 {
257         int ret_snd = SVI_SUCCESS;
258         int ret = 0;
259         int retry = 1;
260
261         if (handle < 0) {
262                 SVILOG("ERROR!! Please call svi_init() for sound init ");
263                 ret_snd = SVI_ERROR;
264         } else {
265                 if (sound_key > SVI_SND_NONE && sound_key <= SVI_SND_OPERATION_SCRCAPTURE) {
266                         SVILOG("sound_key = %d, soundon = %d, sndstatus = %d ", sound_key, soundon, sndstatus);
267                         if (soundon != 0 && sndstatus == 0) {
268                                 do {
269                                         ret = mm_sound_play_keysound(snd_file[sound_key], __svi_get_volume_type(sound_key));
270                                         if(ret == MM_ERROR_NONE) {
271                                                 SVILOG("Play success! SND filename is %s", snd_file[sound_key]);
272                                                 break;
273                                         } else {
274                                                 if(ret == MM_ERROR_SOUND_FILE_NOT_FOUND) {
275                                                         SVILOG("mm_sound_play_keysound MM_ERROR_SOUND_FILE_NOT_FOUND error");
276                                                         if(__svi_restore_default_file(SVI_TYPE_SND, sound_key) == SVI_ERROR) {
277                                                                 SVILOG("ERROR!! __svi_restore_origin_file(%d/%d) error", SVI_TYPE_SND, sound_key);
278                                                                 ret_snd = SVI_ERROR;
279                                                                 break;
280                                                         } else {
281                                                                 SVILOG("sound file link is restored. sound play will be retried. ");
282                                                         }
283                                                 } else {
284                                                         SVILOG("ERROR!! mm_sound_play_keysound() returned error(%d)", ret);
285                                                         ret_snd = SVI_ERROR;
286                                                         break;
287                                                 }
288                                         }
289                                 } while(retry--);
290                         }
291                 } else if (sound_key != SVI_SND_NONE) {
292                         ret_snd = SVI_ERROR;
293                 }
294         }
295
296         return ret_snd;
297 }
298
299 API int svi_play_vib(int handle, vibration_type vibration_key)
300 {
301         int ret_vib = SVI_SUCCESS;
302         int vib_lev = 0;
303
304         if (handle < 0) {
305                 SVILOG("ERROR!! Please call svi_init() for vibration init ");
306                 ret_vib = SVI_ERROR;
307         } else  {
308                 if (vibration_key > SVI_VIB_NONE && vibration_key < SVI_VIB_ENUM_END) {
309
310                         if (vibration_key == SVI_VIB_OPERATION_FULLCHARGED || vibration_key == SVI_VIB_OPERATION_LOWBATT) {
311                                 vib_lev = 5;
312                         } else {
313                                 vib_lev = vib_level;
314                         }
315
316                         SVILOG("key = %d, vibstatus = %d, vib_level = %d", vibration_key, vibstatus, vib_lev);
317
318                         if (vibstatus != 0) {
319
320                                 struct stat buf;
321                                 if(stat(haptic_file[vibration_key], &buf)) { /*check file existence*/
322                                         SVILOG("ERROR!! %s is not presents", haptic_file[vibration_key]);
323                                         if(__svi_restore_default_file(SVI_TYPE_VIB, vibration_key) == SVI_ERROR) {
324                                                 SVILOG("ERROR!! __svi_restore_default_file(%d/%d) error", SVI_TYPE_VIB, vibration_key);
325                                                 return SVI_ERROR;
326                                         } else {
327                                                 SVILOG("%s is restored", haptic_file[vibration_key]);
328                                         }
329                                 }
330
331                                 int ret = 0;
332                                 ret = device_haptic_play_file(handle, haptic_file[vibration_key], 1, vib_lev);
333                                 if(ret < 0) {
334                                         SVILOG("ERROR!! device_haptic_play_file(%s) returned error(%d).", haptic_file[vibration_key], ret);
335                                         return SVI_ERROR;
336                                 }
337                         }
338                 } else {
339                         ret_vib = SVI_ERROR;
340                 }
341         }
342
343         return ret_vib;
344
345 }
346
347 API int svi_play(int handle, vibration_type vibration_key, sound_type sound_key)
348 {
349         int ret_snd = svi_play_sound(handle, sound_key);
350         int ret_vib = svi_play_vib(handle, vibration_key);
351
352         if (ret_snd == SVI_ERROR || ret_vib == SVI_ERROR) {
353                 return SVI_ERROR;
354         } else {
355                 return SVI_SUCCESS;
356         }
357 }
358
359 API int svi_set_path(int svi_type, int svi_enum, char* path)
360 {
361         vibration_type vib_enum_type = SVI_VIB_NONE;
362         sound_type snd_enum_type = SVI_SND_NONE;
363         const char* cur_path = NULL;
364
365         if(svi_type <=SVI_TYPE_NONE || svi_type >= SVI_TYPE_END) {
366                 SVILOG("ERROR!! invalid svi_type(%d).", svi_type);
367                 return SVI_ERROR;
368         }
369
370         if (path == NULL) {
371                 SVILOG("ERROR!! invalid path param.");
372                 return SVI_ERROR;
373         } else {
374                 if(access(path, F_OK) != 0) {
375                         SVILOG("ERROR!! path does not exist.");
376                         return SVI_ERROR;
377                 }
378         }
379
380         if (svi_type == SVI_TYPE_SND) {
381                 snd_enum_type = (sound_type)svi_enum;
382
383                 if (snd_enum_type <= SVI_SND_NONE || snd_enum_type >= SVI_SND_ENUM_END) {
384                         SVILOG("ERROR! invalid svi_enum(%d)", snd_enum_type);
385                         return SVI_ERROR;
386                 }
387
388                 cur_path = snd_file[snd_enum_type];
389         } else {
390                 vib_enum_type = (vibration_type)svi_enum;
391
392                 if (vib_enum_type <= SVI_VIB_NONE || vib_enum_type >= SVI_VIB_ENUM_END) {
393                         SVILOG("ERROR! invalid svi_enum(%d)", vib_enum_type);
394                         return SVI_ERROR;
395                 }
396
397                 cur_path = haptic_file[vib_enum_type];
398         }
399
400         if( (cur_path == NULL) || (strlen(cur_path) == 0) ) {
401                 SVILOG("ERROR! current path is invalid");
402                 return SVI_ERROR;
403         }
404
405         if(unlink(cur_path) < 0) {
406                 SVILOG("ERROR!! unlink(%s) error(%d)", cur_path, errno);
407                 return SVI_ERROR;
408         }
409
410         if(symlink(path,cur_path) < 0) {
411                 SVILOG("ERROR!! symlink(%s) error(%d)", path, errno);
412                 return SVI_ERROR;
413         }
414
415         return SVI_SUCCESS;
416 }
417
418 API int svi_get_path(int svi_type, int svi_enum, char* buf, unsigned int bufLen)
419 {
420         vibration_type vib_enum_type = SVI_VIB_NONE;
421         sound_type snd_enum_type = SVI_SND_NONE;
422         const char* cur_path = NULL;
423         int retry = SVI_RETRY_CNT;
424
425         if (buf == NULL || bufLen <= 0) {
426                 SVILOG("ERROR!! invalid input parameters.");
427                 return SVI_ERROR;
428         }
429
430         if (!(svi_type == SVI_TYPE_SND || svi_type == SVI_TYPE_VIB)) {
431                 SVILOG("ERROR!! invalid svi_type(%d).", svi_type);
432                 return SVI_ERROR;
433         }
434
435         if (svi_type == SVI_TYPE_SND) {
436                 snd_enum_type = (sound_type)svi_enum;
437
438                 if (snd_enum_type <= SVI_SND_NONE || snd_enum_type >= SVI_SND_ENUM_END) {
439                         SVILOG("ERROR! invalid svi_enum(%d)", snd_enum_type);
440                         return SVI_ERROR;
441                 }
442
443                 cur_path = snd_file[snd_enum_type];
444
445         } else if (svi_type == SVI_TYPE_VIB) {
446                 vib_enum_type = (vibration_type) svi_enum;
447
448                 if (vib_enum_type <= SVI_VIB_NONE || vib_enum_type >= SVI_VIB_ENUM_END) {
449                         SVILOG("ERROR! invalid svi_enum(%d)", vib_enum_type);
450                         return SVI_ERROR;
451                 }
452
453                 cur_path = haptic_file[vib_enum_type];
454         }
455
456         do {
457                 if(readlink(cur_path, buf, bufLen) < 0) {
458                         if(errno == ENOENT) {
459                                 /* restore svi origin path because of invalid link */
460                                 if(__svi_restore_default_file(svi_type, svi_enum) == SVI_ERROR) {
461                                         SVILOG("ERROR!! __svi_restore_default_file(%d/%d) error", svi_type, svi_enum);
462                                         return SVI_ERROR;
463                                 }
464                         } else {
465                                 SVILOG("ERROR!! readlink(%s) error(%d)", cur_path, errno);
466                                 return SVI_ERROR;
467                         }
468                 }
469         } while(retry--);
470
471         return SVI_SUCCESS;
472 }
473