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