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