Add logic to set default language of the engine
[platform/core/uifw/stt.git] / common / stt_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 <glib.h>
19 #include <unistd.h>
20 #include <sys/inotify.h>
21 #include <vconf.h>
22 #include <buxton2.h>
23
24 #include "stt_config_mgr.h"
25 #include "stt_defs.h"
26 #include "stt_config_parser.h"
27
28
29 typedef struct {
30         int     uid;
31         stt_config_engine_changed_cb    engine_cb;
32         stt_config_lang_changed_cb      lang_cb;
33         stt_config_bool_changed_cb      bool_cb;
34         void*   user_data;
35 } stt_config_client_s;
36
37
38 extern const char* stt_tag();
39
40 static GSList* g_engine_list = NULL;
41
42 static GSList* g_config_client_list = NULL;
43
44 static stt_config_s* g_config_info;
45
46 static Ecore_Fd_Handler* g_fd_handler_noti = NULL;
47 static int g_fd_noti;
48 static int g_wd_noti;
49
50 int __stt_config_mgr_print_engine_info();
51
52 bool __stt_config_mgr_check_lang_is_valid(const char* engine_id, const char* language)
53 {
54         if (NULL == engine_id || NULL == language) {
55                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Input parameter is NULL");
56                 return false;
57         }
58
59         GSList *iter = NULL;
60         stt_engine_info_s *engine_info = NULL;
61
62         if (0 >= g_slist_length(g_engine_list)) {
63                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] There is no engine!!");
64                 return false;
65         }
66
67         /* Get a first item */
68         iter = g_slist_nth(g_engine_list, 0);
69
70         while (NULL != iter) {
71                 engine_info = iter->data;
72
73                 if (NULL == engine_info) {
74                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Engine info is NULL");
75                         return false;
76                 }
77
78                 if (0 != strcmp(engine_id, engine_info->uuid)) {
79                         iter = g_slist_next(iter);
80                         continue;
81                 }
82
83                 GSList *iter_lang = NULL;
84                 char* engine_lang;
85                 if (g_slist_length(engine_info->languages) > 0) {
86                         /* Get a first item */
87                         iter_lang = g_slist_nth(engine_info->languages, 0);
88
89                         int i = 1;
90                         while (NULL != iter_lang) {
91                                 /*Get handle data from list*/
92                                 engine_lang = iter_lang->data;
93
94                                 SLOG(LOG_DEBUG, stt_tag(), "  [%dth] %s", i, engine_lang);
95
96                                 if (0 == strcmp(language, engine_lang)) {
97                                         return true;
98                                 }
99
100                                 /*Get next item*/
101                                 iter_lang = g_slist_next(iter_lang);
102                                 i++;
103                         }
104                 }
105                 break;
106         }
107
108         return false;
109 }
110
111 int __stt_config_mgr_select_lang(const char* engine_id, char** language)
112 {
113         if (NULL == engine_id || NULL == language) {
114                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Input parameter is NULL");
115                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
116         }
117
118         GSList *iter = NULL;
119         stt_engine_info_s *engine_info = NULL;
120
121         if (0 >= g_slist_length(g_engine_list)) {
122                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] There is no engine!!");
123                 return STT_CONFIG_ERROR_OPERATION_FAILED;
124         }
125
126         /* Get a first item */
127         iter = g_slist_nth(g_engine_list, 0);
128
129         while (NULL != iter) {
130                 engine_info = iter->data;
131
132                 if (NULL == engine_info) {
133                         SLOG(LOG_ERROR, stt_tag(), "engine info is NULL");
134                         iter = g_slist_next(iter);
135                         continue;
136                 }
137
138                 if (0 != strcmp(engine_id, engine_info->uuid)) {
139                         iter = g_slist_next(iter);
140                         continue;
141                 }
142
143                 if (NULL == engine_info->default_lang) {
144                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Default language of the engine info is NULL");
145                         return STT_CONFIG_ERROR_INVALID_LANGUAGE;
146                 }
147
148                 *language = strdup(engine_info->default_lang);
149
150                 if (NULL != *language) {
151                         SLOG(LOG_DEBUG, stt_tag(), "Selected language : %s", *language);
152                         return STT_CONFIG_ERROR_NONE;
153                 }
154         }
155
156         return STT_CONFIG_ERROR_OPERATION_FAILED;
157 }
158
159 Eina_Bool stt_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler)
160 {
161         SLOG(LOG_DEBUG, stt_tag(), "===== Config changed callback event");
162
163         int length;
164         struct inotify_event event;
165         memset(&event, '\0', sizeof(struct inotify_event));
166
167         length = read(g_fd_noti, &event, sizeof(struct inotify_event));
168         if (0 > length) {
169                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty Inotify event");
170                 SLOG(LOG_DEBUG, stt_tag(), "=====");
171                 SLOG(LOG_DEBUG, stt_tag(), " ");
172                 return ECORE_CALLBACK_PASS_ON;
173         }
174
175         if (IN_MODIFY == event.mask) {
176                 char* engine = NULL;
177                 char* setting = NULL;
178                 char* lang = NULL;
179                 int auto_lang = -1;
180                 int silence = -1;
181                 int credential = -1;
182
183                 GSList *iter = NULL;
184                 stt_config_client_s* temp_client = NULL;
185
186                 if (0 != stt_parser_find_config_changed(&engine, &setting, &auto_lang, &lang, &silence, &credential))
187                         return ECORE_CALLBACK_PASS_ON;
188
189                 /* Engine changed */
190                 if (NULL != engine || NULL != setting) {
191                         /* engine changed */
192                         if (NULL != engine) {
193                                 if (NULL != g_config_info->engine_id)   free(g_config_info->engine_id);
194                                 g_config_info->engine_id = strdup(engine);
195                         }
196
197                         if (NULL != setting) {
198                                 if (NULL != g_config_info->setting)     free(g_config_info->setting);
199                                 g_config_info->setting = strdup(setting);
200                         }
201
202                         if (NULL != lang) {
203                                 if (NULL != g_config_info->language)    free(g_config_info->language);
204                                 g_config_info->language = strdup(lang);
205                         }
206
207                         if (-1 != silence)      g_config_info->silence_detection = silence;
208
209                         if (-1 != credential)   g_config_info->credential = credential;
210
211                         /* Call all callbacks of client*/
212                         iter = g_slist_nth(g_config_client_list, 0);
213
214                         while (NULL != iter) {
215                                 temp_client = iter->data;
216
217                                 if (NULL != temp_client) {
218                                         if (NULL != temp_client->engine_cb) {
219                                                 temp_client->engine_cb(g_config_info->engine_id, g_config_info->setting, g_config_info->language,
220                                                         g_config_info->silence_detection, g_config_info->credential, temp_client->user_data);
221                                         }
222                                 }
223
224                                 iter = g_slist_next(iter);
225                         }
226                 }
227
228                 if (-1 != auto_lang) {
229                         g_config_info->auto_lang = auto_lang;
230                 }
231
232                 /* Only language changed */
233                 if (NULL == engine && NULL != lang) {
234                         char* before_lang = NULL;
235                         before_lang = strdup(g_config_info->language);
236
237                         if (NULL != lang) {
238                                 if (NULL != g_config_info->language)    free(g_config_info->language);
239                                 g_config_info->language = strdup(lang);
240                         }
241
242                         /* Call all callbacks of client*/
243                         iter = g_slist_nth(g_config_client_list, 0);
244
245                         while (NULL != iter) {
246                                 temp_client = iter->data;
247
248                                 if (NULL != temp_client) {
249                                         if (NULL != temp_client->lang_cb) {
250                                                 temp_client->lang_cb(before_lang, g_config_info->language, temp_client->user_data);
251                                         }
252                                 }
253
254                                 iter = g_slist_next(iter);
255                         }
256
257                         if (NULL != before_lang) {
258                                 free(before_lang);
259                         }
260                 }
261
262                 if (-1 != silence) {
263                         /* silence detection changed */
264                         g_config_info->silence_detection = silence;
265
266                         /* Call all callbacks of client*/
267                         iter = g_slist_nth(g_config_client_list, 0);
268
269                         while (NULL != iter) {
270                                 temp_client = iter->data;
271
272                                 if (NULL != temp_client) {
273                                         if (NULL != temp_client->bool_cb) {
274                                                 temp_client->bool_cb(STT_CONFIG_TYPE_OPTION_SILENCE_DETECTION, silence, temp_client->user_data);
275                                         }
276                                 }
277
278                                 iter = g_slist_next(iter);
279                         }
280                 }
281
282                 if (NULL != engine)     free(engine);
283                 if (NULL != setting)    free(setting);
284                 if (NULL != lang)       free(lang);
285         } else {
286                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Undefined event");
287         }
288
289         SLOG(LOG_DEBUG, stt_tag(), "=====");
290         SLOG(LOG_DEBUG, stt_tag(), " ");
291
292         return ECORE_CALLBACK_PASS_ON;
293 }
294
295 int __stt_config_mgr_register_config_event()
296 {
297         /* get file notification handler */
298         int fd;
299         int wd;
300
301         fd = inotify_init();
302         if (fd < 0) {
303                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail get inotify fd");
304                 return -1;
305         }
306         g_fd_noti = fd;
307
308         wd = inotify_add_watch(fd, STT_CONFIG, IN_MODIFY);
309         g_wd_noti = wd;
310
311         g_fd_handler_noti = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)stt_config_mgr_inotify_event_cb, NULL, NULL, NULL);
312         if (NULL == g_fd_handler_noti) {
313                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to get handler_noti");
314                 return -1;
315         }
316
317         return 0;
318 }
319
320 int __stt_config_mgr_unregister_config_event()
321 {
322         /* delete inotify variable */
323         ecore_main_fd_handler_del(g_fd_handler_noti);
324         inotify_rm_watch(g_fd_noti, g_wd_noti);
325         close(g_fd_noti);
326
327         return 0;
328 }
329
330 int __stt_config_set_auto_language()
331 {
332         char* value = NULL;
333         char candidate_lang[6] = {'\0', };
334
335         value = vconf_get_str(VCONFKEY_LANGSET);
336         if (NULL == value) {
337                 SLOG(LOG_ERROR, stt_tag(), "[Config ERROR] Fail to get display language");
338                 return -1;
339         }
340
341         strncpy(candidate_lang, value, 5);
342         free(value);
343
344         /* Check current config info */
345         if (NULL == g_config_info) {
346                 SLOG(LOG_ERROR, stt_tag(), "Current config info is NULL");
347                 return STT_CONFIG_ERROR_OPERATION_FAILED;
348         }
349
350         /* Check current language */
351         if (NULL == g_config_info->language) {
352                 SLOG(LOG_ERROR, stt_tag(), "Current config language is NULL");
353                 return STT_CONFIG_ERROR_OPERATION_FAILED;
354         }
355
356         if (0 == strncmp(g_config_info->language, candidate_lang, 5)) {
357                 SLOG(LOG_DEBUG, stt_tag(), "[Config] Language is auto. STT language(%s) is same with display lang", g_config_info->language);
358                 return 0;
359         } else {
360                 SLOG(LOG_DEBUG, stt_tag(), "[Config] Display language : %s", candidate_lang);
361         }
362
363         if (true == __stt_config_mgr_check_lang_is_valid(g_config_info->engine_id, candidate_lang)) {
364                 char* before_lang = NULL;
365                 if (0 != stt_parser_set_language(candidate_lang)) {
366                         SLOG(LOG_ERROR, stt_tag(), "Fail to save default language");
367                         return -1;
368                 }
369
370                 before_lang = strdup(g_config_info->language);
371
372                 free(g_config_info->language);
373                 g_config_info->language = strdup(candidate_lang);
374
375                 SLOG(LOG_DEBUG, stt_tag(), "[Config] Language is auto. Set default language(%s)", g_config_info->language);
376
377                 /* Call all callbacks of client*/
378                 GSList *iter = NULL;
379                 stt_config_client_s* temp_client = NULL;
380
381                 iter = g_slist_nth(g_config_client_list, 0);
382
383                 while (NULL != iter) {
384                         temp_client = iter->data;
385
386                         if (NULL != temp_client) {
387                                 if (NULL != temp_client->lang_cb) {
388                                         temp_client->lang_cb(before_lang, g_config_info->language, temp_client->user_data);
389                                 }
390                         }
391
392                         iter = g_slist_next(iter);
393                 }
394
395                 if (NULL != before_lang) {
396                         free(before_lang);
397                 }
398         } else {
399                 /* Candidate language is not valid */
400                 char* tmp_language = NULL;
401                 if (0 != __stt_config_mgr_select_lang(g_config_info->engine_id, &tmp_language)) {
402                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to select language");
403                         return -1;
404                 }
405
406                 if (NULL == tmp_language) {
407                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Selected language is NULL");
408                         return -1;
409                 }
410
411                 if (0 != stt_parser_set_language(tmp_language)) {
412                         free(tmp_language);
413                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to save config");
414                         return -1;
415                 }
416
417                 SLOG(LOG_DEBUG, stt_tag(), "[Config] Language is auto but display lang is not supported. Default language change(%s)", tmp_language);
418
419                 /* Call all callbacks of client*/
420                 GSList *iter = NULL;
421                 stt_config_client_s* temp_client = NULL;
422
423                 iter = g_slist_nth(g_config_client_list, 0);
424
425                 while (NULL != iter) {
426                         temp_client = iter->data;
427
428                         if (NULL != temp_client) {
429                                 if (NULL != temp_client->lang_cb) {
430                                         temp_client->lang_cb(g_config_info->language, tmp_language, temp_client->user_data);
431                                 }
432                         }
433
434                         iter = g_slist_next(iter);
435                 }
436
437                 free(g_config_info->language);
438                 g_config_info->language = strdup(tmp_language);
439
440                 free(tmp_language);
441                 tmp_language = NULL;
442         }
443
444         return 0;
445 }
446
447 void __stt_config_language_changed_cb(keynode_t *key, void *data)
448 {
449         if (true == g_config_info->auto_lang) {
450                 /* Get voice input vconf key */
451                 __stt_config_set_auto_language();
452         }
453
454         return;
455 }
456
457 void __stt_config_release_client(int uid)
458 {
459         GSList *iter = NULL;
460         stt_config_client_s* temp_client = NULL;
461
462         if (0 < g_slist_length(g_config_client_list)) {
463                 /* Check uid */
464                 iter = g_slist_nth(g_config_client_list, 0);
465
466                 while (NULL != iter) {
467                         temp_client = iter->data;
468
469                         if (NULL != temp_client) {
470                                 if (uid == temp_client->uid) {
471                                         g_config_client_list = g_slist_remove(g_config_client_list, temp_client);
472                                         free(temp_client);
473                                         temp_client = NULL;
474                                         break;
475                                 }
476                         }
477
478                         iter = g_slist_next(iter);
479                 }
480         }
481
482         if (0 < g_slist_length(g_config_client_list)) {
483                 SLOG(LOG_DEBUG, stt_tag(), "Client count (%d)", g_slist_length(g_config_client_list));
484         }
485         return;
486 }
487
488 void __stt_config_release_engine()
489 {
490         GSList *iter = NULL;
491         stt_engine_info_s *engine_info = NULL;
492
493         if (0 < g_slist_length(g_engine_list)) {
494
495                 /* Get a first item */
496                 iter = g_slist_nth(g_engine_list, 0);
497
498                 while (NULL != iter) {
499                         engine_info = iter->data;
500
501                         if (NULL != engine_info) {
502                                 g_engine_list = g_slist_remove(g_engine_list, engine_info);
503
504                                 stt_parser_free_engine_info(engine_info);
505                         }
506
507                         iter = g_slist_nth(g_engine_list, 0);
508                 }
509         }
510         return;
511 }
512
513 int __stt_config_mgr_check_engine_is_valid(const char* engine_id)
514 {
515         if (NULL == engine_id) {
516                 SLOG(LOG_ERROR, stt_tag(), "Input parameter is NULL");
517                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
518         }
519
520         GSList *iter = NULL;
521         stt_engine_info_s *engine_info = NULL;
522
523         if (0 >= g_slist_length(g_engine_list)) {
524                 SLOG(LOG_ERROR, stt_tag(), "There is no engine!!");
525                 return STT_CONFIG_ERROR_ENGINE_NOT_FOUND;
526         }
527
528         /* Get a first item */
529         iter = g_slist_nth(g_engine_list, 0);
530
531         while (NULL != iter) {
532                 engine_info = iter->data;
533
534                 if (NULL == engine_info) {
535                         SLOG(LOG_ERROR, stt_tag(), "engine info is NULL");
536                         return STT_CONFIG_ERROR_ENGINE_NOT_FOUND;
537                 }
538
539                 if (0 == strcmp(engine_id, engine_info->uuid)) {
540                         SLOG(LOG_DEBUG, stt_tag(), "Default engine is valid : %s", engine_id);
541                         return STT_CONFIG_ERROR_NONE;
542                 }
543
544                 iter = g_slist_next(iter);
545         }
546
547         /* Change default engine */
548         iter = g_slist_nth(g_engine_list, 0);
549         if (NULL == iter) {
550                 SLOG(LOG_ERROR, stt_tag(), "Operation failed - false engine");
551                 return STT_CONFIG_ERROR_OPERATION_FAILED;
552         }
553
554         engine_info = iter->data;
555         if (NULL == engine_info) {
556                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Engine info is NULL");
557                 return STT_CONFIG_ERROR_ENGINE_NOT_FOUND;
558         }
559
560         if (NULL != g_config_info->engine_id) {
561                 free(g_config_info->engine_id);
562                 g_config_info->engine_id = NULL;
563         }
564         if (NULL != g_config_info->setting) {
565                 free(g_config_info->setting);
566                 g_config_info->setting = NULL;
567         }
568
569         if (NULL != engine_info->uuid) {
570                 g_config_info->engine_id = strdup(engine_info->uuid);
571         }
572
573         if (NULL != engine_info->setting) {
574                 g_config_info->setting = strdup(engine_info->setting);
575         }
576
577         /* Engine is valid*/
578         GSList *iter_lang = NULL;
579         char* lang;
580         bool is_valid_lang = false;
581
582         if (0 >= g_slist_length(engine_info->languages)) {
583                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty supported language");
584                 return STT_CONFIG_ERROR_ENGINE_NOT_FOUND;
585         }
586
587         /* Get a first item */
588         iter_lang = g_slist_nth(engine_info->languages, 0);
589
590         while (NULL != iter_lang) {
591                 /*Get handle data from list*/
592                 lang = iter_lang->data;
593
594                 SLOG(LOG_DEBUG, stt_tag(), " %s", lang);
595                 if (NULL != lang) {
596                         if (0 == strcmp(lang, g_config_info->language)) {
597                                 /* language is valid */
598                                 is_valid_lang = true;
599                                 break;
600                         }
601                 }
602
603                 /*Get next item*/
604                 iter_lang = g_slist_next(iter_lang);
605         }
606
607         if (false == is_valid_lang) {
608                 iter_lang = g_slist_nth(engine_info->languages, 0);
609                 if (NULL != iter_lang) {
610                         lang = iter_lang->data;
611                         if (NULL != lang) {
612                                 if (NULL != g_config_info->language)
613                                         free(g_config_info->language);
614                                 g_config_info->language = strdup(lang);
615                         }
616                 }
617         }
618
619         /* Check options */
620         if (false == engine_info->support_silence_detection) {
621                 if (true == g_config_info->silence_detection)
622                         g_config_info->silence_detection = false;
623         }
624
625         SLOG(LOG_DEBUG, stt_tag(), "[Config] Engine changed");
626         SLOG(LOG_DEBUG, stt_tag(), "  Engine : %s", g_config_info->engine_id);
627         SLOG(LOG_DEBUG, stt_tag(), "  Setting : %s", g_config_info->setting);
628         SLOG(LOG_DEBUG, stt_tag(), "  language : %s", g_config_info->language);
629         SLOG(LOG_DEBUG, stt_tag(), "  Silence detection : %s", g_config_info->silence_detection ? "on" : "off");
630         SLOG(LOG_DEBUG, stt_tag(), "  Credential : %s", g_config_info->credential ? "true" : "false");
631
632         if (0 != stt_parser_set_engine(g_config_info->engine_id, g_config_info->setting, g_config_info->language,
633                 g_config_info->silence_detection, g_config_info->credential)) {
634                         SLOG(LOG_ERROR, stt_tag(), "Fail to save config");
635                         return STT_CONFIG_ERROR_OPERATION_FAILED;
636         }
637
638         return STT_CONFIG_ERROR_NONE;
639 }
640
641 static void __get_engine_list(const char* directory)
642 {
643         DIR *dp = NULL;
644         struct dirent *dirp = NULL;
645
646         if (NULL == directory) {
647                 SLOG(LOG_ERROR, stt_tag(), "[Directory ERROR] Directory is NULL");
648                 return;
649         } else {
650                 SLOG(LOG_DEBUG, stt_tag(), "[Directory DEBUG] Directory: %s", directory);
651         }
652
653         dp  = opendir(directory);
654         if (NULL != dp) {
655                 do {
656                         dirp = readdir(dp);
657
658                         if (NULL != dirp) {
659                                 if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name))
660                                         continue;
661
662                                 stt_engine_info_s* info;
663                                 char* filepath = NULL;
664                                 int filesize;
665
666                                 filesize = strlen(directory) + strlen(dirp->d_name) + 5;
667                                 filepath = (char*)calloc(filesize, sizeof(char));
668
669                                 if (NULL != filepath) {
670                                         snprintf(filepath, filesize, "%s/%s", directory, dirp->d_name);
671                                 } else {
672                                         SLOG(LOG_ERROR, stt_tag(), "[Config ERROR] Memory not enough!!");
673                                         continue;
674                                 }
675
676                                 SLOG(LOG_DEBUG, stt_tag(), "[File DEBUG] File path: %s", filepath);
677
678                                 if (0 == stt_parser_get_engine_info(filepath, &info)) {
679                                         g_engine_list = g_slist_append(g_engine_list, info);
680                                 }
681
682                                 if (NULL != filepath) {
683                                         free(filepath);
684                                         filepath = NULL;
685                                 }
686                         }
687                 } while (NULL != dirp);
688
689                 closedir(dp);
690         } else {
691                 SLOG(LOG_WARN, stt_tag(), "[Config WARNING] Fail to open directory"); 
692         }
693
694         return;
695 }
696
697 int stt_config_mgr_initialize(int uid)
698 {
699         GSList *iter = NULL;
700         int* get_uid;
701         stt_config_client_s* temp_client = NULL;
702
703         if (0 < g_slist_length(g_config_client_list)) {
704                 /* Check uid */
705                 iter = g_slist_nth(g_config_client_list, 0);
706
707                 while (NULL != iter) {
708                         get_uid = iter->data;
709
710                         if (uid == *get_uid) {
711                                 SLOG(LOG_WARN, stt_tag(), "[CONFIG] uid(%d) has already registered", uid);
712                                 return 0;
713                         }
714
715                         iter = g_slist_next(iter);
716                 }
717
718                 temp_client = (stt_config_client_s*)calloc(1, sizeof(stt_config_client_s));
719                 if (NULL == temp_client) {
720                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to allocate memory");
721                         return STT_CONFIG_ERROR_OUT_OF_MEMORY;
722                 }
723                 temp_client->uid = uid;
724                 temp_client->bool_cb = NULL;
725                 temp_client->engine_cb = NULL;
726                 temp_client->lang_cb = NULL;
727                 temp_client->user_data = NULL;
728
729                 /* Add uid */
730                 g_config_client_list = g_slist_append(g_config_client_list, temp_client);
731
732                 SLOG(LOG_WARN, stt_tag(), "[CONFIG] Add uid(%d) but config has already initialized", uid);
733                 return STT_CONFIG_ERROR_NONE;
734         }
735
736         /* Make directories */
737         if (0 != access(STT_CONFIG_BASE, F_OK)) {
738                 if (0 != mkdir(STT_CONFIG_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
739                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to make directory : %s", STT_CONFIG_BASE);
740                         __stt_config_release_client(uid);
741                         return STT_CONFIG_ERROR_OPERATION_FAILED;
742                 } else {
743                         SLOG(LOG_DEBUG, stt_tag(), "Success to make directory : %s", STT_CONFIG_BASE);
744                 }
745         }
746
747         if (0 != access(STT_HOME, F_OK)) {
748                 if (0 != mkdir(STT_HOME, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
749                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to make directory : %s", STT_HOME);
750                         __stt_config_release_client(uid);
751                         return STT_CONFIG_ERROR_OPERATION_FAILED;
752                 } else {
753                         SLOG(LOG_DEBUG, stt_tag(), "Success to make directory : %s", STT_HOME);
754                 }
755         }
756
757         if (0 != access(STT_DOWNLOAD_BASE, F_OK)) {
758                 if (0 != mkdir(STT_DOWNLOAD_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
759                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to make directory : %s", STT_DOWNLOAD_BASE);
760                         __stt_config_release_client(uid);
761                         return STT_CONFIG_ERROR_OPERATION_FAILED;
762                 } else {
763                         SLOG(LOG_DEBUG, stt_tag(), "Success to make directory : %s", STT_DOWNLOAD_BASE);
764                 }
765         }
766
767         if (0 != access(STT_DOWNLOAD_ENGINE_INFO, F_OK)) {
768                 if (0 != mkdir(STT_DOWNLOAD_ENGINE_INFO, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
769                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to make directory : %s", STT_DOWNLOAD_ENGINE_INFO);
770                         __stt_config_release_client(uid);
771                         return STT_CONFIG_ERROR_OPERATION_FAILED;
772                 } else {
773                         SLOG(LOG_DEBUG, stt_tag(), "Success to make directory : %s", STT_DOWNLOAD_ENGINE_INFO);
774                 }
775         }
776
777
778         /* Get file name from default engine directory */
779         g_engine_list = NULL;
780
781         SLOG(LOG_WARN, stt_tag(), "[CONFIG] default engine info(%s)", STT_DEFAULT_ENGINE_INFO);
782
783         SLOG(LOG_DEBUG, stt_tag(), "[CONFIG] Get default engine list");
784         __get_engine_list(STT_DEFAULT_ENGINE_INFO);
785         SLOG(LOG_DEBUG, stt_tag(), "[CONFIG] Get download engine list");
786         __get_engine_list(STT_DOWNLOAD_ENGINE_INFO);
787
788         __stt_config_mgr_print_engine_info();
789
790         if (0 != stt_parser_load_config(&g_config_info)) {
791                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to parse configure information");
792                 __stt_config_release_client(uid);
793                 __stt_config_release_engine();
794                 return STT_CONFIG_ERROR_OPERATION_FAILED;
795         }
796
797         /* Check whether engine id is valid */
798         if (0 != __stt_config_mgr_check_engine_is_valid(g_config_info->engine_id)) {
799                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to get default engine");
800                 __stt_config_release_client(uid);
801                 __stt_config_release_engine();
802                 stt_parser_unload_config(g_config_info);
803                 return STT_CONFIG_ERROR_ENGINE_NOT_FOUND;
804         }
805
806         if (true == g_config_info->auto_lang) {
807                 /* Check language with display language */
808                 __stt_config_set_auto_language();
809         } else {
810                 if (false == __stt_config_mgr_check_lang_is_valid(g_config_info->engine_id, g_config_info->language)) {
811                         /* Default language is not valid */
812                         char* tmp_language;
813                         if (0 != __stt_config_mgr_select_lang(g_config_info->engine_id, &tmp_language)) {
814                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to select language");
815                                 __stt_config_release_client(uid);
816                                 __stt_config_release_engine();
817                                 stt_parser_unload_config(g_config_info);
818                                 return STT_CONFIG_ERROR_OPERATION_FAILED;
819                         }
820
821                         if (NULL != tmp_language) {
822                                 if (NULL != g_config_info->language) {
823                                         free(g_config_info->language);
824                                         g_config_info->language = strdup(tmp_language);
825                                 }
826
827                                 free(tmp_language);
828                         }
829                 }
830         }
831
832         /* print stt-service config */
833         SLOG(LOG_DEBUG, stt_tag(), "== STT service config ==");
834         SLOG(LOG_DEBUG, stt_tag(), " engine : %s", g_config_info->engine_id);
835         SLOG(LOG_DEBUG, stt_tag(), " setting : %s", g_config_info->setting);
836         SLOG(LOG_DEBUG, stt_tag(), " auto language : %s", g_config_info->auto_lang ? "on" : "off");
837         SLOG(LOG_DEBUG, stt_tag(), " language : %s", g_config_info->language);
838         SLOG(LOG_DEBUG, stt_tag(), " silence detection : %s", g_config_info->silence_detection ? "on" : "off");
839         SLOG(LOG_DEBUG, stt_tag(), " credential : %s", g_config_info->credential ? "true" : "false");
840         SLOG(LOG_DEBUG, stt_tag(), "===================");
841
842         if (0 != __stt_config_mgr_register_config_event()) {
843                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to register config event");
844                 __stt_config_release_client(uid);
845                 __stt_config_release_engine();
846                 stt_parser_unload_config(g_config_info);
847                 return STT_CONFIG_ERROR_OPERATION_FAILED;
848         }
849
850         /* Register to detect display language change */
851         vconf_notify_key_changed(VCONFKEY_LANGSET, __stt_config_language_changed_cb, NULL);
852
853         temp_client = (stt_config_client_s*)calloc(1, sizeof(stt_config_client_s));
854         if (NULL == temp_client) {
855                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to allocate memory");
856                 return STT_CONFIG_ERROR_OUT_OF_MEMORY;
857         }
858         temp_client->uid = uid;
859         temp_client->bool_cb = NULL;
860         temp_client->engine_cb = NULL;
861         temp_client->lang_cb = NULL;
862         temp_client->user_data = NULL;
863
864         /* Add uid */
865         g_config_client_list = g_slist_append(g_config_client_list, temp_client);
866
867         return STT_CONFIG_ERROR_NONE;
868 }
869
870 int stt_config_mgr_finalize(int uid)
871 {
872         GSList *iter = NULL;
873         stt_config_client_s* temp_client = NULL;
874
875         if (0 < g_slist_length(g_config_client_list)) {
876                 /* Check uid */
877                 iter = g_slist_nth(g_config_client_list, 0);
878
879                 while (NULL != iter) {
880                         temp_client = iter->data;
881
882                         if (NULL != temp_client) {
883                                 if (uid == temp_client->uid) {
884                                         g_config_client_list = g_slist_remove(g_config_client_list, temp_client);
885                                         free(temp_client);
886                                         temp_client = NULL;
887                                         break;
888                                 }
889                         }
890
891                         iter = g_slist_next(iter);
892                 }
893         }
894
895         if (0 < g_slist_length(g_config_client_list)) {
896                 SLOG(LOG_DEBUG, stt_tag(), "Client count (%d)", g_slist_length(g_config_client_list));
897                 return STT_CONFIG_ERROR_NONE;
898         }
899
900         stt_engine_info_s *engine_info = NULL;
901
902         if (0 < g_slist_length(g_engine_list)) {
903
904                 /* Get a first item */
905                 iter = g_slist_nth(g_engine_list, 0);
906
907                 while (NULL != iter) {
908                         engine_info = iter->data;
909
910                         if (NULL != engine_info) {
911                                 g_engine_list = g_slist_remove(g_engine_list, engine_info);
912
913                                 stt_parser_free_engine_info(engine_info);
914                         }
915
916                         iter = g_slist_nth(g_engine_list, 0);
917                 }
918         }
919
920         vconf_ignore_key_changed(VCONFKEY_LANGSET, __stt_config_language_changed_cb);
921
922         __stt_config_mgr_unregister_config_event();
923
924         if (NULL != g_config_info) {
925                 stt_parser_unload_config(g_config_info);
926                 g_config_info = NULL;
927         }
928
929         return STT_CONFIG_ERROR_NONE;
930 }
931
932 int stt_config_mgr_set_callback(int uid, stt_config_engine_changed_cb engine_cb, stt_config_lang_changed_cb lang_cb, stt_config_bool_changed_cb bool_cb, void* user_data)
933 {
934         GSList *iter = NULL;
935         stt_config_client_s* temp_client = NULL;
936
937         /* Call all callbacks of client*/
938         iter = g_slist_nth(g_config_client_list, 0);
939
940         while (NULL != iter) {
941                 temp_client = iter->data;
942
943                 if (NULL != temp_client) {
944                         if (uid == temp_client->uid) {
945                                 temp_client->engine_cb = engine_cb;
946                                 temp_client->lang_cb = lang_cb;
947                                 temp_client->bool_cb = bool_cb;
948                                 temp_client->user_data = user_data;
949                         }
950                 }
951
952                 iter = g_slist_next(iter);
953         }
954
955         return STT_CONFIG_ERROR_NONE;
956 }
957
958 int stt_config_mgr_unset_callback(int uid)
959 {
960         GSList *iter = NULL;
961         stt_config_client_s* temp_client = NULL;
962
963         /* Call all callbacks of client*/
964         iter = g_slist_nth(g_config_client_list, 0);
965
966         while (NULL != iter) {
967                 temp_client = iter->data;
968
969                 if (NULL != temp_client) {
970                         if (uid == temp_client->uid) {
971                                 temp_client->engine_cb = NULL;
972                                 temp_client->lang_cb = NULL;
973                                 temp_client->bool_cb = NULL;
974                                 temp_client->user_data = NULL;
975                         }
976                 }
977
978                 iter = g_slist_next(iter);
979         }
980
981         return STT_CONFIG_ERROR_NONE;
982 }
983
984 int stt_config_mgr_get_engine_list(stt_config_supported_engine_cb callback, void* user_data)
985 {
986         if (0 >= g_slist_length(g_config_client_list)) {
987                 SLOG(LOG_ERROR, stt_tag(), "Not initialized");
988                 return STT_CONFIG_ERROR_INVALID_STATE;
989         }
990
991         if (NULL == callback) {
992                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
993         }
994
995         GSList *iter = NULL;
996         stt_engine_info_s *engine_info = NULL;
997
998         if (0 >= g_slist_length(g_engine_list)) {
999                 SLOG(LOG_WARN, stt_tag(), "[ERROR] Engine list is NULL");
1000                 return STT_CONFIG_ERROR_ENGINE_NOT_FOUND;
1001         }
1002
1003         /* Get a first item */
1004         iter = g_slist_nth(g_engine_list, 0);
1005
1006         while (NULL != iter) {
1007                 engine_info = iter->data;
1008
1009                 if (NULL == engine_info) {
1010                         SLOG(LOG_ERROR, stt_tag(), " Engine info is NULL");
1011                         return STT_CONFIG_ERROR_OPERATION_FAILED;
1012                 }
1013
1014                 if (false == callback(engine_info->uuid, engine_info->name, 
1015                         engine_info->setting, engine_info->support_silence_detection, user_data)) {
1016                         break;
1017                 }
1018
1019                 iter = g_slist_next(iter);
1020         }
1021
1022         return STT_CONFIG_ERROR_NONE;
1023 }
1024
1025 int stt_config_mgr_get_engine(char** engine)
1026 {
1027         if (0 >= g_slist_length(g_config_client_list)) {
1028                 SLOG(LOG_ERROR, stt_tag(), "Not initialized");
1029                 return STT_CONFIG_ERROR_INVALID_STATE;
1030         }
1031
1032         if (NULL == engine) {
1033                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1034         }
1035
1036         if (NULL != g_config_info->engine_id) {
1037                 *engine = strdup(g_config_info->engine_id);
1038         } else {
1039                 SLOG(LOG_ERROR, stt_tag(), " Engine id is NULL");
1040                 return STT_CONFIG_ERROR_ENGINE_NOT_FOUND;
1041         }
1042
1043         return STT_CONFIG_ERROR_NONE;
1044 }
1045
1046 int __stt_config_set_buxtonkey(const char* engine)
1047 {
1048         /* Set vconfkey */
1049         struct buxton_client * bux_cli;
1050         struct buxton_layer * bux_layer;
1051         struct buxton_value * bux_val;
1052
1053         int ret = buxton_open(&bux_cli, NULL, NULL);
1054         if (0 != ret) {
1055                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] Fail to open buxton client, ret(%d)", ret);
1056                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1057         }
1058         bux_layer = buxton_create_layer("system");
1059         if (NULL == bux_layer) {
1060                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] buxton_create_layer FAIL");
1061                 buxton_close(bux_cli);
1062                 bux_cli = NULL;
1063                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1064         }
1065         bux_val = buxton_value_create_string(engine);
1066         if (NULL == bux_val) {
1067                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] buxton_value_create_string FAIL");
1068                 buxton_free_layer(bux_layer);
1069                 buxton_close(bux_cli);
1070                 bux_layer = NULL;
1071                 bux_cli = NULL;
1072                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1073         } else {
1074                 SLOG(LOG_DEBUG, stt_tag(), "[DBUS-BUXTON2] layer: %s", buxton_layer_get_name(bux_layer));
1075         }
1076
1077         ret = buxton_set_value_sync(bux_cli, bux_layer, STT_ENGINE_DB_DEFAULT, bux_val);
1078         if (0 != ret) {
1079                 SLOG(LOG_ERROR, stt_tag(), "[DBUS-BUXTON2] Fail to set value sync, ret(%d)", ret);
1080                 buxton_value_free(bux_val);
1081                 buxton_free_layer(bux_layer);
1082                 buxton_close(bux_cli);
1083
1084                 bux_cli = NULL;
1085                 bux_layer = NULL;
1086                 bux_val = NULL;
1087                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1088         }
1089         SLOG(LOG_DEBUG, stt_tag(), "[DBUS-BUXTON2] buxton_set_value_sync: %s", STT_ENGINE_DB_DEFAULT);
1090
1091         buxton_value_free(bux_val);
1092         buxton_free_layer(bux_layer);
1093         buxton_close(bux_cli);
1094
1095         bux_cli = NULL;
1096         bux_layer = NULL;
1097         bux_val = NULL;
1098
1099         return STT_CONFIG_ERROR_NONE;
1100 }
1101
1102 int stt_config_mgr_set_engine(const char* engine)
1103 {
1104         if (0 >= g_slist_length(g_config_client_list)) {
1105                 SLOG(LOG_ERROR, stt_tag(), "Not initialized");
1106                 return STT_CONFIG_ERROR_INVALID_STATE;
1107         }
1108
1109         if (NULL == g_config_info) {
1110                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1111         }
1112
1113         if (NULL == engine || NULL == g_config_info->engine_id) {
1114                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1115         }
1116
1117         /* Check current engine id with new engine id */
1118         if (0 == strcmp(g_config_info->engine_id, engine)) {
1119                 return 0;
1120         }
1121
1122         SLOG(LOG_DEBUG, stt_tag(), "New engine id : %s", engine);
1123
1124         int ret = __stt_config_set_buxtonkey(engine);
1125         if (0 != ret) {
1126                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] set buxtonkey Failed!!!");
1127                 return ret;
1128         }
1129
1130         GSList *iter = NULL;
1131         stt_engine_info_s *engine_info = NULL;
1132         bool is_valid_engine = false;
1133
1134         /* Get a first item */
1135         iter = g_slist_nth(g_engine_list, 0);
1136
1137         while (NULL != iter) {
1138                 engine_info = iter->data;
1139
1140                 if (NULL == engine_info) {
1141                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Engine info is NULL");
1142                         iter = g_slist_next(iter);
1143                         continue;
1144                 }
1145
1146                 /* Check engine id is valid */
1147                 if (0 != strcmp(engine, engine_info->uuid)) {
1148                         iter = g_slist_next(iter);
1149                         continue;
1150                 }
1151
1152                 if (NULL != g_config_info->engine_id) {
1153                         free(g_config_info->engine_id);
1154                         g_config_info->engine_id = NULL;
1155                 }
1156
1157                 g_config_info->engine_id = strdup(engine);
1158
1159                 if (NULL != g_config_info->setting) {
1160                         free(g_config_info->setting);
1161                         g_config_info->setting = NULL;
1162                 }
1163
1164                 if (NULL != engine_info->setting) {
1165                         g_config_info->setting = strdup(engine_info->setting);
1166                 } else {
1167                         g_config_info->setting = NULL;
1168                 }
1169
1170                 /* Engine is valid*/
1171                 GSList *iter_lang = NULL;
1172                 char* lang;
1173                 bool is_valid_lang = false;
1174
1175                 /* Get a first item */
1176                 iter_lang = g_slist_nth(engine_info->languages, 0);
1177
1178                 while (NULL != iter_lang) {
1179                         /*Get handle data from list*/
1180                         lang = iter_lang->data;
1181
1182                         SLOG(LOG_DEBUG, stt_tag(), " %s", lang);
1183                         if (NULL != lang && NULL != g_config_info->language) {
1184                                 if (0 == strcmp(lang, g_config_info->language)) {
1185                                         /* language is valid */
1186                                         is_valid_lang = true;
1187
1188                                         free(g_config_info->language);
1189                                         g_config_info->language = strdup(lang);
1190
1191                                         break;
1192                                 }
1193                         }
1194
1195                         /*Get next item*/
1196                         iter_lang = g_slist_next(iter_lang);
1197                 }
1198
1199                 if (false == is_valid_lang) {
1200                         if (NULL != g_config_info->language) {
1201                                 free(g_config_info->language);
1202                                 g_config_info->language = NULL;
1203
1204                                 iter_lang = g_slist_nth(engine_info->languages, 0);
1205                                 if (NULL == iter_lang) {
1206                                         SLOG(LOG_ERROR, stt_tag(), "Fail to get default language");
1207                                         break;
1208                                 }
1209
1210                                 lang = iter_lang->data;
1211
1212                                 g_config_info->language = strdup(lang);
1213                         }
1214                 }
1215
1216                 /* Check options */
1217                 if (false == engine_info->support_silence_detection) {
1218                         if (true == g_config_info->silence_detection)
1219                                 g_config_info->silence_detection = false;
1220                 }
1221
1222                 if (false == engine_info->need_credential) {
1223                         if (true == g_config_info->credential)
1224                                 g_config_info->credential = false;
1225                 }
1226
1227                 is_valid_engine = true;
1228                 break;
1229         }
1230
1231         if (true == is_valid_engine) {
1232                 SLOG(LOG_DEBUG, stt_tag(), "[Config] Engine changed");
1233                 SLOG(LOG_DEBUG, stt_tag(), "  Engine : %s", g_config_info->engine_id);
1234                 SLOG(LOG_DEBUG, stt_tag(), "  Setting : %s", g_config_info->setting);
1235                 SLOG(LOG_DEBUG, stt_tag(), "  language : %s", g_config_info->language);
1236                 SLOG(LOG_DEBUG, stt_tag(), "  Silence detection : %s", g_config_info->silence_detection ? "on" : "off");
1237                 SLOG(LOG_DEBUG, stt_tag(), "  Credential : %s", g_config_info->credential ? "true" : "false");
1238
1239                 if (0 != stt_parser_set_engine(g_config_info->engine_id, g_config_info->setting, g_config_info->language,
1240                         g_config_info->silence_detection, g_config_info->credential)) {
1241                                 SLOG(LOG_ERROR, stt_tag(), " Fail to save config");
1242                                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1243                 }
1244         } else {
1245                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Engine id is not valid");
1246                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1247         }
1248
1249         return 0;
1250 }
1251
1252 int stt_config_mgr_get_engine_agreement(const char* engine, char** agreement)
1253 {
1254         if (0 >= g_slist_length(g_engine_list)) {
1255                 SLOG(LOG_ERROR, stt_tag(), "There is no engine");
1256                 return STT_CONFIG_ERROR_INVALID_STATE;
1257         }
1258
1259         if (NULL == agreement) {
1260                 SLOG(LOG_ERROR, stt_tag(), "Input parameter is NULL");
1261                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1262         }
1263
1264         GSList *iter = NULL;
1265         stt_engine_info_s *engine_info = NULL;
1266         char* current_engine = NULL;
1267
1268         if (NULL == engine) {
1269                 current_engine = strdup(g_config_info->engine_id);
1270                 if (NULL == current_engine) {
1271                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to allocate memory");
1272                         return STT_CONFIG_ERROR_OUT_OF_MEMORY;;
1273                 }
1274         } else {
1275                 current_engine = strdup(engine);
1276                 if (NULL == current_engine) {
1277                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to allocate memory");
1278                         return STT_CONFIG_ERROR_OUT_OF_MEMORY;;
1279                 }
1280         }
1281
1282         /* Get a first item */
1283         iter = g_slist_nth(g_engine_list, 0);
1284
1285         while (NULL != iter) {
1286                 engine_info = iter->data;
1287
1288                 if (NULL == engine_info) {
1289                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] engine info is NULL");
1290                         if (NULL != current_engine)     free(current_engine);
1291                         return STT_CONFIG_ERROR_OPERATION_FAILED;
1292                 }
1293
1294                 if (0 != strcmp(current_engine, engine_info->uuid)) {
1295                         iter = g_slist_next(iter);
1296                         continue;
1297                 }
1298
1299                 if (NULL != engine_info->agreement) {
1300                         *agreement = strdup(engine_info->agreement);
1301                 } else {
1302                         SLOG(LOG_WARN, stt_tag(), "[WARNING] engine agreement is not support");
1303                 }
1304                 break;
1305         }
1306
1307         if (NULL != current_engine)     free(current_engine);
1308
1309         return STT_CONFIG_ERROR_NONE;
1310 }
1311
1312 int stt_config_mgr_get_language_list(const char* engine_id, stt_config_supported_langauge_cb callback, void* user_data)
1313 {
1314         if (0 >= g_slist_length(g_config_client_list)) {
1315                 SLOG(LOG_ERROR, stt_tag(), "Not initialized");
1316                 return STT_CONFIG_ERROR_INVALID_STATE;
1317         }
1318
1319         if (0 >= g_slist_length(g_engine_list)) {
1320                 SLOG(LOG_ERROR, stt_tag(), "There is no engine");
1321                 return STT_CONFIG_ERROR_ENGINE_NOT_FOUND;
1322         }
1323
1324         GSList *iter = NULL;
1325         stt_engine_info_s *engine_info = NULL;
1326
1327         /* Get a first item */
1328         iter = g_slist_nth(g_engine_list, 0);
1329
1330         while (NULL != iter) {
1331                 engine_info = iter->data;
1332
1333                 if (NULL == engine_info) {
1334                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] engine info is NULL");
1335                         return STT_CONFIG_ERROR_OPERATION_FAILED;
1336                 }
1337
1338                 if (0 != strcmp(engine_id, engine_info->uuid)) {
1339                         iter = g_slist_next(iter);
1340                         continue;
1341                 }
1342
1343                 GSList *iter_lang = NULL;
1344                 char* lang;
1345
1346                 /* Get a first item */
1347                 iter_lang = g_slist_nth(engine_info->languages, 0);
1348
1349                 while (NULL != iter_lang) {
1350                         /*Get handle data from list*/
1351                         lang = iter_lang->data;
1352
1353                         if (NULL != lang) {
1354                                 SLOG(LOG_DEBUG, stt_tag(), " %s", lang);
1355                                 if (false == callback(engine_info->uuid, lang, user_data))
1356                                         break;
1357                         }
1358
1359                         /*Get next item*/
1360                         iter_lang = g_slist_next(iter_lang);
1361                 }
1362                 break;
1363         }
1364
1365         return STT_CONFIG_ERROR_NONE;
1366 }
1367
1368 int stt_config_mgr_get_default_language(char** language)
1369 {
1370         if (0 >= g_slist_length(g_config_client_list)) {
1371                 SLOG(LOG_ERROR, stt_tag(), "Not initialized");
1372                 return STT_CONFIG_ERROR_INVALID_STATE;
1373         }
1374
1375         if (NULL == language) {
1376                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1377         }
1378
1379         if (NULL != g_config_info->language) {
1380                 *language = strdup(g_config_info->language);
1381         } else {
1382                 SLOG(LOG_ERROR, stt_tag(), " language is NULL");
1383                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1384         }
1385
1386         return STT_CONFIG_ERROR_NONE;
1387 }
1388
1389 int stt_config_mgr_set_default_language(const char* language)
1390 {
1391         if (0 >= g_slist_length(g_config_client_list)) {
1392                 SLOG(LOG_ERROR, stt_tag(), "Not initialized");
1393                 return STT_CONFIG_ERROR_INVALID_STATE;
1394         }
1395
1396         if (NULL == language) {
1397                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1398         }
1399
1400         /* Check language is valid */
1401         if (NULL != g_config_info->language) {
1402                 if (0 != stt_parser_set_language(language)) {
1403                         SLOG(LOG_ERROR, stt_tag(), "Fail to save engine id");
1404                         return STT_CONFIG_ERROR_OPERATION_FAILED;
1405                 }
1406                 free(g_config_info->language);
1407                 g_config_info->language = strdup(language);
1408         } else {
1409                 SLOG(LOG_ERROR, stt_tag(), " language is NULL");
1410                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1411         }
1412
1413         return STT_CONFIG_ERROR_NONE;
1414 }
1415
1416 int stt_config_mgr_get_auto_language(bool* value)
1417 {
1418         if (0 >= g_slist_length(g_config_client_list)) {
1419                 SLOG(LOG_ERROR, stt_tag(), "Not initialized");
1420                 return STT_CONFIG_ERROR_INVALID_STATE;
1421         }
1422
1423         if (NULL == value) {
1424                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1425         }
1426
1427         *value = g_config_info->auto_lang;
1428
1429         return STT_CONFIG_ERROR_NONE;
1430 }
1431
1432 int stt_config_mgr_set_auto_language(bool value)
1433 {
1434         if (0 >= g_slist_length(g_config_client_list)) {
1435                 SLOG(LOG_ERROR, stt_tag(), "Not initialized");
1436                 return STT_CONFIG_ERROR_INVALID_STATE;
1437         }
1438
1439         if (g_config_info->auto_lang != value) {
1440                 /* Check language is valid */
1441                 if (0 != stt_parser_set_auto_lang(value)) {
1442                         SLOG(LOG_ERROR, stt_tag(), "Fail to save engine id");
1443                         return STT_CONFIG_ERROR_OPERATION_FAILED;
1444                 }
1445                 g_config_info->auto_lang = value;
1446
1447                 if (true == g_config_info->auto_lang) {
1448                         __stt_config_set_auto_language();
1449                 }
1450         }
1451
1452         return STT_CONFIG_ERROR_NONE;
1453 }
1454
1455 int stt_config_mgr_get_silence_detection(bool* value)
1456 {
1457         if (0 >= g_slist_length(g_config_client_list)) {
1458                 SLOG(LOG_ERROR, stt_tag(), "Not initialized");
1459                 return STT_CONFIG_ERROR_INVALID_STATE;
1460         }
1461
1462         if (NULL == value)
1463                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1464
1465         *value = g_config_info->silence_detection;
1466
1467         return STT_CONFIG_ERROR_NONE;
1468 }
1469
1470 int stt_config_mgr_set_silence_detection(bool value)
1471 {
1472         if (0 >= g_slist_length(g_config_client_list)) {
1473                 SLOG(LOG_ERROR, stt_tag(), "Not initialized");
1474                 return STT_CONFIG_ERROR_INVALID_STATE;
1475         }
1476
1477         if (0 != stt_parser_set_silence_detection(value)) {
1478                 SLOG(LOG_ERROR, stt_tag(), "Fail to save engine id");
1479                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1480         }
1481
1482         g_config_info->silence_detection = value;
1483
1484         return STT_CONFIG_ERROR_NONE;
1485 }
1486
1487 bool stt_config_check_default_engine_is_valid(const char* engine)
1488 {
1489         if (0 >= g_slist_length(g_config_client_list)) {
1490                 SLOG(LOG_ERROR, stt_tag(), "Not initialized");
1491                 return false;
1492         }
1493
1494         if (NULL == engine) {
1495                 return false;
1496         }
1497
1498         if (0 >= g_slist_length(g_engine_list))
1499                 return false;
1500
1501         GSList *iter = NULL;
1502         stt_engine_info_s *engine_info = NULL;
1503
1504         /* Get a first item */
1505         iter = g_slist_nth(g_engine_list, 0);
1506
1507         while (NULL != iter) {
1508                 engine_info = iter->data;
1509
1510                 if (NULL != engine_info) {
1511                         if (0 == strcmp(engine, engine_info->uuid)) {
1512                                 return true;
1513                         }
1514                 }
1515                 iter = g_slist_next(iter);
1516         }
1517
1518         return false;
1519 }
1520
1521 bool stt_config_check_default_language_is_valid(const char* language)
1522 {
1523         if (0 >= g_slist_length(g_config_client_list)) {
1524                 SLOG(LOG_ERROR, stt_tag(), "Not initialized");
1525                 return false;
1526         }
1527
1528         if (NULL == language) {
1529                 return false;
1530         }
1531
1532         if (NULL == g_config_info->engine_id) {
1533                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Default engine id is NULL");
1534                 return false;
1535         }
1536
1537         if (0 >= g_slist_length(g_engine_list))
1538                 return false;
1539
1540         GSList *iter = NULL;
1541         stt_engine_info_s *engine_info = NULL;
1542
1543         /* Get a first item */
1544         iter = g_slist_nth(g_engine_list, 0);
1545
1546         while (NULL != iter) {
1547                 engine_info = iter->data;
1548
1549                 if (NULL == engine_info) {
1550                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Engine info is NULL");
1551                         iter = g_slist_next(iter);
1552                         continue;
1553                 }
1554
1555                 if (0 != strcmp(g_config_info->engine_id, engine_info->uuid)) {
1556                         iter = g_slist_next(iter);
1557                         continue;
1558                 }
1559
1560                 GSList *iter_lang = NULL;
1561                 char* lang;
1562
1563                 /* Get a first item */
1564                 iter_lang = g_slist_nth(engine_info->languages, 0);
1565
1566                 while (NULL != iter_lang) {
1567                         lang = iter_lang->data;
1568
1569                         if (0 == strcmp(language, lang))
1570                                 return true;
1571
1572                         /*Get next item*/
1573                         iter_lang = g_slist_next(iter_lang);
1574                 }
1575                 break;
1576         }
1577
1578         return false;
1579 }
1580
1581 int __stt_config_mgr_print_engine_info()
1582 {
1583         GSList *iter = NULL;
1584         stt_engine_info_s *engine_info = NULL;
1585
1586         if (0 >= g_slist_length(g_engine_list)) {
1587                 SLOG(LOG_DEBUG, stt_tag(), "-------------- engine list -----------------");
1588                 SLOG(LOG_DEBUG, stt_tag(), "  No Engine in engine directory");
1589                 SLOG(LOG_DEBUG, stt_tag(), "--------------------------------------------");
1590                 return 0;
1591         }
1592
1593         /* Get a first item */
1594         iter = g_slist_nth(g_engine_list, 0);
1595
1596         SLOG(LOG_DEBUG, stt_tag(), "--------------- engine list -----------------");
1597
1598         int i = 1;
1599         while (NULL != iter) {
1600                 engine_info = iter->data;
1601
1602                 SLOG(LOG_DEBUG, stt_tag(), "[%dth]", i);
1603                 SLOG(LOG_DEBUG, stt_tag(), " name : %s", engine_info->name);
1604                 SLOG(LOG_DEBUG, stt_tag(), " id   : %s", engine_info->uuid);
1605                 SLOG(LOG_DEBUG, stt_tag(), " setting : %s", engine_info->setting);
1606                 SLOG(LOG_DEBUG, stt_tag(), " agreement : %s", engine_info->agreement);
1607
1608                 SLOG(LOG_DEBUG, stt_tag(), " languages");
1609                 GSList *iter_lang = NULL;
1610                 char* lang;
1611                 if (g_slist_length(engine_info->languages) > 0) {
1612                         /* Get a first item */
1613                         iter_lang = g_slist_nth(engine_info->languages, 0);
1614
1615                         int j = 1;
1616                         while (NULL != iter_lang) {
1617                                 /*Get handle data from list*/
1618                                 lang = iter_lang->data;
1619
1620                                 SLOG(LOG_DEBUG, stt_tag(), "  [%dth] %s", j, lang);
1621
1622                                 /*Get next item*/
1623                                 iter_lang = g_slist_next(iter_lang);
1624                                 j++;
1625                         }
1626                 } else {
1627                         SLOG(LOG_ERROR, stt_tag(), "  language is NONE");
1628                 }
1629                 SLOG(LOG_DEBUG, stt_tag(), " silence support : %s", 
1630                         engine_info->support_silence_detection ? "true" : "false");
1631                 iter = g_slist_next(iter);
1632                 i++;
1633         }
1634         SLOG(LOG_DEBUG, stt_tag(), "--------------------------------------------");
1635
1636         return 0;
1637 }
1638
1639
1640
1641 /**
1642 * time info functions
1643 */
1644 static GSList* g_time_list = NULL;
1645
1646 int stt_config_mgr_reset_time_info()
1647 {
1648         /* Remove time info */
1649         GSList *iter = NULL;
1650         stt_result_time_info_s *data = NULL;
1651
1652         /* Remove time info */
1653         iter = g_slist_nth(g_time_list, 0);
1654         while (NULL != iter) {
1655                 data = iter->data;
1656
1657                 g_time_list = g_slist_remove(g_time_list, data);
1658                 if (NULL != data) {
1659                         if (NULL != data->text) {
1660                                 free(data->text);
1661                                 data->text = NULL;
1662                         }
1663                         free(data);
1664                         data = NULL;
1665                 }
1666
1667                 /*Get next item*/
1668                 iter = g_slist_nth(g_time_list, 0);
1669         }
1670
1671         return 0;
1672 }
1673
1674 int stt_config_mgr_add_time_info(int index, int event, const char* text, long start_time, long end_time)
1675 {
1676         if (NULL == text) {
1677                 SLOG(LOG_ERROR, stt_tag(), "Invalid paramter : text is NULL");
1678                 return -1;
1679         }
1680
1681         stt_result_time_info_s *info = (stt_result_time_info_s*)calloc(1, sizeof(stt_result_time_info_s));
1682         if (NULL == info) {
1683                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to allocate memory");
1684                 return STT_CONFIG_ERROR_OUT_OF_MEMORY;
1685         }
1686         info->index = index;
1687         info->event = event;
1688         if (NULL != text) {
1689                 info->text = strdup(text);
1690         }
1691         info->start_time = start_time;
1692         info->end_time = end_time;
1693
1694         SLOG(LOG_DEBUG, stt_tag(), "[DEBUG] inside stt_config_mgr_add_time_info: index(%d), text(%s), start time(%ld), end_time(%ld)", info->index, (NULL == info->text) ? "NULL" : info->text, info->start_time, info->end_time);
1695
1696         /* Add item to global list */
1697         g_time_list = g_slist_append(g_time_list, info);
1698
1699         SLOG(LOG_DEBUG, stt_tag(), "[DEBUG] inside stt_config_mgr_add_time_info: g_time_list length(%d)", g_slist_length(g_time_list));
1700
1701         return 0;
1702 }
1703
1704 int stt_config_mgr_foreach_time_info(stt_config_result_time_cb callback, void* user_data)
1705 {
1706         if (NULL == callback) {
1707                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Input paramter is NULL : callback function");
1708                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1709         }
1710
1711         GSList* temp_time = NULL;
1712         int ret;
1713         ret = stt_parser_get_time_info(&temp_time);
1714         if (0 != ret) {
1715                 SLOG(LOG_WARN, stt_tag(), "[WARNING] Fail to get time info : %d", ret);
1716                 return STT_CONFIG_ERROR_NONE;
1717         }
1718
1719         GSList *iter = NULL;
1720         stt_result_time_info_s *data = NULL;
1721
1722         /* Get a first item */
1723         iter = g_slist_nth(temp_time, 0);
1724         while (NULL != iter) {
1725                 data = iter->data;
1726
1727                 if (false == callback(data->index, data->event, data->text, 
1728                         data->start_time, data->end_time, user_data)) {
1729                         break;
1730                 }
1731
1732                 /*Get next item*/
1733                 iter = g_slist_next(iter);
1734         }
1735
1736         /* Remove time info */
1737         iter = g_slist_nth(temp_time, 0);
1738         while (NULL != iter) {
1739                 data = iter->data;
1740
1741                 if (NULL != data) {
1742                         temp_time = g_slist_remove(temp_time, data);
1743
1744                         if (NULL != data->text) {
1745                                 free(data->text);
1746                                 data->text = NULL;
1747                         }
1748                         free(data);
1749                         data = NULL;
1750                 }
1751
1752                 /*Get next item*/
1753                 iter = g_slist_nth(temp_time, 0);
1754         }
1755
1756         return STT_CONFIG_ERROR_NONE;
1757 }
1758
1759 int stt_config_mgr_save_time_info_file()
1760 {
1761         if (0 == g_slist_length(g_time_list)) {
1762                 SLOG(LOG_WARN, stt_tag(), "[WARNING] There is no time info to save");
1763                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1764         }
1765
1766         int ret = 0;
1767         ret = stt_parser_set_time_info(g_time_list);
1768         if (0 != ret) {
1769                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to save time info : %d", ret);
1770                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1771         }
1772
1773         return STT_CONFIG_ERROR_NONE;
1774 }
1775
1776 int stt_config_mgr_remove_time_info_file()
1777 {
1778         stt_parser_clear_time_info();
1779
1780         return STT_CONFIG_ERROR_NONE;
1781 }