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