Merge "Extract to get base node from config" into tizen
[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         unsigned 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 static GSList* g_engine_list = NULL;
39
40 static GSList* g_config_client_list = NULL;
41
42 static stt_config_s* g_config_info;
43
44 static Ecore_Fd_Handler* g_fd_handler_noti = NULL;
45 static int g_fd_noti;
46 static int g_wd_noti;
47
48 int __stt_config_mgr_print_engine_info();
49
50 bool __stt_config_mgr_check_lang_is_valid(const char* engine_id, const char* language)
51 {
52         if (NULL == engine_id || NULL == language) {
53                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Input parameter is NULL");
54                 return false;
55         }
56
57         GSList *iter = NULL;
58         stt_engine_info_s *engine_info = NULL;
59
60         if (0 >= g_slist_length(g_engine_list)) {
61                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] There is no engine!!");
62                 return false;
63         }
64
65         /* Get a first item */
66         iter = g_slist_nth(g_engine_list, 0);
67
68         while (NULL != iter) {
69                 engine_info = iter->data;
70
71                 if (NULL == engine_info) {
72                         SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Engine info is NULL");
73                         return false;
74                 }
75
76                 if (0 != strcmp(engine_id, engine_info->uuid)) {
77                         iter = g_slist_next(iter);
78                         continue;
79                 }
80
81                 GSList *iter_lang = NULL;
82                 char* engine_lang;
83                 if (g_slist_length(engine_info->languages) > 0) {
84                         /* Get a first item */
85                         iter_lang = g_slist_nth(engine_info->languages, 0);
86
87                         int i = 1;
88                         while (NULL != iter_lang) {
89                                 /*Get handle data from list*/
90                                 engine_lang = iter_lang->data;
91
92                                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "  [%dth] %s", i, engine_lang);
93
94                                 if (0 == strcmp(language, engine_lang)) {
95                                         return true;
96                                 }
97
98                                 /*Get next item*/
99                                 iter_lang = g_slist_next(iter_lang);
100                                 i++;
101                         }
102                 }
103                 break;
104         }
105
106         return false;
107 }
108
109 int __stt_config_mgr_select_lang(const char* engine_id, char** language)
110 {
111         if (NULL == engine_id || NULL == language) {
112                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Input parameter is NULL");
113                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
114         }
115
116         GSList *iter = NULL;
117         stt_engine_info_s *engine_info = NULL;
118
119         if (0 >= g_slist_length(g_engine_list)) {
120                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] There is no engine!!");
121                 return STT_CONFIG_ERROR_OPERATION_FAILED;
122         }
123
124         /* Get a first item */
125         iter = g_slist_nth(g_engine_list, 0);
126
127         while (NULL != iter) {
128                 engine_info = iter->data;
129
130                 if (NULL == engine_info) {
131                         SLOG(LOG_ERROR, TAG_STTCONFIG, "engine info is NULL");
132                         iter = g_slist_next(iter);
133                         continue;
134                 }
135
136                 if (0 != strcmp(engine_id, engine_info->uuid)) {
137                         iter = g_slist_next(iter);
138                         continue;
139                 }
140
141                 if (NULL == engine_info->default_lang) {
142                         SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Default language of the engine info is NULL");
143                         return STT_CONFIG_ERROR_INVALID_LANGUAGE;
144                 }
145
146                 *language = strdup(engine_info->default_lang);
147
148                 if (NULL != *language) {
149                         SLOG(LOG_DEBUG, TAG_STTCONFIG, "Selected language : %s", *language);
150                         return STT_CONFIG_ERROR_NONE;
151                 }
152         }
153
154         return STT_CONFIG_ERROR_OPERATION_FAILED;
155 }
156
157 Eina_Bool stt_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler)
158 {
159         SLOG(LOG_DEBUG, TAG_STTCONFIG, "===== Config changed callback event");
160
161         int length;
162         struct inotify_event event;
163         memset(&event, '\0', sizeof(struct inotify_event));
164
165         length = read(g_fd_noti, &event, sizeof(struct inotify_event));
166         if (0 > length) {
167                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Empty Inotify event"); //LCOV_EXCL_LINE
168                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "====="); //LCOV_EXCL_LINE
169                 SLOG(LOG_DEBUG, TAG_STTCONFIG, " "); //LCOV_EXCL_LINE
170                 return ECORE_CALLBACK_PASS_ON; //LCOV_EXCL_LINE
171         }
172
173         if (IN_MODIFY == event.mask) {
174                 char* engine = NULL;
175                 char* setting = NULL;
176                 char* lang = NULL;
177                 int auto_lang = -1;
178                 int silence = -1;
179                 int credential = -1;
180
181                 GSList *iter = NULL;
182                 stt_config_client_s* temp_client = NULL;
183
184                 if (0 != stt_parser_find_config_changed(&engine, &setting, &auto_lang, &lang, &silence, &credential))
185                         return ECORE_CALLBACK_PASS_ON;
186
187                 /* Engine changed */
188                 if (NULL != engine || NULL != setting) {
189                         /* engine changed */
190                         if (NULL != engine) {
191                                 if (NULL != g_config_info->engine_id)   free(g_config_info->engine_id);
192                                 g_config_info->engine_id = strdup(engine);
193                         }
194
195                         if (NULL != setting) {
196                                 if (NULL != g_config_info->setting)     free(g_config_info->setting);
197                                 g_config_info->setting = strdup(setting);
198                         }
199
200                         if (NULL != lang) {
201                                 if (NULL != g_config_info->language)    free(g_config_info->language);
202                                 g_config_info->language = strdup(lang);
203                         }
204
205                         if (-1 != silence)      g_config_info->silence_detection = silence;
206
207                         if (-1 != credential)   g_config_info->credential = credential;
208
209                         /* Call all callbacks of client*/
210                         iter = g_slist_nth(g_config_client_list, 0);
211
212                         while (NULL != iter) {
213                                 temp_client = iter->data;
214
215                                 if (NULL != temp_client) {
216                                         if (NULL != temp_client->engine_cb) {
217                                                 temp_client->engine_cb(g_config_info->engine_id, g_config_info->setting, g_config_info->language,
218                                                         g_config_info->silence_detection, g_config_info->credential, temp_client->user_data);
219                                         }
220                                 }
221
222                                 iter = g_slist_next(iter);
223                         }
224                 }
225
226                 if (-1 != auto_lang) {
227                         g_config_info->auto_lang = auto_lang;
228                 }
229
230                 /* Only language changed */
231                 if (NULL == engine && NULL != lang) {
232                         char* before_lang = NULL;
233                         before_lang = strdup(g_config_info->language);
234
235                         if (NULL != lang) {
236                                 if (NULL != g_config_info->language)    free(g_config_info->language);
237                                 g_config_info->language = strdup(lang);
238                         }
239
240                         /* Call all callbacks of client*/
241                         iter = g_slist_nth(g_config_client_list, 0);
242
243                         while (NULL != iter) {
244                                 temp_client = iter->data;
245
246                                 if (NULL != temp_client) {
247                                         if (NULL != temp_client->lang_cb) {
248                                                 temp_client->lang_cb(before_lang, g_config_info->language, temp_client->user_data);
249                                         }
250                                 }
251
252                                 iter = g_slist_next(iter);
253                         }
254
255                         if (NULL != before_lang) {
256                                 free(before_lang);
257                         }
258                 }
259
260                 if (-1 != silence) {
261                         /* silence detection changed */
262                         g_config_info->silence_detection = silence;
263
264                         /* Call all callbacks of client*/
265                         iter = g_slist_nth(g_config_client_list, 0);
266
267                         while (NULL != iter) {
268                                 temp_client = iter->data;
269
270                                 if (NULL != temp_client) {
271                                         if (NULL != temp_client->bool_cb) {
272                                                 temp_client->bool_cb(STT_CONFIG_TYPE_OPTION_SILENCE_DETECTION, silence, temp_client->user_data);
273                                         }
274                                 }
275
276                                 iter = g_slist_next(iter);
277                         }
278                 }
279
280                 if (NULL != engine)     free(engine);
281                 if (NULL != setting)    free(setting);
282                 if (NULL != lang)       free(lang);
283         } else {
284                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Undefined event"); //LCOV_EXCL_LINE
285         }
286
287         SLOG(LOG_DEBUG, TAG_STTCONFIG, "=====");
288         SLOG(LOG_DEBUG, TAG_STTCONFIG, " ");
289
290         return ECORE_CALLBACK_PASS_ON;
291 }
292
293 int __stt_config_mgr_register_config_event()
294 {
295         /* get file notification handler */
296         int fd;
297         int wd;
298
299         fd = inotify_init();
300         if (fd < 0) {
301                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Fail get inotify fd"); //LCOV_EXCL_LINE
302                 return -1; //LCOV_EXCL_LINE
303         }
304         g_fd_noti = fd;
305
306         wd = inotify_add_watch(fd, STT_CONFIG, IN_MODIFY);
307         g_wd_noti = wd;
308
309         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);
310         if (NULL == g_fd_handler_noti) {
311                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Fail to get handler_noti"); //LCOV_EXCL_LINE
312                 return -1; //LCOV_EXCL_LINE
313         }
314
315         return 0;
316 }
317
318 int __stt_config_mgr_unregister_config_event()
319 {
320         /* delete inotify variable */
321         ecore_main_fd_handler_del(g_fd_handler_noti);
322         inotify_rm_watch(g_fd_noti, g_wd_noti);
323         close(g_fd_noti);
324
325         return 0;
326 }
327
328 int __stt_config_set_auto_language()
329 {
330         char* value = NULL;
331         char candidate_lang[6] = {'\0', };
332
333         value = vconf_get_str(VCONFKEY_LANGSET);
334         if (NULL == value) {
335                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[Config ERROR] Fail to get display language"); //LCOV_EXCL_LINE
336                 return -1;
337         }
338
339         strncpy(candidate_lang, value, 5);
340         free(value);
341
342         /* Check current config info */
343         if (NULL == g_config_info) {
344                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Current config info is NULL"); //LCOV_EXCL_LINE
345                 return STT_CONFIG_ERROR_OPERATION_FAILED;
346         }
347
348         /* Check current language */
349         if (NULL == g_config_info->language) {
350                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Current config language is NULL"); //LCOV_EXCL_LINE
351                 return STT_CONFIG_ERROR_OPERATION_FAILED;
352         }
353
354         if (0 == strncmp(g_config_info->language, candidate_lang, 5)) {
355                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "[Config] Language is auto. STT language(%s) is same with display lang", g_config_info->language);
356                 return 0;
357         } else {
358                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "[Config] Display language : %s", candidate_lang); //LCOV_EXCL_LINE
359         }
360
361         if (true == __stt_config_mgr_check_lang_is_valid(g_config_info->engine_id, candidate_lang)) {
362                 char* before_lang = NULL;
363                 if (0 != stt_parser_set_language(candidate_lang)) {
364                         SLOG(LOG_ERROR, TAG_STTCONFIG, "Fail to save default language");
365                         return -1;
366                 }
367
368                 before_lang = strdup(g_config_info->language);
369
370                 free(g_config_info->language);
371                 g_config_info->language = strdup(candidate_lang);
372
373                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "[Config] Language is auto. Set default language(%s)", g_config_info->language);
374
375                 /* Call all callbacks of client*/
376                 GSList *iter = NULL;
377                 stt_config_client_s* temp_client = NULL;
378
379                 iter = g_slist_nth(g_config_client_list, 0);
380
381                 while (NULL != iter) {
382                         temp_client = iter->data;
383
384                         if (NULL != temp_client) {
385                                 if (NULL != temp_client->lang_cb) {
386                                         temp_client->lang_cb(before_lang, g_config_info->language, temp_client->user_data);
387                                 }
388                         }
389
390                         iter = g_slist_next(iter);
391                 }
392
393                 if (NULL != before_lang) {
394                         free(before_lang);
395                         before_lang = NULL;
396                 }
397         } else {
398                 /* Candidate language is not valid */
399                 char* tmp_language = NULL;
400                 if (0 != __stt_config_mgr_select_lang(g_config_info->engine_id, &tmp_language)) {
401                         SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Fail to select language");
402                         return -1;
403                 }
404
405                 if (NULL == tmp_language) {
406                         SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Selected language is NULL");
407                         return -1;
408                 }
409
410                 if (0 != stt_parser_set_language(tmp_language)) {
411                         free(tmp_language);
412                         tmp_language = NULL;
413                         SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Fail to save config");
414                         return -1;
415                 }
416
417                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "[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(unsigned 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, TAG_STTCONFIG, "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, TAG_STTCONFIG, "Input parameter is NULL"); //LCOV_EXCL_LINE
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, TAG_STTCONFIG, "There is no engine!!"); //LCOV_EXCL_LINE
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, TAG_STTCONFIG, "engine info is NULL"); //LCOV_EXCL_LINE
536                         return STT_CONFIG_ERROR_ENGINE_NOT_FOUND;
537                 }
538
539                 if (0 == strcmp(engine_id, engine_info->uuid)) {
540                         SLOG(LOG_DEBUG, TAG_STTCONFIG, "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, TAG_STTCONFIG, "Operation failed - false engine"); //LCOV_EXCL_LINE
551                 return STT_CONFIG_ERROR_OPERATION_FAILED;
552         }
553
554         engine_info = iter->data;
555         if (NULL == engine_info) {
556                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Engine info is NULL"); //LCOV_EXCL_LINE
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, TAG_STTCONFIG, "[ERROR] Empty supported language"); //LCOV_EXCL_LINE
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, TAG_STTCONFIG, " %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         //LCOV_EXCL_START
626         SLOG(LOG_DEBUG, TAG_STTCONFIG, "[Config] Engine changed");
627         SLOG(LOG_DEBUG, TAG_STTCONFIG, "  Engine : %s", g_config_info->engine_id);
628         SLOG(LOG_DEBUG, TAG_STTCONFIG, "  Setting : %s", g_config_info->setting);
629         SLOG(LOG_DEBUG, TAG_STTCONFIG, "  language : %s", g_config_info->language);
630         SLOG(LOG_DEBUG, TAG_STTCONFIG, "  Silence detection : %s", g_config_info->silence_detection ? "on" : "off");
631         SLOG(LOG_DEBUG, TAG_STTCONFIG, "  Credential : %s", g_config_info->credential ? "true" : "false");
632         //LCOV_EXCL_STOP
633
634         if (0 != stt_parser_set_engine(g_config_info->engine_id, g_config_info->setting, g_config_info->language,
635                 g_config_info->silence_detection, g_config_info->credential)) {
636                         SLOG(LOG_ERROR, TAG_STTCONFIG, "Fail to save config"); //LCOV_EXCL_LINE
637                         return STT_CONFIG_ERROR_OPERATION_FAILED;
638         }
639
640         return STT_CONFIG_ERROR_NONE;
641 }
642
643 static void __get_engine_list(const char* directory)
644 {
645         DIR *dp = NULL;
646         struct dirent *dirp = NULL;
647
648         if (NULL == directory) {
649                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[Directory ERROR] Directory is NULL"); //LCOV_EXCL_LINE
650                 return;
651         } else {
652                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "[Directory DEBUG] Directory: %s", directory);
653         }
654
655         dp  = opendir(directory);
656         if (NULL != dp) {
657                 do {
658                         dirp = readdir(dp);
659
660                         if (NULL != dirp) {
661                                 if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name))
662                                         continue;
663
664                                 stt_engine_info_s* info;
665                                 char* filepath = NULL;
666                                 int filesize;
667
668                                 filesize = strlen(directory) + strlen(dirp->d_name) + 5;
669                                 filepath = (char*)calloc(filesize, sizeof(char));
670
671                                 if (NULL != filepath) {
672                                         snprintf(filepath, filesize, "%s/%s", directory, dirp->d_name);
673                                 } else {
674                                         SLOG(LOG_ERROR, TAG_STTCONFIG, "[Config ERROR] Memory not enough!!"); //LCOV_EXCL_LINE
675                                         continue;
676                                 }
677
678                                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "[File DEBUG] File path: %s", filepath);
679
680                                 if (0 == stt_parser_get_engine_info(filepath, &info)) {
681                                         g_engine_list = g_slist_append(g_engine_list, info);
682                                 }
683
684                                 if (NULL != filepath) {
685                                         free(filepath);
686                                         filepath = NULL;
687                                 }
688                         }
689                 } while (NULL != dirp);
690
691                 closedir(dp);
692         } else {
693                 SLOG(LOG_WARN, TAG_STTCONFIG, "[Config WARNING] Fail to open directory");
694         }
695
696         return;
697 }
698
699 int stt_config_mgr_initialize(unsigned int uid)
700 {
701         stt_config_client_s* new_client = NULL;
702
703         if (0 < g_slist_length(g_config_client_list)) {
704                 /* Check uid */
705                 GSList *iter = g_slist_nth(g_config_client_list, 0);
706
707                 while (NULL != iter) {
708                         stt_config_client_s* client = (stt_config_client_s*)iter->data;
709
710                         if (NULL != client && uid == client->uid) {
711                                 SLOG(LOG_WARN, TAG_STTCONFIG, "[CONFIG] uid(%u) has already registered", uid);
712                                 return STT_CONFIG_ERROR_NONE;
713                         }
714
715                         iter = g_slist_next(iter);
716                 }
717
718                 new_client = (stt_config_client_s*)calloc(1, sizeof(stt_config_client_s));
719                 if (NULL == new_client) {
720                         SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Fail to allocate memory");
721                         return STT_CONFIG_ERROR_OUT_OF_MEMORY;
722                 }
723                 new_client->uid = uid;
724                 new_client->bool_cb = NULL;
725                 new_client->engine_cb = NULL;
726                 new_client->lang_cb = NULL;
727                 new_client->user_data = NULL;
728
729                 /* Add uid */
730                 g_config_client_list = g_slist_append(g_config_client_list, new_client);
731
732                 SLOG(LOG_WARN, TAG_STTCONFIG, "[CONFIG] Add uid(%u) 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, TAG_STTCONFIG, "[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, TAG_STTCONFIG, "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, TAG_STTCONFIG, "[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, TAG_STTCONFIG, "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, TAG_STTCONFIG, "[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, TAG_STTCONFIG, "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, TAG_STTCONFIG, "[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, TAG_STTCONFIG, "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, TAG_STTCONFIG, "[CONFIG] default engine info(%s)", STT_DEFAULT_ENGINE_INFO);
782
783         SLOG(LOG_DEBUG, TAG_STTCONFIG, "[CONFIG] Get default engine list");
784         __get_engine_list(STT_DEFAULT_ENGINE_INFO);
785         SLOG(LOG_DEBUG, TAG_STTCONFIG, "[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, TAG_STTCONFIG, "[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, TAG_STTCONFIG, "[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, TAG_STTCONFIG, "[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, TAG_STTCONFIG, "== STT service config ==");
834         SLOG(LOG_DEBUG, TAG_STTCONFIG, " engine : %s", g_config_info->engine_id);
835         SLOG(LOG_DEBUG, TAG_STTCONFIG, " setting : %s", g_config_info->setting);
836         SLOG(LOG_DEBUG, TAG_STTCONFIG, " auto language : %s", g_config_info->auto_lang ? "on" : "off");
837         SLOG(LOG_DEBUG, TAG_STTCONFIG, " language : %s", g_config_info->language);
838         SLOG(LOG_DEBUG, TAG_STTCONFIG, " silence detection : %s", g_config_info->silence_detection ? "on" : "off");
839         SLOG(LOG_DEBUG, TAG_STTCONFIG, " credential : %s", g_config_info->credential ? "true" : "false");
840         SLOG(LOG_DEBUG, TAG_STTCONFIG, "===================");
841
842         if (0 != __stt_config_mgr_register_config_event()) {
843                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[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         new_client = (stt_config_client_s*)calloc(1, sizeof(stt_config_client_s));
854         if (NULL == new_client) {
855                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Fail to allocate memory"); //LCOV_EXCL_LINE
856                 return STT_CONFIG_ERROR_OUT_OF_MEMORY;
857         }
858         new_client->uid = uid;
859         new_client->bool_cb = NULL;
860         new_client->engine_cb = NULL;
861         new_client->lang_cb = NULL;
862         new_client->user_data = NULL;
863
864         /* Add uid */
865         g_config_client_list = g_slist_append(g_config_client_list, new_client);
866
867         return STT_CONFIG_ERROR_NONE;
868 }
869
870 int stt_config_mgr_finalize(unsigned 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, TAG_STTCONFIG, "Client count (%d)", g_slist_length(g_config_client_list)); //LCOV_EXCL_LINE
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(unsigned 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 //LCOV_EXCL_START
959 int stt_config_mgr_unset_callback(unsigned int uid)
960 {
961         GSList *iter = NULL;
962         stt_config_client_s* temp_client = NULL;
963
964         /* Call all callbacks of client*/
965         iter = g_slist_nth(g_config_client_list, 0);
966
967         while (NULL != iter) {
968                 temp_client = iter->data;
969
970                 if (NULL != temp_client) {
971                         if (uid == temp_client->uid) {
972                                 temp_client->engine_cb = NULL;
973                                 temp_client->lang_cb = NULL;
974                                 temp_client->bool_cb = NULL;
975                                 temp_client->user_data = NULL;
976                         }
977                 }
978
979                 iter = g_slist_next(iter);
980         }
981
982         return STT_CONFIG_ERROR_NONE;
983 }
984 //LCOV_EXCL_STOP
985
986 int stt_config_mgr_get_engine_list(stt_config_supported_engine_cb callback, void* user_data)
987 {
988         if (0 >= g_slist_length(g_config_client_list)) {
989                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Not initialized");
990                 return STT_CONFIG_ERROR_INVALID_STATE;
991         }
992
993         if (NULL == callback) {
994                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
995         }
996
997         GSList *iter = NULL;
998         stt_engine_info_s *engine_info = NULL;
999
1000         if (0 >= g_slist_length(g_engine_list)) {
1001                 SLOG(LOG_WARN, TAG_STTCONFIG, "[ERROR] Engine list is NULL");
1002                 return STT_CONFIG_ERROR_ENGINE_NOT_FOUND;
1003         }
1004
1005         /* Get a first item */
1006         iter = g_slist_nth(g_engine_list, 0);
1007
1008         while (NULL != iter) {
1009                 engine_info = iter->data;
1010
1011                 if (NULL == engine_info) {
1012                         SLOG(LOG_ERROR, TAG_STTCONFIG, " Engine info is NULL");
1013                         return STT_CONFIG_ERROR_OPERATION_FAILED;
1014                 }
1015
1016                 if (false == callback(engine_info->uuid, engine_info->name,
1017                         engine_info->setting, engine_info->support_silence_detection, user_data)) {
1018                         break;
1019                 }
1020
1021                 iter = g_slist_next(iter);
1022         }
1023
1024         return STT_CONFIG_ERROR_NONE;
1025 }
1026
1027 int stt_config_mgr_get_engine(char** engine)
1028 {
1029         if (0 >= g_slist_length(g_config_client_list)) {
1030                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Not initialized"); //LCOV_EXCL_LINE
1031                 return STT_CONFIG_ERROR_INVALID_STATE;
1032         }
1033
1034         if (NULL == engine) {
1035                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1036         }
1037
1038         if (NULL != g_config_info->engine_id) {
1039                 *engine = strdup(g_config_info->engine_id);
1040         } else {
1041                 SLOG(LOG_ERROR, TAG_STTCONFIG, " Engine id is NULL"); //LCOV_EXCL_LINE
1042                 *engine = NULL;
1043                 return STT_CONFIG_ERROR_ENGINE_NOT_FOUND;
1044         }
1045
1046         return STT_CONFIG_ERROR_NONE;
1047 }
1048
1049 //LCOV_EXCL_START
1050 int __stt_config_set_buxtonkey(const char* engine)
1051 {
1052         /* Set vconfkey */
1053         struct buxton_client * bux_cli;
1054         struct buxton_layer * bux_layer;
1055         struct buxton_value * bux_val;
1056
1057         int ret = buxton_open(&bux_cli, NULL, NULL);
1058         if (0 != ret) {
1059                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[DBUS-BUXTON2] Fail to open buxton client, ret(%d)", ret);
1060                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1061         }
1062         bux_layer = buxton_create_layer("system");
1063         if (NULL == bux_layer) {
1064                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[DBUS-BUXTON2] buxton_create_layer FAIL");
1065                 buxton_close(bux_cli);
1066                 bux_cli = NULL;
1067                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1068         }
1069         bux_val = buxton_value_create_string(engine);
1070         if (NULL == bux_val) {
1071                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[DBUS-BUXTON2] buxton_value_create_string FAIL");
1072                 buxton_free_layer(bux_layer);
1073                 buxton_close(bux_cli);
1074                 bux_layer = NULL;
1075                 bux_cli = NULL;
1076                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1077         } else {
1078                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "[DBUS-BUXTON2] layer: %s", buxton_layer_get_name(bux_layer));
1079         }
1080
1081         ret = buxton_set_value_sync(bux_cli, bux_layer, STT_ENGINE_DB_DEFAULT, bux_val);
1082         if (0 != ret) {
1083                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[DBUS-BUXTON2] Fail to set value sync, ret(%d)", ret);
1084                 buxton_value_free(bux_val);
1085                 buxton_free_layer(bux_layer);
1086                 buxton_close(bux_cli);
1087
1088                 bux_cli = NULL;
1089                 bux_layer = NULL;
1090                 bux_val = NULL;
1091                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1092         }
1093         SLOG(LOG_DEBUG, TAG_STTCONFIG, "[DBUS-BUXTON2] buxton_set_value_sync: %s", STT_ENGINE_DB_DEFAULT);
1094
1095         buxton_value_free(bux_val);
1096         buxton_free_layer(bux_layer);
1097         buxton_close(bux_cli);
1098
1099         bux_cli = NULL;
1100         bux_layer = NULL;
1101         bux_val = NULL;
1102
1103         return STT_CONFIG_ERROR_NONE;
1104 }
1105
1106 int stt_config_mgr_set_engine(const char* engine)
1107 {
1108         if (0 >= g_slist_length(g_config_client_list)) {
1109                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Not initialized");
1110                 return STT_CONFIG_ERROR_INVALID_STATE;
1111         }
1112
1113         if (NULL == g_config_info) {
1114                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1115         }
1116
1117         if (NULL == engine || NULL == g_config_info->engine_id) {
1118                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1119         }
1120
1121         /* Check current engine id with new engine id */
1122         if (0 == strcmp(g_config_info->engine_id, engine)) {
1123                 return 0;
1124         }
1125
1126         SLOG(LOG_DEBUG, TAG_STTCONFIG, "New engine id : %s", engine);
1127
1128         int ret = __stt_config_set_buxtonkey(engine);
1129         if (0 != ret) {
1130                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] set buxtonkey Failed!!!");
1131                 return ret;
1132         }
1133
1134         GSList *iter = NULL;
1135         stt_engine_info_s *engine_info = NULL;
1136         bool is_valid_engine = false;
1137
1138         /* Get a first item */
1139         iter = g_slist_nth(g_engine_list, 0);
1140
1141         while (NULL != iter) {
1142                 engine_info = iter->data;
1143
1144                 if (NULL == engine_info) {
1145                         SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Engine info is NULL");
1146                         iter = g_slist_next(iter);
1147                         continue;
1148                 }
1149
1150                 /* Check engine id is valid */
1151                 if (0 != strcmp(engine, engine_info->uuid)) {
1152                         iter = g_slist_next(iter);
1153                         continue;
1154                 }
1155
1156                 if (NULL != g_config_info->engine_id) {
1157                         free(g_config_info->engine_id);
1158                         g_config_info->engine_id = NULL;
1159                 }
1160
1161                 g_config_info->engine_id = strdup(engine);
1162
1163                 if (NULL != g_config_info->setting) {
1164                         free(g_config_info->setting);
1165                         g_config_info->setting = NULL;
1166                 }
1167
1168                 if (NULL != engine_info->setting) {
1169                         g_config_info->setting = strdup(engine_info->setting);
1170                 } else {
1171                         g_config_info->setting = NULL;
1172                 }
1173
1174                 /* Engine is valid*/
1175                 GSList *iter_lang = NULL;
1176                 char* lang;
1177                 bool is_valid_lang = false;
1178
1179                 /* Get a first item */
1180                 iter_lang = g_slist_nth(engine_info->languages, 0);
1181
1182                 while (NULL != iter_lang) {
1183                         /*Get handle data from list*/
1184                         lang = iter_lang->data;
1185
1186                         SLOG(LOG_DEBUG, TAG_STTCONFIG, " %s", lang);
1187                         if (NULL != lang && NULL != g_config_info->language) {
1188                                 if (0 == strcmp(lang, g_config_info->language)) {
1189                                         /* language is valid */
1190                                         is_valid_lang = true;
1191
1192                                         free(g_config_info->language);
1193                                         g_config_info->language = strdup(lang);
1194
1195                                         break;
1196                                 }
1197                         }
1198
1199                         /*Get next item*/
1200                         iter_lang = g_slist_next(iter_lang);
1201                 }
1202
1203                 if (false == is_valid_lang) {
1204                         if (NULL != g_config_info->language) {
1205                                 free(g_config_info->language);
1206                                 g_config_info->language = NULL;
1207
1208                                 iter_lang = g_slist_nth(engine_info->languages, 0);
1209                                 if (NULL == iter_lang) {
1210                                         SLOG(LOG_ERROR, TAG_STTCONFIG, "Fail to get default language");
1211                                         break;
1212                                 }
1213
1214                                 lang = iter_lang->data;
1215
1216                                 g_config_info->language = strdup(lang);
1217                         }
1218                 }
1219
1220                 /* Check options */
1221                 if (false == engine_info->support_silence_detection) {
1222                         if (true == g_config_info->silence_detection)
1223                                 g_config_info->silence_detection = false;
1224                 }
1225
1226                 if (false == engine_info->need_credential) {
1227                         if (true == g_config_info->credential)
1228                                 g_config_info->credential = false;
1229                 }
1230
1231                 is_valid_engine = true;
1232                 break;
1233         }
1234
1235         if (true == is_valid_engine) {
1236                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "[Config] Engine changed");
1237                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "  Engine : %s", g_config_info->engine_id);
1238                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "  Setting : %s", g_config_info->setting);
1239                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "  language : %s", g_config_info->language);
1240                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "  Silence detection : %s", g_config_info->silence_detection ? "on" : "off");
1241                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "  Credential : %s", g_config_info->credential ? "true" : "false");
1242
1243                 if (0 != stt_parser_set_engine(g_config_info->engine_id, g_config_info->setting, g_config_info->language,
1244                         g_config_info->silence_detection, g_config_info->credential)) {
1245                                 SLOG(LOG_ERROR, TAG_STTCONFIG, " Fail to save config");
1246                                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1247                 }
1248         } else {
1249                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Engine id is not valid");
1250                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1251         }
1252
1253         return 0;
1254 }
1255
1256 int stt_config_mgr_get_engine_agreement(const char* engine, char** agreement)
1257 {
1258         if (0 >= g_slist_length(g_engine_list)) {
1259                 SLOG(LOG_ERROR, TAG_STTCONFIG, "There is no engine");
1260                 return STT_CONFIG_ERROR_INVALID_STATE;
1261         }
1262
1263         if (NULL == agreement) {
1264                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Input parameter is NULL");
1265                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1266         }
1267
1268         GSList *iter = NULL;
1269         stt_engine_info_s *engine_info = NULL;
1270         char* current_engine = NULL;
1271
1272         if (NULL == engine) {
1273                 current_engine = strdup(g_config_info->engine_id);
1274                 if (NULL == current_engine) {
1275                         SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Fail to allocate memory");
1276                         return STT_CONFIG_ERROR_OUT_OF_MEMORY;;
1277                 }
1278         } else {
1279                 current_engine = strdup(engine);
1280                 if (NULL == current_engine) {
1281                         SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Fail to allocate memory");
1282                         return STT_CONFIG_ERROR_OUT_OF_MEMORY;;
1283                 }
1284         }
1285
1286         /* Get a first item */
1287         iter = g_slist_nth(g_engine_list, 0);
1288
1289         while (NULL != iter) {
1290                 engine_info = iter->data;
1291
1292                 if (NULL == engine_info) {
1293                         SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] engine info is NULL");
1294                         if (NULL != current_engine)     free(current_engine);
1295                         return STT_CONFIG_ERROR_OPERATION_FAILED;
1296                 }
1297
1298                 if (0 != strcmp(current_engine, engine_info->uuid)) {
1299                         iter = g_slist_next(iter);
1300                         continue;
1301                 }
1302
1303                 if (NULL != engine_info->agreement) {
1304                         *agreement = strdup(engine_info->agreement);
1305                 } else {
1306                         SLOG(LOG_WARN, TAG_STTCONFIG, "[WARNING] engine agreement is not support");
1307                 }
1308                 break;
1309         }
1310
1311         if (NULL != current_engine)     free(current_engine);
1312
1313         return STT_CONFIG_ERROR_NONE;
1314 }
1315 //LCOV_EXCL_STOP
1316
1317 int stt_config_mgr_get_language_list(const char* engine_id, stt_config_supported_langauge_cb callback, void* user_data)
1318 {
1319         if (0 >= g_slist_length(g_config_client_list)) {
1320                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Not initialized"); //LCOV_EXCL_LINE
1321                 return STT_CONFIG_ERROR_INVALID_STATE;
1322         }
1323
1324         if (0 >= g_slist_length(g_engine_list)) {
1325                 SLOG(LOG_ERROR, TAG_STTCONFIG, "There is no engine"); //LCOV_EXCL_LINE
1326                 return STT_CONFIG_ERROR_ENGINE_NOT_FOUND;
1327         }
1328
1329         GSList *iter = NULL;
1330         stt_engine_info_s *engine_info = NULL;
1331
1332         /* Get a first item */
1333         iter = g_slist_nth(g_engine_list, 0);
1334
1335         while (NULL != iter) {
1336                 engine_info = iter->data;
1337
1338                 if (NULL == engine_info) {
1339                         SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] engine info is NULL"); //LCOV_EXCL_LINE
1340                         return STT_CONFIG_ERROR_OPERATION_FAILED;
1341                 }
1342
1343                 if (0 != strcmp(engine_id, engine_info->uuid)) {
1344                         iter = g_slist_next(iter);
1345                         continue;
1346                 }
1347
1348                 GSList *iter_lang = NULL;
1349                 char* lang;
1350
1351                 /* Get a first item */
1352                 iter_lang = g_slist_nth(engine_info->languages, 0);
1353
1354                 while (NULL != iter_lang) {
1355                         /*Get handle data from list*/
1356                         lang = iter_lang->data;
1357
1358                         if (NULL != lang) {
1359                                 SLOG(LOG_DEBUG, TAG_STTCONFIG, " %s", lang);
1360                                 if (false == callback(engine_info->uuid, lang, user_data))
1361                                         break;
1362                         }
1363
1364                         /*Get next item*/
1365                         iter_lang = g_slist_next(iter_lang);
1366                 }
1367                 break;
1368         }
1369
1370         return STT_CONFIG_ERROR_NONE;
1371 }
1372
1373 int stt_config_mgr_get_default_language(char** language)
1374 {
1375         if (0 >= g_slist_length(g_config_client_list)) {
1376                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Not initialized"); //LCOV_EXCL_LINE
1377                 return STT_CONFIG_ERROR_INVALID_STATE;
1378         }
1379
1380         if (NULL == language) {
1381                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1382         }
1383
1384         if (NULL != g_config_info->language) {
1385                 *language = strdup(g_config_info->language);
1386         } else {
1387                 SLOG(LOG_ERROR, TAG_STTCONFIG, " language is NULL"); //LCOV_EXCL_LINE
1388                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1389         }
1390
1391         return STT_CONFIG_ERROR_NONE;
1392 }
1393
1394 //LCOV_EXCL_START
1395 int stt_config_mgr_set_default_language(const char* language)
1396 {
1397         if (0 >= g_slist_length(g_config_client_list)) {
1398                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Not initialized");
1399                 return STT_CONFIG_ERROR_INVALID_STATE;
1400         }
1401
1402         if (NULL == language) {
1403                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1404         }
1405
1406         /* Check language is valid */
1407         if (NULL != g_config_info->language) {
1408                 if (0 != stt_parser_set_language(language)) {
1409                         SLOG(LOG_ERROR, TAG_STTCONFIG, "Fail to save engine id");
1410                         return STT_CONFIG_ERROR_OPERATION_FAILED;
1411                 }
1412                 free(g_config_info->language);
1413                 g_config_info->language = strdup(language);
1414         } else {
1415                 SLOG(LOG_ERROR, TAG_STTCONFIG, " language is NULL");
1416                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1417         }
1418
1419         return STT_CONFIG_ERROR_NONE;
1420 }
1421
1422 int stt_config_mgr_get_auto_language(bool* value)
1423 {
1424         if (0 >= g_slist_length(g_config_client_list)) {
1425                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Not initialized");
1426                 return STT_CONFIG_ERROR_INVALID_STATE;
1427         }
1428
1429         if (NULL == value) {
1430                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1431         }
1432
1433         *value = g_config_info->auto_lang;
1434
1435         return STT_CONFIG_ERROR_NONE;
1436 }
1437
1438 int stt_config_mgr_set_auto_language(bool value)
1439 {
1440         if (0 >= g_slist_length(g_config_client_list)) {
1441                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Not initialized");
1442                 return STT_CONFIG_ERROR_INVALID_STATE;
1443         }
1444
1445         if (g_config_info->auto_lang != value) {
1446                 /* Check language is valid */
1447                 if (0 != stt_parser_set_auto_lang(value)) {
1448                         SLOG(LOG_ERROR, TAG_STTCONFIG, "Fail to save engine id");
1449                         return STT_CONFIG_ERROR_OPERATION_FAILED;
1450                 }
1451                 g_config_info->auto_lang = value;
1452
1453                 if (true == g_config_info->auto_lang) {
1454                         __stt_config_set_auto_language();
1455                 }
1456         }
1457
1458         return STT_CONFIG_ERROR_NONE;
1459 }
1460
1461 int stt_config_mgr_get_silence_detection(bool* value)
1462 {
1463         if (0 >= g_slist_length(g_config_client_list)) {
1464                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Not initialized");
1465                 return STT_CONFIG_ERROR_INVALID_STATE;
1466         }
1467
1468         if (NULL == value)
1469                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1470
1471         *value = g_config_info->silence_detection;
1472
1473         return STT_CONFIG_ERROR_NONE;
1474 }
1475
1476 int stt_config_mgr_set_silence_detection(bool value)
1477 {
1478         if (0 >= g_slist_length(g_config_client_list)) {
1479                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Not initialized");
1480                 return STT_CONFIG_ERROR_INVALID_STATE;
1481         }
1482
1483         if (0 != stt_parser_set_silence_detection(value)) {
1484                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Fail to save engine id");
1485                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1486         }
1487
1488         g_config_info->silence_detection = value;
1489
1490         return STT_CONFIG_ERROR_NONE;
1491 }
1492
1493 bool stt_config_check_default_engine_is_valid(const char* engine)
1494 {
1495         if (0 >= g_slist_length(g_config_client_list)) {
1496                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Not initialized");
1497                 return false;
1498         }
1499
1500         if (NULL == engine) {
1501                 return false;
1502         }
1503
1504         if (0 >= g_slist_length(g_engine_list))
1505                 return false;
1506
1507         GSList *iter = NULL;
1508         stt_engine_info_s *engine_info = NULL;
1509
1510         /* Get a first item */
1511         iter = g_slist_nth(g_engine_list, 0);
1512
1513         while (NULL != iter) {
1514                 engine_info = iter->data;
1515
1516                 if (NULL != engine_info && NULL != engine_info->uuid) {
1517                         if (0 == strcmp(engine, engine_info->uuid)) {
1518                                 return true;
1519                         }
1520                 }
1521                 iter = g_slist_next(iter);
1522         }
1523
1524         return false;
1525 }
1526
1527 bool stt_config_check_default_language_is_valid(const char* language)
1528 {
1529         if (0 >= g_slist_length(g_config_client_list)) {
1530                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Not initialized");
1531                 return false;
1532         }
1533
1534         if (NULL == language) {
1535                 return false;
1536         }
1537
1538         if (NULL == g_config_info->engine_id) {
1539                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Default engine id is NULL");
1540                 return false;
1541         }
1542
1543         if (0 >= g_slist_length(g_engine_list))
1544                 return false;
1545
1546         GSList *iter = NULL;
1547         stt_engine_info_s *engine_info = NULL;
1548
1549         /* Get a first item */
1550         iter = g_slist_nth(g_engine_list, 0);
1551
1552         while (NULL != iter) {
1553                 engine_info = iter->data;
1554
1555                 if (NULL == engine_info) {
1556                         SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Engine info is NULL");
1557                         iter = g_slist_next(iter);
1558                         continue;
1559                 }
1560
1561                 if (0 != strcmp(g_config_info->engine_id, engine_info->uuid)) {
1562                         iter = g_slist_next(iter);
1563                         continue;
1564                 }
1565
1566                 GSList *iter_lang = NULL;
1567                 char* lang;
1568
1569                 /* Get a first item */
1570                 iter_lang = g_slist_nth(engine_info->languages, 0);
1571
1572                 while (NULL != iter_lang) {
1573                         lang = iter_lang->data;
1574
1575                         if (0 == strcmp(language, lang))
1576                                 return true;
1577
1578                         /*Get next item*/
1579                         iter_lang = g_slist_next(iter_lang);
1580                 }
1581                 break;
1582         }
1583
1584         return false;
1585 }
1586 //LCOV_EXCL_STOP
1587
1588 int __stt_config_mgr_print_engine_info()
1589 {
1590         GSList *iter = NULL;
1591         stt_engine_info_s *engine_info = NULL;
1592
1593         if (0 >= g_slist_length(g_engine_list)) {
1594                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "-------------- engine list -----------------"); //LCOV_EXCL_LINE
1595                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "  No Engine in engine directory"); //LCOV_EXCL_LINE
1596                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "--------------------------------------------"); //LCOV_EXCL_LINE
1597                 return 0;
1598         }
1599
1600         /* Get a first item */
1601         iter = g_slist_nth(g_engine_list, 0);
1602
1603         SLOG(LOG_DEBUG, TAG_STTCONFIG, "--------------- engine list -----------------");
1604
1605         int i = 1;
1606         while (NULL != iter) {
1607                 engine_info = iter->data;
1608
1609                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "[%dth]", i);
1610                 SLOG(LOG_DEBUG, TAG_STTCONFIG, " name : %s", engine_info->name);
1611                 SLOG(LOG_DEBUG, TAG_STTCONFIG, " id   : %s", engine_info->uuid);
1612                 SLOG(LOG_DEBUG, TAG_STTCONFIG, " setting : %s", engine_info->setting);
1613                 SLOG(LOG_DEBUG, TAG_STTCONFIG, " agreement : %s", engine_info->agreement);
1614
1615                 SLOG(LOG_DEBUG, TAG_STTCONFIG, " languages");
1616                 GSList *iter_lang = NULL;
1617                 char* lang;
1618                 if (g_slist_length(engine_info->languages) > 0) {
1619                         /* Get a first item */
1620                         iter_lang = g_slist_nth(engine_info->languages, 0);
1621
1622                         int j = 1;
1623                         while (NULL != iter_lang) {
1624                                 /*Get handle data from list*/
1625                                 lang = iter_lang->data;
1626
1627                                 SLOG(LOG_DEBUG, TAG_STTCONFIG, "  [%dth] %s", j, lang);
1628
1629                                 /*Get next item*/
1630                                 iter_lang = g_slist_next(iter_lang);
1631                                 j++;
1632                         }
1633                 } else {
1634                         SLOG(LOG_ERROR, TAG_STTCONFIG, "  language is NONE"); //LCOV_EXCL_LINE
1635                 }
1636                 SLOG(LOG_DEBUG, TAG_STTCONFIG, " silence support : %s",
1637                         engine_info->support_silence_detection ? "true" : "false");
1638                 iter = g_slist_next(iter);
1639                 i++;
1640         }
1641         SLOG(LOG_DEBUG, TAG_STTCONFIG, "--------------------------------------------");
1642
1643         return 0;
1644 }
1645
1646
1647
1648 /**
1649 * time info functions
1650 */
1651 static GSList* g_time_list = NULL;
1652
1653 //LCOV_EXCL_START
1654 int stt_config_mgr_reset_time_info()
1655 {
1656         /* Remove time info */
1657         GSList *iter = NULL;
1658         stt_result_time_info_s *data = NULL;
1659
1660         /* Remove time info */
1661         iter = g_slist_nth(g_time_list, 0);
1662         while (NULL != iter) {
1663                 data = iter->data;
1664
1665                 g_time_list = g_slist_remove(g_time_list, data);
1666                 if (NULL != data) {
1667                         if (NULL != data->text) {
1668                                 free(data->text);
1669                                 data->text = NULL;
1670                         }
1671                         free(data);
1672                         data = NULL;
1673                 }
1674
1675                 /*Get next item*/
1676                 iter = g_slist_nth(g_time_list, 0);
1677         }
1678
1679         return 0;
1680 }
1681
1682 int stt_config_mgr_add_time_info(int index, int event, const char* text, long start_time, long end_time)
1683 {
1684         if (NULL == text) {
1685                 SLOG(LOG_ERROR, TAG_STTCONFIG, "Invalid parameter : text is NULL");
1686                 return -1;
1687         }
1688
1689         stt_result_time_info_s *info = (stt_result_time_info_s*)calloc(1, sizeof(stt_result_time_info_s));
1690         if (NULL == info) {
1691                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Fail to allocate memory");
1692                 return STT_CONFIG_ERROR_OUT_OF_MEMORY;
1693         }
1694         info->index = index;
1695         info->event = event;
1696         if (NULL != text) {
1697                 info->text = strdup(text);
1698         }
1699         info->start_time = start_time;
1700         info->end_time = end_time;
1701
1702         SECURE_SLOG(LOG_DEBUG, TAG_STTCONFIG, "[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);
1703
1704         /* Add item to global list */
1705         g_time_list = g_slist_append(g_time_list, info);
1706
1707         SLOG(LOG_DEBUG, TAG_STTCONFIG, "[DEBUG] inside stt_config_mgr_add_time_info: g_time_list length(%d)", g_slist_length(g_time_list));
1708
1709         return 0;
1710 }
1711 //LCOV_EXCL_STOP
1712
1713 int stt_config_mgr_foreach_time_info(stt_config_result_time_cb callback, void* user_data)
1714 {
1715         if (NULL == callback) {
1716                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Input parameter is NULL : callback function"); //LCOV_EXCL_LINE
1717                 return STT_CONFIG_ERROR_INVALID_PARAMETER;
1718         }
1719
1720         GSList* temp_time = NULL;
1721         int ret;
1722         ret = stt_parser_get_time_info(&temp_time);
1723         if (0 != ret) {
1724                 SLOG(LOG_WARN, TAG_STTCONFIG, "[WARNING] Fail to get time info : %d", ret); //LCOV_EXCL_LINE
1725                 return STT_CONFIG_ERROR_NONE;
1726         }
1727
1728         GSList *iter = NULL;
1729         stt_result_time_info_s *data = NULL;
1730
1731         /* Get a first item */
1732         iter = g_slist_nth(temp_time, 0);
1733         while (NULL != iter) {
1734                 data = iter->data;
1735
1736                 if (false == callback(data->index, data->event, data->text,
1737                         data->start_time, data->end_time, user_data)) {
1738                         break;
1739                 }
1740
1741                 /*Get next item*/
1742                 iter = g_slist_next(iter);
1743         }
1744
1745         /* Remove time info */
1746         iter = g_slist_nth(temp_time, 0);
1747         while (NULL != iter) {
1748                 data = iter->data;
1749
1750                 if (NULL != data) {
1751                         temp_time = g_slist_remove(temp_time, data);
1752
1753                         if (NULL != data->text) {
1754                                 free(data->text);
1755                                 data->text = NULL;
1756                         }
1757                         free(data);
1758                         data = NULL;
1759                 }
1760
1761                 /*Get next item*/
1762                 iter = g_slist_nth(temp_time, 0);
1763         }
1764
1765         return STT_CONFIG_ERROR_NONE;
1766 }
1767
1768 //LCOV_EXCL_START
1769 int stt_config_mgr_save_time_info_file()
1770 {
1771         if (0 == g_slist_length(g_time_list)) {
1772                 SLOG(LOG_WARN, TAG_STTCONFIG, "[WARNING] There is no time info to save");
1773                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1774         }
1775
1776         int ret = 0;
1777         ret = stt_parser_set_time_info(g_time_list);
1778         if (0 != ret) {
1779                 SLOG(LOG_ERROR, TAG_STTCONFIG, "[ERROR] Fail to save time info : %d", ret);
1780                 return STT_CONFIG_ERROR_OPERATION_FAILED;
1781         }
1782
1783         return STT_CONFIG_ERROR_NONE;
1784 }
1785
1786 int stt_config_mgr_remove_time_info_file()
1787 {
1788         stt_parser_clear_time_info();
1789
1790         return STT_CONFIG_ERROR_NONE;
1791 }
1792 //LCOV_EXCL_STOP