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