From: Suyeon Hwang Date: Tue, 29 Nov 2022 08:33:03 +0000 (+0900) Subject: Change file format from c to cpp X-Git-Tag: submit/tizen/20230313.042534~15 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F00%2F286200%2F1;p=platform%2Fcore%2Fuifw%2Fvoice-control.git Change file format from c to cpp - Requirement: It is hard to assure thread safe in C based code. - Solution: This patch changes the file format of vc_config_mgr from c to cpp. Through this patch, refactoring vc_config_mgr will become easier. Change-Id: I0cf1c672daf74daa97d759564f2610a0074ff127 Signed-off-by: Suyeon Hwang --- diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index c5e8b31..1d144d2 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -7,7 +7,7 @@ SET(SRCS ../common/vc_cmd_db.c ../common/vc_command.c ../common/vc_command_util.c - ../common/vc_config_mgr.c + ../common/vc_config_mgr.cpp ../common/vc_config_parser.c ../common/vc_info_parser.c ../common/vc_json_parser.c @@ -17,7 +17,7 @@ SET(SETTING_SRCS vc_setting_tidl.c vc_setting_proxy.c vc_setting.c - ../common/vc_config_mgr.c + ../common/vc_config_mgr.cpp ../common/vc_config_parser.c ) @@ -30,7 +30,7 @@ SET(WIDGET_SRCS ../common/vc_cmd_db.c ../common/vc_command.c ../common/vc_command_util.c - ../common/vc_config_mgr.c + ../common/vc_config_mgr.cpp ../common/vc_config_parser.c ../common/vc_info_parser.c ../common/vc_json_parser.c @@ -49,7 +49,7 @@ SET(MANAGER_SRCS ../common/vc_cmd_db.c ../common/vc_command.c ../common/vc_command_util.c - ../common/vc_config_mgr.c + ../common/vc_config_mgr.cpp ../common/vc_config_parser.c ../common/vc_info_parser.c ../common/vc_json_parser.c diff --git a/common/vc_config_mgr.c b/common/vc_config_mgr.c deleted file mode 100644 index e77e7f9..0000000 --- a/common/vc_config_mgr.c +++ /dev/null @@ -1,1896 +0,0 @@ -/* -* Copyright (c) 2011-2019 Samsung Electronics Co., Ltd All Rights Reserved -* -* Licensed under the Apache License, Version 2.0 (the License); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an AS IS BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vc_config_mgr.h" -#include "vc_config_parser.h" -#include "vc_defs.h" -#include "vc_main.h" -#include "voice_control_command.h" - -#define EVENT_SIZE (sizeof(struct inotify_event)) -#define BUF_LEN (EVENT_SIZE + 16) - -typedef struct { - unsigned int uid; - vc_config_engine_changed_cb engine_cb; - vc_config_lang_changed_cb lang_cb; - vc_config_enabled_cb enabled_cb; -} vc_config_client_s; - -/* for engine directory monitoring */ -typedef struct { - Ecore_Fd_Handler* dir_fd_handler; - int dir_fd; - int dir_wd; -} vc_engine_inotify_s; - -typedef struct { - const char* before_lang; - const char* current_lang; -} lang_cb_parameter_s; - -typedef struct { - const char *engine_appid; -} engine_cb_parameter_s; - -typedef struct { - bool enable; -} enabled_cb_parameter_s; - -const char* vc_config_tag() -{ - return TAG_VCCONFIG; -} - -static GSList* g_engine_list = NULL; - -static GSList* g_config_client_list = NULL; - -static vc_config_s* g_config_info; - -static int g_lang_ref_count; -static Ecore_Fd_Handler* g_fd_handler_lang = NULL; -static int g_fd_lang = -1; -static int g_wd_lang = -1; - -static GList* g_ino_list = NULL; - -static pthread_mutex_t vc_config_mgr_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t vc_config_engine_mutex = PTHREAD_MUTEX_INITIALIZER; - -static int __vc_config_mgr_register_engine_config_updated_event(const char* path); -static int __vc_config_mgr_unregister_engine_config_updated_event(); -static int __vc_config_mgr_set_default_language(const char* language); - -int __vc_config_mgr_print_engine_info(); -int __vc_config_mgr_print_client_info(); - -static gint __compare_uid_in_client_list(gconstpointer a, gconstpointer b) -{ - const vc_config_client_s *client_info = a; - uintptr_t ptr_uid = (uintptr_t)b; - unsigned int uid = ptr_uid; - - if (NULL == client_info) { - return 1; - } - - if (uid == client_info->uid) { - SLOG(LOG_DEBUG, vc_config_tag(), "Find client information of %d", uid); - return 0; - } - - return 1; -} - -static vc_config_client_s *__find_client_info(unsigned int uid) -{ - uintptr_t ptr_uid = uid; - GSList *target = g_slist_find_custom(g_config_client_list, (gconstpointer)ptr_uid, __compare_uid_in_client_list); - - vc_config_client_s *result = NULL; - if (NULL != target) { - result = target->data; - } - - return result; -} - -static gint __compare_engine_id_in_engine_list(gconstpointer a, gconstpointer b) -{ - const vc_engine_info_s *engine_info = a; - const char *engine_id = b; - - if (NULL == engine_id) { - return 1; - } - - if (NULL == engine_info || NULL == engine_info->uuid) { - return 1; - } - - SLOG(LOG_DEBUG, vc_config_tag(), "Compare engine(%s). Target(%s)", engine_info->uuid, engine_id); - return strcmp(engine_info->uuid, engine_id); -} - -static vc_engine_info_s *__find_engine_info(const char *engine_id) -{ - GSList *target = g_slist_find_custom(g_engine_list, engine_id, __compare_engine_id_in_engine_list); - vc_engine_info_s *result = NULL; - if (NULL != target) { - result = target->data; - } - - return result; -} - -static gint __compare_language_in_languages_of_engine_info(gconstpointer a, gconstpointer b) -{ - const char *language = a; - const char *target_language = b; - - if (NULL == language || NULL == target_language) { - return 1; - } - - SLOG(LOG_DEBUG, vc_config_tag(), "Compare langauge(%s), Target(%s)", language, target_language); - return strcmp(language, target_language); -} - -static bool __is_language_valid(vc_engine_info_s *engine_info, const char *language) -{ - if (NULL == engine_info || NULL == language) { - return false; - } - - GSList *target = g_slist_find_custom(engine_info->languages, language, __compare_language_in_languages_of_engine_info); - return (NULL != target); -} - -static void __invoke_lang_cb_in_client_list(gpointer data, gpointer user_data) -{ - vc_config_client_s* client_info = (vc_config_client_s*)data; - lang_cb_parameter_s* parameter = (lang_cb_parameter_s*)user_data; - - if (NULL == client_info || NULL == parameter) { - return; - } - - if (NULL != client_info->lang_cb) { - client_info->lang_cb(parameter->before_lang, parameter->current_lang); - } -} - -static void __invoke_engine_cb_in_client_list(gpointer data, gpointer user_data) -{ - vc_config_client_s* client_info = (vc_config_client_s*)data; - engine_cb_parameter_s* parameter = (engine_cb_parameter_s*)user_data; - - if (NULL == client_info || NULL == parameter) { - return; - } - - if (NULL != client_info->engine_cb) { - client_info->engine_cb(parameter->engine_appid); - } -} - -static void __invoke_enabled_cb_in_client_list(gpointer data, gpointer user_data) -{ - vc_config_client_s* client_info = (vc_config_client_s*)data; - enabled_cb_parameter_s* parameter = (enabled_cb_parameter_s*)user_data; - - if (NULL == client_info || NULL == parameter) { - return; - } - - if (NULL != client_info->enabled_cb) { - client_info->enabled_cb(parameter->enable); - } -} - -static void __vc_config_mgr_notify_language_changed(const char* before_lang, const char* current_lang) -{ - if (NULL == before_lang || NULL == current_lang) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL"); - return; - } - - lang_cb_parameter_s lang_cb_parameter; - lang_cb_parameter.before_lang = before_lang; - lang_cb_parameter.current_lang = current_lang; - - g_slist_foreach(g_config_client_list, __invoke_lang_cb_in_client_list, &lang_cb_parameter); -} - -static void __vc_config_mgr_notify_engine_changed(const char *engine_appid) -{ - if (NULL == engine_appid) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL"); - return; - } - - engine_cb_parameter_s engine_cb_parameter; - engine_cb_parameter.engine_appid = engine_appid; - - g_slist_foreach(g_config_client_list, __invoke_engine_cb_in_client_list, &engine_cb_parameter); -} - -static void __vc_config_mgr_notify_enabled_changed(bool enable) -{ - enabled_cb_parameter_s enabled_cb_parameter; - enabled_cb_parameter.enable = enable; - - g_slist_foreach(g_config_client_list, __invoke_enabled_cb_in_client_list, &enabled_cb_parameter); -} - -int vc_config_convert_error_code(vc_config_error_e code) -{ - if (code == VC_CONFIG_ERROR_NONE) return VC_ERROR_NONE; - if (code == VC_CONFIG_ERROR_OPERATION_FAILED) return VC_ERROR_OPERATION_FAILED; - if (code == VC_CONFIG_ERROR_INVALID_PARAMETER) return VC_ERROR_INVALID_PARAMETER; - if (code == VC_CONFIG_ERROR_ENGINE_NOT_FOUND) return VC_ERROR_ENGINE_NOT_FOUND; - if (code == VC_CONFIG_ERROR_INVALID_STATE) return VC_ERROR_INVALID_STATE; - if (code == VC_CONFIG_ERROR_INVALID_LANGUAGE) return VC_ERROR_INVALID_LANGUAGE; - if (code == VC_CONFIG_ERROR_IO_ERROR) return VC_ERROR_IO_ERROR; - if (code == VC_CONFIG_ERROR_OUT_OF_MEMORY) return VC_ERROR_OUT_OF_MEMORY; - - return VC_CONFIG_ERROR_NONE; -} - -int __vc_config_mgr_check_engine_is_valid(const char* engine_id) -{ - if (NULL == engine_id) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL"); - return VC_CONFIG_ERROR_INVALID_PARAMETER; - } - - if (0 >= g_slist_length(g_engine_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine!!"); - return VC_CONFIG_ERROR_OPERATION_FAILED; - } - - if (NULL != __find_engine_info(engine_id)) { - SLOG(LOG_DEBUG, vc_config_tag(), "Default engine is valid : %s", engine_id); - return VC_CONFIG_ERROR_NONE; - } - - GSList *iter = g_slist_nth(g_engine_list, 0); - if (NULL == iter) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] No engine in list"); - return -1; - } - - vc_engine_info_s *engine_info = iter->data; - if (NULL == engine_info) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Engine info is NULL"); - return -1; - } - - if (NULL == engine_info->uuid) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Engine id is NULL"); - return -1; - } - - if (NULL == g_config_info) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Config info is NULL"); - return -1; - } - - if (NULL != g_config_info->engine_id) - free(g_config_info->engine_id); - - g_config_info->engine_id = strdup(engine_info->uuid); - - SLOG(LOG_DEBUG, vc_config_tag(), "Default engine is changed : %s", g_config_info->engine_id); - if (0 != vc_parser_set_engine(g_config_info->engine_id)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save config"); - return -1; - } - - return VC_ERROR_NONE; -} - -bool __vc_config_mgr_check_lang_is_valid(const char* engine_id, const char* language) -{ - if (NULL == engine_id || NULL == language) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL"); - return false; - } - - if (0 >= g_slist_length(g_engine_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine!!"); - return false; - } - - vc_engine_info_s *engine_info = __find_engine_info(engine_id); - if (NULL == engine_info) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", engine_id); - return false; - } - - bool is_language_valid = __is_language_valid(engine_info, language); - SLOG(LOG_INFO, vc_config_tag(), "[INFO] Language(%s), is valid(%d)", language, (int)is_language_valid); - - return is_language_valid; -} - -int __vc_config_mgr_select_lang(const char* engine_id, char** language) -{ - if (NULL == engine_id || NULL == language) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL"); - return VC_ERROR_OPERATION_FAILED; - } - - if (0 >= g_slist_length(g_engine_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine!!"); - return VC_ERROR_OPERATION_FAILED; - } - - vc_engine_info_s *engine_info = __find_engine_info(engine_id); - if (NULL == engine_info) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", engine_id); - return VC_ERROR_INVALID_PARAMETER; - } - - if (NULL == engine_info->default_lang) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] default language of engine info is NULL"); - return VC_CONFIG_ERROR_INVALID_LANGUAGE; - } - - *language = strdup(engine_info->default_lang); - if (NULL == *language) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate memory"); - return VC_CONFIG_ERROR_OUT_OF_MEMORY; - } - - SLOG(LOG_DEBUG, vc_config_tag(), "Selected language : %s", *language); - return VC_CONFIG_ERROR_NONE; -} - -int __vc_config_release_client(unsigned int uid) -{ - vc_config_client_s* temp_client = __find_client_info(uid); - - if (NULL != temp_client) { - g_config_client_list = g_slist_remove(g_config_client_list, temp_client); - free(temp_client); - } - - SLOG(LOG_DEBUG, vc_config_tag(), "Client count (%d)", g_slist_length(g_config_client_list)); - - return g_slist_length(g_config_client_list); -} - -void __vc_config_release_engine() -{ - GSList *iter = NULL; - vc_engine_info_s *engine_info = NULL; - - if (0 < g_slist_length(g_engine_list)) { - - /* Get a first item */ - iter = g_slist_nth(g_engine_list, 0); - - while (NULL != iter) { - engine_info = iter->data; - - if (NULL != engine_info) { - g_engine_list = g_slist_remove(g_engine_list, engine_info); - - vc_parser_free_engine_info(engine_info); - } - - iter = g_slist_nth(g_engine_list, 0); - } - } - - return; -} - -int __vc_config_mgr_get_engine_info() -{ - DIR *dp = NULL; - struct dirent *dirp = NULL; - - char filepath[512] = {'\0',}; - int filesize; - vc_engine_info_s* info = NULL; - - SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] Release engine and Unregister engine config"); - - __vc_config_release_engine(); - g_engine_list = NULL; - __vc_config_mgr_unregister_engine_config_updated_event(); - - SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] default directory : %s", VC_DEFAULT_ENGINE_INFO); - - /* Copy default info directory to download directory */ - dp = opendir(VC_DEFAULT_ENGINE_INFO); - if (NULL == dp) { - SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] No default directory : %s", VC_DEFAULT_ENGINE_INFO); - } else { - do { - dirp = readdir(dp); - - if (NULL != dirp) { - if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name)) - continue; - - filesize = strlen(VC_DEFAULT_ENGINE_INFO) + strlen(dirp->d_name) + 2; - if (filesize >= 512) { - SECURE_SLOG(LOG_ERROR, vc_config_tag(), "[CONFIG ERROR] File path is too long : %s", dirp->d_name); - closedir(dp); - return -1; - } - - memset(filepath, '\0', 512); - snprintf(filepath, 512, "%s/%s", VC_DEFAULT_ENGINE_INFO, dirp->d_name); - - SECURE_SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] Filepath(%s)", filepath); - - char dest[512] = {'\0',}; - snprintf(dest, 512, "%s/%s", VC_DOWNLOAD_ENGINE_INFO, dirp->d_name); - - if (0 != access(dest, F_OK)) { - if (0 != vc_parser_copy_xml(filepath, dest)) { - SLOG(LOG_ERROR, vc_config_tag(), "[CONFIG ERROR] Fail to copy engine info"); - } - } - } - } while (NULL != dirp); - - closedir(dp); - } - - /* Get engine info from default engine directory */ - dp = opendir(VC_DOWNLOAD_ENGINE_INFO); - if (NULL == dp) { - SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] No downloadable directory : %s", VC_DOWNLOAD_ENGINE_INFO); - } else { - do { - dirp = readdir(dp); - - if (NULL != dirp) { - if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name)) - continue; - - filesize = strlen(VC_DOWNLOAD_ENGINE_INFO) + strlen(dirp->d_name) + 2; - if (filesize >= 512) { - SECURE_SLOG(LOG_ERROR, vc_config_tag(), "[CONFIG ERROR] File path is too long : %s", dirp->d_name); - closedir(dp); - return -1; - } - - memset(filepath, '\0', 512); - snprintf(filepath, 512, "%s/%s", VC_DOWNLOAD_ENGINE_INFO, dirp->d_name); - - SECURE_SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] Filepath(%s)", filepath); - - if (0 == vc_parser_get_engine_info(filepath, &info)) { - g_engine_list = g_slist_append(g_engine_list, info); - if (0 != __vc_config_mgr_register_engine_config_updated_event(filepath)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to register engine config updated event"); - } - } - } - } while (NULL != dirp); - - closedir(dp); - } - - if (0 >= g_slist_length(g_engine_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] No engine"); - return -1; - } - - return VC_ERROR_NONE; -} - -static Eina_Bool __vc_config_mgr_engine_config_inotify_event_callback(void* data, Ecore_Fd_Handler *fd_handler) -{ - SLOG(LOG_DEBUG, vc_config_tag(), "@@@ Engine config updated callback event"); - ecore_thread_main_loop_begin(); - pthread_mutex_lock(&vc_config_mgr_mutex); - - vc_engine_inotify_s *ino = (vc_engine_inotify_s *)data; - int dir_fd = ino->dir_fd; - - int length; - struct inotify_event event; - memset(&event, '\0', sizeof(struct inotify_event)); - - length = read(dir_fd, &event, sizeof(struct inotify_event)); - if (0 > length) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty Inotify event"); - SLOG(LOG_DEBUG, vc_config_tag(), "@@@"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return ECORE_CALLBACK_DONE; - } - - if (IN_CLOSE_WRITE == event.mask) { - int ret = __vc_config_mgr_get_engine_info(); - if (0 != ret) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get engine info when config updated"); - } - __vc_config_mgr_print_engine_info(); - bool is_language_valid = vc_config_check_default_language_is_valid(g_config_info->language); - if (false == is_language_valid) { - SLOG(LOG_DEBUG, vc_config_tag(), "[ERROR] Default language is not valid"); - char* temp_lang = NULL; - ret = __vc_config_mgr_select_lang(g_config_info->engine_id, &temp_lang); - if (0 != ret) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get language"); - } - - ret = __vc_config_mgr_set_default_language(temp_lang); - if (0 != ret) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to set language"); - } else { - SLOG(LOG_DEBUG, vc_config_tag(), "[DEBUG] Saved default language : lang(%s)", g_config_info->language); - } - if (NULL != temp_lang) { - free(temp_lang); - temp_lang = NULL; - } - } - } else { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Undefined event"); - } - - SLOG(LOG_DEBUG, vc_config_tag(), "@@@"); - - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return ECORE_CALLBACK_PASS_ON; -} - -static int __vc_config_mgr_register_engine_config_updated_event(const char* path) -{ - if (NULL == path) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Path is NULL"); - return -1; - } - - /* For engine directory monitoring */ - vc_engine_inotify_s *ino = (vc_engine_inotify_s *)calloc(1, sizeof(vc_engine_inotify_s)); - if (NULL == ino) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate memory"); - return -1; - } - - ino->dir_fd = inotify_init(); - if (ino->dir_fd < 0) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to init inotify"); - free(ino); - ino = NULL; - - return -1; - } - - ino->dir_wd = inotify_add_watch(ino->dir_fd, path, IN_CLOSE_WRITE); - SLOG(LOG_DEBUG, vc_config_tag(), "Add inotify watch(%s)", path); - if (ino->dir_wd < 0) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to add watch"); - free(ino); - ino = NULL; - return -1; - } - - ino->dir_fd_handler = ecore_main_fd_handler_add(ino->dir_fd, ECORE_FD_READ, (Ecore_Fd_Cb)__vc_config_mgr_engine_config_inotify_event_callback, (void *)ino, NULL, NULL); - if (NULL == ino->dir_fd_handler) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to add fd handler"); - free(ino); - ino = NULL; - return -1; - } - - /* Set non-blocking mode of file */ - int value; - value = fcntl(ino->dir_fd, F_GETFL, 0); - value |= O_NONBLOCK; - - if (0 > fcntl(ino->dir_fd, F_SETFL, value)) { - SLOG(LOG_WARN, vc_config_tag(), "[WARNING] Fail to set non-block mode"); - } - - pthread_mutex_lock(&vc_config_engine_mutex); - g_ino_list = g_list_append(g_ino_list, ino); - pthread_mutex_unlock(&vc_config_engine_mutex); - - return VC_ERROR_NONE; -} - -static int __vc_config_mgr_unregister_engine_config_updated_event() -{ - pthread_mutex_lock(&vc_config_engine_mutex); - - /* delete all inotify variable */ - if (0 < g_list_length(g_ino_list)) { - GList *iter = NULL; - iter = g_list_first(g_ino_list); - - while (NULL != iter) { - vc_engine_inotify_s *tmp = iter->data; - - if (NULL != tmp) { - ecore_main_fd_handler_del(tmp->dir_fd_handler); - inotify_rm_watch(tmp->dir_fd, tmp->dir_wd); - close(tmp->dir_fd); - - free(tmp); - tmp = NULL; - } - - g_ino_list = g_list_delete_link(g_ino_list, iter); - iter = g_list_first(g_ino_list); - } - } - pthread_mutex_unlock(&vc_config_engine_mutex); - return VC_ERROR_NONE; -} - -Eina_Bool vc_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler) -{ - SLOG(LOG_DEBUG, vc_config_tag(), "@@@ Config changed callback event"); - - if (g_fd_lang < 0) { - SLOG(LOG_WARN, vc_config_tag(), "[WARN] FD for config file is closed"); - SLOG(LOG_DEBUG, vc_config_tag(), "@@@"); - return ECORE_CALLBACK_PASS_ON; - } - - int length; - struct inotify_event event; - memset(&event, '\0', sizeof(struct inotify_event)); - - length = read(g_fd_lang, &event, sizeof(struct inotify_event)); - if (0 > length) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty Inotify event"); - SLOG(LOG_DEBUG, vc_config_tag(), "@@@"); - return ECORE_CALLBACK_PASS_ON; - } - - if (IN_CLOSE_WRITE == event.mask) { - int auto_lang = -1; - char* lang = NULL; - char* engine = NULL; - int enabled = -1; - - if (0 != vc_parser_find_config_changed(&auto_lang, &lang, &engine, &enabled)) - return ECORE_CALLBACK_PASS_ON; - - if (-1 != auto_lang) { - g_config_info->auto_lang = auto_lang; - } - - /* Only language changed */ - if (NULL != lang) { - char* before_lang = NULL; - - before_lang = strdup(g_config_info->language); - - if (NULL != g_config_info->language) free(g_config_info->language); - g_config_info->language = strdup(lang); - - /* Call all callbacks of client*/ - __vc_config_mgr_notify_language_changed(before_lang, lang); - - if (NULL != before_lang) free(before_lang); - free(lang); - lang = NULL; - } - - /* Only Engine changed */ - if (NULL != engine) { - - if (NULL != g_config_info->engine_id) { - free(g_config_info->engine_id); - g_config_info->engine_id = NULL; - } - g_config_info->engine_id = strdup(engine); - - /* Call all callbacks of client*/ - __vc_config_mgr_notify_engine_changed(engine); - free(engine); - engine = NULL; - } - - if (-1 != enabled) { - g_config_info->enabled = enabled; - - /* Call all callbacks of client*/ - __vc_config_mgr_notify_enabled_changed((bool)enabled); - } - } else { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Undefined event"); - } - - SLOG(LOG_DEBUG, vc_config_tag(), "@@@"); - - return ECORE_CALLBACK_PASS_ON; -} - -int __vc_config_set_auto_language() -{ - char candidate_lang[6] = {'\0', }; - char* value = NULL; - - value = vconf_get_str(VCONFKEY_LANGSET); - if (NULL == value) { - SLOG(LOG_ERROR, vc_config_tag(), "[Config ERROR] Fail to get display language"); - return -1; - } - - strncpy(candidate_lang, value, 5); - free(value); - - SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Display language : %s", candidate_lang); - - /* Check current config info */ - if (NULL == g_config_info) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Current config info is NULL"); - return VC_CONFIG_ERROR_OPERATION_FAILED; - } - - /* Check current language */ - if (NULL == g_config_info->language) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Current config language is NULL"); - return VC_CONFIG_ERROR_OPERATION_FAILED; - } - - if (0 == strncmp(g_config_info->language, candidate_lang, 5)) { - SLOG(LOG_DEBUG, vc_config_tag(), "[Config] VC language(%s) is same with display language", g_config_info->language); - return VC_ERROR_NONE; - } - - if (true == __vc_config_mgr_check_lang_is_valid(g_config_info->engine_id, candidate_lang)) { - /* vc default language change */ - char* before_lang = NULL; - if (0 != vc_parser_set_language(candidate_lang)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save default language"); - return -1; - } - - before_lang = strdup(g_config_info->language); - - free(g_config_info->language); - g_config_info->language = strdup(candidate_lang); - - SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Default language change : before(%s) current(%s)", - before_lang, g_config_info->language); - - /* Call all callbacks of client*/ - __vc_config_mgr_notify_language_changed(before_lang, g_config_info->language); - - if (NULL != before_lang) free(before_lang); - } else { - /* Candidate language is not valid */ - char* tmp_language = NULL; - if (0 != __vc_config_mgr_select_lang(g_config_info->engine_id, &tmp_language)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to select language"); - return -1; - } - - if (NULL == tmp_language) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Selected language is NULL"); - return -1; - } - - char* before_lang = NULL; - if (0 != vc_parser_set_language(tmp_language)) { - free(tmp_language); - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save config"); - return -1; - } - - before_lang = strdup(g_config_info->language); - - free(g_config_info->language); - g_config_info->language = strdup(tmp_language); - free(tmp_language); - - SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Default language change : before(%s) current(%s)", - before_lang, g_config_info->language); - - /* Call all callbacks of client*/ - __vc_config_mgr_notify_language_changed(before_lang, g_config_info->language); - - if (NULL != before_lang) free(before_lang); - } - - return VC_ERROR_NONE; -} - -void __vc_config_language_changed_cb(keynode_t *key, void *data) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - if (g_config_info && true == g_config_info->auto_lang) { - /* Get voice input vconf key */ - __vc_config_set_auto_language(); - } - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return; -} - -int vc_config_mgr_initialize(unsigned int uid) -{ - vc_config_client_s* temp_client = NULL; - - SLOG(LOG_INFO, vc_config_tag(), "[WARNING] Enter critical section"); - ecore_thread_main_loop_begin(); - pthread_mutex_lock(&vc_config_mgr_mutex); - - if (0 < g_slist_length(g_config_client_list)) { - /* Check uid */ - if (NULL != __find_client_info(uid)) { - SLOG(LOG_WARN, vc_config_tag(), "[CONFIG] uid(%u) has already registered", uid); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section"); - return VC_CONFIG_ERROR_NONE; - } - - temp_client = (vc_config_client_s*)calloc(1, sizeof(vc_config_client_s)); - if (NULL == temp_client) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate memory"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return VC_ERROR_OUT_OF_MEMORY; - } - - temp_client->uid = uid; - temp_client->engine_cb = NULL; - temp_client->lang_cb = NULL; - temp_client->enabled_cb = NULL; - - /* Add uid */ - g_config_client_list = g_slist_append(g_config_client_list, temp_client); - - SLOG(LOG_WARN, vc_config_tag(), "[CONFIG] Add uid(%u) but config has already initialized", uid); - - __vc_config_mgr_print_client_info(); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section"); - return VC_ERROR_NONE; - } - - /* Get file name from default engine directory */ - g_engine_list = NULL; - - if (0 != access(VC_CONFIG_BASE, F_OK)) { - if (0 != mkdir(VC_CONFIG_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to make directory : %s", VC_CONFIG_BASE); - __vc_config_release_client(uid); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return -1; - } else { - SLOG(LOG_DEBUG, vc_config_tag(), "Success to make directory : %s", VC_CONFIG_BASE); - } - } - if (0 != access(VC_RUNTIME_INFO_ROOT, F_OK)) { - if (0 != mkdir(VC_RUNTIME_INFO_ROOT, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to make directory : %s", VC_RUNTIME_INFO_ROOT); - __vc_config_release_client(uid); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return -1; - } else { - SLOG(LOG_DEBUG, vc_config_tag(), "Success to make directory : %s", VC_RUNTIME_INFO_ROOT); - } - } - - if (0 != access(VC_DOWNLOAD_BASE, F_OK)) { - if (0 != mkdir(VC_DOWNLOAD_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to make directory : %s", VC_DOWNLOAD_BASE); - __vc_config_release_client(uid); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return -1; - } else { - SLOG(LOG_DEBUG, vc_config_tag(), "Success to make directory : %s", VC_DOWNLOAD_BASE); - } - } - if (0 != access(VC_DOWNLOAD_ENGINE_INFO, F_OK)) { - if (0 != mkdir(VC_DOWNLOAD_ENGINE_INFO, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to make directory : %s", VC_DOWNLOAD_ENGINE_INFO); - __vc_config_release_client(uid); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return -1; - } else { - SLOG(LOG_DEBUG, vc_config_tag(), "Success to make directory : %s", VC_DOWNLOAD_ENGINE_INFO); - } - } - - if (0 != __vc_config_mgr_get_engine_info()) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get engine info"); - __vc_config_release_client(uid); - __vc_config_release_engine(); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return VC_CONFIG_ERROR_ENGINE_NOT_FOUND; - } - - __vc_config_mgr_print_engine_info(); - - if (0 != vc_parser_load_config(&g_config_info)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to parse configure information"); - __vc_config_release_client(uid); - __vc_config_release_engine(); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return -1; - } - - if (0 != __vc_config_mgr_check_engine_is_valid(g_config_info->engine_id)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get default engine"); - __vc_config_release_client(uid); - __vc_config_release_engine(); - vc_parser_unload_config(g_config_info); - g_config_info = NULL; - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return VC_CONFIG_ERROR_ENGINE_NOT_FOUND; - } - - if (true == g_config_info->auto_lang) { - /* Check language with display language */ - __vc_config_set_auto_language(); - } else { - if (false == __vc_config_mgr_check_lang_is_valid(g_config_info->engine_id, g_config_info->language)) { - /* Default language is not valid */ - char* tmp_language; - if (0 != __vc_config_mgr_select_lang(g_config_info->engine_id, &tmp_language)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to select language"); - __vc_config_release_client(uid); - __vc_config_release_engine(); - vc_parser_unload_config(g_config_info); - g_config_info = NULL; - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return -1; - } - - if (NULL != tmp_language) { - if (NULL != g_config_info->language) { - free(g_config_info->language); - g_config_info->language = strdup(tmp_language); - } - - if (0 != vc_parser_set_language(tmp_language)) { - free(tmp_language); - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save config"); - __vc_config_release_client(uid); - __vc_config_release_engine(); - vc_parser_unload_config(g_config_info); - g_config_info = NULL; - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return -1; - } - - free(tmp_language); - } - } - } - - /* print daemon config */ - SLOG(LOG_DEBUG, vc_config_tag(), "@ Daemon config @"); - SLOG(LOG_DEBUG, vc_config_tag(), " engine : %s", g_config_info->engine_id); - SLOG(LOG_DEBUG, vc_config_tag(), " auto language : %s", g_config_info->auto_lang ? "on" : "off"); - SLOG(LOG_DEBUG, vc_config_tag(), " language : %s", g_config_info->language); - SLOG(LOG_DEBUG, vc_config_tag(), "@@@@"); - - g_lang_ref_count = 0; - - /* Register to detect display language change */ - vconf_notify_key_changed(VCONFKEY_LANGSET, __vc_config_language_changed_cb, NULL); - - temp_client = (vc_config_client_s*)calloc(1, sizeof(vc_config_client_s)); - if (NULL == temp_client) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate memory"); - __vc_config_release_client(uid); - __vc_config_release_engine(); - vc_parser_unload_config(g_config_info); - g_config_info = NULL; - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return VC_ERROR_OUT_OF_MEMORY; - } - - temp_client->uid = uid; - temp_client->engine_cb = NULL; - temp_client->lang_cb = NULL; - temp_client->enabled_cb = NULL; - - SLOG(LOG_DEBUG, vc_config_tag(), "uid(%u) temp_uid(%u)", uid, temp_client->uid); - - /* Add uid */ - g_config_client_list = g_slist_append(g_config_client_list, temp_client); - - __vc_config_mgr_print_client_info(); - - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section"); - return VC_ERROR_NONE; -} - -int vc_config_mgr_finalize(unsigned int uid) -{ - SLOG(LOG_INFO, vc_config_tag(), "[WARNING] Enter critical section"); - - pthread_mutex_lock(&vc_config_mgr_mutex); - - if (0 < __vc_config_release_client(uid)) { - pthread_mutex_unlock(&vc_config_mgr_mutex); - SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section"); - - return VC_ERROR_NONE; - } - - __vc_config_release_engine(); - - __vc_config_mgr_unregister_engine_config_updated_event(); - - vconf_ignore_key_changed(VCONFKEY_LANGSET, __vc_config_language_changed_cb); - - vc_parser_unload_config(g_config_info); - g_config_info = NULL; - - pthread_mutex_unlock(&vc_config_mgr_mutex); - SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section"); - - SLOG(LOG_DEBUG, vc_config_tag(), "[Success] Finalize config"); - return VC_ERROR_NONE; -} - - -int __vc_config_mgr_register_lang_event() -{ - if (0 == g_lang_ref_count) { - /* get file notification handler */ - int fd; - int wd; - - fd = inotify_init(); - if (fd < 0) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail get inotify fd"); - return -1; - } - g_fd_lang = fd; - - wd = inotify_add_watch(fd, VC_CONFIG, IN_CLOSE_WRITE); - g_wd_lang = wd; - - g_fd_handler_lang = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)vc_config_mgr_inotify_event_cb, NULL, NULL, NULL); - if (NULL == g_fd_handler_lang) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get handler_noti"); - return -1; - } - - /* Set non-blocking mode of file */ - int value; - value = fcntl(fd, F_GETFL, 0); - value |= O_NONBLOCK; - - if (0 > fcntl(fd, F_SETFL, value)) { - SLOG(LOG_WARN, vc_config_tag(), "[WARNING] Fail to set non-block mode"); - } - } - g_lang_ref_count++; - - return VC_ERROR_NONE; -} - -int __vc_config_mgr_unregister_config_event() -{ - if (0 == g_lang_ref_count) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Lang ref count is 0"); - return VC_CONFIG_ERROR_INVALID_STATE; - } - - g_lang_ref_count--; - if (0 == g_lang_ref_count) { - /* delete inotify variable */ - ecore_main_fd_handler_del(g_fd_handler_lang); - inotify_rm_watch(g_fd_lang, g_wd_lang); - close(g_fd_lang); - g_fd_handler_lang = NULL; - g_fd_lang = -1; - - vconf_ignore_key_changed(VCONFKEY_LANGSET, __vc_config_language_changed_cb); - } - - return VC_ERROR_NONE; -} - -int vc_config_mgr_set_engine_cb(unsigned int uid, vc_config_engine_changed_cb engine_cb) -{ - ecore_thread_main_loop_begin(); - pthread_mutex_lock(&vc_config_mgr_mutex); - - /* Call all callbacks of client*/ - vc_config_client_s* temp_client = __find_client_info(uid); - if (NULL == temp_client) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Uid is not valid (%u)", uid); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return VC_CONFIG_ERROR_INVALID_PARAMETER; - } - - temp_client->engine_cb = engine_cb; - if (VC_CONFIG_ERROR_NONE != __vc_config_mgr_register_lang_event()) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to register config event"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return VC_CONFIG_ERROR_OPERATION_FAILED; - } - - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return VC_ERROR_NONE; -} - -int vc_config_mgr_unset_engine_cb(unsigned int uid) -{ - ecore_thread_main_loop_begin(); - pthread_mutex_lock(&vc_config_mgr_mutex); - - /* Call all callbacks of client*/ - vc_config_client_s* temp_client = __find_client_info(uid); - if (NULL == temp_client) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Uid is not valid (%u)", uid); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return VC_CONFIG_ERROR_INVALID_PARAMETER; - } - - temp_client->engine_cb = NULL; - __vc_config_mgr_unregister_config_event(); - - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return VC_ERROR_NONE; -} - - -int vc_config_mgr_set_lang_cb(unsigned int uid, vc_config_lang_changed_cb lang_cb) -{ - ecore_thread_main_loop_begin(); - pthread_mutex_lock(&vc_config_mgr_mutex); - - /* Call all callbacks of client*/ - vc_config_client_s* temp_client = __find_client_info(uid); - if (NULL == temp_client) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Uid is not valid (%u)", uid); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return VC_CONFIG_ERROR_INVALID_PARAMETER; - } - - temp_client->lang_cb = lang_cb; - if (0 != __vc_config_mgr_register_lang_event()) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to register config event"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return VC_CONFIG_ERROR_OPERATION_FAILED; - } - - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return VC_ERROR_NONE; -} - -int vc_config_mgr_unset_lang_cb(unsigned int uid) -{ - ecore_thread_main_loop_begin(); - pthread_mutex_lock(&vc_config_mgr_mutex); - - /* Call all callbacks of client*/ - vc_config_client_s* temp_client = __find_client_info(uid); - if (NULL == temp_client) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Uid is not valid (%u)", uid); - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return VC_CONFIG_ERROR_INVALID_PARAMETER; - } - - temp_client->lang_cb = NULL; - __vc_config_mgr_unregister_config_event(); - - pthread_mutex_unlock(&vc_config_mgr_mutex); - ecore_thread_main_loop_end(); - return VC_ERROR_NONE; -} - -int vc_config_mgr_set_enabled_cb(unsigned int uid, vc_config_enabled_cb enabled_cb) -{ - if (NULL == enabled_cb) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] enabled cb is NULL : uid(%u) ", uid); - return VC_CONFIG_ERROR_INVALID_PARAMETER; - } - - pthread_mutex_lock(&vc_config_mgr_mutex); - - /* Call all callbacks of client*/ - vc_config_client_s* temp_client = __find_client_info(uid); - if (NULL == temp_client) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Uid is not valid (%u)", uid); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_INVALID_PARAMETER; - } - - temp_client->enabled_cb = enabled_cb; - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_NONE; -} - -int vc_config_mgr_unset_enabled_cb(unsigned int uid) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - - /* Call all callbacks of client*/ - vc_config_client_s* temp_client = __find_client_info(uid); - if (NULL == temp_client) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Uid is not valid (%u)", uid); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_INVALID_PARAMETER; - } - - temp_client->enabled_cb = NULL; - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_ERROR_NONE; -} - -int vc_config_mgr_get_auto_language(bool* value) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - if (NULL == value) { - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - *value = g_config_info->auto_lang; - pthread_mutex_unlock(&vc_config_mgr_mutex); - - return VC_ERROR_NONE; -} - -int vc_config_mgr_set_auto_language(bool value) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - if (g_config_info->auto_lang != value) { - /* Check language is valid */ - if (0 != vc_parser_set_auto_lang(value)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save engine id"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - g_config_info->auto_lang = value; - - if (true == g_config_info->auto_lang) { - __vc_config_set_auto_language(); - } - } - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_ERROR_NONE; -} - -int vc_config_mgr_get_engine_list(vc_config_supported_engine_cb callback, void* user_data) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "Not initialized"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_INVALID_STATE; - } - - if (NULL == callback) { - SLOG(LOG_ERROR, vc_config_tag(), " callback is NULL"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_INVALID_PARAMETER; - } - - GSList *iter = NULL; - vc_engine_info_s *engine_info = NULL; - - if (0 >= g_slist_length(g_engine_list)) { - SLOG(LOG_WARN, vc_config_tag(), "[ERROR] Engine list is NULL"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_ENGINE_NOT_FOUND; - } - - /* Get a first item */ - iter = g_slist_nth(g_engine_list, 0); - - while (NULL != iter) { - engine_info = iter->data; - - if (NULL == engine_info) { - SLOG(LOG_ERROR, vc_config_tag(), " Engine info is NULL"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_OPERATION_FAILED; - } - - if (false == callback(engine_info->name, engine_info->uuid, engine_info->setting, engine_info->default_lang, engine_info->non_fixed_support, user_data)) - break; - - iter = g_slist_next(iter); - } - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_NONE; -} - - -int vc_config_mgr_get_engine(char** engine) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "Not initialized"); //LCOV_EXCL_LINE - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_INVALID_STATE; - } - - if (NULL == engine) { - SLOG(LOG_ERROR, vc_config_tag(), "Parameter is NULL"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_INVALID_PARAMETER; - } - - if (NULL != g_config_info->engine_id) { - *engine = strdup(g_config_info->engine_id); - } else { - SLOG(LOG_ERROR, vc_config_tag(), " Engine id is NULL"); //LCOV_EXCL_LINE - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_ENGINE_NOT_FOUND; - } - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_NONE; -} - -int __vc_config_set_buxtonkey(const char* engine) -{ - /* Set vconfkey */ - struct buxton_client * bux_cli; - struct buxton_layer * bux_layer; - struct buxton_value * bux_val; - - int ret = buxton_open(&bux_cli, NULL, NULL); - if (0 != ret) { - SLOG(LOG_ERROR, vc_config_tag(), "[DBUS-BUXTON2] Fail to open buxton client, ret(%d)", ret); - return VC_CONFIG_ERROR_OPERATION_FAILED; - } - bux_layer = buxton_create_layer("system"); - if (NULL == bux_layer) { - SLOG(LOG_ERROR, vc_config_tag(), "[DBUS-BUXTON2] buxton_create_layer FAIL"); - buxton_close(bux_cli); - bux_cli = NULL; - return VC_CONFIG_ERROR_OPERATION_FAILED; - } - bux_val = buxton_value_create_string(engine); - if (NULL == bux_val) { - SLOG(LOG_ERROR, vc_config_tag(), "[DBUS-BUXTON2] buxton_value_create_string FAIL"); - buxton_free_layer(bux_layer); - buxton_close(bux_cli); - bux_layer = NULL; - bux_cli = NULL; - return VC_CONFIG_ERROR_OPERATION_FAILED; - } else { - SLOG(LOG_DEBUG, vc_config_tag(), "[DBUS-BUXTON2] layer: %s", buxton_layer_get_name(bux_layer)); - } - - ret = buxton_set_value_sync(bux_cli, bux_layer, VC_ENGINE_DB_DEFAULT, bux_val); - if (0 != ret) { - SLOG(LOG_ERROR, vc_config_tag(), "[DBUS-BUXTON2] Fail to set value sync, ret(%d)", ret); - buxton_value_free(bux_val); - buxton_free_layer(bux_layer); - buxton_close(bux_cli); - - bux_cli = NULL; - bux_layer = NULL; - bux_val = NULL; - return VC_CONFIG_ERROR_OPERATION_FAILED; - } - SLOG(LOG_DEBUG, vc_config_tag(), "[DBUS-BUXTON2] buxton_set_value_sync: %s", VC_ENGINE_DB_DEFAULT); - - buxton_value_free(bux_val); - buxton_free_layer(bux_layer); - buxton_close(bux_cli); - - bux_cli = NULL; - bux_layer = NULL; - bux_val = NULL; - - return VC_CONFIG_ERROR_NONE; -} - -int vc_config_mgr_set_engine(const char* engine) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "Not initialized"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_INVALID_STATE; - } - - if (NULL == g_config_info) { - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_OPERATION_FAILED; - } - - if (NULL == engine || NULL == g_config_info->engine_id) { - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_INVALID_PARAMETER; - } - - /* Check current engine id with new engine id */ - if (0 == strncmp(g_config_info->engine_id, engine, strlen(g_config_info->engine_id))) { - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_NONE; - } - - SLOG(LOG_DEBUG, vc_config_tag(), "New engine id : %s", engine); - - int ret = __vc_config_set_buxtonkey(engine); - if (0 != ret) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] set buxtonkey Failed!!!"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return ret; - } - - vc_engine_info_s *engine_info = __find_engine_info(engine); - if (NULL == engine_info) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", engine); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_INVALID_PARAMETER; - } - - free(g_config_info->engine_id); - g_config_info->engine_id = strdup(engine_info->uuid); - - /* Engine is valid*/ - bool is_language_valid = __is_language_valid(engine_info, g_config_info->language); - SLOG(LOG_ERROR, vc_config_tag(), "[INFO] Language(%s), is valid(%d)", g_config_info->language, (int)is_language_valid); - - char* lang = NULL; - if (false == is_language_valid) { - free(g_config_info->language); - g_config_info->language = NULL; - - GSList *iter_lang = g_slist_nth(engine_info->languages, 0); - if (NULL == iter_lang || NULL == iter_lang->data) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get default language. Engine id(%s) is not valid", engine); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_OPERATION_FAILED; - } - - lang = iter_lang->data; - g_config_info->language = strdup(lang); - } - - SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Engine changed"); - SLOG(LOG_DEBUG, vc_config_tag(), "Engine : %s", g_config_info->engine_id); - SLOG(LOG_DEBUG, vc_config_tag(), "Auto lang : %s", g_config_info->auto_lang ? "true" : "false"); - SLOG(LOG_DEBUG, vc_config_tag(), "Language : %s", g_config_info->language); - SLOG(LOG_DEBUG, vc_config_tag(), "Enabled : %s", g_config_info->enabled ? "true" : "false"); - - if (0 != vc_parser_set_engine(g_config_info->engine_id)) { - SLOG(LOG_ERROR, vc_config_tag(), " Fail to save config"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_OPERATION_FAILED; - } - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_NONE; -} - -int vc_config_mgr_get_language_list(vc_supported_language_cb callback, void* user_data) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - if (0 >= g_slist_length(g_engine_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - vc_engine_info_s *engine_info = __find_engine_info(g_config_info->engine_id); - if (NULL == engine_info) { - SLOG(LOG_ERROR, vc_config_tag(), "Fail to find engine information : %s", g_config_info->engine_id); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_NONE; - } - - /* Get a first item */ - GSList *iter_lang = g_slist_nth(engine_info->languages, 0); - - while (NULL != iter_lang) { - /*Get handle data from list*/ - char* lang = iter_lang->data; - - SLOG(LOG_INFO, vc_config_tag(), "lang(%s)", lang); - if (NULL != lang) { - if (false == callback(lang, user_data)) - break; - } - - /*Get next item*/ - iter_lang = g_slist_next(iter_lang); - } - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_ERROR_NONE; -} - -int vc_config_mgr_get_default_language(char** language) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - if (NULL == language) { - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - if (NULL != g_config_info->language) { - *language = strdup(g_config_info->language); - } else { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] language is NULL"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_ERROR_NONE; -} - -static int __vc_config_mgr_set_default_language(const char* language) -{ - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); - return -1; - } - - if (NULL == language) { - return -1; - } - - /* Check language is valid */ - if (NULL != g_config_info->language) { - if (0 != vc_parser_set_language(language)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save engine id"); - return -1; - } - free(g_config_info->language); - g_config_info->language = strdup(language); - } else { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] language is NULL"); - return -1; - } - - return VC_ERROR_NONE; -} - -int vc_config_mgr_set_default_language(const char* language) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - int ret = __vc_config_mgr_set_default_language(language); - pthread_mutex_unlock(&vc_config_mgr_mutex); - - return ret; -} - -int vc_config_mgr_get_enabled(bool* value) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - if (NULL == value) { - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - *value = g_config_info->enabled; - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_ERROR_NONE; -} - -int vc_config_mgr_set_enabled(bool value) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - if (0 != vc_parser_set_enabled(value)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to set enabled"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - g_config_info->enabled = value; - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_ERROR_NONE; -} - -int vc_config_mgr_get_nonfixed_support(bool* value) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - if (NULL == value) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - if (0 >= g_slist_length(g_engine_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - if (NULL == g_config_info || NULL == g_config_info->engine_id) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Engine ID is not set in global config!!"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_ENGINE_NOT_FOUND; - } - - vc_engine_info_s *engine_info = __find_engine_info(g_config_info->engine_id); - if (NULL == engine_info) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", g_config_info->engine_id); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_CONFIG_ERROR_ENGINE_NOT_FOUND; - }; - - *value = engine_info->non_fixed_support; - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return VC_ERROR_NONE; -} - -bool vc_config_check_default_engine_is_valid(const char* engine) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - if (NULL == engine) { - pthread_mutex_unlock(&vc_config_mgr_mutex); - return false; - } - - if (0 >= g_slist_length(g_engine_list)) { - pthread_mutex_unlock(&vc_config_mgr_mutex); - return false; - } - - vc_engine_info_s *engine_info = __find_engine_info(engine); - if (NULL == engine_info) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", engine); - }; - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return (NULL != engine_info); -} - -bool vc_config_check_default_language_is_valid(const char* language) -{ - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); - return -1; - } - - if (NULL == language) { - return false; - } - - if (NULL == g_config_info->engine_id) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Default engine id is NULL"); - return false; - } - - if (0 >= g_slist_length(g_engine_list)) { - return false; - } - - vc_engine_info_s *engine_info = __find_engine_info(g_config_info->engine_id); - if (NULL == engine_info) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", g_config_info->engine_id); - return false; - }; - - bool is_language_valid = __is_language_valid(engine_info, language); - SLOG(LOG_INFO, vc_config_tag(), "[INFO] Language(%s), is valid(%d)", language, (int)is_language_valid); - - return is_language_valid; -} - -int vc_config_mgr_set_foreground(int pid, bool value) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return vc_parser_set_foreground(pid, value); -} - -int vc_config_mgr_get_foreground(int* pid) -{ - pthread_mutex_lock(&vc_config_mgr_mutex); - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); - pthread_mutex_unlock(&vc_config_mgr_mutex); - return -1; - } - - pthread_mutex_unlock(&vc_config_mgr_mutex); - return vc_parser_get_foreground(pid); -} - -int __vc_config_mgr_print_engine_info() -{ - GSList *iter = NULL; - vc_engine_info_s *engine_info = NULL; - - if (0 >= g_slist_length(g_engine_list)) { - SLOG(LOG_DEBUG, vc_config_tag(), "@ engine list @"); - SLOG(LOG_DEBUG, vc_config_tag(), " No Engine in engine directory"); - SLOG(LOG_DEBUG, vc_config_tag(), "@@@@"); - return VC_ERROR_NONE; - } - - /* Get a first item */ - iter = g_slist_nth(g_engine_list, 0); - - SLOG(LOG_DEBUG, vc_config_tag(), "@ engine list @"); - - int i = 1; - while (NULL != iter) { - engine_info = iter->data; - - SLOG(LOG_DEBUG, vc_config_tag(), "[%dth]", i); - SLOG(LOG_DEBUG, vc_config_tag(), " name : %s", engine_info->name); - SLOG(LOG_DEBUG, vc_config_tag(), " id : %s", engine_info->uuid); - - - SLOG(LOG_DEBUG, vc_config_tag(), " languages"); - GSList *iter_lang = NULL; - char* lang; - if (g_slist_length(engine_info->languages) > 0) { - /* Get a first item */ - iter_lang = g_slist_nth(engine_info->languages, 0); - - int j = 1; - while (NULL != iter_lang) { - /*Get handle data from list*/ - lang = iter_lang->data; - - SLOG(LOG_DEBUG, vc_config_tag(), " [%dth] %s", j, lang); - - /*Get next item*/ - iter_lang = g_slist_next(iter_lang); - j++; - } - } else { - SLOG(LOG_DEBUG, vc_config_tag(), " language is NONE"); - } - iter = g_slist_next(iter); - i++; - } - SLOG(LOG_DEBUG, vc_config_tag(), "@@@@"); - - return VC_ERROR_NONE; -} - -int __vc_config_mgr_print_client_info() -{ - GSList *iter = NULL; - vc_config_client_s* temp_client = NULL; - - if (0 >= g_slist_length(g_config_client_list)) { - SLOG(LOG_DEBUG, vc_config_tag(), "@ Client list @"); - SLOG(LOG_DEBUG, vc_config_tag(), " No Client"); - SLOG(LOG_DEBUG, vc_config_tag(), "@@@@"); - return VC_ERROR_NONE; - } - - /* Get a first item */ - iter = g_slist_nth(g_config_client_list, 0); - - SLOG(LOG_DEBUG, vc_config_tag(), "@ Client list @"); - - int i = 1; - while (NULL != iter) { - temp_client = iter->data; - - SLOG(LOG_DEBUG, vc_config_tag(), "[%dth] uid(%u)", i, temp_client->uid); - - iter = g_slist_next(iter); - i++; - } - SLOG(LOG_DEBUG, vc_config_tag(), "@@@@"); - - return VC_ERROR_NONE; -} diff --git a/common/vc_config_mgr.cpp b/common/vc_config_mgr.cpp new file mode 100644 index 0000000..8c5f8cc --- /dev/null +++ b/common/vc_config_mgr.cpp @@ -0,0 +1,1896 @@ +/* +* Copyright (c) 2011-2019 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the License); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vc_config_mgr.h" +#include "vc_config_parser.h" +#include "vc_defs.h" +#include "vc_main.h" +#include "voice_control_command.h" + +#define EVENT_SIZE (sizeof(struct inotify_event)) +#define BUF_LEN (EVENT_SIZE + 16) + +typedef struct { + unsigned int uid; + vc_config_engine_changed_cb engine_cb; + vc_config_lang_changed_cb lang_cb; + vc_config_enabled_cb enabled_cb; +} vc_config_client_s; + +/* for engine directory monitoring */ +typedef struct { + Ecore_Fd_Handler* dir_fd_handler; + int dir_fd; + int dir_wd; +} vc_engine_inotify_s; + +typedef struct { + const char* before_lang; + const char* current_lang; +} lang_cb_parameter_s; + +typedef struct { + const char *engine_appid; +} engine_cb_parameter_s; + +typedef struct { + bool enable; +} enabled_cb_parameter_s; + +static const char* vc_config_tag() +{ + return TAG_VCCONFIG; +} + +static GSList* g_engine_list = NULL; + +static GSList* g_config_client_list = NULL; + +static vc_config_s* g_config_info; + +static int g_lang_ref_count; +static Ecore_Fd_Handler* g_fd_handler_lang = NULL; +static int g_fd_lang = -1; +static int g_wd_lang = -1; + +static GList* g_ino_list = NULL; + +static pthread_mutex_t vc_config_mgr_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t vc_config_engine_mutex = PTHREAD_MUTEX_INITIALIZER; + +static int __vc_config_mgr_register_engine_config_updated_event(const char* path); +static int __vc_config_mgr_unregister_engine_config_updated_event(); +static int __vc_config_mgr_set_default_language(const char* language); + +int __vc_config_mgr_print_engine_info(); +int __vc_config_mgr_print_client_info(); + +static gint __compare_uid_in_client_list(gconstpointer a, gconstpointer b) +{ + const vc_config_client_s *client_info = static_cast(a); + uintptr_t ptr_uid = (uintptr_t)b; + unsigned int uid = ptr_uid; + + if (NULL == client_info) { + return 1; + } + + if (uid == client_info->uid) { + SLOG(LOG_DEBUG, vc_config_tag(), "Find client information of %d", uid); + return 0; + } + + return 1; +} + +static vc_config_client_s *__find_client_info(unsigned int uid) +{ + uintptr_t ptr_uid = uid; + GSList *target = g_slist_find_custom(g_config_client_list, (gconstpointer)ptr_uid, __compare_uid_in_client_list); + + vc_config_client_s *result = NULL; + if (NULL != target) { + result = static_cast(target->data); + } + + return result; +} + +static gint __compare_engine_id_in_engine_list(gconstpointer a, gconstpointer b) +{ + const vc_engine_info_s *engine_info = static_cast(a); + const char *engine_id = static_cast(b); + + if (NULL == engine_id) { + return 1; + } + + if (NULL == engine_info || NULL == engine_info->uuid) { + return 1; + } + + SLOG(LOG_DEBUG, vc_config_tag(), "Compare engine(%s). Target(%s)", engine_info->uuid, engine_id); + return strcmp(engine_info->uuid, engine_id); +} + +static vc_engine_info_s *__find_engine_info(const char *engine_id) +{ + GSList *target = g_slist_find_custom(g_engine_list, engine_id, __compare_engine_id_in_engine_list); + vc_engine_info_s *result = NULL; + if (NULL != target) { + result = static_cast(target->data); + } + + return result; +} + +static gint __compare_language_in_languages_of_engine_info(gconstpointer a, gconstpointer b) +{ + const char *language = static_cast(a); + const char *target_language = static_cast(b); + + if (NULL == language || NULL == target_language) { + return 1; + } + + SLOG(LOG_DEBUG, vc_config_tag(), "Compare langauge(%s), Target(%s)", language, target_language); + return strcmp(language, target_language); +} + +static bool __is_language_valid(vc_engine_info_s *engine_info, const char *language) +{ + if (NULL == engine_info || NULL == language) { + return false; + } + + GSList *target = g_slist_find_custom(engine_info->languages, language, __compare_language_in_languages_of_engine_info); + return (NULL != target); +} + +static void __invoke_lang_cb_in_client_list(gpointer data, gpointer user_data) +{ + vc_config_client_s* client_info = (vc_config_client_s*)data; + lang_cb_parameter_s* parameter = (lang_cb_parameter_s*)user_data; + + if (NULL == client_info || NULL == parameter) { + return; + } + + if (NULL != client_info->lang_cb) { + client_info->lang_cb(parameter->before_lang, parameter->current_lang); + } +} + +static void __invoke_engine_cb_in_client_list(gpointer data, gpointer user_data) +{ + vc_config_client_s* client_info = (vc_config_client_s*)data; + engine_cb_parameter_s* parameter = (engine_cb_parameter_s*)user_data; + + if (NULL == client_info || NULL == parameter) { + return; + } + + if (NULL != client_info->engine_cb) { + client_info->engine_cb(parameter->engine_appid); + } +} + +static void __invoke_enabled_cb_in_client_list(gpointer data, gpointer user_data) +{ + vc_config_client_s* client_info = (vc_config_client_s*)data; + enabled_cb_parameter_s* parameter = (enabled_cb_parameter_s*)user_data; + + if (NULL == client_info || NULL == parameter) { + return; + } + + if (NULL != client_info->enabled_cb) { + client_info->enabled_cb(parameter->enable); + } +} + +static void __vc_config_mgr_notify_language_changed(const char* before_lang, const char* current_lang) +{ + if (NULL == before_lang || NULL == current_lang) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL"); + return; + } + + lang_cb_parameter_s lang_cb_parameter; + lang_cb_parameter.before_lang = before_lang; + lang_cb_parameter.current_lang = current_lang; + + g_slist_foreach(g_config_client_list, __invoke_lang_cb_in_client_list, &lang_cb_parameter); +} + +static void __vc_config_mgr_notify_engine_changed(const char *engine_appid) +{ + if (NULL == engine_appid) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL"); + return; + } + + engine_cb_parameter_s engine_cb_parameter; + engine_cb_parameter.engine_appid = engine_appid; + + g_slist_foreach(g_config_client_list, __invoke_engine_cb_in_client_list, &engine_cb_parameter); +} + +static void __vc_config_mgr_notify_enabled_changed(bool enable) +{ + enabled_cb_parameter_s enabled_cb_parameter; + enabled_cb_parameter.enable = enable; + + g_slist_foreach(g_config_client_list, __invoke_enabled_cb_in_client_list, &enabled_cb_parameter); +} + +int vc_config_convert_error_code(vc_config_error_e code) +{ + if (code == VC_CONFIG_ERROR_NONE) return VC_ERROR_NONE; + if (code == VC_CONFIG_ERROR_OPERATION_FAILED) return VC_ERROR_OPERATION_FAILED; + if (code == VC_CONFIG_ERROR_INVALID_PARAMETER) return VC_ERROR_INVALID_PARAMETER; + if (code == VC_CONFIG_ERROR_ENGINE_NOT_FOUND) return VC_ERROR_ENGINE_NOT_FOUND; + if (code == VC_CONFIG_ERROR_INVALID_STATE) return VC_ERROR_INVALID_STATE; + if (code == VC_CONFIG_ERROR_INVALID_LANGUAGE) return VC_ERROR_INVALID_LANGUAGE; + if (code == VC_CONFIG_ERROR_IO_ERROR) return VC_ERROR_IO_ERROR; + if (code == VC_CONFIG_ERROR_OUT_OF_MEMORY) return VC_ERROR_OUT_OF_MEMORY; + + return VC_CONFIG_ERROR_NONE; +} + +int __vc_config_mgr_check_engine_is_valid(const char* engine_id) +{ + if (NULL == engine_id) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL"); + return VC_CONFIG_ERROR_INVALID_PARAMETER; + } + + if (0 >= g_slist_length(g_engine_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine!!"); + return VC_CONFIG_ERROR_OPERATION_FAILED; + } + + if (NULL != __find_engine_info(engine_id)) { + SLOG(LOG_DEBUG, vc_config_tag(), "Default engine is valid : %s", engine_id); + return VC_CONFIG_ERROR_NONE; + } + + GSList *iter = g_slist_nth(g_engine_list, 0); + if (NULL == iter) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] No engine in list"); + return -1; + } + + vc_engine_info_s *engine_info = static_cast(iter->data); + if (NULL == engine_info) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Engine info is NULL"); + return -1; + } + + if (NULL == engine_info->uuid) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Engine id is NULL"); + return -1; + } + + if (NULL == g_config_info) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Config info is NULL"); + return -1; + } + + if (NULL != g_config_info->engine_id) + free(g_config_info->engine_id); + + g_config_info->engine_id = strdup(engine_info->uuid); + + SLOG(LOG_DEBUG, vc_config_tag(), "Default engine is changed : %s", g_config_info->engine_id); + if (0 != vc_parser_set_engine(g_config_info->engine_id)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save config"); + return -1; + } + + return VC_ERROR_NONE; +} + +bool __vc_config_mgr_check_lang_is_valid(const char* engine_id, const char* language) +{ + if (NULL == engine_id || NULL == language) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL"); + return false; + } + + if (0 >= g_slist_length(g_engine_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine!!"); + return false; + } + + vc_engine_info_s *engine_info = __find_engine_info(engine_id); + if (NULL == engine_info) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", engine_id); + return false; + } + + bool is_language_valid = __is_language_valid(engine_info, language); + SLOG(LOG_INFO, vc_config_tag(), "[INFO] Language(%s), is valid(%d)", language, (int)is_language_valid); + + return is_language_valid; +} + +int __vc_config_mgr_select_lang(const char* engine_id, char** language) +{ + if (NULL == engine_id || NULL == language) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL"); + return VC_ERROR_OPERATION_FAILED; + } + + if (0 >= g_slist_length(g_engine_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine!!"); + return VC_ERROR_OPERATION_FAILED; + } + + vc_engine_info_s *engine_info = __find_engine_info(engine_id); + if (NULL == engine_info) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", engine_id); + return VC_ERROR_INVALID_PARAMETER; + } + + if (NULL == engine_info->default_lang) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] default language of engine info is NULL"); + return VC_CONFIG_ERROR_INVALID_LANGUAGE; + } + + *language = strdup(engine_info->default_lang); + if (NULL == *language) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate memory"); + return VC_CONFIG_ERROR_OUT_OF_MEMORY; + } + + SLOG(LOG_DEBUG, vc_config_tag(), "Selected language : %s", *language); + return VC_CONFIG_ERROR_NONE; +} + +int __vc_config_release_client(unsigned int uid) +{ + vc_config_client_s* temp_client = __find_client_info(uid); + + if (NULL != temp_client) { + g_config_client_list = g_slist_remove(g_config_client_list, temp_client); + free(temp_client); + } + + SLOG(LOG_DEBUG, vc_config_tag(), "Client count (%d)", g_slist_length(g_config_client_list)); + + return g_slist_length(g_config_client_list); +} + +void __vc_config_release_engine() +{ + GSList *iter = NULL; + vc_engine_info_s *engine_info = NULL; + + if (0 < g_slist_length(g_engine_list)) { + + /* Get a first item */ + iter = g_slist_nth(g_engine_list, 0); + + while (NULL != iter) { + engine_info = static_cast(iter->data); + + if (NULL != engine_info) { + g_engine_list = g_slist_remove(g_engine_list, engine_info); + + vc_parser_free_engine_info(engine_info); + } + + iter = g_slist_nth(g_engine_list, 0); + } + } + + return; +} + +int __vc_config_mgr_get_engine_info() +{ + DIR *dp = NULL; + struct dirent *dirp = NULL; + + char filepath[512] = {'\0',}; + int filesize; + vc_engine_info_s* info = NULL; + + SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] Release engine and Unregister engine config"); + + __vc_config_release_engine(); + g_engine_list = NULL; + __vc_config_mgr_unregister_engine_config_updated_event(); + + SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] default directory : %s", VC_DEFAULT_ENGINE_INFO); + + /* Copy default info directory to download directory */ + dp = opendir(VC_DEFAULT_ENGINE_INFO); + if (NULL == dp) { + SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] No default directory : %s", VC_DEFAULT_ENGINE_INFO); + } else { + do { + dirp = readdir(dp); + + if (NULL != dirp) { + if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name)) + continue; + + filesize = strlen(VC_DEFAULT_ENGINE_INFO) + strlen(dirp->d_name) + 2; + if (filesize >= 512) { + SECURE_SLOG(LOG_ERROR, vc_config_tag(), "[CONFIG ERROR] File path is too long : %s", dirp->d_name); + closedir(dp); + return -1; + } + + memset(filepath, '\0', 512); + snprintf(filepath, 512, "%s/%s", VC_DEFAULT_ENGINE_INFO, dirp->d_name); + + SECURE_SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] Filepath(%s)", filepath); + + char dest[512] = {'\0',}; + snprintf(dest, 512, "%s/%s", VC_DOWNLOAD_ENGINE_INFO, dirp->d_name); + + if (0 != access(dest, F_OK)) { + if (0 != vc_parser_copy_xml(filepath, dest)) { + SLOG(LOG_ERROR, vc_config_tag(), "[CONFIG ERROR] Fail to copy engine info"); + } + } + } + } while (NULL != dirp); + + closedir(dp); + } + + /* Get engine info from default engine directory */ + dp = opendir(VC_DOWNLOAD_ENGINE_INFO); + if (NULL == dp) { + SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] No downloadable directory : %s", VC_DOWNLOAD_ENGINE_INFO); + } else { + do { + dirp = readdir(dp); + + if (NULL != dirp) { + if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name)) + continue; + + filesize = strlen(VC_DOWNLOAD_ENGINE_INFO) + strlen(dirp->d_name) + 2; + if (filesize >= 512) { + SECURE_SLOG(LOG_ERROR, vc_config_tag(), "[CONFIG ERROR] File path is too long : %s", dirp->d_name); + closedir(dp); + return -1; + } + + memset(filepath, '\0', 512); + snprintf(filepath, 512, "%s/%s", VC_DOWNLOAD_ENGINE_INFO, dirp->d_name); + + SECURE_SLOG(LOG_DEBUG, vc_config_tag(), "[CONFIG] Filepath(%s)", filepath); + + if (0 == vc_parser_get_engine_info(filepath, &info)) { + g_engine_list = g_slist_append(g_engine_list, info); + if (0 != __vc_config_mgr_register_engine_config_updated_event(filepath)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to register engine config updated event"); + } + } + } + } while (NULL != dirp); + + closedir(dp); + } + + if (0 >= g_slist_length(g_engine_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] No engine"); + return -1; + } + + return VC_ERROR_NONE; +} + +static Eina_Bool __vc_config_mgr_engine_config_inotify_event_callback(void* data, Ecore_Fd_Handler *fd_handler) +{ + SLOG(LOG_DEBUG, vc_config_tag(), "@@@ Engine config updated callback event"); + ecore_thread_main_loop_begin(); + pthread_mutex_lock(&vc_config_mgr_mutex); + + vc_engine_inotify_s *ino = (vc_engine_inotify_s *)data; + int dir_fd = ino->dir_fd; + + int length; + struct inotify_event event; + memset(&event, '\0', sizeof(struct inotify_event)); + + length = read(dir_fd, &event, sizeof(struct inotify_event)); + if (0 > length) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty Inotify event"); + SLOG(LOG_DEBUG, vc_config_tag(), "@@@"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return ECORE_CALLBACK_DONE; + } + + if (IN_CLOSE_WRITE == event.mask) { + int ret = __vc_config_mgr_get_engine_info(); + if (0 != ret) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get engine info when config updated"); + } + __vc_config_mgr_print_engine_info(); + bool is_language_valid = vc_config_check_default_language_is_valid(g_config_info->language); + if (false == is_language_valid) { + SLOG(LOG_DEBUG, vc_config_tag(), "[ERROR] Default language is not valid"); + char* temp_lang = NULL; + ret = __vc_config_mgr_select_lang(g_config_info->engine_id, &temp_lang); + if (0 != ret) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get language"); + } + + ret = __vc_config_mgr_set_default_language(temp_lang); + if (0 != ret) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to set language"); + } else { + SLOG(LOG_DEBUG, vc_config_tag(), "[DEBUG] Saved default language : lang(%s)", g_config_info->language); + } + if (NULL != temp_lang) { + free(temp_lang); + temp_lang = NULL; + } + } + } else { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Undefined event"); + } + + SLOG(LOG_DEBUG, vc_config_tag(), "@@@"); + + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return ECORE_CALLBACK_PASS_ON; +} + +static int __vc_config_mgr_register_engine_config_updated_event(const char* path) +{ + if (NULL == path) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Path is NULL"); + return -1; + } + + /* For engine directory monitoring */ + vc_engine_inotify_s *ino = (vc_engine_inotify_s *)calloc(1, sizeof(vc_engine_inotify_s)); + if (NULL == ino) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate memory"); + return -1; + } + + ino->dir_fd = inotify_init(); + if (ino->dir_fd < 0) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to init inotify"); + free(ino); + ino = NULL; + + return -1; + } + + ino->dir_wd = inotify_add_watch(ino->dir_fd, path, IN_CLOSE_WRITE); + SLOG(LOG_DEBUG, vc_config_tag(), "Add inotify watch(%s)", path); + if (ino->dir_wd < 0) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to add watch"); + free(ino); + ino = NULL; + return -1; + } + + ino->dir_fd_handler = ecore_main_fd_handler_add(ino->dir_fd, ECORE_FD_READ, (Ecore_Fd_Cb)__vc_config_mgr_engine_config_inotify_event_callback, (void *)ino, NULL, NULL); + if (NULL == ino->dir_fd_handler) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to add fd handler"); + free(ino); + ino = NULL; + return -1; + } + + /* Set non-blocking mode of file */ + int value; + value = fcntl(ino->dir_fd, F_GETFL, 0); + value |= O_NONBLOCK; + + if (0 > fcntl(ino->dir_fd, F_SETFL, value)) { + SLOG(LOG_WARN, vc_config_tag(), "[WARNING] Fail to set non-block mode"); + } + + pthread_mutex_lock(&vc_config_engine_mutex); + g_ino_list = g_list_append(g_ino_list, ino); + pthread_mutex_unlock(&vc_config_engine_mutex); + + return VC_ERROR_NONE; +} + +static int __vc_config_mgr_unregister_engine_config_updated_event() +{ + pthread_mutex_lock(&vc_config_engine_mutex); + + /* delete all inotify variable */ + if (0 < g_list_length(g_ino_list)) { + GList *iter = NULL; + iter = g_list_first(g_ino_list); + + while (NULL != iter) { + vc_engine_inotify_s *tmp = static_cast(iter->data); + + if (NULL != tmp) { + ecore_main_fd_handler_del(tmp->dir_fd_handler); + inotify_rm_watch(tmp->dir_fd, tmp->dir_wd); + close(tmp->dir_fd); + + free(tmp); + tmp = NULL; + } + + g_ino_list = g_list_delete_link(g_ino_list, iter); + iter = g_list_first(g_ino_list); + } + } + pthread_mutex_unlock(&vc_config_engine_mutex); + return VC_ERROR_NONE; +} + +Eina_Bool vc_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler) +{ + SLOG(LOG_DEBUG, vc_config_tag(), "@@@ Config changed callback event"); + + if (g_fd_lang < 0) { + SLOG(LOG_WARN, vc_config_tag(), "[WARN] FD for config file is closed"); + SLOG(LOG_DEBUG, vc_config_tag(), "@@@"); + return ECORE_CALLBACK_PASS_ON; + } + + int length; + struct inotify_event event; + memset(&event, '\0', sizeof(struct inotify_event)); + + length = read(g_fd_lang, &event, sizeof(struct inotify_event)); + if (0 > length) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty Inotify event"); + SLOG(LOG_DEBUG, vc_config_tag(), "@@@"); + return ECORE_CALLBACK_PASS_ON; + } + + if (IN_CLOSE_WRITE == event.mask) { + int auto_lang = -1; + char* lang = NULL; + char* engine = NULL; + int enabled = -1; + + if (0 != vc_parser_find_config_changed(&auto_lang, &lang, &engine, &enabled)) + return ECORE_CALLBACK_PASS_ON; + + if (-1 != auto_lang) { + g_config_info->auto_lang = auto_lang; + } + + /* Only language changed */ + if (NULL != lang) { + char* before_lang = NULL; + + before_lang = strdup(g_config_info->language); + + if (NULL != g_config_info->language) free(g_config_info->language); + g_config_info->language = strdup(lang); + + /* Call all callbacks of client*/ + __vc_config_mgr_notify_language_changed(before_lang, lang); + + if (NULL != before_lang) free(before_lang); + free(lang); + lang = NULL; + } + + /* Only Engine changed */ + if (NULL != engine) { + + if (NULL != g_config_info->engine_id) { + free(g_config_info->engine_id); + g_config_info->engine_id = NULL; + } + g_config_info->engine_id = strdup(engine); + + /* Call all callbacks of client*/ + __vc_config_mgr_notify_engine_changed(engine); + free(engine); + engine = NULL; + } + + if (-1 != enabled) { + g_config_info->enabled = enabled; + + /* Call all callbacks of client*/ + __vc_config_mgr_notify_enabled_changed((bool)enabled); + } + } else { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Undefined event"); + } + + SLOG(LOG_DEBUG, vc_config_tag(), "@@@"); + + return ECORE_CALLBACK_PASS_ON; +} + +int __vc_config_set_auto_language() +{ + char candidate_lang[6] = {'\0', }; + char* value = NULL; + + value = vconf_get_str(VCONFKEY_LANGSET); + if (NULL == value) { + SLOG(LOG_ERROR, vc_config_tag(), "[Config ERROR] Fail to get display language"); + return -1; + } + + strncpy(candidate_lang, value, 5); + free(value); + + SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Display language : %s", candidate_lang); + + /* Check current config info */ + if (NULL == g_config_info) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Current config info is NULL"); + return VC_CONFIG_ERROR_OPERATION_FAILED; + } + + /* Check current language */ + if (NULL == g_config_info->language) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Current config language is NULL"); + return VC_CONFIG_ERROR_OPERATION_FAILED; + } + + if (0 == strncmp(g_config_info->language, candidate_lang, 5)) { + SLOG(LOG_DEBUG, vc_config_tag(), "[Config] VC language(%s) is same with display language", g_config_info->language); + return VC_ERROR_NONE; + } + + if (true == __vc_config_mgr_check_lang_is_valid(g_config_info->engine_id, candidate_lang)) { + /* vc default language change */ + char* before_lang = NULL; + if (0 != vc_parser_set_language(candidate_lang)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save default language"); + return -1; + } + + before_lang = strdup(g_config_info->language); + + free(g_config_info->language); + g_config_info->language = strdup(candidate_lang); + + SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Default language change : before(%s) current(%s)", + before_lang, g_config_info->language); + + /* Call all callbacks of client*/ + __vc_config_mgr_notify_language_changed(before_lang, g_config_info->language); + + if (NULL != before_lang) free(before_lang); + } else { + /* Candidate language is not valid */ + char* tmp_language = NULL; + if (0 != __vc_config_mgr_select_lang(g_config_info->engine_id, &tmp_language)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to select language"); + return -1; + } + + if (NULL == tmp_language) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Selected language is NULL"); + return -1; + } + + char* before_lang = NULL; + if (0 != vc_parser_set_language(tmp_language)) { + free(tmp_language); + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save config"); + return -1; + } + + before_lang = strdup(g_config_info->language); + + free(g_config_info->language); + g_config_info->language = strdup(tmp_language); + free(tmp_language); + + SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Default language change : before(%s) current(%s)", + before_lang, g_config_info->language); + + /* Call all callbacks of client*/ + __vc_config_mgr_notify_language_changed(before_lang, g_config_info->language); + + if (NULL != before_lang) free(before_lang); + } + + return VC_ERROR_NONE; +} + +void __vc_config_language_changed_cb(keynode_t *key, void *data) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + if (g_config_info && true == g_config_info->auto_lang) { + /* Get voice input vconf key */ + __vc_config_set_auto_language(); + } + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return; +} + +int vc_config_mgr_initialize(unsigned int uid) +{ + vc_config_client_s* temp_client = NULL; + + SLOG(LOG_INFO, vc_config_tag(), "[WARNING] Enter critical section"); + ecore_thread_main_loop_begin(); + pthread_mutex_lock(&vc_config_mgr_mutex); + + if (0 < g_slist_length(g_config_client_list)) { + /* Check uid */ + if (NULL != __find_client_info(uid)) { + SLOG(LOG_WARN, vc_config_tag(), "[CONFIG] uid(%u) has already registered", uid); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section"); + return VC_CONFIG_ERROR_NONE; + } + + temp_client = (vc_config_client_s*)calloc(1, sizeof(vc_config_client_s)); + if (NULL == temp_client) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate memory"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return VC_ERROR_OUT_OF_MEMORY; + } + + temp_client->uid = uid; + temp_client->engine_cb = NULL; + temp_client->lang_cb = NULL; + temp_client->enabled_cb = NULL; + + /* Add uid */ + g_config_client_list = g_slist_append(g_config_client_list, temp_client); + + SLOG(LOG_WARN, vc_config_tag(), "[CONFIG] Add uid(%u) but config has already initialized", uid); + + __vc_config_mgr_print_client_info(); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section"); + return VC_ERROR_NONE; + } + + /* Get file name from default engine directory */ + g_engine_list = NULL; + + if (0 != access(VC_CONFIG_BASE, F_OK)) { + if (0 != mkdir(VC_CONFIG_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to make directory : %s", VC_CONFIG_BASE); + __vc_config_release_client(uid); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return -1; + } else { + SLOG(LOG_DEBUG, vc_config_tag(), "Success to make directory : %s", VC_CONFIG_BASE); + } + } + if (0 != access(VC_RUNTIME_INFO_ROOT, F_OK)) { + if (0 != mkdir(VC_RUNTIME_INFO_ROOT, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to make directory : %s", VC_RUNTIME_INFO_ROOT); + __vc_config_release_client(uid); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return -1; + } else { + SLOG(LOG_DEBUG, vc_config_tag(), "Success to make directory : %s", VC_RUNTIME_INFO_ROOT); + } + } + + if (0 != access(VC_DOWNLOAD_BASE, F_OK)) { + if (0 != mkdir(VC_DOWNLOAD_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to make directory : %s", VC_DOWNLOAD_BASE); + __vc_config_release_client(uid); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return -1; + } else { + SLOG(LOG_DEBUG, vc_config_tag(), "Success to make directory : %s", VC_DOWNLOAD_BASE); + } + } + if (0 != access(VC_DOWNLOAD_ENGINE_INFO, F_OK)) { + if (0 != mkdir(VC_DOWNLOAD_ENGINE_INFO, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to make directory : %s", VC_DOWNLOAD_ENGINE_INFO); + __vc_config_release_client(uid); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return -1; + } else { + SLOG(LOG_DEBUG, vc_config_tag(), "Success to make directory : %s", VC_DOWNLOAD_ENGINE_INFO); + } + } + + if (0 != __vc_config_mgr_get_engine_info()) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get engine info"); + __vc_config_release_client(uid); + __vc_config_release_engine(); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return VC_CONFIG_ERROR_ENGINE_NOT_FOUND; + } + + __vc_config_mgr_print_engine_info(); + + if (0 != vc_parser_load_config(&g_config_info)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to parse configure information"); + __vc_config_release_client(uid); + __vc_config_release_engine(); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return -1; + } + + if (0 != __vc_config_mgr_check_engine_is_valid(g_config_info->engine_id)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get default engine"); + __vc_config_release_client(uid); + __vc_config_release_engine(); + vc_parser_unload_config(g_config_info); + g_config_info = NULL; + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return VC_CONFIG_ERROR_ENGINE_NOT_FOUND; + } + + if (true == g_config_info->auto_lang) { + /* Check language with display language */ + __vc_config_set_auto_language(); + } else { + if (false == __vc_config_mgr_check_lang_is_valid(g_config_info->engine_id, g_config_info->language)) { + /* Default language is not valid */ + char* tmp_language; + if (0 != __vc_config_mgr_select_lang(g_config_info->engine_id, &tmp_language)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to select language"); + __vc_config_release_client(uid); + __vc_config_release_engine(); + vc_parser_unload_config(g_config_info); + g_config_info = NULL; + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return -1; + } + + if (NULL != tmp_language) { + if (NULL != g_config_info->language) { + free(g_config_info->language); + g_config_info->language = strdup(tmp_language); + } + + if (0 != vc_parser_set_language(tmp_language)) { + free(tmp_language); + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save config"); + __vc_config_release_client(uid); + __vc_config_release_engine(); + vc_parser_unload_config(g_config_info); + g_config_info = NULL; + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return -1; + } + + free(tmp_language); + } + } + } + + /* print daemon config */ + SLOG(LOG_DEBUG, vc_config_tag(), "@ Daemon config @"); + SLOG(LOG_DEBUG, vc_config_tag(), " engine : %s", g_config_info->engine_id); + SLOG(LOG_DEBUG, vc_config_tag(), " auto language : %s", g_config_info->auto_lang ? "on" : "off"); + SLOG(LOG_DEBUG, vc_config_tag(), " language : %s", g_config_info->language); + SLOG(LOG_DEBUG, vc_config_tag(), "@@@@"); + + g_lang_ref_count = 0; + + /* Register to detect display language change */ + vconf_notify_key_changed(VCONFKEY_LANGSET, __vc_config_language_changed_cb, NULL); + + temp_client = (vc_config_client_s*)calloc(1, sizeof(vc_config_client_s)); + if (NULL == temp_client) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate memory"); + __vc_config_release_client(uid); + __vc_config_release_engine(); + vc_parser_unload_config(g_config_info); + g_config_info = NULL; + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return VC_ERROR_OUT_OF_MEMORY; + } + + temp_client->uid = uid; + temp_client->engine_cb = NULL; + temp_client->lang_cb = NULL; + temp_client->enabled_cb = NULL; + + SLOG(LOG_DEBUG, vc_config_tag(), "uid(%u) temp_uid(%u)", uid, temp_client->uid); + + /* Add uid */ + g_config_client_list = g_slist_append(g_config_client_list, temp_client); + + __vc_config_mgr_print_client_info(); + + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section"); + return VC_ERROR_NONE; +} + +int vc_config_mgr_finalize(unsigned int uid) +{ + SLOG(LOG_INFO, vc_config_tag(), "[WARNING] Enter critical section"); + + pthread_mutex_lock(&vc_config_mgr_mutex); + + if (0 < __vc_config_release_client(uid)) { + pthread_mutex_unlock(&vc_config_mgr_mutex); + SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section"); + + return VC_ERROR_NONE; + } + + __vc_config_release_engine(); + + __vc_config_mgr_unregister_engine_config_updated_event(); + + vconf_ignore_key_changed(VCONFKEY_LANGSET, __vc_config_language_changed_cb); + + vc_parser_unload_config(g_config_info); + g_config_info = NULL; + + pthread_mutex_unlock(&vc_config_mgr_mutex); + SLOG(LOG_DEBUG, vc_config_tag(), "[WARNING] Leave critical section"); + + SLOG(LOG_DEBUG, vc_config_tag(), "[Success] Finalize config"); + return VC_ERROR_NONE; +} + + +int __vc_config_mgr_register_lang_event() +{ + if (0 == g_lang_ref_count) { + /* get file notification handler */ + int fd; + int wd; + + fd = inotify_init(); + if (fd < 0) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail get inotify fd"); + return -1; + } + g_fd_lang = fd; + + wd = inotify_add_watch(fd, VC_CONFIG, IN_CLOSE_WRITE); + g_wd_lang = wd; + + g_fd_handler_lang = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)vc_config_mgr_inotify_event_cb, NULL, NULL, NULL); + if (NULL == g_fd_handler_lang) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get handler_noti"); + return -1; + } + + /* Set non-blocking mode of file */ + int value; + value = fcntl(fd, F_GETFL, 0); + value |= O_NONBLOCK; + + if (0 > fcntl(fd, F_SETFL, value)) { + SLOG(LOG_WARN, vc_config_tag(), "[WARNING] Fail to set non-block mode"); + } + } + g_lang_ref_count++; + + return VC_ERROR_NONE; +} + +int __vc_config_mgr_unregister_config_event() +{ + if (0 == g_lang_ref_count) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Lang ref count is 0"); + return VC_CONFIG_ERROR_INVALID_STATE; + } + + g_lang_ref_count--; + if (0 == g_lang_ref_count) { + /* delete inotify variable */ + ecore_main_fd_handler_del(g_fd_handler_lang); + inotify_rm_watch(g_fd_lang, g_wd_lang); + close(g_fd_lang); + g_fd_handler_lang = NULL; + g_fd_lang = -1; + + vconf_ignore_key_changed(VCONFKEY_LANGSET, __vc_config_language_changed_cb); + } + + return VC_ERROR_NONE; +} + +int vc_config_mgr_set_engine_cb(unsigned int uid, vc_config_engine_changed_cb engine_cb) +{ + ecore_thread_main_loop_begin(); + pthread_mutex_lock(&vc_config_mgr_mutex); + + /* Call all callbacks of client*/ + vc_config_client_s* temp_client = __find_client_info(uid); + if (NULL == temp_client) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Uid is not valid (%u)", uid); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return VC_CONFIG_ERROR_INVALID_PARAMETER; + } + + temp_client->engine_cb = engine_cb; + if (VC_CONFIG_ERROR_NONE != __vc_config_mgr_register_lang_event()) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to register config event"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return VC_CONFIG_ERROR_OPERATION_FAILED; + } + + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return VC_ERROR_NONE; +} + +int vc_config_mgr_unset_engine_cb(unsigned int uid) +{ + ecore_thread_main_loop_begin(); + pthread_mutex_lock(&vc_config_mgr_mutex); + + /* Call all callbacks of client*/ + vc_config_client_s* temp_client = __find_client_info(uid); + if (NULL == temp_client) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Uid is not valid (%u)", uid); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return VC_CONFIG_ERROR_INVALID_PARAMETER; + } + + temp_client->engine_cb = NULL; + __vc_config_mgr_unregister_config_event(); + + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return VC_ERROR_NONE; +} + + +int vc_config_mgr_set_lang_cb(unsigned int uid, vc_config_lang_changed_cb lang_cb) +{ + ecore_thread_main_loop_begin(); + pthread_mutex_lock(&vc_config_mgr_mutex); + + /* Call all callbacks of client*/ + vc_config_client_s* temp_client = __find_client_info(uid); + if (NULL == temp_client) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Uid is not valid (%u)", uid); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return VC_CONFIG_ERROR_INVALID_PARAMETER; + } + + temp_client->lang_cb = lang_cb; + if (0 != __vc_config_mgr_register_lang_event()) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to register config event"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return VC_CONFIG_ERROR_OPERATION_FAILED; + } + + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return VC_ERROR_NONE; +} + +int vc_config_mgr_unset_lang_cb(unsigned int uid) +{ + ecore_thread_main_loop_begin(); + pthread_mutex_lock(&vc_config_mgr_mutex); + + /* Call all callbacks of client*/ + vc_config_client_s* temp_client = __find_client_info(uid); + if (NULL == temp_client) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Uid is not valid (%u)", uid); + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return VC_CONFIG_ERROR_INVALID_PARAMETER; + } + + temp_client->lang_cb = NULL; + __vc_config_mgr_unregister_config_event(); + + pthread_mutex_unlock(&vc_config_mgr_mutex); + ecore_thread_main_loop_end(); + return VC_ERROR_NONE; +} + +int vc_config_mgr_set_enabled_cb(unsigned int uid, vc_config_enabled_cb enabled_cb) +{ + if (NULL == enabled_cb) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] enabled cb is NULL : uid(%u) ", uid); + return VC_CONFIG_ERROR_INVALID_PARAMETER; + } + + pthread_mutex_lock(&vc_config_mgr_mutex); + + /* Call all callbacks of client*/ + vc_config_client_s* temp_client = __find_client_info(uid); + if (NULL == temp_client) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Uid is not valid (%u)", uid); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_INVALID_PARAMETER; + } + + temp_client->enabled_cb = enabled_cb; + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_NONE; +} + +int vc_config_mgr_unset_enabled_cb(unsigned int uid) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + + /* Call all callbacks of client*/ + vc_config_client_s* temp_client = __find_client_info(uid); + if (NULL == temp_client) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Uid is not valid (%u)", uid); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_INVALID_PARAMETER; + } + + temp_client->enabled_cb = NULL; + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_ERROR_NONE; +} + +int vc_config_mgr_get_auto_language(bool* value) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + if (NULL == value) { + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + *value = g_config_info->auto_lang; + pthread_mutex_unlock(&vc_config_mgr_mutex); + + return VC_ERROR_NONE; +} + +int vc_config_mgr_set_auto_language(bool value) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + if (g_config_info->auto_lang != value) { + /* Check language is valid */ + if (0 != vc_parser_set_auto_lang(value)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save engine id"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + g_config_info->auto_lang = value; + + if (true == g_config_info->auto_lang) { + __vc_config_set_auto_language(); + } + } + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_ERROR_NONE; +} + +int vc_config_mgr_get_engine_list(vc_config_supported_engine_cb callback, void* user_data) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "Not initialized"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_INVALID_STATE; + } + + if (NULL == callback) { + SLOG(LOG_ERROR, vc_config_tag(), " callback is NULL"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_INVALID_PARAMETER; + } + + GSList *iter = NULL; + vc_engine_info_s *engine_info = NULL; + + if (0 >= g_slist_length(g_engine_list)) { + SLOG(LOG_WARN, vc_config_tag(), "[ERROR] Engine list is NULL"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_ENGINE_NOT_FOUND; + } + + /* Get a first item */ + iter = g_slist_nth(g_engine_list, 0); + + while (NULL != iter) { + engine_info = static_cast(iter->data); + + if (NULL == engine_info) { + SLOG(LOG_ERROR, vc_config_tag(), " Engine info is NULL"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_OPERATION_FAILED; + } + + if (false == callback(engine_info->name, engine_info->uuid, engine_info->setting, engine_info->default_lang, engine_info->non_fixed_support, user_data)) + break; + + iter = g_slist_next(iter); + } + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_NONE; +} + + +int vc_config_mgr_get_engine(char** engine) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "Not initialized"); //LCOV_EXCL_LINE + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_INVALID_STATE; + } + + if (NULL == engine) { + SLOG(LOG_ERROR, vc_config_tag(), "Parameter is NULL"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_INVALID_PARAMETER; + } + + if (NULL != g_config_info->engine_id) { + *engine = strdup(g_config_info->engine_id); + } else { + SLOG(LOG_ERROR, vc_config_tag(), " Engine id is NULL"); //LCOV_EXCL_LINE + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_ENGINE_NOT_FOUND; + } + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_NONE; +} + +int __vc_config_set_buxtonkey(const char* engine) +{ + /* Set vconfkey */ + struct buxton_client * bux_cli; + struct buxton_layer * bux_layer; + struct buxton_value * bux_val; + + int ret = buxton_open(&bux_cli, NULL, NULL); + if (0 != ret) { + SLOG(LOG_ERROR, vc_config_tag(), "[DBUS-BUXTON2] Fail to open buxton client, ret(%d)", ret); + return VC_CONFIG_ERROR_OPERATION_FAILED; + } + bux_layer = buxton_create_layer("system"); + if (NULL == bux_layer) { + SLOG(LOG_ERROR, vc_config_tag(), "[DBUS-BUXTON2] buxton_create_layer FAIL"); + buxton_close(bux_cli); + bux_cli = NULL; + return VC_CONFIG_ERROR_OPERATION_FAILED; + } + bux_val = buxton_value_create_string(engine); + if (NULL == bux_val) { + SLOG(LOG_ERROR, vc_config_tag(), "[DBUS-BUXTON2] buxton_value_create_string FAIL"); + buxton_free_layer(bux_layer); + buxton_close(bux_cli); + bux_layer = NULL; + bux_cli = NULL; + return VC_CONFIG_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, vc_config_tag(), "[DBUS-BUXTON2] layer: %s", buxton_layer_get_name(bux_layer)); + } + + ret = buxton_set_value_sync(bux_cli, bux_layer, VC_ENGINE_DB_DEFAULT, bux_val); + if (0 != ret) { + SLOG(LOG_ERROR, vc_config_tag(), "[DBUS-BUXTON2] Fail to set value sync, ret(%d)", ret); + buxton_value_free(bux_val); + buxton_free_layer(bux_layer); + buxton_close(bux_cli); + + bux_cli = NULL; + bux_layer = NULL; + bux_val = NULL; + return VC_CONFIG_ERROR_OPERATION_FAILED; + } + SLOG(LOG_DEBUG, vc_config_tag(), "[DBUS-BUXTON2] buxton_set_value_sync: %s", VC_ENGINE_DB_DEFAULT); + + buxton_value_free(bux_val); + buxton_free_layer(bux_layer); + buxton_close(bux_cli); + + bux_cli = NULL; + bux_layer = NULL; + bux_val = NULL; + + return VC_CONFIG_ERROR_NONE; +} + +int vc_config_mgr_set_engine(const char* engine) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "Not initialized"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_INVALID_STATE; + } + + if (NULL == g_config_info) { + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_OPERATION_FAILED; + } + + if (NULL == engine || NULL == g_config_info->engine_id) { + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_INVALID_PARAMETER; + } + + /* Check current engine id with new engine id */ + if (0 == strncmp(g_config_info->engine_id, engine, strlen(g_config_info->engine_id))) { + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_NONE; + } + + SLOG(LOG_DEBUG, vc_config_tag(), "New engine id : %s", engine); + + int ret = __vc_config_set_buxtonkey(engine); + if (0 != ret) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] set buxtonkey Failed!!!"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return ret; + } + + vc_engine_info_s *engine_info = __find_engine_info(engine); + if (NULL == engine_info) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", engine); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_INVALID_PARAMETER; + } + + free(g_config_info->engine_id); + g_config_info->engine_id = strdup(engine_info->uuid); + + /* Engine is valid*/ + bool is_language_valid = __is_language_valid(engine_info, g_config_info->language); + SLOG(LOG_ERROR, vc_config_tag(), "[INFO] Language(%s), is valid(%d)", g_config_info->language, (int)is_language_valid); + + char* lang = NULL; + if (false == is_language_valid) { + free(g_config_info->language); + g_config_info->language = NULL; + + GSList *iter_lang = g_slist_nth(engine_info->languages, 0); + if (NULL == iter_lang || NULL == iter_lang->data) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get default language. Engine id(%s) is not valid", engine); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_OPERATION_FAILED; + } + + lang = static_cast(iter_lang->data); + g_config_info->language = strdup(lang); + } + + SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Engine changed"); + SLOG(LOG_DEBUG, vc_config_tag(), "Engine : %s", g_config_info->engine_id); + SLOG(LOG_DEBUG, vc_config_tag(), "Auto lang : %s", g_config_info->auto_lang ? "true" : "false"); + SLOG(LOG_DEBUG, vc_config_tag(), "Language : %s", g_config_info->language); + SLOG(LOG_DEBUG, vc_config_tag(), "Enabled : %s", g_config_info->enabled ? "true" : "false"); + + if (0 != vc_parser_set_engine(g_config_info->engine_id)) { + SLOG(LOG_ERROR, vc_config_tag(), " Fail to save config"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_OPERATION_FAILED; + } + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_NONE; +} + +int vc_config_mgr_get_language_list(vc_supported_language_cb callback, void* user_data) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + if (0 >= g_slist_length(g_engine_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + vc_engine_info_s *engine_info = __find_engine_info(g_config_info->engine_id); + if (NULL == engine_info) { + SLOG(LOG_ERROR, vc_config_tag(), "Fail to find engine information : %s", g_config_info->engine_id); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_NONE; + } + + /* Get a first item */ + GSList *iter_lang = g_slist_nth(engine_info->languages, 0); + + while (NULL != iter_lang) { + /*Get handle data from list*/ + char* lang = static_cast(iter_lang->data); + + SLOG(LOG_INFO, vc_config_tag(), "lang(%s)", lang); + if (NULL != lang) { + if (false == callback(lang, user_data)) + break; + } + + /*Get next item*/ + iter_lang = g_slist_next(iter_lang); + } + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_ERROR_NONE; +} + +int vc_config_mgr_get_default_language(char** language) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + if (NULL == language) { + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + if (NULL != g_config_info->language) { + *language = strdup(g_config_info->language); + } else { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] language is NULL"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_ERROR_NONE; +} + +static int __vc_config_mgr_set_default_language(const char* language) +{ + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); + return -1; + } + + if (NULL == language) { + return -1; + } + + /* Check language is valid */ + if (NULL != g_config_info->language) { + if (0 != vc_parser_set_language(language)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save engine id"); + return -1; + } + free(g_config_info->language); + g_config_info->language = strdup(language); + } else { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] language is NULL"); + return -1; + } + + return VC_ERROR_NONE; +} + +int vc_config_mgr_set_default_language(const char* language) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + int ret = __vc_config_mgr_set_default_language(language); + pthread_mutex_unlock(&vc_config_mgr_mutex); + + return ret; +} + +int vc_config_mgr_get_enabled(bool* value) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + if (NULL == value) { + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + *value = g_config_info->enabled; + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_ERROR_NONE; +} + +int vc_config_mgr_set_enabled(bool value) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + if (0 != vc_parser_set_enabled(value)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to set enabled"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + g_config_info->enabled = value; + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_ERROR_NONE; +} + +int vc_config_mgr_get_nonfixed_support(bool* value) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + if (NULL == value) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + if (0 >= g_slist_length(g_engine_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + if (NULL == g_config_info || NULL == g_config_info->engine_id) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Engine ID is not set in global config!!"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_ENGINE_NOT_FOUND; + } + + vc_engine_info_s *engine_info = __find_engine_info(g_config_info->engine_id); + if (NULL == engine_info) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", g_config_info->engine_id); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_CONFIG_ERROR_ENGINE_NOT_FOUND; + }; + + *value = engine_info->non_fixed_support; + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return VC_ERROR_NONE; +} + +bool vc_config_check_default_engine_is_valid(const char* engine) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + if (NULL == engine) { + pthread_mutex_unlock(&vc_config_mgr_mutex); + return false; + } + + if (0 >= g_slist_length(g_engine_list)) { + pthread_mutex_unlock(&vc_config_mgr_mutex); + return false; + } + + vc_engine_info_s *engine_info = __find_engine_info(engine); + if (NULL == engine_info) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", engine); + }; + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return (NULL != engine_info); +} + +bool vc_config_check_default_language_is_valid(const char* language) +{ + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); + return -1; + } + + if (NULL == language) { + return false; + } + + if (NULL == g_config_info->engine_id) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Default engine id is NULL"); + return false; + } + + if (0 >= g_slist_length(g_engine_list)) { + return false; + } + + vc_engine_info_s *engine_info = __find_engine_info(g_config_info->engine_id); + if (NULL == engine_info) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine with id (%s)!!", g_config_info->engine_id); + return false; + }; + + bool is_language_valid = __is_language_valid(engine_info, language); + SLOG(LOG_INFO, vc_config_tag(), "[INFO] Language(%s), is valid(%d)", language, (int)is_language_valid); + + return is_language_valid; +} + +int vc_config_mgr_set_foreground(int pid, bool value) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return vc_parser_set_foreground(pid, value); +} + +int vc_config_mgr_get_foreground(int* pid) +{ + pthread_mutex_lock(&vc_config_mgr_mutex); + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Not initialized"); + pthread_mutex_unlock(&vc_config_mgr_mutex); + return -1; + } + + pthread_mutex_unlock(&vc_config_mgr_mutex); + return vc_parser_get_foreground(pid); +} + +int __vc_config_mgr_print_engine_info() +{ + GSList *iter = NULL; + vc_engine_info_s *engine_info = NULL; + + if (0 >= g_slist_length(g_engine_list)) { + SLOG(LOG_DEBUG, vc_config_tag(), "@ engine list @"); + SLOG(LOG_DEBUG, vc_config_tag(), " No Engine in engine directory"); + SLOG(LOG_DEBUG, vc_config_tag(), "@@@@"); + return VC_ERROR_NONE; + } + + /* Get a first item */ + iter = g_slist_nth(g_engine_list, 0); + + SLOG(LOG_DEBUG, vc_config_tag(), "@ engine list @"); + + int i = 1; + while (NULL != iter) { + engine_info = static_cast(iter->data); + + SLOG(LOG_DEBUG, vc_config_tag(), "[%dth]", i); + SLOG(LOG_DEBUG, vc_config_tag(), " name : %s", engine_info->name); + SLOG(LOG_DEBUG, vc_config_tag(), " id : %s", engine_info->uuid); + + + SLOG(LOG_DEBUG, vc_config_tag(), " languages"); + GSList *iter_lang = NULL; + char* lang; + if (g_slist_length(engine_info->languages) > 0) { + /* Get a first item */ + iter_lang = g_slist_nth(engine_info->languages, 0); + + int j = 1; + while (NULL != iter_lang) { + /*Get handle data from list*/ + lang = static_cast(iter_lang->data); + + SLOG(LOG_DEBUG, vc_config_tag(), " [%dth] %s", j, lang); + + /*Get next item*/ + iter_lang = g_slist_next(iter_lang); + j++; + } + } else { + SLOG(LOG_DEBUG, vc_config_tag(), " language is NONE"); + } + iter = g_slist_next(iter); + i++; + } + SLOG(LOG_DEBUG, vc_config_tag(), "@@@@"); + + return VC_ERROR_NONE; +} + +int __vc_config_mgr_print_client_info() +{ + GSList *iter = NULL; + vc_config_client_s* temp_client = NULL; + + if (0 >= g_slist_length(g_config_client_list)) { + SLOG(LOG_DEBUG, vc_config_tag(), "@ Client list @"); + SLOG(LOG_DEBUG, vc_config_tag(), " No Client"); + SLOG(LOG_DEBUG, vc_config_tag(), "@@@@"); + return VC_ERROR_NONE; + } + + /* Get a first item */ + iter = g_slist_nth(g_config_client_list, 0); + + SLOG(LOG_DEBUG, vc_config_tag(), "@ Client list @"); + + int i = 1; + while (NULL != iter) { + temp_client = static_cast(iter->data); + + SLOG(LOG_DEBUG, vc_config_tag(), "[%dth] uid(%u)", i, temp_client->uid); + + iter = g_slist_next(iter); + i++; + } + SLOG(LOG_DEBUG, vc_config_tag(), "@@@@"); + + return VC_ERROR_NONE; +} diff --git a/common/vc_config_parser.c b/common/vc_config_parser.c index cf7e088..6fb18d0 100644 --- a/common/vc_config_parser.c +++ b/common/vc_config_parser.c @@ -45,7 +45,10 @@ #define VC_TAG_INFO_FOREGROUND "foreground_pid" -extern char* vc_config_tag(); +static const char* vc_config_tag() +{ + return TAG_VCCONFIG; +} static xmlDocPtr g_config_doc = NULL; diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 399781c..39c61dc 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -2,7 +2,7 @@ SET(SRCS ../common/vc_cmd_db.c ../common/vc_command_util.c ../common/vc_command.c - ../common/vc_config_mgr.c + ../common/vc_config_mgr.cpp ../common/vc_config_parser.c ../common/vc_info_parser.c ../common/vc_json_parser.c