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