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