2 * Copyright (c) 2011-2019 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
25 #include <sys/inotify.h>
27 #include <vconf-internal-keys.h>
33 #include "VoiceControlConfig.h"
34 #include "VoiceControlEngines.h"
35 #include "VoiceControlClients.h"
37 #include "vc_config_mgr.h"
38 #include "vc_config_parser.h"
41 #include "voice_control_command.h"
46 #define EVENT_SIZE (sizeof(struct inotify_event))
47 #define BUF_LEN (EVENT_SIZE + 16)
49 /* for engine directory monitoring */
51 Ecore_Fd_Handler* dir_fd_handler;
54 } vc_engine_inotify_s;
59 } language_changed_cb_parameters_s;
61 static const char* vc_config_tag()
66 static atomic<bool> g_config_mgr_initialized(false);
68 static VoiceControlEngines *g_VoiceControlEngines = nullptr;
70 static VoiceControlClients *g_VoiceControlClients = nullptr;
72 static VoiceControlConfig *g_VoiceControlConfig = nullptr;
74 static Ecore_Idler *g_engine_changed_event_idler = NULL;
75 static Ecore_Idler *g_language_changed_event_idler = NULL;
76 static Ecore_Idler *g_enabled_changed_event_idler = NULL;
78 static int g_lang_ref_count;
79 static Ecore_Fd_Handler* g_fd_handler_lang = NULL;
80 static int g_fd_lang = -1;
81 static int g_wd_lang = -1;
83 static GList* g_ino_list = nullptr;
84 static mutex g_ino_list_mutex;
86 static int register_engine_config_updated_event(const char* path);
87 static int unregister_engine_config_updated_event();
88 static int set_current_language(const char* language);
90 static Eina_Bool notify_engine_changed_event_by_idler(void *data)
92 SLOG(LOG_INFO, vc_config_tag(), "[INFO] Invoke engine changed callback by idler");
93 char *engine_appid = static_cast<char *>(data);
95 if (nullptr == engine_appid) {
96 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Engine is not specified.");
100 if (nullptr == g_VoiceControlClients) {
101 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] No clients exist");
105 SLOG(LOG_INFO, vc_config_tag(), "[INFO] Engine ID : %s", engine_appid);
106 auto clients = g_VoiceControlClients->getClients();
107 for (auto &clientInfo : clients) {
108 if (false == g_VoiceControlClients->isUidValid(clientInfo.getUid())) {
109 SLOG(LOG_WARN, vc_config_tag(), "[ERROR] Skip invalid client (%u)", clientInfo.getUid());
113 clientInfo.invokeEngineChangedCallback(engine_appid);
118 g_engine_changed_event_idler = nullptr;
122 static inline void delete_engine_changed_event_invoker()
124 if (nullptr != g_engine_changed_event_idler) {
125 void *param = ecore_idler_del(g_engine_changed_event_idler);
126 g_engine_changed_event_idler = nullptr;
127 free(static_cast<char *>(param));
131 static void notify_engine_changed(const char *engine_appid)
133 SLOG(LOG_INFO, vc_config_tag(), "[INFO] Invoke engine changed callback");
134 if (nullptr == engine_appid) {
135 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
139 char *param = strdup(engine_appid);
140 if (nullptr == param) {
141 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate the memory for parameter");
145 delete_engine_changed_event_invoker();
146 g_engine_changed_event_idler = ecore_idler_add(notify_engine_changed_event_by_idler, static_cast<void *>(param));
149 static inline void release_language_changed_cb_params(language_changed_cb_parameters_s *params)
151 if (nullptr == params) {
155 free(params->before_lang);
156 free(params->current_lang);
160 static Eina_Bool notify_language_changed_event_by_idler(void *data)
162 SLOG(LOG_INFO, vc_config_tag(), "[INFO] Invoke language changed callback by idler");
163 language_changed_cb_parameters_s *params = static_cast<language_changed_cb_parameters_s *>(data);
165 if (nullptr == params) {
166 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Parameters are not specified.");
170 if (nullptr == g_VoiceControlClients) {
171 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] No clients exist");
175 SLOG(LOG_INFO, vc_config_tag(), "[INFO] Before : %s, Current : %s", params->before_lang, params->current_lang);
176 auto clients = g_VoiceControlClients->getClients();
177 for (auto &clientInfo : clients) {
178 if (false == g_VoiceControlClients->isUidValid(clientInfo.getUid())) {
179 SLOG(LOG_WARN, vc_config_tag(), "[ERROR] Skip invalid client (%u)", clientInfo.getUid());
183 clientInfo.invokeLanguageChangedCallback(params->before_lang, params->current_lang);
187 release_language_changed_cb_params(params);
188 g_language_changed_event_idler = nullptr;
192 static inline void delete_language_changed_event_invoker()
194 if (nullptr != g_language_changed_event_idler) {
195 void *params = ecore_idler_del(g_language_changed_event_idler);
196 g_language_changed_event_idler = nullptr;
197 release_language_changed_cb_params(static_cast<language_changed_cb_parameters_s *>(params));
201 static void notify_language_changed(const char* before_lang, const char* current_lang)
203 SLOG(LOG_INFO, vc_config_tag(), "[INFO] Invoke language changed callback");
204 if (nullptr == before_lang || nullptr == current_lang) {
205 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
209 auto *params = new language_changed_cb_parameters_s();
210 if (nullptr == params) {
211 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate the memory for parameter");
215 params->before_lang = strdup(before_lang);
216 params->current_lang = strdup(current_lang);
218 delete_language_changed_event_invoker();
219 g_engine_changed_event_idler = ecore_idler_add(notify_language_changed_event_by_idler, static_cast<void *>(params));
222 static Eina_Bool notify_enabled_changed_event_by_idler(void *data)
224 SLOG(LOG_INFO, vc_config_tag(), "[INFO] Invoke enabled changed callback by idler");
225 bool *enable = static_cast<bool *>(data);
227 if (nullptr == enable) {
228 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Engine is not specified.");
232 if (nullptr == g_VoiceControlClients) {
233 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] No clients exist");
237 SLOG(LOG_INFO, vc_config_tag(), "[INFO] Enabled : %s", *enable ? "True" : "False");
238 auto clients = g_VoiceControlClients->getClients();
239 for (auto &clientInfo : clients) {
240 if (false == g_VoiceControlClients->isUidValid(clientInfo.getUid())) {
241 SLOG(LOG_WARN, vc_config_tag(), "[ERROR] Skip invalid client (%u)", clientInfo.getUid());
245 clientInfo.invokeEnabledChangedCallback(*enable);
250 g_enabled_changed_event_idler = nullptr;
254 static inline void delete_enabled_changed_event_invoker()
256 if (nullptr != g_enabled_changed_event_idler) {
257 void *param = ecore_idler_del(g_enabled_changed_event_idler);
258 g_enabled_changed_event_idler = nullptr;
259 free(static_cast<bool *>(param));
263 static void notify_enabled_changed(bool enable)
265 SLOG(LOG_INFO, vc_config_tag(), "[INFO] Invoke enabled callback");
267 bool *param = new bool(enable);
268 if (nullptr == param) {
269 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate the memory for parameter");
273 delete_enabled_changed_event_invoker();
274 g_engine_changed_event_idler = ecore_idler_add(notify_enabled_changed_event_by_idler, static_cast<void *>(param));
277 static int initialize_config_info()
279 g_VoiceControlConfig = new(nothrow) VoiceControlConfig();
280 if (nullptr == g_VoiceControlConfig) {
281 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to construct config");
282 return VC_CONFIG_ERROR_OPERATION_FAILED;
285 return VC_CONFIG_ERROR_NONE;
288 static void finalize_config_info()
290 delete g_VoiceControlConfig;
291 g_VoiceControlConfig = nullptr;
294 int vc_config_convert_error_code(vc_config_error_e code)
296 if (code == VC_CONFIG_ERROR_NONE) return VC_CONFIG_ERROR_NONE;
297 if (code == VC_CONFIG_ERROR_OPERATION_FAILED) return VC_ERROR_OPERATION_FAILED;
298 if (code == VC_CONFIG_ERROR_INVALID_PARAMETER) return VC_ERROR_INVALID_PARAMETER;
299 if (code == VC_CONFIG_ERROR_ENGINE_NOT_FOUND) return VC_ERROR_ENGINE_NOT_FOUND;
300 if (code == VC_CONFIG_ERROR_INVALID_STATE) return VC_ERROR_INVALID_STATE;
301 if (code == VC_CONFIG_ERROR_INVALID_LANGUAGE) return VC_ERROR_INVALID_LANGUAGE;
302 if (code == VC_CONFIG_ERROR_IO_ERROR) return VC_ERROR_IO_ERROR;
303 if (code == VC_CONFIG_ERROR_OUT_OF_MEMORY) return VC_ERROR_OUT_OF_MEMORY;
305 return VC_CONFIG_ERROR_NONE;
308 static int check_and_set_default_engine_id(const char* engine_id)
310 if (NULL == engine_id) {
311 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
312 return VC_CONFIG_ERROR_INVALID_PARAMETER;
315 if (g_VoiceControlEngines->isEngineIdValid(engine_id)) {
316 SLOG(LOG_DEBUG, vc_config_tag(), "Default engine is valid : %s", engine_id);
317 return VC_CONFIG_ERROR_NONE;
320 shared_ptr<VoiceControlEngineInfo> engineInfo = g_VoiceControlEngines->getFirstEngineInfo();
321 if (nullptr == engineInfo || engineInfo->getEngineId().empty()) {
322 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no valid engine!!");
323 return VC_CONFIG_ERROR_OPERATION_FAILED;
326 string engineId = engineInfo->getEngineId();
327 SLOG(LOG_DEBUG, vc_config_tag(), "Default engine is changed : %s", engineId.c_str());
328 if (0 != vc_parser_set_engine(engineId.c_str())) {
329 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save config");
330 return VC_CONFIG_ERROR_OPERATION_FAILED;
332 notify_engine_changed(engineId.c_str());
333 g_VoiceControlConfig->setEngineId(engineId.c_str());
335 return VC_CONFIG_ERROR_NONE;
338 static bool is_language_valid_in_engine(const char* engine_id, const char* language)
340 if (NULL == engine_id || NULL == language) {
341 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
345 shared_ptr<VoiceControlEngineInfo> engineInfo = g_VoiceControlEngines->getEngineInfo(engine_id);
346 if (nullptr == engineInfo) {
347 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", engine_id);
351 bool is_language_valid = engineInfo->isLanguageValid(language);
352 SLOG(LOG_INFO, vc_config_tag(), "[INFO] Language(%s), is valid(%d)", language, (int)is_language_valid);
354 return is_language_valid;
357 static int get_default_language_of_engine(const char* engine_id, char** language)
359 if (NULL == engine_id || NULL == language) {
360 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
361 return VC_ERROR_OPERATION_FAILED;
364 if (g_VoiceControlEngines->isEngineEmpty()) {
365 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine!!");
366 return VC_ERROR_OPERATION_FAILED;
369 shared_ptr<VoiceControlEngineInfo> engineInfo = g_VoiceControlEngines->getEngineInfo(engine_id);
370 if (nullptr == engineInfo) {
371 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", engine_id);
372 return VC_ERROR_INVALID_PARAMETER;
375 if (engineInfo->getDefaultLanguage().empty()) {
376 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] default language of engine info is NULL");
377 return VC_CONFIG_ERROR_INVALID_LANGUAGE;
380 *language = strdup(engineInfo->getDefaultLanguage().c_str());
381 if (NULL == *language) {
382 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate memory");
383 return VC_CONFIG_ERROR_OUT_OF_MEMORY;
386 SLOG(LOG_DEBUG, vc_config_tag(), "Selected language : %s", *language);
387 return VC_CONFIG_ERROR_NONE;
390 static void release_engines_information()
392 delete g_VoiceControlEngines;
393 g_VoiceControlEngines = nullptr;
396 static int load_engines_information()
399 struct dirent *dirp = NULL;
401 char filepath[512] = {'\0',};
404 SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] Release engine and Unregister engine config");
406 release_engines_information();
408 g_VoiceControlEngines = new(nothrow) VoiceControlEngines();
409 if (g_VoiceControlEngines == nullptr) {
410 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate VoiceControlEngines");
411 return VC_CONFIG_ERROR_OUT_OF_MEMORY;
414 unregister_engine_config_updated_event();
416 SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] default directory : %s", VC_DEFAULT_ENGINE_INFO);
418 /* Copy default info directory to download directory */
419 dp = opendir(VC_DEFAULT_ENGINE_INFO);
421 SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] No default directory : %s", VC_DEFAULT_ENGINE_INFO);
427 if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name))
430 filesize = strlen(VC_DEFAULT_ENGINE_INFO) + strlen(dirp->d_name) + 2;
431 if (filesize >= 512) {
432 SECURE_SLOG(LOG_ERROR, vc_config_tag(), "[CONFIG ERROR] File path is too long : %s", dirp->d_name);
434 return VC_CONFIG_ERROR_OPERATION_FAILED;
437 memset(filepath, '\0', 512);
438 snprintf(filepath, 512, "%s/%s", VC_DEFAULT_ENGINE_INFO, dirp->d_name);
440 SECURE_SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] Filepath(%s)", filepath);
442 char dest[512] = {'\0',};
443 snprintf(dest, 512, "%s/%s", VC_DOWNLOAD_ENGINE_INFO, dirp->d_name);
445 if (0 != access(dest, F_OK)) {
446 if (0 != vc_parser_copy_xml(filepath, dest)) {
447 SLOG(LOG_ERROR, vc_config_tag(), "[CONFIG ERROR] Fail to copy engine info");
451 } while (NULL != dirp);
456 /* Get engine info from default engine directory */
457 dp = opendir(VC_DOWNLOAD_ENGINE_INFO);
459 SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] No downloadable directory : %s", VC_DOWNLOAD_ENGINE_INFO);
465 if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name))
468 filesize = strlen(VC_DOWNLOAD_ENGINE_INFO) + strlen(dirp->d_name) + 2;
469 if (filesize >= 512) {
470 SECURE_SLOG(LOG_ERROR, vc_config_tag(), "[CONFIG ERROR] File path is too long : %s", dirp->d_name);
472 return VC_CONFIG_ERROR_OPERATION_FAILED;
475 memset(filepath, '\0', 512);
476 snprintf(filepath, 512, "%s/%s", VC_DOWNLOAD_ENGINE_INFO, dirp->d_name);
478 SECURE_SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] Filepath(%s)", filepath);
481 g_VoiceControlEngines->appendEngine(filepath);
482 if (0 != register_engine_config_updated_event(filepath)) {
483 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to register engine config updated event");
485 } catch (exception &error) {
486 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get engine info from filepath(%s). (%s)", filepath, error.what());
489 } while (NULL != dirp);
494 if (g_VoiceControlEngines->isEngineEmpty()) {
495 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] No engine");
496 return VC_CONFIG_ERROR_OPERATION_FAILED;
499 return VC_CONFIG_ERROR_NONE;
502 static Eina_Bool engine_config_inotify_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
504 SLOG(LOG_DEBUG, vc_config_tag(), "@@@ Engine config updated callback event");
505 ecore_thread_main_loop_begin();
507 vc_engine_inotify_s *ino = (vc_engine_inotify_s *)data;
508 int dir_fd = ino->dir_fd;
511 struct inotify_event event;
512 memset(&event, '\0', sizeof(struct inotify_event));
514 length = read(dir_fd, &event, sizeof(struct inotify_event));
516 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty Inotify event");
517 SLOG(LOG_DEBUG, vc_config_tag(), "@@@");
518 ecore_thread_main_loop_end();
519 return ECORE_CALLBACK_DONE;
522 if (IN_CLOSE_WRITE == event.mask) {
523 int ret = load_engines_information();
525 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get engine info when config updated");
528 g_VoiceControlEngines->printOutEngineInfo();
529 string default_language = g_VoiceControlConfig->getCurrentLanguage();
530 bool is_language_valid = vc_config_check_default_language_is_valid(default_language.c_str());
531 if (false == is_language_valid) {
532 SLOG(LOG_DEBUG, vc_config_tag(), "[ERROR] Default language is not valid");
533 char* temp_lang = NULL;
534 string default_engine_id = g_VoiceControlConfig->getEngineId();
535 ret = get_default_language_of_engine(default_engine_id.c_str(), &temp_lang);
538 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get language");
541 ret = set_current_language(temp_lang);
543 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to set language");
545 SLOG(LOG_DEBUG, vc_config_tag(), "[DEBUG] Saved default language : lang(%s)", default_language.c_str());
547 if (NULL != temp_lang) {
553 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Undefined event");
556 SLOG(LOG_DEBUG, vc_config_tag(), "@@@");
558 ecore_thread_main_loop_end();
559 return ECORE_CALLBACK_PASS_ON;
562 static int register_engine_config_updated_event(const char* path)
565 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Path is NULL");
566 return VC_CONFIG_ERROR_INVALID_PARAMETER;
569 /* For engine directory monitoring */
570 vc_engine_inotify_s *ino = (vc_engine_inotify_s *)calloc(1, sizeof(vc_engine_inotify_s));
572 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate memory");
573 return VC_CONFIG_ERROR_OUT_OF_MEMORY;
576 ino->dir_fd = inotify_init();
577 if (ino->dir_fd < 0) {
578 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to init inotify");
582 return VC_CONFIG_ERROR_OPERATION_FAILED;
585 ino->dir_wd = inotify_add_watch(ino->dir_fd, path, IN_CLOSE_WRITE);
586 SLOG(LOG_DEBUG, vc_config_tag(), "Add inotify watch(%s)", path);
587 if (ino->dir_wd < 0) {
588 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to add watch");
591 return VC_CONFIG_ERROR_OPERATION_FAILED;
594 ino->dir_fd_handler = ecore_main_fd_handler_add(ino->dir_fd, ECORE_FD_READ, (Ecore_Fd_Cb)engine_config_inotify_event_callback, (void *)ino, NULL, NULL);
595 if (NULL == ino->dir_fd_handler) {
596 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to add fd handler");
599 return VC_CONFIG_ERROR_OPERATION_FAILED;
602 /* Set non-blocking mode of file */
604 value = fcntl(ino->dir_fd, F_GETFL, 0);
607 if (0 > fcntl(ino->dir_fd, F_SETFL, value)) {
608 SLOG(LOG_WARN, vc_config_tag(), "[WARNING] Fail to set non-block mode");
611 unique_lock<mutex> lock(g_ino_list_mutex);
612 g_ino_list = g_list_append(g_ino_list, ino);
614 return VC_CONFIG_ERROR_NONE;
617 static int unregister_engine_config_updated_event()
619 unique_lock<mutex> lock(g_ino_list_mutex);
621 /* delete all inotify variable */
622 if (0 < g_list_length(g_ino_list)) {
624 iter = g_list_first(g_ino_list);
626 while (NULL != iter) {
627 vc_engine_inotify_s *tmp = static_cast<vc_engine_inotify_s *>(iter->data);
630 ecore_main_fd_handler_del(tmp->dir_fd_handler);
631 inotify_rm_watch(tmp->dir_fd, tmp->dir_wd);
638 g_ino_list = g_list_delete_link(g_ino_list, iter);
639 iter = g_list_first(g_ino_list);
642 return VC_CONFIG_ERROR_NONE;
645 static Eina_Bool language_config_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler)
647 SLOG(LOG_DEBUG, vc_config_tag(), "@@@ Config changed callback event");
650 SLOG(LOG_WARN, vc_config_tag(), "[WARN] FD for config file is closed");
651 SLOG(LOG_DEBUG, vc_config_tag(), "@@@");
652 return ECORE_CALLBACK_PASS_ON;
656 struct inotify_event event;
657 memset(&event, '\0', sizeof(struct inotify_event));
659 length = read(g_fd_lang, &event, sizeof(struct inotify_event));
661 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty Inotify event");
662 SLOG(LOG_DEBUG, vc_config_tag(), "@@@");
663 return ECORE_CALLBACK_PASS_ON;
666 if (IN_CLOSE_WRITE == event.mask) {
672 if (0 != vc_parser_find_config_changed(&auto_lang, &lang, &engine, &enabled))
673 return ECORE_CALLBACK_PASS_ON;
675 if (-1 != auto_lang) {
676 g_VoiceControlConfig->setAutoLanguageEnabled(auto_lang);
679 /* Only language changed */
681 string before_lang = g_VoiceControlConfig->getCurrentLanguage();
682 g_VoiceControlConfig->setCurrentLanguage(lang);
684 /* Call all callbacks of client*/
685 notify_language_changed(before_lang.c_str(), lang);
691 /* Only Engine changed */
692 if (NULL != engine) {
693 g_VoiceControlConfig->setEngineId(engine);
695 /* Call all callbacks of client*/
696 notify_engine_changed(engine);
702 g_VoiceControlConfig->setEnabled((bool)enabled);
704 /* Call all callbacks of client*/
705 notify_enabled_changed((bool)enabled);
708 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Undefined event");
711 SLOG(LOG_DEBUG, vc_config_tag(), "@@@");
713 return ECORE_CALLBACK_PASS_ON;
716 static int set_language_by_automatic_selection()
718 char candidate_lang[6] = {'\0', };
721 value = vconf_get_str(VCONFKEY_LANGSET);
723 SLOG(LOG_ERROR, vc_config_tag(), "[Config ERROR] Fail to get display language");
724 return VC_CONFIG_ERROR_OPERATION_FAILED;
727 strncpy(candidate_lang, value, 5);
730 SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Display language : %s", candidate_lang);
732 /* Check current language */
733 string default_language = g_VoiceControlConfig->getCurrentLanguage();
734 if (0 == default_language.compare(candidate_lang)) {
735 SLOG(LOG_DEBUG, vc_config_tag(), "[Config] VC language(%s) is same with display language", default_language.c_str());
736 return VC_CONFIG_ERROR_NONE;
739 string default_engine_id = g_VoiceControlConfig->getEngineId();
740 if (true == is_language_valid_in_engine(default_engine_id.c_str(), candidate_lang)) {
741 /* vc default language change */
742 string before_language = g_VoiceControlConfig->getCurrentLanguage();
743 if (0 != vc_parser_set_language(candidate_lang)) {
744 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save default language");
745 return VC_CONFIG_ERROR_OPERATION_FAILED;
747 notify_language_changed(before_language.c_str(), candidate_lang);
748 g_VoiceControlConfig->setCurrentLanguage(candidate_lang);
750 SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Default language change : before(%s) current(%s)",
751 before_language.c_str(), candidate_lang);
753 /* Call all callbacks of client*/
754 notify_language_changed(before_language.c_str(), candidate_lang);
756 /* Candidate language is not valid */
757 char* tmp_language = NULL;
758 if (0 != get_default_language_of_engine(default_engine_id.c_str(), &tmp_language)) {
759 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to select language");
760 return VC_CONFIG_ERROR_OPERATION_FAILED;
763 if (NULL == tmp_language) {
764 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Selected language is NULL");
765 return VC_CONFIG_ERROR_OPERATION_FAILED;
768 string before_language = g_VoiceControlConfig->getCurrentLanguage();
769 if (0 != vc_parser_set_language(tmp_language)) {
771 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save config");
772 return VC_CONFIG_ERROR_OPERATION_FAILED;
774 notify_language_changed(before_language.c_str(), tmp_language);
775 g_VoiceControlConfig->setCurrentLanguage(tmp_language);
777 SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Default language change : before(%s) current(%s)",
778 before_language.c_str(), tmp_language);
780 /* Call all callbacks of client*/
781 notify_language_changed(before_language.c_str(), tmp_language);
785 return VC_CONFIG_ERROR_NONE;
788 static void language_changed_cb(keynode_t *key, void *data)
790 if (g_VoiceControlConfig->isAutoLanguageEnabled()) {
791 /* Get voice input vconf key */
792 set_language_by_automatic_selection();
796 static int initialize_vc_config_mgr()
798 if (g_config_mgr_initialized.load()) {
799 SLOG(LOG_DEBUG, vc_config_tag(), "Config mgr module is already initialized");
800 return VC_CONFIG_ERROR_NONE;
803 /* Get file name from default engine directory */
804 if (0 != access(VC_CONFIG_BASE, F_OK)) {
805 if (0 != mkdir(VC_CONFIG_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
806 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to make directory : %s", VC_CONFIG_BASE);
807 return VC_CONFIG_ERROR_OPERATION_FAILED;
809 SLOG(LOG_DEBUG, vc_config_tag(), "Success to make directory : %s", VC_CONFIG_BASE);
812 if (0 != access(VC_RUNTIME_INFO_ROOT, F_OK)) {
813 if (0 != mkdir(VC_RUNTIME_INFO_ROOT, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
814 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to make directory : %s", VC_RUNTIME_INFO_ROOT);
815 return VC_CONFIG_ERROR_OPERATION_FAILED;
817 SLOG(LOG_DEBUG, vc_config_tag(), "Success to make directory : %s", VC_RUNTIME_INFO_ROOT);
821 if (0 != access(VC_DOWNLOAD_BASE, F_OK)) {
822 if (0 != mkdir(VC_DOWNLOAD_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
823 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to make directory : %s", VC_DOWNLOAD_BASE);
824 return VC_CONFIG_ERROR_OPERATION_FAILED;
826 SLOG(LOG_DEBUG, vc_config_tag(), "Success to make directory : %s", VC_DOWNLOAD_BASE);
829 if (0 != access(VC_DOWNLOAD_ENGINE_INFO, F_OK)) {
830 if (0 != mkdir(VC_DOWNLOAD_ENGINE_INFO, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) {
831 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to make directory : %s", VC_DOWNLOAD_ENGINE_INFO);
832 return VC_CONFIG_ERROR_OPERATION_FAILED;
834 SLOG(LOG_DEBUG, vc_config_tag(), "Success to make directory : %s", VC_DOWNLOAD_ENGINE_INFO);
838 if (0 != load_engines_information()) {
839 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get engine info");
840 release_engines_information();
841 return VC_CONFIG_ERROR_ENGINE_NOT_FOUND;
844 g_VoiceControlEngines->printOutEngineInfo();
846 if (0 != initialize_config_info()) {
847 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to parse configure information");
848 release_engines_information();
849 return VC_CONFIG_ERROR_OPERATION_FAILED;
852 string default_engine_id = g_VoiceControlConfig->getEngineId();
853 if (0 != check_and_set_default_engine_id(default_engine_id.c_str())) {
854 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to set default engine");
855 release_engines_information();
856 finalize_config_info();
857 return VC_CONFIG_ERROR_ENGINE_NOT_FOUND;
860 if (g_VoiceControlConfig->isAutoLanguageEnabled()) {
861 /* Check language with display language */
862 set_language_by_automatic_selection();
864 string default_language = g_VoiceControlConfig->getCurrentLanguage();
865 if (false == is_language_valid_in_engine(default_engine_id.c_str(), default_language.c_str())) {
866 /* Default language is not valid */
868 if (0 != get_default_language_of_engine(default_engine_id.c_str(), &tmp_language)) {
869 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to select language");
870 release_engines_information();
871 finalize_config_info();
872 return VC_CONFIG_ERROR_OPERATION_FAILED;
875 if (NULL != tmp_language) {
876 g_VoiceControlConfig->setCurrentLanguage(tmp_language);
877 if (0 != vc_parser_set_language(tmp_language)) {
879 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save config");
880 release_engines_information();
881 finalize_config_info();
882 return VC_CONFIG_ERROR_OPERATION_FAILED;
890 /* print daemon config */
891 SLOG(LOG_DEBUG, vc_config_tag(), "@ Daemon config @");
892 g_VoiceControlConfig->printOutConfig();
893 SLOG(LOG_DEBUG, vc_config_tag(), "@@@@");
895 g_lang_ref_count = 0;
897 /* Register to detect display language change */
898 vconf_notify_key_changed(VCONFKEY_LANGSET, language_changed_cb, nullptr);
900 g_config_mgr_initialized = true;
901 return VC_CONFIG_ERROR_NONE;
904 int vc_config_mgr_initialize(unsigned int uid)
906 SLOG(LOG_INFO, vc_config_tag(), "[WARNING] Enter critical section");
907 ecore_thread_main_loop_begin();
909 int ret = initialize_vc_config_mgr();
910 if (VC_CONFIG_ERROR_NONE != ret) {
911 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to initialize vc_config_mgr");
912 ecore_thread_main_loop_end();
913 SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section");
917 if (g_VoiceControlClients == nullptr) {
918 g_VoiceControlClients = new VoiceControlClients();
922 if (g_VoiceControlClients->isUidValid(uid)) {
923 SLOG(LOG_WARN, vc_config_tag(), "[CONFIG] uid(%u) has already registered", uid);
924 ecore_thread_main_loop_end();
925 SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section");
926 return VC_CONFIG_ERROR_NONE;
929 VoiceControlClientInfo clientInfo(uid);
930 g_VoiceControlClients->appendClient(clientInfo);
932 SLOG(LOG_INFO, vc_config_tag(), "[CONFIG] Add new client. uid(%u)", uid);
934 g_VoiceControlClients->printOutClients();
936 ecore_thread_main_loop_end();
937 SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section");
938 return VC_CONFIG_ERROR_NONE;
941 int vc_config_mgr_finalize(unsigned int uid)
943 SLOG(LOG_INFO, vc_config_tag(), "[WARNING] Enter critical section");
945 if (0 < g_VoiceControlClients->removeClient(uid)) {
946 SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section");
947 return VC_CONFIG_ERROR_NONE;
950 delete g_VoiceControlClients;
951 g_VoiceControlClients = nullptr;
953 release_engines_information();
955 unregister_engine_config_updated_event();
957 vconf_ignore_key_changed(VCONFKEY_LANGSET, language_changed_cb);
958 finalize_config_info();
960 SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section");
962 g_config_mgr_initialized = false;
963 SLOG(LOG_DEBUG, vc_config_tag(), "[Success] Finalize config");
964 return VC_CONFIG_ERROR_NONE;
968 static int register_language_config_changed_event()
970 if (0 == g_lang_ref_count) {
971 /* get file notification handler */
977 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail get inotify fd");
978 return VC_CONFIG_ERROR_OPERATION_FAILED;
982 wd = inotify_add_watch(fd, VC_CONFIG, IN_CLOSE_WRITE);
985 g_fd_handler_lang = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)language_config_inotify_event_cb, NULL, NULL, NULL);
986 if (NULL == g_fd_handler_lang) {
987 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get handler_noti");
988 return VC_CONFIG_ERROR_OPERATION_FAILED;
991 /* Set non-blocking mode of file */
993 value = fcntl(fd, F_GETFL, 0);
996 if (0 > fcntl(fd, F_SETFL, value)) {
997 SLOG(LOG_WARN, vc_config_tag(), "[WARNING] Fail to set non-block mode");
1002 return VC_CONFIG_ERROR_NONE;
1005 static int unregister_language_config_event()
1007 if (0 == g_lang_ref_count) {
1008 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Lang ref count is 0");
1009 return VC_CONFIG_ERROR_INVALID_STATE;
1013 if (0 == g_lang_ref_count) {
1014 /* delete inotify variable */
1015 ecore_main_fd_handler_del(g_fd_handler_lang);
1016 inotify_rm_watch(g_fd_lang, g_wd_lang);
1018 g_fd_handler_lang = NULL;
1021 vconf_ignore_key_changed(VCONFKEY_LANGSET, language_changed_cb);
1024 return VC_CONFIG_ERROR_NONE;
1027 int vc_config_mgr_set_engine_cb(unsigned int uid, vc_config_engine_changed_cb engine_cb)
1029 if (nullptr == engine_cb) {
1030 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] enagine cb is NULL : uid(%u) ", uid);
1031 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1034 ecore_thread_main_loop_begin();
1035 if (false == g_VoiceControlClients->isUidValid(uid)) {
1036 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no valid client : uid(%u) ", uid);
1037 ecore_thread_main_loop_end();
1038 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1041 g_VoiceControlClients->setEngineChangedCallback(uid, engine_cb);
1043 if (VC_CONFIG_ERROR_NONE != register_language_config_changed_event()) {
1044 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to register config event");
1045 ecore_thread_main_loop_end();
1046 return VC_CONFIG_ERROR_OPERATION_FAILED;
1049 ecore_thread_main_loop_end();
1050 return VC_CONFIG_ERROR_NONE;
1053 int vc_config_mgr_unset_engine_cb(unsigned int uid)
1055 ecore_thread_main_loop_begin();
1056 if (false == g_VoiceControlClients->isUidValid(uid)) {
1057 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no valid client : uid(%u) ", uid);
1058 ecore_thread_main_loop_end();
1059 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1062 g_VoiceControlClients->setEngineChangedCallback(uid, nullptr);
1064 unregister_language_config_event();
1066 ecore_thread_main_loop_end();
1067 return VC_CONFIG_ERROR_NONE;
1070 int vc_config_mgr_set_lang_cb(unsigned int uid, vc_config_lang_changed_cb lang_cb)
1072 if (nullptr == lang_cb) {
1073 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] enagine cb is NULL : uid(%u) ", uid);
1074 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1077 ecore_thread_main_loop_begin();
1078 if (false == g_VoiceControlClients->isUidValid(uid)) {
1079 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no valid client : uid(%u) ", uid);
1080 ecore_thread_main_loop_end();
1081 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1084 g_VoiceControlClients->setLanguageChangedCallback(uid, lang_cb);
1085 ecore_thread_main_loop_end();
1086 return VC_CONFIG_ERROR_NONE;
1089 int vc_config_mgr_unset_lang_cb(unsigned int uid)
1091 ecore_thread_main_loop_begin();
1092 if (false == g_VoiceControlClients->isUidValid(uid)) {
1093 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no valid client : uid(%u) ", uid);
1094 ecore_thread_main_loop_end();
1095 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1098 g_VoiceControlClients->setLanguageChangedCallback(uid, nullptr);
1099 ecore_thread_main_loop_end();
1100 return VC_CONFIG_ERROR_NONE;
1103 int vc_config_mgr_set_enabled_cb(unsigned int uid, vc_config_enabled_cb enabled_cb)
1105 if (NULL == enabled_cb) {
1106 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] enabled cb is NULL : uid(%u) ", uid);
1107 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1110 if (false == g_VoiceControlClients->isUidValid(uid)) {
1111 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no valid client : uid(%u) ", uid);
1112 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1115 g_VoiceControlClients->setEnabledChangedCallback(uid, enabled_cb);
1116 return VC_CONFIG_ERROR_NONE;
1119 int vc_config_mgr_unset_enabled_cb(unsigned int uid)
1121 if (false == g_VoiceControlClients->isUidValid(uid)) {
1122 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no valid client : uid(%u) ", uid);
1123 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1126 g_VoiceControlClients->setEnabledChangedCallback(uid, nullptr);
1127 return VC_CONFIG_ERROR_NONE;
1130 int vc_config_mgr_get_auto_language(bool* value)
1132 if (g_config_mgr_initialized.load() == false) {
1133 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized");
1134 return VC_CONFIG_ERROR_INVALID_STATE;
1137 if (NULL == value) {
1138 return VC_ERROR_INVALID_PARAMETER;
1141 *value = g_VoiceControlConfig->isAutoLanguageEnabled();
1142 return VC_CONFIG_ERROR_NONE;
1145 int vc_config_mgr_set_auto_language(bool value)
1147 if (g_config_mgr_initialized.load() == false) {
1148 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized");
1149 return VC_CONFIG_ERROR_INVALID_STATE;
1152 if (g_VoiceControlConfig->isAutoLanguageEnabled() != value) {
1153 /* Check language is valid */
1154 if (0 != vc_parser_set_auto_lang(value)) {
1155 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save engine id");
1156 return VC_CONFIG_ERROR_OPERATION_FAILED;
1158 g_VoiceControlConfig->setAutoLanguageEnabled(value);
1160 if (true == value) {
1161 set_language_by_automatic_selection();
1165 return VC_CONFIG_ERROR_NONE;
1168 int vc_config_mgr_get_engine_list(vc_config_supported_engine_cb callback, void* user_data)
1170 if (g_config_mgr_initialized.load() == false) {
1171 SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
1172 return VC_CONFIG_ERROR_INVALID_STATE;
1175 if (NULL == callback) {
1176 SLOG(LOG_ERROR, vc_config_tag(), " callback is NULL");
1177 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1180 if (g_VoiceControlEngines->isEngineEmpty()) {
1181 SLOG(LOG_WARN, vc_config_tag(), "[ERROR] Engine list is NULL");
1182 return VC_CONFIG_ERROR_ENGINE_NOT_FOUND;
1185 auto engines = g_VoiceControlEngines->getEngines();
1186 for (auto &engineInfo : engines) {
1187 if (false == g_VoiceControlEngines->isEngineIdValid(engineInfo.getEngineId())) {
1188 SLOG(LOG_WARN, vc_config_tag(), "Engine info is not valid. (%s)", engineInfo.getEngineId().c_str());
1192 if (false == callback(engineInfo.getEngineName().c_str(), engineInfo.getEngineId().c_str(), engineInfo.getSettingPath().c_str(),
1193 engineInfo.getDefaultLanguage().c_str(), engineInfo.isNonFixedSupported(), user_data)) {
1194 SLOG(LOG_DEBUG, vc_config_tag(), "Callback returns false. (%s)", engineInfo.getEngineId().c_str());
1199 return VC_CONFIG_ERROR_NONE;
1203 int vc_config_mgr_get_engine(char** engine)
1205 if (g_config_mgr_initialized.load() == false) {
1206 SLOG(LOG_ERROR, vc_config_tag(), "Not initialized"); //LCOV_EXCL_LINE
1207 return VC_CONFIG_ERROR_INVALID_STATE;
1210 if (NULL == engine) {
1211 SLOG(LOG_ERROR, vc_config_tag(), "Parameter is NULL");
1212 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1215 string default_engine_id = g_VoiceControlConfig->getEngineId();
1216 if (default_engine_id.empty()) {
1217 SLOG(LOG_ERROR, vc_config_tag(), " Engine id is NULL"); //LCOV_EXCL_LINE
1218 return VC_CONFIG_ERROR_ENGINE_NOT_FOUND;
1220 *engine = strdup(default_engine_id.c_str());
1222 return VC_CONFIG_ERROR_NONE;
1225 static int set_default_engine_id_on_buxtonkey(const char* engine)
1228 struct buxton_client * bux_cli;
1229 struct buxton_layer * bux_layer;
1230 struct buxton_value * bux_val;
1232 int ret = buxton_open(&bux_cli, NULL, NULL);
1234 SLOG(LOG_ERROR, vc_config_tag(), "[DBUS-BUXTON2] Fail to open buxton client, ret(%d)", ret);
1235 return VC_CONFIG_ERROR_OPERATION_FAILED;
1237 bux_layer = buxton_create_layer("system");
1238 if (NULL == bux_layer) {
1239 SLOG(LOG_ERROR, vc_config_tag(), "[DBUS-BUXTON2] buxton_create_layer FAIL");
1240 buxton_close(bux_cli);
1242 return VC_CONFIG_ERROR_OPERATION_FAILED;
1244 bux_val = buxton_value_create_string(engine);
1245 if (NULL == bux_val) {
1246 SLOG(LOG_ERROR, vc_config_tag(), "[DBUS-BUXTON2] buxton_value_create_string FAIL");
1247 buxton_free_layer(bux_layer);
1248 buxton_close(bux_cli);
1251 return VC_CONFIG_ERROR_OPERATION_FAILED;
1253 SLOG(LOG_DEBUG, vc_config_tag(), "[DBUS-BUXTON2] layer: %s", buxton_layer_get_name(bux_layer));
1256 ret = buxton_set_value_sync(bux_cli, bux_layer, VC_ENGINE_DB_DEFAULT, bux_val);
1258 SLOG(LOG_ERROR, vc_config_tag(), "[DBUS-BUXTON2] Fail to set value sync, ret(%d)", ret);
1259 buxton_value_free(bux_val);
1260 buxton_free_layer(bux_layer);
1261 buxton_close(bux_cli);
1266 return VC_CONFIG_ERROR_OPERATION_FAILED;
1268 SLOG(LOG_DEBUG, vc_config_tag(), "[DBUS-BUXTON2] buxton_set_value_sync: %s", VC_ENGINE_DB_DEFAULT);
1270 buxton_value_free(bux_val);
1271 buxton_free_layer(bux_layer);
1272 buxton_close(bux_cli);
1278 return VC_CONFIG_ERROR_NONE;
1281 int vc_config_mgr_set_engine(const char* engine)
1283 if (g_config_mgr_initialized.load() == false) {
1284 SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
1285 return VC_CONFIG_ERROR_INVALID_STATE;
1288 if (NULL == engine) {
1289 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1292 /* Check current engine id with new engine id */
1293 string default_engine_id = g_VoiceControlConfig->getEngineId();
1294 if (0 == default_engine_id.compare(engine)) {
1295 return VC_CONFIG_ERROR_NONE;
1298 SLOG(LOG_DEBUG, vc_config_tag(), "New engine id : %s", engine);
1300 int ret = set_default_engine_id_on_buxtonkey(engine);
1302 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] set buxtonkey Failed!!!");
1306 shared_ptr<VoiceControlEngineInfo> engineInfo = g_VoiceControlEngines->getEngineInfo(engine);
1307 if (nullptr == engineInfo) {
1308 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", engine);
1309 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1312 if (0 != vc_parser_set_engine(engine)) {
1313 SLOG(LOG_ERROR, vc_config_tag(), " Fail to save config");
1314 return VC_CONFIG_ERROR_OPERATION_FAILED;
1316 notify_engine_changed(engine);
1317 g_VoiceControlConfig->setEngineId(engine);
1319 /* Engine is valid*/
1320 string default_language = g_VoiceControlConfig->getCurrentLanguage();
1321 bool is_language_valid = engineInfo->isLanguageValid(default_language);
1322 SLOG(LOG_ERROR, vc_config_tag(), "[INFO] Language(%s), is valid(%d)", default_language.c_str(), (int)is_language_valid);
1324 if (false == is_language_valid) {
1325 auto languages = engineInfo->getSupportedLanguages();
1326 if (languages.empty()) {
1327 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get default language. Engine id(%s) is not valid", engine);
1328 return VC_CONFIG_ERROR_OPERATION_FAILED;
1331 g_VoiceControlConfig->setCurrentLanguage(languages[0].c_str());
1334 SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Engine changed");
1335 g_VoiceControlConfig->printOutConfig();
1336 return VC_CONFIG_ERROR_NONE;
1339 int vc_config_mgr_get_language_list(vc_supported_language_cb callback, void* user_data)
1341 if (g_config_mgr_initialized.load() == false) {
1342 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized");
1343 return VC_CONFIG_ERROR_INVALID_STATE;
1346 if (nullptr == callback) {
1347 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Callback is null");
1348 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1351 string default_engine_id = g_VoiceControlConfig->getEngineId();
1352 shared_ptr<VoiceControlEngineInfo> engineInfo = g_VoiceControlEngines->getEngineInfo(default_engine_id);
1353 if (nullptr == engineInfo) {
1354 SLOG(LOG_ERROR, vc_config_tag(), "Fail to find engine information : %s", default_engine_id.c_str());
1355 return VC_CONFIG_ERROR_ENGINE_NOT_FOUND;
1358 /* Get a first item */
1359 auto languages = engineInfo->getSupportedLanguages();
1360 for (auto &language : languages) {
1361 SLOG(LOG_INFO, vc_config_tag(), "language (%s)", language.c_str());
1362 if (language.empty()) {
1363 SLOG(LOG_WARN, vc_config_tag(), "Language is not valid");
1367 if (false == callback(language.c_str(), user_data)) {
1368 SLOG(LOG_DEBUG, vc_config_tag(), "Callback returns false (%s)", language.c_str());
1373 return VC_CONFIG_ERROR_NONE;
1376 int vc_config_mgr_get_default_language(char** language)
1378 if (g_config_mgr_initialized.load() == false) {
1379 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized");
1380 return VC_CONFIG_ERROR_INVALID_STATE;
1383 if (NULL == language) {
1384 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1387 string default_language = g_VoiceControlConfig->getCurrentLanguage();
1388 if (default_language.empty()) {
1389 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] language is NULL");
1390 return VC_CONFIG_ERROR_OPERATION_FAILED;
1393 *language = strdup(default_language.c_str());
1394 return VC_CONFIG_ERROR_NONE;
1397 static int set_current_language(const char* language)
1399 if (g_config_mgr_initialized.load() == false) {
1400 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized");
1401 return VC_CONFIG_ERROR_INVALID_STATE;
1404 if (NULL == language) {
1405 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1408 /* Check language is valid */
1409 string default_language = g_VoiceControlConfig->getCurrentLanguage();
1410 if (default_language.empty()) {
1411 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] language is NULL");
1412 return VC_CONFIG_ERROR_OPERATION_FAILED;
1415 if (0 != vc_parser_set_language(language)) {
1416 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save engine id");
1417 return VC_CONFIG_ERROR_OPERATION_FAILED;
1419 notify_language_changed(default_language.c_str(), language);
1420 g_VoiceControlConfig->setCurrentLanguage(language);
1422 return VC_CONFIG_ERROR_NONE;
1425 int vc_config_mgr_set_default_language(const char* language)
1427 int ret = set_current_language(language);
1431 int vc_config_mgr_get_enabled(bool* value)
1433 if (g_config_mgr_initialized.load() == false) {
1434 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized");
1435 return VC_CONFIG_ERROR_INVALID_STATE;
1438 if (NULL == value) {
1439 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1442 *value = g_VoiceControlConfig->isEnabled();
1443 return VC_CONFIG_ERROR_NONE;
1446 int vc_config_mgr_set_enabled(bool value)
1448 if (g_config_mgr_initialized.load() == false) {
1449 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized");
1450 return VC_CONFIG_ERROR_INVALID_STATE;
1453 if (0 != vc_parser_set_enabled(value)) {
1454 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to set enabled");
1455 return VC_CONFIG_ERROR_OPERATION_FAILED;
1457 notify_enabled_changed(value);
1458 g_VoiceControlConfig->setEnabled(value);
1460 return VC_CONFIG_ERROR_NONE;
1463 int vc_config_mgr_get_nonfixed_support(bool* value)
1465 if (g_config_mgr_initialized.load() == false) {
1466 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized");
1467 return VC_CONFIG_ERROR_INVALID_STATE;
1470 if (NULL == value) {
1471 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
1472 return VC_CONFIG_ERROR_INVALID_PARAMETER;
1475 string default_engine_id = g_VoiceControlConfig->getEngineId();
1476 shared_ptr<VoiceControlEngineInfo> engineInfo = g_VoiceControlEngines->getEngineInfo(default_engine_id);
1477 if (nullptr == engineInfo) {
1478 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", default_engine_id.c_str());
1479 return VC_CONFIG_ERROR_ENGINE_NOT_FOUND;
1482 *value = engineInfo->isNonFixedSupported();
1483 return VC_CONFIG_ERROR_NONE;
1486 bool vc_config_check_default_engine_is_valid(const char* engine)
1488 if (g_config_mgr_initialized.load() == false) {
1489 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized");
1493 bool is_engine_valid = g_VoiceControlEngines->isEngineIdValid(engine);
1494 return is_engine_valid;
1497 bool vc_config_check_default_language_is_valid(const char* language)
1499 if (g_config_mgr_initialized.load() == false) {
1500 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized");
1504 if (NULL == language) {
1508 string default_engine_id = g_VoiceControlConfig->getEngineId();
1509 shared_ptr<VoiceControlEngineInfo> engineInfo = g_VoiceControlEngines->getEngineInfo(default_engine_id);
1510 if (nullptr == engineInfo) {
1511 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", default_engine_id.c_str());
1515 bool is_language_valid = engineInfo->isLanguageValid(language);
1516 SLOG(LOG_INFO, vc_config_tag(), "[INFO] Language(%s), is valid(%d)", language, (int)is_language_valid);
1518 return is_language_valid;
1521 int vc_config_mgr_set_foreground(int pid, bool value)
1523 if (g_config_mgr_initialized.load() == false) {
1524 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized");
1525 return VC_CONFIG_ERROR_INVALID_STATE;
1528 return vc_parser_set_foreground(pid, value);
1531 int vc_config_mgr_get_foreground(int* pid)
1533 if (g_config_mgr_initialized.load() == false) {
1534 SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized");
1535 return VC_CONFIG_ERROR_INVALID_STATE;
1538 return vc_parser_get_foreground(pid);