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