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