Fix bugs
[platform/core/uifw/tts.git] / common / tts_config_mgr.c
1 /*
2 *  Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved
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 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14 #include <dirent.h>
15 #include <dlfcn.h>
16 #include <dlog.h>
17 #include <Ecore.h>
18 #include <fcntl.h>
19 #include <glib.h>
20 #include <unistd.h>
21 #include <sys/inotify.h>
22 #include <vconf.h>
23
24 #include "tts_config_mgr.h"
25 #include "tts_config_parser.h"
26 #include "tts_defs.h"
27
28 typedef struct {
29         int     uid;
30         tts_config_engine_changed_cb            engine_cb;
31         tts_config_voice_changed_cb             voice_cb;
32         tts_config_speech_rate_changed_cb       speech_cb;
33         tts_config_screen_reader_changed_cb     screen_cb;
34         tts_config_pitch_changed_cb             pitch_cb;
35         void*   user_data;
36 } tts_config_client_s;
37
38 extern char* tts_tag();
39
40 static GSList* g_engine_list = NULL;
41
42 static GSList* g_config_client_list = NULL;
43
44 static tts_config_s* g_config_info;
45
46 static Ecore_Fd_Handler* g_config_fd_handler_noti = NULL;
47 static int g_config_fd_noti;
48 static int g_config_wd_noti;
49
50 /* For engine directory monitoring */
51 static Ecore_Fd_Handler* g_dir_fd_handler = NULL;
52 static int g_dir_fd;
53 static int g_dir_wd;
54
55 int __tts_config_mgr_print_engine_info();
56
57 int __tts_config_mgr_check_engine_is_valid(const char* engine_id)
58 {
59         if (NULL == engine_id) {
60                 SLOG(LOG_ERROR, tts_tag(), "Input parameter is NULL");
61                 return -1;
62         }
63
64         GSList *iter = NULL;
65         tts_engine_info_s *engine_info = NULL;
66
67         if (0 >= g_slist_length(g_engine_list)) {
68                 SLOG(LOG_ERROR, tts_tag(), "There is no engine!!");
69                 return -1;
70         }
71
72         /* Get a first item */
73         iter = g_slist_nth(g_engine_list, 0);
74
75         while (NULL != iter) {
76                 engine_info = iter->data;
77
78                 if (NULL == engine_info) {
79                         SLOG(LOG_ERROR, tts_tag(), "engine info is NULL");
80                         return -1;
81                 }
82
83                 if (0 == strcmp(engine_id, engine_info->uuid)) {
84                         SLOG(LOG_DEBUG, tts_tag(), "Default engine is valid : %s", engine_id);
85                         return 0;
86                 }
87
88                 iter = g_slist_next(iter);
89         }
90
91         /* Change default engine */
92         iter = g_slist_nth(g_engine_list, 0);
93         engine_info = iter->data;
94
95         if (NULL == g_config_info) {
96                 return TTS_CONFIG_ERROR_OPERATION_FAILED;
97         }
98
99         if (NULL != g_config_info->engine_id)   free(g_config_info->engine_id);
100         if (NULL != g_config_info->setting)     free(g_config_info->setting);
101
102         g_config_info->engine_id = strdup(engine_info->uuid);
103         g_config_info->setting = strdup(engine_info->setting);
104
105         SLOG(LOG_DEBUG, tts_tag(), "Default engine is changed : %s", g_config_info->engine_id);
106
107         /* Change is default voice */
108         GSList *iter_voice = NULL;
109         tts_config_voice_s* voice = NULL;
110         bool is_valid_voice = false;
111
112         /* Get a first item */
113         iter_voice = g_slist_nth(engine_info->voices, 0);
114
115         while (NULL != iter_voice) {
116                 /*Get handle data from list*/
117                 voice = iter_voice->data;
118
119                 if (NULL != voice) {
120                         if (NULL != voice->language && NULL != g_config_info->language) {
121                                 if (0 == strcmp(voice->language, g_config_info->language)) {
122                                         if (voice->type == g_config_info->type) {
123                                                 /* language is valid */
124                                                 is_valid_voice = true;
125
126                                                 free(g_config_info->language);
127                                                 g_config_info->language = strdup(voice->language);
128                                                 g_config_info->type = voice->type;
129
130                                                 SLOG(LOG_DEBUG, tts_tag(), "Default voice is changed : lang(%s) type(%d)", voice->language, voice->type);
131                                                 break;
132                                         }
133                                 }
134                         }
135                 }
136
137                 iter_voice = g_slist_next(iter_voice);
138         }
139
140         if (false == is_valid_voice) {
141                 /* Select first voice as default */
142                 if (NULL != g_config_info->language) {
143                         free(g_config_info->language);
144
145                         iter_voice = g_slist_nth(engine_info->voices, 0);
146                         voice = iter_voice->data;
147
148                         g_config_info->language = strdup(voice->language);
149                         g_config_info->type = voice->type;
150                         SLOG(LOG_DEBUG, tts_tag(), "Default voice is changed : lang(%s) type(%d)", voice->language, voice->type);
151                 }
152         }
153
154         if (0 != tts_parser_set_engine(g_config_info->engine_id, g_config_info->setting, 
155                 g_config_info->language, g_config_info->type)) {
156                 SLOG(LOG_ERROR, tts_tag(), " Fail to save config");
157                 return TTS_CONFIG_ERROR_OPERATION_FAILED;
158         }
159
160         return 0;
161 }
162
163 bool __tts_config_mgr_check_lang_is_valid(const char* engine_id, const char* language, int type)
164 {
165         if (NULL == engine_id || NULL == language) {
166                 SLOG(LOG_ERROR, tts_tag(), "Input parameter is NULL");
167                 return false;
168         }
169
170         GSList *iter = NULL;
171         tts_engine_info_s *engine_info = NULL;
172
173         if (0 >= g_slist_length(g_engine_list)) {
174                 SLOG(LOG_ERROR, tts_tag(), "There is no engine!!");
175                 return false;
176         }
177
178         /* Get a first item */
179         iter = g_slist_nth(g_engine_list, 0);
180
181         while (NULL != iter) {
182                 engine_info = iter->data;
183
184                 if (NULL == engine_info) {
185                         SLOG(LOG_ERROR, tts_tag(), "engine info is NULL");
186                         return false;
187                 }
188
189                 if (0 != strcmp(engine_id, engine_info->uuid)) {
190                         iter = g_slist_next(iter);
191                         continue;
192                 }
193
194                 GSList *iter_voice = NULL;
195                 tts_config_voice_s* voice = NULL;
196
197                 if (g_slist_length(engine_info->voices) <= 0) {
198                         SLOG(LOG_ERROR, tts_tag(), "There is no voice : %s", engine_info->uuid);
199                         iter = g_slist_next(iter);
200                         return false;
201                 }
202
203                 /* Get a first item */
204                 iter_voice = g_slist_nth(engine_info->voices, 0);
205
206                 int i = 1;
207                 while (NULL != iter_voice) {
208                         /*Get handle data from list*/
209                         voice = iter_voice->data;
210
211                         if (NULL != voice) {
212                                 if (0 == strcmp(language, voice->language)) {
213                                         if (type == voice->type) {
214                                                 return true;
215                                         }
216                                 }
217                         }
218
219                         /*Get next item*/
220                         iter_voice = g_slist_next(iter_voice);
221                         i++;
222                 }
223
224                 return false;
225         }
226
227         return false;
228 }
229
230 int __tts_config_mgr_select_lang(const char* engine_id, char** language, int* type)
231 {
232         if (NULL == engine_id || NULL == language) {
233                 SLOG(LOG_ERROR, tts_tag(), "Input parameter is NULL");
234                 return false;
235         }
236
237         GSList *iter = NULL;
238         tts_engine_info_s *engine_info = NULL;
239
240         if (0 >= g_slist_length(g_engine_list)) {
241                 SLOG(LOG_ERROR, tts_tag(), "There is no engine!!");
242                 return false;
243         }
244
245         /* Get a first item */
246         iter = g_slist_nth(g_engine_list, 0);
247
248         while (NULL != iter) {
249                 engine_info = iter->data;
250
251                 if (NULL == engine_info) {
252                         SLOG(LOG_ERROR, tts_tag(), "engine info is NULL");
253                         return false;
254                 }
255
256                 if (0 != strcmp(engine_id, engine_info->uuid)) {
257                         iter = g_slist_next(iter);
258                         continue;
259                 }
260
261                 GSList *iter_voice = NULL;
262                 tts_config_voice_s* voice = NULL;
263
264                 if (g_slist_length(engine_info->voices) <= 0) {
265                         SLOG(LOG_ERROR, tts_tag(), "There is no voice : %s", engine_info->uuid);
266                         return -1;
267                 }
268
269                 /* Get a first item */
270                 iter_voice = g_slist_nth(engine_info->voices, 0);
271
272                 while (NULL != iter_voice) {
273                         voice = iter_voice->data;
274                         if (NULL != voice) {
275                                 /* Default language */
276                                 if (0 == strcmp(TTS_BASE_LANGUAGE, voice->language)) {
277                                         *language = strdup(voice->language);
278                                         *type = voice->type;
279
280                                         SECURE_SLOG(LOG_DEBUG, tts_tag(), "Selected language(%s) type(%d)", *language, *type);
281                                         return 0;
282                                 }
283                         }
284                         iter_voice = g_slist_next(iter_voice);
285                 }
286
287                 /* Not support base language */
288                 if (NULL != voice) {
289                         *language = strdup(voice->language);
290                         *type = voice->type;
291
292                         SECURE_SLOG(LOG_DEBUG, tts_tag(), "Selected language(%s) type(%d)", *language, *type);
293                         return 0;
294                 }
295                 break;
296         }
297
298         return -1;
299 }
300
301 Eina_Bool tts_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler)
302 {
303         SLOG(LOG_DEBUG, tts_tag(), "===== Config changed callback event");
304
305         int length;
306         struct inotify_event event;
307         memset(&event, '\0', sizeof(struct inotify_event));
308
309         length = read(g_config_fd_noti, &event, sizeof(struct inotify_event));
310         if (0 > length) {
311                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty Inotify event");
312                 SLOG(LOG_DEBUG, tts_tag(), "=====");
313                 SLOG(LOG_DEBUG, tts_tag(), " ");
314                 return ECORE_CALLBACK_DONE;
315         }
316
317         if (IN_CLOSE_WRITE == event.mask) {
318                 /* check config changed state */
319                 char* engine = NULL;
320                 char* setting = NULL;
321                 char* lang = NULL;
322                 bool auto_voice = g_config_info->auto_voice;
323                 int voice_type = -1;
324                 int speech_rate = -1;
325                 int pitch = -1;
326
327                 GSList *iter = NULL;
328                 tts_config_client_s* temp_client = NULL;
329
330                 if (0 != tts_parser_find_config_changed(&engine, &setting, &auto_voice, &lang, &voice_type, &speech_rate, &pitch))
331                         return ECORE_CALLBACK_PASS_ON;
332
333                 /* engine changed */
334                 if (NULL != engine || NULL != setting) {
335                         if (NULL != engine) {
336                                 if (NULL != g_config_info->engine_id)
337                                         free(g_config_info->engine_id);
338
339                                 g_config_info->engine_id = strdup(engine);
340                         }
341                         if (NULL != setting) {
342                                 if (NULL != g_config_info->setting)
343                                         free(g_config_info->setting);
344
345                                 g_config_info->setting = strdup(setting);
346                         }
347
348                         SECURE_SLOG(LOG_DEBUG, tts_tag(), "Engine change(%s)", g_config_info->engine_id);
349
350                         /* Call all callbacks of client*/
351                         iter = g_slist_nth(g_config_client_list, 0);
352
353                         while (NULL != iter) {
354                                 temp_client = iter->data;
355
356                                 if (NULL != temp_client) {
357                                         if (NULL != temp_client->engine_cb) {
358                                                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "Engine changed callback : uid(%d)", temp_client->uid);
359                                                 temp_client->engine_cb(g_config_info->engine_id, g_config_info->setting, 
360                                                         g_config_info->language, g_config_info->type, 
361                                                         g_config_info->auto_voice, temp_client->user_data);
362                                         }
363                                 }
364
365                                 iter = g_slist_next(iter);
366                         }
367                 }
368
369                 if (auto_voice != g_config_info->auto_voice) {
370                         g_config_info->auto_voice = auto_voice;
371                 }
372
373                 if (NULL != lang || -1 != voice_type) {
374                         char* before_lang = NULL;
375                         int before_type;
376
377                         before_lang = strdup(g_config_info->language);
378                         before_type = g_config_info->type;
379
380                         if (NULL != lang) {
381                                 if (NULL != g_config_info->language)
382                                         free(g_config_info->language);
383
384                                 g_config_info->language = strdup(lang);
385                         }
386                         if (-1 != voice_type) {
387                                 g_config_info->type = voice_type;
388                         }
389
390                         SECURE_SLOG(LOG_DEBUG, tts_tag(), "Voice change(%s, %d)", g_config_info->language, g_config_info->type);
391
392                         /* Call all callbacks of client*/
393                         iter = g_slist_nth(g_config_client_list, 0);
394
395                         while (NULL != iter) {
396                                 temp_client = iter->data;
397
398                                 if (NULL != temp_client) {
399                                         if (NULL != temp_client->voice_cb) {
400                                                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "Voice changed callback : uid(%d)", temp_client->uid);
401                                                 temp_client->voice_cb(before_lang, before_type, 
402                                                         g_config_info->language, g_config_info->type, 
403                                                         g_config_info->auto_voice, temp_client->user_data);
404                                         }
405                                 }
406
407                                 iter = g_slist_next(iter);
408                         }
409
410                         if (NULL != before_lang) {
411                                 free(before_lang);
412                         }
413                 }
414
415                 if (-1 != speech_rate) {
416                         g_config_info->speech_rate = speech_rate;
417
418                         SECURE_SLOG(LOG_DEBUG, tts_tag(), "Speech rate change(%d)", g_config_info->speech_rate);
419
420                         /* Call all callbacks of client*/
421                         iter = g_slist_nth(g_config_client_list, 0);
422
423                         while (NULL != iter) {
424                                 temp_client = iter->data;
425
426                                 if (NULL != temp_client) {
427                                         if (NULL != temp_client->speech_cb) {
428                                                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "Speech rate changed callback : uid(%d)", temp_client->uid);
429                                                 temp_client->speech_cb(g_config_info->speech_rate, temp_client->user_data);
430                                         }
431                                 }
432
433                                 iter = g_slist_next(iter);
434                         }
435                 }
436
437                 if (-1 != pitch) {
438                         g_config_info->pitch = pitch;
439
440                         SECURE_SLOG(LOG_DEBUG, tts_tag(), "pitch change(%d)", g_config_info->pitch);
441
442                         /* Call all callbacks of client*/
443                         iter = g_slist_nth(g_config_client_list, 0);
444
445                         while (NULL != iter) {
446                                 temp_client = iter->data;
447
448                                 if (NULL != temp_client) {
449                                         if (NULL != temp_client->pitch_cb) {
450                                                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "Pitch changed callback : uid(%d)", temp_client->uid);
451                                                 temp_client->pitch_cb(g_config_info->pitch, temp_client->user_data);
452                                         }
453                                 }
454
455                                 iter = g_slist_next(iter);
456                         }
457                 }
458
459                 if (NULL != engine)     free(engine);
460                 if (NULL != setting)    free(setting);
461                 if (NULL != lang)       free(lang);
462         } else {
463                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Undefined event");
464         }
465
466         SLOG(LOG_DEBUG, tts_tag(), "=====");
467         SLOG(LOG_DEBUG, tts_tag(), " ");
468
469         return ECORE_CALLBACK_PASS_ON;
470 }
471
472 int __tts_config_mgr_register_config_event()
473 {
474         /* get file notification handler */
475         int fd;
476         int wd;
477
478         fd = inotify_init();
479         if (fd < 0) {
480                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail get inotify fd");
481                 return -1;
482         }
483         g_config_fd_noti = fd;
484
485         wd = inotify_add_watch(fd, TTS_CONFIG, IN_CLOSE_WRITE);
486         g_config_wd_noti = wd;
487
488         g_config_fd_handler_noti = ecore_main_fd_handler_add(fd, ECORE_FD_READ,
489                 (Ecore_Fd_Cb)tts_config_mgr_inotify_event_cb, NULL, NULL, NULL);
490         if (NULL == g_config_fd_handler_noti) {
491                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get handler_noti");
492                 return -1;
493         }
494
495         /* Set non-blocking mode of file */
496         int value;
497         value = fcntl(fd, F_GETFL, 0);
498         value |= O_NONBLOCK;
499
500         if (0 > fcntl(fd, F_SETFL, value)) {
501                 SLOG(LOG_WARN, tts_tag(), "[WARNING] Fail to set non-block mode");
502         }
503
504         return 0;
505 }
506
507 int __tts_config_mgr_unregister_config_event()
508 {
509         /* delete inotify variable */
510         ecore_main_fd_handler_del(g_config_fd_handler_noti);
511         inotify_rm_watch(g_config_fd_noti, g_config_wd_noti);
512         close(g_config_fd_noti);
513
514         return 0;
515 }
516
517 int __tts_config_set_auto_language()
518 {
519         char* value = NULL;
520         value = vconf_get_str(TTS_LANGSET_KEY);
521         if (NULL == value) {
522                 SLOG(LOG_ERROR, tts_tag(), "[Config ERROR] Fail to get display language");
523                 return -1;
524         }
525
526         char temp_lang[6] = {'\0', };
527         strncpy(temp_lang, value, 5);
528         free(value);
529
530         if (true == __tts_config_mgr_check_lang_is_valid(g_config_info->engine_id, temp_lang, g_config_info->type)) {
531                 /* tts default voice change */
532                 if (NULL == g_config_info->language) {
533                         SLOG(LOG_ERROR, tts_tag(), "Current config language is NULL");
534                         return -1;
535                 }
536
537                 char* before_lang = NULL;
538                 int before_type;
539
540                 if (0 != tts_parser_set_voice(temp_lang, g_config_info->type)) {
541                         SLOG(LOG_ERROR, tts_tag(), "Fail to save default voice");
542                         return -1;
543                 }
544
545                 before_lang = strdup(g_config_info->language);
546                 before_type = g_config_info->type;
547
548                 free(g_config_info->language);
549                 g_config_info->language = strdup(temp_lang);
550
551                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Config] Default voice : lang(%s) type(%d)", 
552                         g_config_info->language, g_config_info->type);
553
554                 GSList *iter = NULL;
555                 tts_config_client_s* temp_client = NULL;
556
557                 /* Call all callbacks of client*/
558                 iter = g_slist_nth(g_config_client_list, 0);
559
560                 while (NULL != iter) {
561                         temp_client = iter->data;
562
563                         if (NULL != temp_client) {
564                                 if (NULL != temp_client->voice_cb) {
565                                         temp_client->voice_cb(before_lang, before_type, 
566                                                 g_config_info->language, g_config_info->type, 
567                                                 g_config_info->auto_voice, temp_client->user_data);
568                                 }
569                         }
570
571                         iter = g_slist_next(iter);
572                 }
573
574                 if (NULL != before_lang) {
575                         free(before_lang);
576                 }
577         } else {
578                 /* Display language is not valid */
579                 char* tmp_language = NULL;
580                 int tmp_type = -1;
581                 if (0 != __tts_config_mgr_select_lang(g_config_info->engine_id, &tmp_language, &tmp_type)) {
582                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to select language");
583                         return -1;
584                 }
585
586                 if (NULL == tmp_language) {
587                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] language is NULL");
588                         return -1;
589                 }
590
591                 if (0 != tts_parser_set_voice(tmp_language, tmp_type)) {
592                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to save config");
593                         return -1;
594                 }
595
596                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Config] Default voice : lang(%s) type(%d)", 
597                         tmp_language, tmp_type);
598
599                 GSList *iter = NULL;
600                 tts_config_client_s* temp_client = NULL;
601
602                 /* Call all callbacks of client*/
603                 iter = g_slist_nth(g_config_client_list, 0);
604
605                 while (NULL != iter) {
606                         temp_client = iter->data;
607
608                         if (NULL != temp_client) {
609                                 if (NULL != temp_client->voice_cb) {
610                                         temp_client->voice_cb(g_config_info->language, g_config_info->type, 
611                                                 tmp_language, tmp_type, g_config_info->auto_voice, temp_client->user_data);
612                                 }
613                         }
614
615                         iter = g_slist_next(iter);
616                 }
617
618                 if (NULL != g_config_info->language) {
619                         free(g_config_info->language);
620                         g_config_info->language = strdup(tmp_language);
621                 }
622
623                 g_config_info->type = tmp_type;
624
625                 free(tmp_language);
626         }
627
628         return 0;
629 }
630
631 void __tts_config_display_language_changed_cb(keynode_t *key, void *data)
632 {
633         if (true == g_config_info->auto_voice) {
634                 __tts_config_set_auto_language();
635         }
636
637         return;
638 }
639
640 void __tts_config_screen_reader_changed_cb(keynode_t *key, void *data)
641 {
642         int ret;
643         int screen_reader;
644         ret = vconf_get_bool(TTS_ACCESSIBILITY_KEY, &screen_reader);
645         if (0 != ret) {
646                 SLOG(LOG_ERROR, tts_tag(), "[Config ERROR] Fail to get screen reader");
647                 return;
648         }
649
650         GSList *iter = NULL;
651         tts_config_client_s* temp_client = NULL;
652
653         /* Call all callbacks of client*/
654         iter = g_slist_nth(g_config_client_list, 0);
655
656         while (NULL != iter) {
657                 temp_client = iter->data;
658
659                 if (NULL != temp_client) {
660                         if (NULL != temp_client->screen_cb) {
661                                 temp_client->screen_cb((bool)screen_reader);
662                         }
663                 }
664
665                 iter = g_slist_next(iter);
666         }
667 }
668
669 int __tts_config_release_client(int uid)
670 {
671         GSList *iter = NULL;
672         tts_config_client_s* temp_client = NULL;
673
674         if (0 < g_slist_length(g_config_client_list)) {
675                 /* Check uid */
676                 iter = g_slist_nth(g_config_client_list, 0);
677
678                 while (NULL != iter) {
679                         temp_client = iter->data;
680
681                         if (NULL != temp_client) {
682                                 if (uid == temp_client->uid) {
683                                         g_config_client_list = g_slist_remove(g_config_client_list, temp_client);
684                                         free(temp_client);
685                                         temp_client = NULL;
686                                         break;
687                                 }
688                         }
689
690                         iter = g_slist_next(iter);
691                 }
692         }
693
694         SLOG(LOG_DEBUG, tts_tag(), "Client count (%d)", g_slist_length(g_config_client_list));
695
696         return g_slist_length(g_config_client_list);
697 }
698
699 void __tts_config_release_engine()
700 {
701         GSList *iter = NULL;
702         tts_engine_info_s *engine_info = NULL;
703
704         if (0 < g_slist_length(g_engine_list)) {
705
706                 /* Get a first item */
707                 iter = g_slist_nth(g_engine_list, 0);
708
709                 while (NULL != iter) {
710                         engine_info = iter->data;
711
712                         if (NULL != engine_info) {
713                                 g_engine_list = g_slist_remove(g_engine_list, engine_info);
714
715                                 tts_parser_free_engine_info(engine_info);
716                         }
717
718                         iter = g_slist_nth(g_engine_list, 0);
719                 }
720         }
721
722         return;
723 }
724
725 int __tts_config_mgr_get_engine_info()
726 {
727         DIR *dp = NULL;
728         int ret = -1;
729         struct dirent entry;
730         struct dirent *dirp = NULL;
731
732         char filepath[512] = {'\0',};
733         int filesize;
734         tts_engine_info_s* info = NULL;
735
736         g_engine_list = NULL;
737
738         /* Get engine info from default engine directory */
739         dp  = opendir(TTS_DEFAULT_ENGINE_INFO);
740         if (NULL == dp) {
741                 SLOG(LOG_DEBUG, tts_tag(), "[CONFIG] No downloadable directory : %s", TTS_DEFAULT_ENGINE_INFO);
742         } else {
743                 do {
744                         ret = readdir_r(dp, &entry, &dirp);
745                         if (0 != ret) {
746                                 SLOG(LOG_ERROR, tts_tag(), "[CONFIG] Fail to read directory");
747                                 break;
748                         }
749
750                         if (NULL != dirp) {
751                                 filesize = strlen(TTS_DEFAULT_ENGINE_INFO) + strlen(dirp->d_name) + 2;
752                                 if (filesize >= 512) {
753                                         SECURE_SLOG(LOG_ERROR, tts_tag(), "[CONFIG ERROR] File path is too long : %s", dirp->d_name);
754                                         closedir(dp);
755                                         return -1;
756                                 }
757
758                                 memset(filepath, '\0', 512);
759                                 snprintf(filepath, 512, "%s/%s", TTS_DEFAULT_ENGINE_INFO, dirp->d_name);
760
761                                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[CONFIG] Filepath(%s)", filepath);
762
763                                 if (0 == tts_parser_get_engine_info(filepath, &info)) {
764                                         g_engine_list = g_slist_append(g_engine_list, info);
765                                 }
766                         }
767                 } while (NULL != dirp);
768
769                 closedir(dp);
770         }
771
772         if (0 >= g_slist_length(g_engine_list)) {
773                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] No engine");
774                 return -1;
775         }
776
777         return 0;
778 }
779
780 static Eina_Bool __tts_config_mgr_engine_config_inotify_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
781 {
782         SLOG(LOG_DEBUG, tts_tag(), "===== Engine config updated callback event");
783
784         int length;
785         struct inotify_event event;
786         memset(&event, '\0', sizeof(struct inotify_event));
787
788         length = read(g_dir_fd, &event, sizeof(struct inotify_event));
789         if (0 > length) {
790                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty Inotify event");
791                 SLOG(LOG_DEBUG, tts_tag(), "=====");
792                 SLOG(LOG_DEBUG, tts_tag(), " ");
793                 return ECORE_CALLBACK_DONE;
794         }
795
796         if (IN_CLOSE_WRITE == event.mask) {
797                 int ret = __tts_config_mgr_get_engine_info();
798                 if (0 != ret) {
799                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get engine info when config updated");
800                 }
801                 __tts_config_mgr_print_engine_info();
802                 bool support = tts_config_check_default_voice_is_valid(g_config_info->language, g_config_info->type);
803                 if (false == support) {
804                         SLOG(LOG_DEBUG, tts_tag(), "[ERROR] Default voice is valid");
805                         char* temp_lang = NULL;
806                         int temp_type;
807                         ret = __tts_config_mgr_select_lang(g_config_info->engine_id, &temp_lang, &temp_type);
808                         if (0 != ret) {
809                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get voice");
810                         }
811
812                         ret = tts_config_mgr_set_voice(temp_lang, temp_type);
813                         if (0 != ret) {
814                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to set voice");
815                         } else {
816                                 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Saved default voice : lang(%s), type(%d)", g_config_info->language, g_config_info->type);
817                         }
818                         if (NULL != temp_lang)  free(temp_lang);
819                 }
820         } else {
821                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Undefined event");
822         }
823
824         SLOG(LOG_DEBUG, tts_tag(), "=====");
825         SLOG(LOG_DEBUG, tts_tag(), " ");
826
827         return ECORE_CALLBACK_PASS_ON;
828 }
829
830 static int __tts_config_mgr_register_engine_config_updated_event()
831 {
832         /* For engine directory monitoring */
833         g_dir_fd = inotify_init();
834         if (g_dir_fd < 0) {
835                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to init inotify");
836                 return -1;
837         }
838
839          /* FIX_ME *//* It doesn't need check engine directory, because daemon will change engine-process */
840         g_dir_wd = inotify_add_watch(g_dir_fd, TTS_DEFAULT_ENGINE_INFO, IN_CLOSE_WRITE);
841         if (g_dir_wd < 0) {
842                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to add watch");
843                 return -1;
844         }
845
846         g_dir_fd_handler = ecore_main_fd_handler_add(g_dir_fd, ECORE_FD_READ, (Ecore_Fd_Cb)__tts_config_mgr_engine_config_inotify_event_callback, NULL, NULL, NULL);
847         if (NULL == g_dir_fd_handler) {
848                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to add fd handler");
849                 return -1;
850         }
851
852         /* Set non-blocking mode of file */
853         int value;
854         value = fcntl(g_dir_fd, F_GETFL, 0);
855         value |= O_NONBLOCK;
856
857         if (0 > fcntl(g_dir_fd, F_SETFL, value)) {
858                 SLOG(LOG_WARN, tts_tag(), "[WARNING] Fail to set non-block mode");
859         }
860
861         return 0;
862 }
863
864 static int __tts_config_mgr_unregister_engine_config_updated_event()
865 {
866         /* delete inotify variable */
867         ecore_main_fd_handler_del(g_dir_fd_handler);
868         inotify_rm_watch(g_dir_fd, g_dir_wd);
869         close(g_dir_fd);
870
871         return 0;
872 }
873
874 int tts_config_mgr_initialize(int uid)
875 {
876         GSList *iter = NULL;
877         int* get_uid;
878         tts_config_client_s* temp_client = NULL;
879
880         /* Register uid */
881         if (0 < g_slist_length(g_config_client_list)) {
882                 /* Check uid */
883                 iter = g_slist_nth(g_config_client_list, 0);
884
885                 while (NULL != iter) {
886                         get_uid = iter->data;
887
888                         if (uid == *get_uid) {
889                                 SECURE_SLOG(LOG_WARN, tts_tag(), "[CONFIG] uid(%d) has already registered", uid);
890                                 return 0;
891                         }
892
893                         iter = g_slist_next(iter);
894                 }
895
896                 temp_client = (tts_config_client_s*)calloc(1, sizeof(tts_config_client_s));
897                 if (NULL == temp_client) {
898                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to allocate memory");
899                         return TTS_CONFIG_ERROR_OUT_OF_MEMORY;
900                 }
901                 temp_client->uid = uid;
902
903                 g_config_client_list = g_slist_append(g_config_client_list, temp_client);
904
905                 SECURE_SLOG(LOG_WARN, tts_tag(), "[CONFIG] Add uid(%d) but config has already initialized", uid);
906                 return 0;
907         } else {
908                 temp_client = (tts_config_client_s*)calloc(1, sizeof(tts_config_client_s));
909                 if (NULL == temp_client) {
910                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to allocate memory");
911                         return TTS_CONFIG_ERROR_OUT_OF_MEMORY;
912                 }
913                 temp_client->uid = uid;
914
915                 g_config_client_list = g_slist_append(g_config_client_list, temp_client);
916         }
917
918         if (0 != access(TTS_CONFIG_BASE, F_OK)) {
919                 if (0 != mkdir(TTS_CONFIG_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
920                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to make directory : %s", TTS_CONFIG_BASE);
921                         return -1;
922                 } else {
923                         SLOG(LOG_DEBUG, tts_tag(), "Success to make directory : %s", TTS_CONFIG_BASE);
924                 }
925         }
926
927         if (0 != __tts_config_mgr_get_engine_info()) {
928                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get engine info");
929                 __tts_config_release_client(uid);
930                 __tts_config_release_engine();
931                 return TTS_CONFIG_ERROR_ENGINE_NOT_FOUND;
932         }
933
934         __tts_config_mgr_print_engine_info();
935
936         if (0 != tts_parser_load_config(&g_config_info)) {
937                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse configure information");
938                 __tts_config_release_client(uid);
939                 __tts_config_release_engine();
940                 return TTS_CONFIG_ERROR_OPERATION_FAILED;
941         }
942
943         /* Check whether engine id is valid */
944         if (0 != __tts_config_mgr_check_engine_is_valid(g_config_info->engine_id)) {
945                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to get default engine");
946                 __tts_config_release_client(uid);
947                 __tts_config_release_engine();
948                 tts_parser_unload_config(g_config_info);
949                 return TTS_CONFIG_ERROR_ENGINE_NOT_FOUND;
950         }
951
952         if (true == g_config_info->auto_voice) {
953                 /* Check language with display language */
954                 __tts_config_set_auto_language();
955         } else {
956                 if (false == __tts_config_mgr_check_lang_is_valid(g_config_info->engine_id, g_config_info->language, g_config_info->type)) {
957                         /* Default language is not valid */
958                         char* tmp_language = NULL;
959                         int tmp_type = -1;
960                         if (0 != __tts_config_mgr_select_lang(g_config_info->engine_id, &tmp_language, &tmp_type)) {
961                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to select language");
962                                 __tts_config_release_client(uid);
963                                 __tts_config_release_engine();
964                                 tts_parser_unload_config(g_config_info);
965                                 return TTS_CONFIG_ERROR_OPERATION_FAILED;
966                         }
967
968                         if (NULL != tmp_language) {
969                                 if (NULL != g_config_info->language) {
970                                         free(g_config_info->language);
971                                         g_config_info->language = strdup(tmp_language);
972                                 }
973
974                                 g_config_info->type = tmp_type;
975
976                                 free(tmp_language);
977
978                                 if (0 != tts_parser_set_voice(g_config_info->language, g_config_info->type)) {
979                                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to save config");
980                                         __tts_config_release_client(uid);
981                                         __tts_config_release_engine();
982                                         tts_parser_unload_config(g_config_info);
983                                         return TTS_CONFIG_ERROR_OPERATION_FAILED;
984                                 }
985                         }
986                 }
987         }
988
989         /* print daemon config */
990         SLOG(LOG_DEBUG, tts_tag(), "== TTS config ==");
991         SECURE_SLOG(LOG_DEBUG, tts_tag(), " engine : %s", g_config_info->engine_id);
992         SECURE_SLOG(LOG_DEBUG, tts_tag(), " setting : %s", g_config_info->setting);
993         SECURE_SLOG(LOG_DEBUG, tts_tag(), " auto voice : %s", g_config_info->auto_voice ? "on" : "off");
994         SECURE_SLOG(LOG_DEBUG, tts_tag(), " language : %s", g_config_info->language);
995         SECURE_SLOG(LOG_DEBUG, tts_tag(), " voice type : %d", g_config_info->type);
996         SECURE_SLOG(LOG_DEBUG, tts_tag(), " speech rate : %d", g_config_info->speech_rate);
997         SECURE_SLOG(LOG_DEBUG, tts_tag(), " pitch : %d", g_config_info->pitch);
998         SLOG(LOG_DEBUG, tts_tag(), "=================");
999
1000         if (0 != __tts_config_mgr_register_config_event()) {
1001                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to register config event");
1002                 __tts_config_release_client(uid);
1003                 __tts_config_release_engine();
1004                 tts_parser_unload_config(g_config_info);
1005                 return TTS_CONFIG_ERROR_OPERATION_FAILED;
1006         }
1007
1008         /* Register to detect display language change */
1009         vconf_notify_key_changed(TTS_LANGSET_KEY, __tts_config_display_language_changed_cb, NULL);
1010         vconf_notify_key_changed(TTS_ACCESSIBILITY_KEY, __tts_config_screen_reader_changed_cb, NULL);
1011
1012         /* For engine directory monitoring */
1013         if (0 != __tts_config_mgr_register_engine_config_updated_event()) {
1014                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to register engine config updated event");
1015                 __tts_config_release_client(uid);
1016                 __tts_config_release_engine();
1017                 tts_parser_unload_config(g_config_info);
1018                 __tts_config_mgr_unregister_config_event();
1019                 return TTS_CONFIG_ERROR_OPERATION_FAILED;
1020         }
1021
1022         return 0;
1023 }
1024
1025 int tts_config_mgr_finalize(int uid)
1026 {
1027         if (0 < __tts_config_release_client(uid)) {
1028                 return 0;
1029         }
1030
1031         tts_config_mgr_unset_callback(uid);
1032
1033         __tts_config_release_engine();
1034
1035         tts_parser_unload_config(g_config_info);
1036
1037         __tts_config_mgr_unregister_engine_config_updated_event();
1038
1039         __tts_config_mgr_unregister_config_event();
1040
1041         vconf_ignore_key_changed(TTS_LANGSET_KEY, __tts_config_display_language_changed_cb);
1042         vconf_ignore_key_changed(TTS_ACCESSIBILITY_KEY, __tts_config_screen_reader_changed_cb);
1043
1044         return 0;
1045 }
1046
1047 int tts_config_mgr_set_callback(int uid, 
1048                                 tts_config_engine_changed_cb engine_cb, 
1049                                 tts_config_voice_changed_cb voice_cb, 
1050                                 tts_config_speech_rate_changed_cb speech_cb, 
1051                                 tts_config_pitch_changed_cb pitch_cb,
1052                                 void* user_data)
1053 {
1054         GSList *iter = NULL;
1055         tts_config_client_s* temp_client = NULL;
1056
1057         /* Call all callbacks of client*/
1058         iter = g_slist_nth(g_config_client_list, 0);
1059
1060         while (NULL != iter) {
1061                 temp_client = iter->data;
1062
1063                 if (NULL != temp_client) {
1064                         if (uid == temp_client->uid) {
1065                                 temp_client->engine_cb = engine_cb;
1066                                 temp_client->voice_cb = voice_cb;
1067                                 temp_client->speech_cb = speech_cb;
1068                                 temp_client->pitch_cb = pitch_cb;
1069                                 temp_client->user_data = user_data;
1070                         }
1071                 }
1072
1073                 iter = g_slist_next(iter);
1074         }
1075         return 0;
1076 }
1077
1078 int tts_config_mgr_unset_callback(int uid)
1079 {
1080         GSList *iter = NULL;
1081         tts_config_client_s* temp_client = NULL;
1082
1083         /* Call all callbacks of client*/
1084         iter = g_slist_nth(g_config_client_list, 0);
1085
1086         while (NULL != iter) {
1087                 temp_client = iter->data;
1088
1089                 if (NULL != temp_client) {
1090                         if (uid == temp_client->uid) {
1091                                 temp_client->engine_cb = NULL;
1092                                 temp_client->voice_cb = NULL;
1093                                 temp_client->speech_cb = NULL;
1094                                 temp_client->pitch_cb = NULL;
1095                                 temp_client->user_data = NULL;
1096                         }
1097                 }
1098
1099                 iter = g_slist_next(iter);
1100         }
1101
1102         return 0;
1103 }
1104
1105 int tts_config_set_screen_reader_callback(int uid, tts_config_screen_reader_changed_cb callback)
1106 {
1107         if (NULL == callback) {
1108                 SLOG(LOG_ERROR, tts_tag(), "Input parameter is NULL");
1109                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1110         }
1111
1112         GSList *iter = NULL;
1113         tts_config_client_s* temp_client = NULL;
1114
1115         /* Call all callbacks of client*/
1116         iter = g_slist_nth(g_config_client_list, 0);
1117
1118         while (NULL != iter) {
1119                 temp_client = iter->data;
1120
1121                 if (NULL != temp_client) {
1122                         if (uid == temp_client->uid) {
1123                                 temp_client->screen_cb = callback;
1124                         }
1125                 }
1126
1127                 iter = g_slist_next(iter);
1128         }
1129         return 0;
1130 }
1131
1132 int tts_config_unset_screen_reader_callback(int uid)
1133 {
1134         GSList *iter = NULL;
1135         tts_config_client_s* temp_client = NULL;
1136
1137         /* Call all callbacks of client*/
1138         iter = g_slist_nth(g_config_client_list, 0);
1139
1140         while (NULL != iter) {
1141                 temp_client = iter->data;
1142
1143                 if (NULL != temp_client) {
1144                         if (uid == temp_client->uid) {
1145                                 temp_client->screen_cb = NULL;
1146                         }
1147                 }
1148
1149                 iter = g_slist_next(iter);
1150         }
1151         return 0;
1152 }
1153
1154
1155 int tts_config_mgr_get_engine_list(tts_config_supported_engine_cb callback, void* user_data)
1156 {
1157         if (0 >= g_slist_length(g_config_client_list)) {
1158                 SLOG(LOG_ERROR, tts_tag(), "Not initialized");
1159                 return TTS_CONFIG_ERROR_INVALID_STATE;
1160         }
1161
1162         GSList *iter = NULL;
1163         tts_engine_info_s *engine_info = NULL;
1164
1165         if (0 >= g_slist_length(g_engine_list)) {
1166                 SLOG(LOG_ERROR, tts_tag(), "There is no engine!!");
1167                 return TTS_CONFIG_ERROR_ENGINE_NOT_FOUND;
1168         }
1169
1170         /* Get a first item */
1171         iter = g_slist_nth(g_engine_list, 0);
1172
1173         while (NULL != iter) {
1174                 engine_info = iter->data;
1175
1176                 if (NULL != engine_info) {
1177                         if (false == callback(engine_info->uuid, engine_info->name, engine_info->setting, user_data)) {
1178                                 break;
1179                         }
1180                 }
1181
1182                 iter = g_slist_next(iter);
1183         }
1184
1185         return 0;
1186 }
1187
1188 int tts_config_mgr_get_engine(char** engine)
1189 {
1190         if (0 >= g_slist_length(g_config_client_list)) {
1191                 SLOG(LOG_ERROR, tts_tag(), "Not initialized");
1192                 return TTS_CONFIG_ERROR_INVALID_STATE;
1193         }
1194
1195         if (NULL == engine) {
1196                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
1197                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1198         }
1199
1200         if (NULL != g_config_info->engine_id) {
1201                 /* Check engine id is valid */
1202                 GSList *iter = NULL;
1203                 tts_engine_info_s *engine_info = NULL;
1204
1205                 if (0 >= g_slist_length(g_engine_list)) {
1206                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] There is no engine!!");
1207                         return TTS_CONFIG_ERROR_ENGINE_NOT_FOUND;
1208                 }
1209
1210                 /* Get a first item */
1211                 iter = g_slist_nth(g_engine_list, 0);
1212
1213                 while (NULL != iter) {
1214                         engine_info = iter->data;
1215
1216                         if (NULL != engine_info) {
1217                                 if (0 == strcmp(engine_info->uuid, g_config_info->engine_id)) {
1218                                         *engine = strdup(g_config_info->engine_id);
1219                                         return 0;
1220                                 }
1221                         }
1222                         iter = g_slist_next(iter);
1223                 }
1224
1225                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Current engine id is not valid");
1226         } else {
1227                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Engine id is NULL");
1228         }
1229
1230         return TTS_CONFIG_ERROR_OPERATION_FAILED;
1231 }
1232
1233 int tts_config_mgr_set_engine(const char* engine)
1234 {
1235         if (0 >= g_slist_length(g_config_client_list)) {
1236                 SLOG(LOG_ERROR, tts_tag(), "Not initialized");
1237                 return TTS_CONFIG_ERROR_INVALID_STATE;
1238         }
1239
1240         if (NULL == engine)
1241                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1242
1243         /* Check current engine id with new engine id */
1244         if (NULL != g_config_info->engine_id) {
1245                 if (0 == strcmp(g_config_info->engine_id, engine))
1246                         return 0;
1247         }
1248
1249         if (0 >= g_slist_length(g_engine_list)) {
1250                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] There is no engine!!");
1251                 return TTS_CONFIG_ERROR_ENGINE_NOT_FOUND;
1252         }
1253
1254         SLOG(LOG_DEBUG, tts_tag(), "New engine id : %s", engine);
1255
1256         GSList *iter = NULL;
1257         tts_engine_info_s *engine_info = NULL;
1258         bool is_valid_engine = false;
1259
1260         /* Get a first item */
1261         iter = g_slist_nth(g_engine_list, 0);
1262
1263         while (NULL != iter) {
1264                 engine_info = iter->data;
1265
1266                 if (NULL == engine_info) {
1267                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Engine info is NULL");
1268                         iter = g_slist_next(iter);
1269                         continue;
1270                 }
1271
1272                 /* Check engine id is valid */
1273                 if (0 != strcmp(engine, engine_info->uuid)) {
1274                         iter = g_slist_next(iter);
1275                         continue;
1276                 }
1277
1278                 if (NULL != g_config_info->engine_id)
1279                         free(g_config_info->engine_id);
1280
1281                 g_config_info->engine_id = strdup(engine);
1282
1283                 if (NULL != g_config_info->setting)
1284                         free(g_config_info->setting);
1285
1286                 if (NULL != engine_info->setting)
1287                         g_config_info->setting = strdup(engine_info->setting);
1288
1289                 /* Engine is valid*/
1290                 GSList *iter_voice = NULL;
1291                 tts_config_voice_s* voice = NULL;
1292                 bool is_valid_voice = false;
1293
1294                 /* Get a first item */
1295                 iter_voice = g_slist_nth(engine_info->voices, 0);
1296
1297                 while (NULL != iter_voice) {
1298                         /*Get handle data from list*/
1299                         voice = iter_voice->data;
1300
1301                         if (NULL != voice) {
1302                                 if (NULL == voice->language)
1303                                         continue;
1304                                 SLOG(LOG_DEBUG, tts_tag(), " lang(%s) type(%d)", voice->language, voice->type);
1305
1306                                 if (0 == strcmp(voice->language, g_config_info->language)) {
1307                                         if (voice->type == g_config_info->type) {
1308                                                 /* language is valid */
1309                                                 is_valid_voice = true;
1310                                                 g_config_info->type = voice->type;
1311                                         }
1312                                         break;
1313                                 }
1314                         }
1315
1316                         /*Get next item*/
1317                         iter_voice = g_slist_next(iter_voice);
1318                 }
1319
1320                 if (false == is_valid_voice) {
1321                         if (NULL != g_config_info->language) {
1322                                 free(g_config_info->language);
1323
1324                                 iter_voice = g_slist_nth(engine_info->voices, 0);
1325                                 if (NULL != iter_voice) {
1326                                         voice = iter_voice->data;
1327                                         if (NULL != voice) {
1328                                                 if (NULL != voice->language)
1329                                                         g_config_info->language = strdup(voice->language);
1330                                                 g_config_info->type = voice->type;
1331                                         }
1332                                 }
1333                         }
1334                 }
1335
1336                 is_valid_engine = true;
1337                 break;
1338         }
1339
1340         if (true == is_valid_engine) {
1341                 SLOG(LOG_DEBUG, tts_tag(), "[Config] Engine changed");
1342                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "  Engine : %s", g_config_info->engine_id);
1343                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "  Setting : %s", g_config_info->setting);
1344                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "  Language : %s", g_config_info->language);
1345                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "  Type : %d", g_config_info->type);
1346
1347                 if (0 != tts_parser_set_engine(g_config_info->engine_id, g_config_info->setting,
1348                         g_config_info->language, g_config_info->type)) {
1349                                 SLOG(LOG_ERROR, tts_tag(), " Fail to save config");
1350                                 return TTS_CONFIG_ERROR_OPERATION_FAILED;
1351                 }
1352         } else {
1353                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Engine id is not valid");
1354                 return TTS_CONFIG_ERROR_OPERATION_FAILED;
1355         }
1356
1357         return 0;
1358 }
1359
1360 int tts_config_mgr_get_voice_list(const char* engine_id, tts_config_supported_voice_cb callback, void* user_data)
1361 {
1362         if (0 >= g_slist_length(g_config_client_list)) {
1363                 SLOG(LOG_ERROR, tts_tag(), "Not initialized");
1364                 return TTS_CONFIG_ERROR_INVALID_STATE;
1365         }
1366
1367         if (0 >= g_slist_length(g_engine_list)) {
1368                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] There is no engine");
1369                 return TTS_CONFIG_ERROR_ENGINE_NOT_FOUND;
1370         }
1371
1372         GSList *iter = NULL;
1373         tts_engine_info_s *engine_info = NULL;
1374
1375         /* Get a first item */
1376         iter = g_slist_nth(g_engine_list, 0);
1377
1378         while (NULL != iter) {
1379                 engine_info = iter->data;
1380
1381                 if (NULL == engine_info) {
1382                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] engine info is NULL");
1383                         return TTS_CONFIG_ERROR_OPERATION_FAILED;
1384                 }
1385
1386                 if (0 != strcmp(engine_id, engine_info->uuid)) {
1387                         iter = g_slist_next(iter);
1388                         continue;
1389                 }
1390
1391                 GSList *iter_voice = NULL;
1392                 tts_config_voice_s* voice = NULL;
1393
1394                 /* Get a first item */
1395                 iter_voice = g_slist_nth(engine_info->voices, 0);
1396
1397                 while (NULL != iter_voice) {
1398                         /*Get handle data from list*/
1399                         voice = iter_voice->data;
1400
1401                         SLOG(LOG_DEBUG, tts_tag(), " lang(%s) type(%d)", voice->language, voice->type);
1402                         if (NULL != voice->language) {
1403                                 if (false == callback(engine_info->uuid, voice->language, voice->type, user_data))
1404                                         break;
1405                         }
1406
1407                         /*Get next item*/
1408                         iter_voice = g_slist_next(iter_voice);
1409                 }
1410                 break;
1411         }
1412
1413         return 0;
1414 }
1415
1416 int tts_config_mgr_get_voice(char** language, int* type)
1417 {
1418         if (0 >= g_slist_length(g_config_client_list)) {
1419                 SLOG(LOG_ERROR, tts_tag(), "Not initialized");
1420                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1421         }
1422
1423         if (0 >= g_slist_length(g_engine_list)) {
1424                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] There is no engine");
1425                 return TTS_CONFIG_ERROR_ENGINE_NOT_FOUND;
1426         }
1427
1428         if (NULL == language || NULL == type)
1429                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1430
1431         if (NULL != g_config_info->language) {
1432                 *language = strdup(g_config_info->language);
1433                 *type = g_config_info->type;
1434         } else {
1435                 SLOG(LOG_ERROR, tts_tag(), "language is NULL");
1436                 return TTS_CONFIG_ERROR_OPERATION_FAILED;
1437         }
1438
1439         return 0;
1440 }
1441
1442 int tts_config_mgr_set_voice(const char* language, int type)
1443 {
1444         if (0 >= g_slist_length(g_config_client_list)) {
1445                 SLOG(LOG_ERROR, tts_tag(), "Not initialized");
1446                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1447         }
1448
1449         if (NULL == language) {
1450                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
1451                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1452         }
1453
1454         if (0 >= g_slist_length(g_engine_list)) {
1455                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] There is no engine");
1456                 return TTS_CONFIG_ERROR_ENGINE_NOT_FOUND;
1457         }
1458
1459         /* Check language is valid */
1460         if (NULL != g_config_info->language) {
1461                 if (0 != tts_parser_set_voice(language, type)) {
1462                         SLOG(LOG_ERROR, tts_tag(), "Fail to save default voice");
1463                         return TTS_CONFIG_ERROR_OPERATION_FAILED;
1464                 }
1465                 free(g_config_info->language);
1466                 g_config_info->language = strdup(language);
1467                 g_config_info->type = type;
1468
1469         } else {
1470                 SLOG(LOG_ERROR, tts_tag(), "language is NULL");
1471                 return TTS_CONFIG_ERROR_OPERATION_FAILED;
1472         }
1473
1474         return 0;
1475 }
1476
1477 int tts_config_mgr_get_auto_voice(bool* value)
1478 {
1479         if (0 >= g_slist_length(g_config_client_list)) {
1480                 SLOG(LOG_ERROR, tts_tag(), "Not initialized");
1481                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1482         }
1483
1484         if (NULL == value)
1485                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1486
1487         *value = g_config_info->auto_voice;
1488
1489         return 0;
1490 }
1491
1492 int tts_config_mgr_set_auto_voice(bool value)
1493 {
1494         if (0 >= g_slist_length(g_config_client_list)) {
1495                 SLOG(LOG_ERROR, tts_tag(), "Not initialized");
1496                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1497         }
1498
1499         if (g_config_info->auto_voice != value) {
1500                 /* Check language is valid */
1501                 if (0 != tts_parser_set_auto_voice(value)) {
1502                         SLOG(LOG_ERROR, tts_tag(), "Fail to save auto voice option");
1503                         return TTS_CONFIG_ERROR_OPERATION_FAILED;
1504                 }
1505                 g_config_info->auto_voice = value;
1506
1507                 if (true == g_config_info->auto_voice) {
1508                         __tts_config_set_auto_language();
1509                 }
1510         }
1511
1512         return 0;
1513 }
1514
1515 int tts_config_mgr_get_speech_rate(int* value)
1516 {
1517         if (0 >= g_slist_length(g_config_client_list)) {
1518                 SLOG(LOG_ERROR, tts_tag(), "Not initialized");
1519                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1520         }
1521
1522         if (NULL == value) {
1523                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1524         }
1525
1526         *value = g_config_info->speech_rate;
1527
1528         return 0;
1529 }
1530
1531 int tts_config_mgr_set_speech_rate(int value)
1532 {
1533         if (0 >= g_slist_length(g_config_client_list)) {
1534                 SLOG(LOG_ERROR, tts_tag(), "Not initialized");
1535                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1536         }
1537
1538         if (TTS_CONFIG_SPEED_MIN <= value && value <= TTS_CONFIG_SPEED_MAX) {
1539                 SLOG(LOG_DEBUG, tts_tag(), "[Config] Set speech rate : %d", value);
1540                 if (0 != tts_parser_set_speech_rate(value)) {
1541                         SLOG(LOG_ERROR, tts_tag(), "Fail to save speech rate");
1542                         return TTS_CONFIG_ERROR_OPERATION_FAILED;
1543                 }
1544
1545                 g_config_info->speech_rate = value;
1546         } else {
1547                 SLOG(LOG_ERROR, tts_tag(), "[Config ERROR] Speech rate is invalid : %d", value);
1548         }
1549
1550         return 0;
1551 }
1552
1553 int tts_config_mgr_get_pitch(int* value)
1554 {
1555         if (0 >= g_slist_length(g_config_client_list)) {
1556                 SLOG(LOG_ERROR, tts_tag(), "Not initialized");
1557                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1558         }
1559
1560         if (NULL == value) {
1561                 return TTS_CONFIG_ERROR_INVALID_PARAMETER;
1562         }
1563
1564         GSList *iter = NULL;
1565         tts_engine_info_s *engine_info = NULL;
1566
1567         if (0 >= g_slist_length(g_engine_list)) {
1568                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] There is no engine!!");
1569                 return TTS_CONFIG_ERROR_ENGINE_NOT_FOUND;
1570         }
1571
1572         /* Get a first item */
1573         iter = g_slist_nth(g_engine_list, 0);
1574
1575         while (NULL != iter) {
1576                 engine_info = iter->data;
1577
1578                 if (NULL == engine_info) {
1579                         SLOG(LOG_ERROR, tts_tag(), "engine info is NULL");
1580                         return TTS_CONFIG_ERROR_OPERATION_FAILED;
1581                 }
1582
1583                 if (0 != strcmp(g_config_info->engine_id, engine_info->uuid)) {
1584                         iter = g_slist_next(iter);
1585                         continue;
1586                 }
1587
1588                 if (false == engine_info->pitch_support) {
1589                         return TTS_CONFIG_ERROR_NOT_SUPPORTED_FEATURE;
1590                 }  else {
1591                         break;
1592                 }
1593         }
1594
1595         *value = g_config_info->pitch;
1596
1597         return 0;
1598 }
1599
1600 int tts_config_mgr_set_pitch(int value)
1601 {
1602         if (0 >= g_slist_length(g_config_client_list)) {
1603                 SLOG(LOG_ERROR, tts_tag(), "Not initialized");
1604                 return -1;
1605         }
1606
1607         GSList *iter = NULL;
1608         tts_engine_info_s *engine_info = NULL;
1609
1610         if (0 >= g_slist_length(g_engine_list)) {
1611                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] There is no engine!!");
1612                 return TTS_CONFIG_ERROR_ENGINE_NOT_FOUND;
1613         }
1614
1615         /* Get a first item */
1616         iter = g_slist_nth(g_engine_list, 0);
1617
1618         while (NULL != iter) {
1619                 engine_info = iter->data;
1620
1621                 if (NULL == engine_info) {
1622                         SLOG(LOG_ERROR, tts_tag(), "engine info is NULL");
1623                         return TTS_CONFIG_ERROR_OPERATION_FAILED;
1624                 }
1625
1626                 if (0 != strcmp(g_config_info->engine_id, engine_info->uuid)) {
1627                         iter = g_slist_next(iter);
1628                         continue;
1629                 }
1630
1631                 if (false == engine_info->pitch_support) {
1632                         return TTS_CONFIG_ERROR_NOT_SUPPORTED_FEATURE;
1633                 } else {
1634                         break;
1635                 }
1636         }
1637
1638         if (0 != tts_parser_set_pitch(value)) {
1639                 SLOG(LOG_ERROR, tts_tag(), "Fail to save speech rate");
1640                 return TTS_CONFIG_ERROR_OPERATION_FAILED;
1641         }
1642
1643         g_config_info->pitch = value;
1644
1645         return 0;
1646 }
1647
1648 bool tts_config_check_default_engine_is_valid(const char* engine)
1649 {
1650         if (0 >= g_slist_length(g_config_client_list)) {
1651                 SLOG(LOG_ERROR, tts_tag(), "Not initialized");
1652                 return -1;
1653         }
1654
1655         if (NULL == engine)
1656                 return false;
1657
1658         if (0 >= g_slist_length(g_engine_list))
1659                 return false;
1660
1661         GSList *iter = NULL;
1662         tts_engine_info_s *engine_info = NULL;
1663
1664         /* Get a first item */
1665         iter = g_slist_nth(g_engine_list, 0);
1666
1667         while (NULL != iter) {
1668                 engine_info = iter->data;
1669
1670                 if (NULL != engine_info) {
1671                         if (0 == strcmp(engine, engine_info->uuid)) {
1672                                 return true;
1673                         }
1674                 }
1675                 iter = g_slist_next(iter);
1676         }
1677
1678         return false;
1679 }
1680
1681 bool tts_config_check_default_voice_is_valid(const char* language, int type)
1682 {
1683         if (0 >= g_slist_length(g_config_client_list)) {
1684                 SLOG(LOG_ERROR, tts_tag(), "Not initialized");
1685                 return -1;
1686         }
1687
1688         if (NULL == language)
1689                 return false;
1690
1691         if (NULL == g_config_info->engine_id) {
1692                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Default engine id is NULL");
1693                 return false;
1694         }
1695
1696         if (0 >= g_slist_length(g_engine_list))
1697                 return false;
1698
1699         GSList *iter = NULL;
1700         tts_engine_info_s *engine_info = NULL;
1701
1702         /* Get a first item */
1703         iter = g_slist_nth(g_engine_list, 0);
1704
1705         while (NULL != iter) {
1706                 engine_info = iter->data;
1707
1708                 if (NULL == engine_info) {
1709                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Engine info is NULL");
1710                         iter = g_slist_next(iter);
1711                         continue;
1712                 }
1713
1714                 if (0 != strcmp(g_config_info->engine_id, engine_info->uuid)) {
1715                         iter = g_slist_next(iter);
1716                         continue;
1717                 }
1718
1719                 GSList *iter_voice = NULL;
1720                 tts_config_voice_s* voice = NULL;
1721
1722                 /* Get a first item */
1723                 iter_voice = g_slist_nth(engine_info->voices, 0);
1724
1725                 while (NULL != iter_voice) {
1726                         voice = iter_voice->data;
1727
1728                         if (0 == strcmp(language, voice->language) && voice->type == type)
1729                                 return true;
1730
1731                         /*Get next item*/
1732                         iter_voice = g_slist_next(iter_voice);
1733                 }
1734
1735                 break;
1736         }
1737
1738         return false;
1739 }
1740
1741
1742 int __tts_config_mgr_print_engine_info()
1743 {
1744         GSList *iter = NULL;
1745         tts_engine_info_s *engine_info = NULL;
1746
1747         if (0 >= g_slist_length(g_engine_list)) {
1748                 SLOG(LOG_DEBUG, tts_tag(), "-------------- engine list -----------------");
1749                 SLOG(LOG_DEBUG, tts_tag(), "  No Engine in engine directory");
1750                 SLOG(LOG_DEBUG, tts_tag(), "--------------------------------------------");
1751                 return 0;
1752         }
1753
1754         /* Get a first item */
1755         iter = g_slist_nth(g_engine_list, 0);
1756
1757         SLOG(LOG_DEBUG, tts_tag(), "--------------- engine list -----------------");
1758
1759         int i = 1;
1760         while (NULL != iter) {
1761                 engine_info = iter->data;
1762
1763                 SLOG(LOG_DEBUG, tts_tag(), "[%dth]", i);
1764                 SLOG(LOG_DEBUG, tts_tag(), " name : %s", engine_info->name);
1765                 SLOG(LOG_DEBUG, tts_tag(), " id   : %s", engine_info->uuid);
1766                 SLOG(LOG_DEBUG, tts_tag(), " setting : %s", engine_info->setting);
1767
1768                 SLOG(LOG_DEBUG, tts_tag(), " Voices");
1769                 GSList *iter_voice = NULL;
1770                 tts_config_voice_s* voice = NULL;
1771
1772                 if (g_slist_length(engine_info->voices) > 0) {
1773                         /* Get a first item */
1774                         iter_voice = g_slist_nth(engine_info->voices, 0);
1775
1776                         int j = 1;
1777                         while (NULL != iter_voice) {
1778                                 /*Get handle data from list*/
1779                                 voice = iter_voice->data;
1780
1781                                 SLOG(LOG_DEBUG, tts_tag(), "  [%dth] lang(%s) type(%d)", j, voice->language, voice->type);
1782
1783                                 /*Get next item*/
1784                                 iter_voice = g_slist_next(iter_voice);
1785                                 j++;
1786                         }
1787                 } else {
1788                         SLOG(LOG_ERROR, tts_tag(), "  Voice is NONE");
1789                 }
1790                 iter = g_slist_next(iter);
1791                 i++;
1792         }
1793         SLOG(LOG_DEBUG, tts_tag(), "--------------------------------------------");
1794
1795         return 0;
1796 }