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