From 5f577ce27531836497ce18f41cd409a011725562 Mon Sep 17 00:00:00 2001 From: "stom.hwang" Date: Thu, 14 Jul 2016 16:57:54 +0900 Subject: [PATCH 01/16] Fix - Coding rule Change-Id: I86fdafc6db812191d809a7903f7e1748f073f545 Signed-off-by: stom.hwang --- client/vc.c | 2 +- client/vc_mgr.c | 2 +- client/vc_mgr_dbus.c | 3 +-- common/vc_command.c | 6 +++--- common/vc_info_parser.c | 22 +++++++++++----------- include/voice_control_manager.h | 2 +- include/voice_control_plugin_engine.h | 2 +- server/vcd_recorder.c | 6 ++---- server/vcd_server.c | 14 +++++++------- 9 files changed, 28 insertions(+), 31 deletions(-) diff --git a/client/vc.c b/client/vc.c index 7410708..7ddecc3 100644 --- a/client/vc.c +++ b/client/vc.c @@ -133,7 +133,7 @@ static int __vc_check_privilege() SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Permission is denied"); return VC_ERROR_PERMISSION_DENIED; } else if (-1 == g_privilege_allowed) { - if (false == __check_privilege_initialize()){ + if (false == __check_privilege_initialize()) { SLOG(LOG_ERROR, TAG_VCC, "[ERROR] privilege initialize is failed"); return VC_ERROR_PERMISSION_DENIED; } diff --git a/client/vc_mgr.c b/client/vc_mgr.c index 0623886..e3a2f21 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -1497,7 +1497,7 @@ int vc_mgr_get_nlp_info(char** info) int vc_mgr_set_pre_result_cb(vc_mgr_pre_result_cb callback, void* user_data) { - if (NULL == callback){ + if (NULL == callback) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set error callback : callback is NULL"); return VC_ERROR_INVALID_PARAMETER; } diff --git a/client/vc_mgr_dbus.c b/client/vc_mgr_dbus.c index 40f345e..93f4efd 100644 --- a/client/vc_mgr_dbus.c +++ b/client/vc_mgr_dbus.c @@ -240,8 +240,7 @@ static Eina_Bool vc_mgr_listener_event_callback(void* data, Ecore_Fd_Handler *fd if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr Get Error message : Get arguments error (%s)", err.message); dbus_error_free(&err); - } - else { + } else { SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr Get Error message : reason(%d), daemon_pid(%d), msg(%s)", reason, daemon_pid, err_msg); __vc_mgr_cb_error(reason, daemon_pid, err_msg); } diff --git a/common/vc_command.c b/common/vc_command.c index c42e84e..ef433d4 100644 --- a/common/vc_command.c +++ b/common/vc_command.c @@ -110,13 +110,13 @@ static void __check_privilege_deinitialize() static int __vc_cmd_check_privilege() { - char uid[16]; + char uid[16]; if (0 == g_privilege_allowed) { SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Permission is denied"); return VC_ERROR_PERMISSION_DENIED; } else if (-1 == g_privilege_allowed) { - if (false == __check_privilege_initialize()){ + if (false == __check_privilege_initialize()) { SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] privilege initialize is failed"); return VC_ERROR_PERMISSION_DENIED; } @@ -454,7 +454,7 @@ int vc_cmd_list_filter_by_type(vc_cmd_list_h original, int type, vc_cmd_list_h* if (NULL != iter_cmd) { int iter_type; if (0 != vc_cmd_get_type((vc_cmd_h)iter_cmd, &iter_type)) { - SLOG(LOG_ERROR,TAG_VCCMD, "[ERROR] Fail to get command type"); + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get command type"); continue; } diff --git a/common/vc_info_parser.c b/common/vc_info_parser.c index 3b6095b..1f098f1 100644 --- a/common/vc_info_parser.c +++ b/common/vc_info_parser.c @@ -1278,19 +1278,19 @@ int vc_info_parser_get_nlp_info(char** nlp_info) } SLOG(LOG_DEBUG, vc_info_tag(), "[DEBUG] buffer size (%d)", readn); - if (10000000 < readn || 0 > readn) { - SLOG(LOG_DEBUG, vc_info_tag(), "[ERROR] Invalid buffer size"); - fclose(fp); - return -1; - } - int tmp_readn = readn + 10; + if (10000000 < readn || 0 > readn) { + SLOG(LOG_DEBUG, vc_info_tag(), "[ERROR] Invalid buffer size"); + fclose(fp); + return -1; + } + int tmp_readn = readn + 10; *nlp_info = (char*)calloc(tmp_readn, sizeof(char)); - if (NULL == *nlp_info) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Out of memory"); - fclose(fp); - return -1; - } + if (NULL == *nlp_info) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Out of memory"); + fclose(fp); + return -1; + } readn = fread(*nlp_info, 1, readn, fp); fclose(fp); diff --git a/include/voice_control_manager.h b/include/voice_control_manager.h index 6cb1829..e6d80a4 100644 --- a/include/voice_control_manager.h +++ b/include/voice_control_manager.h @@ -117,7 +117,7 @@ typedef enum { VC_PRE_RESULT_EVENT_FINAL_RESULT = 0, VC_PRE_RESULT_EVENT_PARTIAL_RESULT, VC_PRE_RESULT_EVENT_ERROR -}vc_pre_result_event_e; +} vc_pre_result_event_e; // support pre-result typedef bool(*vc_mgr_pre_result_cb)(vc_pre_result_event_e event, const char* result, void *user_data); diff --git a/include/voice_control_plugin_engine.h b/include/voice_control_plugin_engine.h index c4322ea..0524a8c 100644 --- a/include/voice_control_plugin_engine.h +++ b/include/voice_control_plugin_engine.h @@ -127,7 +127,7 @@ typedef enum { VCP_PRE_RESULT_EVENT_FINAL_RESULT = 0, VCP_PRE_RESULT_EVENT_PARTIAL_RESULT, VCP_PRE_RESULT_EVENT_ERROR -}vcp_pre_result_event_e; +} vcp_pre_result_event_e; // Add new typedef void (*vcpe_pre_result_cb)(vcp_pre_result_event_e event, const char* pre_result, void *user_data); diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index 5e7f0d0..4996cea 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -542,8 +542,7 @@ int vcd_recorder_start() g_bt_extend_count = 0; #endif - } - else if (0 == strncmp(VCP_AUDIO_ID_MSF, g_current_audio_type, strlen(VCP_AUDIO_ID_MSF))) { + } else if (0 == strncmp(VCP_AUDIO_ID_MSF, g_current_audio_type, strlen(VCP_AUDIO_ID_MSF))) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder] call RegisterMSFAudioCallback() function"); #ifdef TV_MSF_WIFI_MODE @@ -633,8 +632,7 @@ int vcd_recorder_stop() return VCD_ERROR_OPERATION_FAILED; } #endif - } - else if (0 == strncmp(VCP_AUDIO_ID_MSF, g_current_audio_type, strlen(VCP_AUDIO_ID_MSF))) { + } else if (0 == strncmp(VCP_AUDIO_ID_MSF, g_current_audio_type, strlen(VCP_AUDIO_ID_MSF))) { #ifdef TV_MSF_WIFI_MODE UnRegisterMSFAudioCallback(); stoped = true; diff --git a/server/vcd_server.c b/server/vcd_server.c index 748e548..e8ea19e 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -257,13 +257,13 @@ static Eina_Bool __vcd_send_selected_result(void *data) static int __convert_type_to_priority(vc_cmd_type_e type) { switch (type) { - case VC_COMMAND_TYPE_NONE: return 0; - case VC_COMMAND_TYPE_BACKGROUND: return 1; - case VC_COMMAND_TYPE_FOREGROUND: return 2; - case VC_COMMAND_TYPE_WIDGET: return 2; - case VC_COMMAND_TYPE_SYSTEM: return 3; - case VC_COMMAND_TYPE_EXCLUSIVE: return 3; - default: return 0; + case VC_COMMAND_TYPE_NONE: return 0; + case VC_COMMAND_TYPE_BACKGROUND: return 1; + case VC_COMMAND_TYPE_FOREGROUND: return 2; + case VC_COMMAND_TYPE_WIDGET: return 2; + case VC_COMMAND_TYPE_SYSTEM: return 3; + case VC_COMMAND_TYPE_EXCLUSIVE: return 3; + default: return 0; } } -- 2.7.4 From b546aeb3fac61f5798ebec3258aac3b3eb3be21b Mon Sep 17 00:00:00 2001 From: Kwangyoun Kim Date: Wed, 3 Aug 2016 17:37:34 +0900 Subject: [PATCH 02/16] Fix bug about privilege check Add dbus error handling Support MSF/BT audio recording policy Change-Id: I0852ef36e220d79757545a91ed214fec007b03c8 --- client/vc.c | 215 ++++++++------------------------------------------ client/vc_dbus.c | 57 +++++++++++++ common/vc_command.c | 5 +- server/vcd_recorder.c | 16 +++- 4 files changed, 103 insertions(+), 190 deletions(-) diff --git a/client/vc.c b/client/vc.c index 7ddecc3..b2e86fc 100644 --- a/client/vc.c +++ b/client/vc.c @@ -42,11 +42,6 @@ static int g_feature_enabled = -1; static int g_privilege_allowed = -1; static cynara *p_cynara = NULL; -#if 0 -static Ecore_Event_Handler* g_focus_in_hander = NULL; -static Ecore_Event_Handler* g_focus_out_hander = NULL; -#endif - Eina_Bool __vc_notify_state_changed(void *data); Eina_Bool __vc_notify_error(void *data); @@ -92,13 +87,14 @@ static int __check_privilege_initialize() static int __check_privilege(const char* uid, const char * privilege) { FILE *fp = NULL; - char smack_label[1024] = "/proc/self/attr/current"; + char label_path[1024] = "/proc/self/attr/current"; + char smack_label[1024] = {'\0',}; if (!p_cynara) { return false; } - fp = fopen(smack_label, "r"); + fp = fopen(label_path, "r"); if (fp != NULL) { if (fread(smack_label, 1, sizeof(smack_label), fp) <= 0) SLOG(LOG_ERROR, TAG_VCC, "[ERROR] fail to fread"); @@ -365,12 +361,6 @@ static void __vc_internal_unprepare(void) SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request finalize : %s", __vc_get_error_code(ret)); } - -#if 0 - ecore_event_handler_del(g_focus_in_hander); - ecore_event_handler_del(g_focus_out_hander); -#endif - vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_FOREGROUND); vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_BACKGROUND); @@ -432,78 +422,6 @@ int vc_deinitialize(void) return VC_ERROR_NONE; } -#if 0 -static Eina_Bool __vc_x_event_window_focus_in(void *data, int type, void *event) -{ - Ecore_X_Event_Window_Focus_In *e; - - e = event; - - int xid = -1; - if (0 != vc_client_get_xid(g_vc, &xid)) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get current xid"); - return ECORE_CALLBACK_PASS_ON; - } - - if (e->win == (Ecore_X_Window)xid) { - SLOG(LOG_DEBUG, TAG_VCC, "Focus in : pid(%d) xid(%d)", getpid(), xid); - int ret = vc_config_mgr_set_foreground(getpid(), true); - if (0 != ret) { - ret = vc_config_convert_error_code((vc_config_error_e)ret); - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set focus in : %s", __vc_get_error_code(ret)); - } - /* set authority valid */ - vc_auth_state_e state = VC_AUTH_STATE_NONE; - if (0 != vc_client_get_auth_state(g_vc, &state)) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get auth state"); - } - if (VC_AUTH_STATE_INVALID == state) { - vc_client_set_auth_state(g_vc, VC_AUTH_STATE_VALID); - - /* notify auth changed cb */ - ecore_timer_add(0, __notify_auth_changed_cb, NULL); - } - } - - return ECORE_CALLBACK_PASS_ON; -} - -static Eina_Bool __vc_x_event_window_focus_out(void *data, int type, void *event) -{ - Ecore_X_Event_Window_Focus_In *e; - - e = event; - - int xid = -1; - if (0 != vc_client_get_xid(g_vc, &xid)) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get current xid"); - return ECORE_CALLBACK_PASS_ON; - } - - if (e->win == (Ecore_X_Window)xid) { - SLOG(LOG_DEBUG, TAG_VCC, "Focus out : pid(%d) xid(%d)", getpid(), xid); - int ret = vc_config_mgr_set_foreground(getpid(), false); - if (0 != ret) { - ret = vc_config_convert_error_code((vc_config_error_e)ret); - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set focus out : %s", __vc_get_error_code(ret)); - } - /* set authority valid */ - vc_auth_state_e state = VC_AUTH_STATE_NONE; - if (0 != vc_client_get_auth_state(g_vc, &state)) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get auth state"); - } - if (VC_AUTH_STATE_VALID == state) { - vc_client_set_auth_state(g_vc, VC_AUTH_STATE_INVALID); - - /* notify authority changed cb */ - ecore_timer_add(0, __notify_auth_changed_cb, NULL); - } - } - - return ECORE_CALLBACK_PASS_ON; -} -#endif - static Eina_Bool __vc_connect_daemon(void *data) { /* Send hello */ @@ -545,15 +463,38 @@ static Eina_Bool __vc_connect_daemon(void *data) vc_client_set_service_state(g_vc, (vc_service_state_e)service_state); g_connect_timer = NULL; -#if 0 - g_focus_in_hander = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, __vc_x_event_window_focus_in, NULL); - g_focus_out_hander = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, __vc_x_event_window_focus_out, NULL); -#else + ret = aul_add_status_local_cb(__vc_app_state_changed_cb, NULL); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set app stae changed callback"); } -#endif + + int status = aul_app_get_status_bypid(getpid()); + if (STATUS_FOCUS == status || STATUS_VISIBLE == status) { + SLOG(LOG_DEBUG, TAG_VCC, "===== Set foreground"); + ret = vc_dbus_set_foreground(getpid(), true); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set foreground (true) : %d", ret); + } + + ret = vc_client_set_is_foreground(g_vc, true); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to save is_foreground (true) : %d", ret); + } + + /* set authority valid */ + vc_auth_state_e state = VC_AUTH_STATE_NONE; + if (0 != vc_client_get_auth_state(g_vc, &state)) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get auth state"); + } + if (VC_AUTH_STATE_INVALID == state) { + vc_client_set_auth_state(g_vc, VC_AUTH_STATE_VALID); + + /* notify auth changed cb */ + ecore_idler_add(__notify_auth_changed_cb, NULL); + } + } + vc_client_set_client_state(g_vc, VC_STATE_READY); ecore_timer_add(0, __vc_notify_state_changed, g_vc); @@ -810,99 +751,6 @@ int vc_get_service_state(vc_service_state_e* state) return VC_ERROR_NONE; } -#if 0 -int vc_set_window_id(int wid) -{ - SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Set Window id"); - - if (0 >= wid) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Input parameter is invalid"); - SLOG(LOG_DEBUG, TAG_VCC, "====="); - SLOG(LOG_DEBUG, TAG_VCC, " "); - return VC_ERROR_INVALID_PARAMETER; - } - - vc_state_e state; - if (0 != vc_client_get_client_state(g_vc, &state)) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available"); - SLOG(LOG_DEBUG, TAG_VCC, "====="); - SLOG(LOG_DEBUG, TAG_VCC, " "); - return VC_ERROR_INVALID_STATE; - } - - /* check state */ - if (state != VC_STATE_READY) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'READY'"); - SLOG(LOG_DEBUG, TAG_VCC, "====="); - SLOG(LOG_DEBUG, TAG_VCC, " "); - return VC_ERROR_INVALID_STATE; - } - - if (0 != vc_client_set_xid(g_vc, wid)) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not valid"); - SLOG(LOG_DEBUG, TAG_VCC, "====="); - SLOG(LOG_DEBUG, TAG_VCC, " "); - return VC_ERROR_INVALID_STATE; - } - - /* Check if current xid is top window */ - int ret = -1; - if ((Ecore_X_Window)wid == ecore_x_window_focus_get()) { - /* Set current pid */ - ret = vc_config_mgr_set_foreground(getpid(), true); - if (0 != ret) { - ret = vc_config_convert_error_code((vc_config_error_e)ret); - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set focus in : %s", __vc_get_error_code(ret)); - } - } - - SLOG(LOG_DEBUG, TAG_VCC, "====="); - SLOG(LOG_DEBUG, TAG_VCC, " "); - - return ret; -} - -int vc_get_window_id(int* wid) -{ - SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Get Window id"); - - if (NULL == wid) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Input parameter is NULL"); - SLOG(LOG_DEBUG, TAG_VCC, "====="); - SLOG(LOG_DEBUG, TAG_VCC, " "); - return VC_ERROR_INVALID_PARAMETER; - } - - vc_state_e state; - if (0 != vc_client_get_client_state(g_vc, &state)) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available"); - SLOG(LOG_DEBUG, TAG_VCC, "====="); - SLOG(LOG_DEBUG, TAG_VCC, " "); - return VC_ERROR_INVALID_STATE; - } - - /* check state */ - if (state != VC_STATE_READY) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'READY'"); - SLOG(LOG_DEBUG, TAG_VCC, "====="); - SLOG(LOG_DEBUG, TAG_VCC, " "); - return VC_ERROR_INVALID_STATE; - } - - if (0 != vc_client_get_xid(g_vc, wid)) { - SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not valid"); - SLOG(LOG_DEBUG, TAG_VCC, "====="); - SLOG(LOG_DEBUG, TAG_VCC, " "); - return VC_ERROR_INVALID_STATE; - } - - SLOG(LOG_DEBUG, TAG_VCC, "====="); - SLOG(LOG_DEBUG, TAG_VCC, " "); - - return VC_ERROR_NONE; -} -#endif - /** * @brief Checks whether the command format is supported. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif @@ -1156,7 +1004,6 @@ int vc_set_exclusive_command_option(bool value) return ret; } - /* Check if current xid is top window */ int count = 0; do { ret = vc_dbus_request_set_exclusive_command(g_vc->handle, value); diff --git a/client/vc_dbus.c b/client/vc_dbus.c index 2f8ca3d..22171c5 100644 --- a/client/vc_dbus.c +++ b/client/vc_dbus.c @@ -307,8 +307,21 @@ int vc_dbus_reconnect() return 0; } +static int __dbus_check() +{ + if (NULL == g_conn_sender) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] NULL connection"); + return vc_dbus_reconnect(); + } + return 0; +} + int vc_dbus_request_hello() { + if (0 != __dbus_check()) { + return VC_ERROR_OPERATION_FAILED; + } + DBusMessage* msg; msg = dbus_message_new_method_call( @@ -349,6 +362,10 @@ int vc_dbus_request_hello() int vc_dbus_request_initialize(int pid, int* mgr_pid, int* service_state) { + if (0 != __dbus_check()) { + return VC_ERROR_OPERATION_FAILED; + } + DBusMessage* msg; msg = dbus_message_new_method_call( @@ -417,6 +434,10 @@ int vc_dbus_request_initialize(int pid, int* mgr_pid, int* service_state) int vc_dbus_request_finalize(int pid) { + if (0 != __dbus_check()) { + return VC_ERROR_OPERATION_FAILED; + } + DBusMessage* msg; msg = dbus_message_new_method_call( @@ -477,6 +498,10 @@ int vc_dbus_request_finalize(int pid) int vc_dbus_request_set_exclusive_command(int pid, bool value) { + if (0 != __dbus_check()) { + return VC_ERROR_OPERATION_FAILED; + } + DBusMessage* msg; msg = dbus_message_new_method_call( @@ -541,6 +566,10 @@ int vc_dbus_request_set_exclusive_command(int pid, bool value) int vc_dbus_request_set_command(int pid, vc_cmd_type_e cmd_type) { + if (0 != __dbus_check()) { + return VC_ERROR_OPERATION_FAILED; + } + DBusMessage* msg; msg = dbus_message_new_method_call( @@ -603,6 +632,10 @@ int vc_dbus_request_set_command(int pid, vc_cmd_type_e cmd_type) int vc_dbus_request_unset_command(int pid, vc_cmd_type_e cmd_type) { + if (0 != __dbus_check()) { + return VC_ERROR_OPERATION_FAILED; + } + DBusMessage* msg; msg = dbus_message_new_method_call( @@ -665,6 +698,10 @@ int vc_dbus_request_unset_command(int pid, vc_cmd_type_e cmd_type) int vc_dbus_set_foreground(int pid, bool value) { + if (0 != __dbus_check()) { + return VC_ERROR_OPERATION_FAILED; + } + DBusMessage* msg = NULL; int tmp_value = 0; @@ -921,6 +958,10 @@ int vc_dbus_request_cancel(int pid) /* Authority */ int vc_dbus_request_auth_enable(int pid, int mgr_pid) { + if (0 != __dbus_check()) { + return VC_ERROR_OPERATION_FAILED; + } + DBusMessage* msg; char service_name[64] = {0,}; @@ -991,6 +1032,10 @@ int vc_dbus_request_auth_enable(int pid, int mgr_pid) int vc_dbus_request_auth_disable(int pid, int mgr_pid) { + if (0 != __dbus_check()) { + return VC_ERROR_OPERATION_FAILED; + } + DBusMessage* msg; char service_name[64] = {0,}; @@ -1061,6 +1106,10 @@ int vc_dbus_request_auth_disable(int pid, int mgr_pid) int vc_dbus_request_auth_start(int pid, int mgr_pid) { + if (0 != __dbus_check()) { + return VC_ERROR_OPERATION_FAILED; + } + DBusMessage* msg; char service_name[64] = {0,}; @@ -1133,6 +1182,10 @@ int vc_dbus_request_auth_start(int pid, int mgr_pid) int vc_dbus_request_auth_stop(int pid, int mgr_pid) { + if (0 != __dbus_check()) { + return VC_ERROR_OPERATION_FAILED; + } + DBusMessage* msg; char service_name[64] = {0,}; @@ -1203,6 +1256,10 @@ int vc_dbus_request_auth_stop(int pid, int mgr_pid) int vc_dbus_request_auth_cancel(int pid, int mgr_pid) { + if (0 != __dbus_check()) { + return VC_ERROR_OPERATION_FAILED; + } + DBusMessage* msg; char service_name[64] = {0,}; diff --git a/common/vc_command.c b/common/vc_command.c index ef433d4..4d5fa9f 100644 --- a/common/vc_command.c +++ b/common/vc_command.c @@ -75,13 +75,14 @@ static int __check_privilege_initialize() static int __check_privilege(const char* uid, const char * privilege) { FILE *fp = NULL; - char smack_label[1024] = "/proc/self/attr/current"; + char label_path[1024] = "/proc/self/attr/current"; + char smack_label[1024] = {'\0',}; if (!p_cynara) { return false; } - fp = fopen(smack_label, "r"); + fp = fopen(label_path, "r"); if (fp != NULL) { if (fread(smack_label, 1, sizeof(smack_label), fp) <= 0) SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] fail to fread"); diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index 4996cea..6c87c63 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -82,11 +82,15 @@ static float get_volume_decibel(char* data, int size); #ifdef TV_MSF_WIFI_MODE static void __msf_wifi_audio_data_receive_cb(msf_wifi_voice_data_s *voice_data, void* user_data) { - if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) { - /*SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Exit audio reading normal func");*/ + if (0 != strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, sizeof(VCP_AUDIO_ID_MSF))){ + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type); return; } + if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) { + SLOG(LOG_WARN, TAG_VCD, "[Recorder] Not start yet, but send audio data vi MSF"); + } + if (NULL != g_audio_cb) { if (0 != g_audio_cb((void*)voice_data->audio_buf, (unsigned int)voice_data->length)) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio"); @@ -135,11 +139,15 @@ static void _bt_cb_hid_state_changed(int result, bool connected, const char *rem static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void *user_data) { - if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) { - /*SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Exit audio reading normal func");*/ + if (0 != strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, sizeof(VCP_AUDIO_ID_BLUETOOTH))){ + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type); return; } + if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) { + SLOG(LOG_WARN, TAG_VCD, "[Recorder] Not start yet, but send audio data vi Bluetooth"); + } + if (NULL != g_audio_cb) { if (0 != g_audio_cb((void*)voice_data->audio_buf, (unsigned int)voice_data->length)) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio"); -- 2.7.4 From 83e61177ed913327e0a22b55816d84ab4140e124 Mon Sep 17 00:00:00 2001 From: "stom.hwang" Date: Tue, 16 Aug 2016 21:24:21 +0900 Subject: [PATCH 03/16] Fix coding rule Change-Id: I8784d3b9aa834a7b319fcbe5aac7332a3e02cc73 Signed-off-by: stom.hwang --- server/vcd_recorder.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index 6c87c63..52a9f3a 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -82,7 +82,7 @@ static float get_volume_decibel(char* data, int size); #ifdef TV_MSF_WIFI_MODE static void __msf_wifi_audio_data_receive_cb(msf_wifi_voice_data_s *voice_data, void* user_data) { - if (0 != strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, sizeof(VCP_AUDIO_ID_MSF))){ + if (0 != strncmp(g_current_audio_type, VCP_AUDIO_ID_MSF, sizeof(VCP_AUDIO_ID_MSF))) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type); return; } @@ -139,7 +139,7 @@ static void _bt_cb_hid_state_changed(int result, bool connected, const char *rem static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void *user_data) { - if (0 != strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, sizeof(VCP_AUDIO_ID_BLUETOOTH))){ + if (0 != strncmp(g_current_audio_type, VCP_AUDIO_ID_BLUETOOTH, sizeof(VCP_AUDIO_ID_BLUETOOTH))) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type); return; } -- 2.7.4 From 1b5bf32264532fce4b2c0d71c93faa10ad4b2465 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Wed, 31 Aug 2016 09:25:14 +0900 Subject: [PATCH 04/16] remove unused macro Change-Id: Id6d3d3db6235ebfccf023da95e31ec71bf9da039 Signed-off-by: Wonnam Jang --- packaging/voice-control.spec | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index 8b38128..7ed37d4 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -84,11 +84,6 @@ cp %{SOURCE1001} %{SOURCE1002} . %build -%if 0%{?tizen_build_binary_release_type_eng} -export CFLAGS="$CFLAGS -DTIZEN_ENGINEER_MODE" -export CXXFLAGS="$CXXFLAGS -DTIZEN_ENGINEER_MODE" -export FFLAGS="$FFLAGS -DTIZEN_ENGINEER_MODE" -%endif %if "%{PRODUCT_TYPE}" == "TV" export CFLAGS="$CFLAGS -DTV_PRODUCT" cmake . -DCMAKE_INSTALL_PREFIX=/usr -DLIBDIR=%{_libdir} -DINCLUDEDIR=%{_includedir} \ -- 2.7.4 From b4393e81495506d6549420a2714873a32f967063 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Fri, 9 Sep 2016 10:10:46 +0900 Subject: [PATCH 05/16] Add upgrade script Change-Id: I4388ab8b660c483ab60ea8456350522fd81be63d Signed-off-by: sooyeon.kim --- 502.vc_upgrade_24to30.sh | 34 ++++++++++++++++++++++++++++++++++ CMakeLists.txt | 4 ++++ packaging/voice-control.spec | 1 + 3 files changed, 39 insertions(+) create mode 100755 502.vc_upgrade_24to30.sh diff --git a/502.vc_upgrade_24to30.sh b/502.vc_upgrade_24to30.sh new file mode 100755 index 0000000..78386c4 --- /dev/null +++ b/502.vc_upgrade_24to30.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +#------------------------------------------# +# Resourced patch for upgrade (2.4 -> 3.0) # +#------------------------------------------# + +# Macro +VOICE_DIR_24=/opt/usr/data/voice +VC_DIR_24=/opt/home/app/.voice/vc + +VOICE_DIR_30=/opt/usr/home/owner/share/.voice +VC_DIR_30=$VOICE_DIR_30/vc + +VC_CONF_FILE_24=/opt/home/app/.voice/vc-config.xml +VC_CONF_FILE_30=$VOICE_DIR_30/vc-config.xml + + +# Make new directories +mkdir -p $VOICE_DIR_30 +chown owner:users $VOICE_DIR_30 +chsmack -a User::App::Shared $VOICE_DIR_30 + + +# Move +mv $VC_DIR_24/ $VOICE_DIR_30/ +chown -R owner:users $VOICE_DIR_30/ +chsmack -ra User::App::Shared $VOICE_DIR_30/ + +mv $VC_CONF_FILE_24 $VC_CONF_FILE_30 +chown owner:users $VC_CONF_FILE_30 +chsmack -a User::App::Shared $VC_CONF_FILE_30 + +# Remove directories +rm -rf /opt/home/app/.voice diff --git a/CMakeLists.txt b/CMakeLists.txt index ae696f0..25a4ede 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,3 +68,7 @@ INSTALL(FILES ${CMAKE_SOURCE_DIR}/vc-config.xml DESTINATION ${TZ_SYS_RO_SHARE}/v INSTALL(FILES ${CMAKE_SOURCE_DIR}/org.tizen.voice.vcserver.service DESTINATION ${TZ_SYS_RO_SHARE}/dbus-1/services) INSTALL(FILES ${CMAKE_SOURCE_DIR}/vc-server.conf DESTINATION /etc/dbus-1/session.d) + +## Upgrade script ## +INSTALL(FILES ${CMAKE_SOURCE_DIR}/vc_upgrade_24to30.sh DESTINATION ${TZ_SYS_RO_SHARE}/upgrade/scripts) + diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index 7ed37d4..432ac4b 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -116,6 +116,7 @@ mkdir -p %{_libdir}/voice/vc %{_libdir}/libvc_widget.so %{_libdir}/libvc_manager.so %{_bindir}/vc-daemon +%{TZ_SYS_RO_SHARE}/upgrade/scripts/vc_upgrade_24to30.sh %{TZ_SYS_RO_SHARE}/voice/vc/1.0/vc-config.xml %{TZ_SYS_RO_SHARE}/dbus-1/services/org.tizen.voice* %{TZ_SYS_RO_SHARE}/license/%{name} -- 2.7.4 From 8d497a7dbb06a44128c20b82f3d883fb7d6578e1 Mon Sep 17 00:00:00 2001 From: "stom.hwang" Date: Fri, 9 Sep 2016 13:28:55 +0900 Subject: [PATCH 06/16] Fix typo in CMakeLists.txt and voice-control.spec Change-Id: Ifae2a35bc09aca8ea28086508cb23fb7c52f95a8 Signed-off-by: stom.hwang --- CMakeLists.txt | 2 +- packaging/voice-control.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 25a4ede..8176793 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,5 +70,5 @@ INSTALL(FILES ${CMAKE_SOURCE_DIR}/org.tizen.voice.vcserver.service DESTINATION $ INSTALL(FILES ${CMAKE_SOURCE_DIR}/vc-server.conf DESTINATION /etc/dbus-1/session.d) ## Upgrade script ## -INSTALL(FILES ${CMAKE_SOURCE_DIR}/vc_upgrade_24to30.sh DESTINATION ${TZ_SYS_RO_SHARE}/upgrade/scripts) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/502.vc_upgrade_24to30.sh DESTINATION ${TZ_SYS_RO_SHARE}/upgrade/scripts) diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index 432ac4b..168f3ec 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -116,7 +116,7 @@ mkdir -p %{_libdir}/voice/vc %{_libdir}/libvc_widget.so %{_libdir}/libvc_manager.so %{_bindir}/vc-daemon -%{TZ_SYS_RO_SHARE}/upgrade/scripts/vc_upgrade_24to30.sh +%{TZ_SYS_RO_SHARE}/upgrade/scripts/502.vc_upgrade_24to30.sh %{TZ_SYS_RO_SHARE}/voice/vc/1.0/vc-config.xml %{TZ_SYS_RO_SHARE}/dbus-1/services/org.tizen.voice* %{TZ_SYS_RO_SHARE}/license/%{name} -- 2.7.4 From cc74a951018fdc4a7b7b47cffe67885fd5f6ca32 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Wed, 21 Sep 2016 18:57:26 +0900 Subject: [PATCH 07/16] Enabling Svoice and db Change-Id: Ifd6ca91c79f8fc3587cf58f6c14f23a3547806c0 Signed-off-by: Wonnam Jang --- CMakeLists.txt | 8 +- client/CMakeLists.txt | 6 + client/vc.c | 489 +++++++++- client/vc_client.c | 44 +- client/vc_client.h | 4 + client/vc_dbus.c | 165 +++- client/vc_dbus.h | 6 +- client/vc_mgr.c | 842 ++++++++++++----- client/vc_mgr_client.c | 117 +-- client/vc_mgr_client.h | 14 +- client/vc_mgr_dbus.c | 290 +++++- client/vc_mgr_dbus.h | 8 + client/vc_widget.c | 71 +- client/vc_widget_dbus.c | 19 +- client/vc_widget_dbus.h | 2 +- common/vc_cmd_db.c | 1583 ++++++++++++++++++++++++++++++++ common/vc_cmd_db.h | 83 ++ common/vc_command.c | 201 +++- common/vc_command.h | 161 +++- common/vc_config_mgr.c | 13 +- common/vc_defs.h | 13 +- common/vc_info_parser.c | 1332 +++------------------------ common/vc_info_parser.h | 12 +- common/vc_json_parser.c | 422 +++++++++ common/vc_json_parser.h | 36 + common/vc_main.h | 1 + include/voice_control.h | 129 +++ include/voice_control_command.h | 107 ++- include/voice_control_command_expand.h | 32 - include/voice_control_manager.h | 237 ++++- include/voice_control_plugin_engine.h | 214 ++++- packaging/voice-control.spec | 5 + server/CMakeLists.txt | 2 + server/vcd_client_data.c | 443 ++++----- server/vcd_client_data.h | 10 +- server/vcd_config.c | 15 +- server/vcd_dbus.c | 71 +- server/vcd_dbus.h | 6 +- server/vcd_dbus_server.c | 351 ++++++- server/vcd_dbus_server.h | 12 + server/vcd_engine_agent.c | 258 +++++- server/vcd_engine_agent.h | 32 +- server/vcd_recorder.c | 6 +- server/vcd_server.c | 679 ++++++++++++-- server/vcd_server.h | 12 + vc-config.xml | 2 +- 46 files changed, 6521 insertions(+), 2044 deletions(-) mode change 100755 => 100644 client/vc_widget.c create mode 100644 common/vc_cmd_db.c create mode 100644 common/vc_cmd_db.h mode change 100755 => 100644 common/vc_command.h create mode 100644 common/vc_json_parser.c create mode 100644 common/vc_json_parser.h mode change 100755 => 100644 include/voice_control.h mode change 100755 => 100644 include/voice_control_command.h mode change 100755 => 100644 include/voice_control_command_expand.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8176793..38fc3c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,13 +42,13 @@ INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include") INCLUDE(FindPkgConfig) IF("${_TV_PRODUCT}" STREQUAL "TRUE") pkg_check_modules(pkgs REQUIRED - aul capi-base-common capi-media-audio-io capi-media-sound-manager capi-network-bluetooth capi-system-info - cynara-client cynara-session dbus-1 dlog ecore glib-2.0 libtzplatform-config libxml-2.0 vconf #msfapi + aul capi-appfw-application capi-appfw-app-manager capi-base-common capi-media-audio-io capi-media-sound-manager + capi-network-bluetooth capi-system-info cynara-client cynara-session dbus-1 db-util dlog ecore glib-2.0 json-glib-1.0 libtzplatform-config libxml-2.0 sqlite3 vconf #msfapi ) ELSE() pkg_check_modules(pkgs REQUIRED - aul capi-base-common capi-media-audio-io capi-media-sound-manager capi-network-bluetooth capi-system-info - cynara-client cynara-session dbus-1 dlog ecore glib-2.0 libtzplatform-config libxml-2.0 vconf + aul capi-appfw-application capi-appfw-app-manager capi-base-common capi-media-audio-io capi-media-sound-manager + capi-system-info cynara-client cynara-session dbus-1 db-util dlog ecore glib-2.0 json-glib-1.0 libtzplatform-config libxml-2.0 sqlite3 vconf ) ENDIF() diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 33c0e15..0103780 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -2,10 +2,12 @@ SET(SRCS vc.c vc_client.c vc_dbus.c + ../common/vc_cmd_db.c ../common/vc_command.c ../common/vc_config_mgr.c ../common/vc_config_parser.c ../common/vc_info_parser.c + ../common/vc_json_parser.c ) SET(SETTING_SRCS @@ -18,20 +20,24 @@ SET(WIDGET_SRCS vc_widget.c vc_widget_client.c vc_widget_dbus.c + ../common/vc_cmd_db.c ../common/vc_command.c ../common/vc_config_mgr.c ../common/vc_config_parser.c ../common/vc_info_parser.c + ../common/vc_json_parser.c ) SET(MANAGER_SRCS vc_mgr.c vc_mgr_client.c vc_mgr_dbus.c + ../common/vc_cmd_db.c ../common/vc_command.c ../common/vc_config_mgr.c ../common/vc_config_parser.c ../common/vc_info_parser.c + ../common/vc_json_parser.c ) #INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) diff --git a/client/vc.c b/client/vc.c index b2e86fc..327db61 100644 --- a/client/vc.c +++ b/client/vc.c @@ -15,16 +15,22 @@ */ #include +#include #include #include #include +#include +#include +#include #include #include "vc_client.h" +#include "vc_cmd_db.h" #include "vc_command.h" #include "vc_config_mgr.h" #include "vc_dbus.h" #include "vc_info_parser.h" +#include "vc_json_parser.h" #include "vc_main.h" #include "voice_control.h" #include "voice_control_authority.h" @@ -37,6 +43,8 @@ static Ecore_Timer* g_connect_timer = NULL; static vc_h g_vc = NULL; +static int g_daemon_pid = 0; + static int g_feature_enabled = -1; static int g_privilege_allowed = -1; @@ -80,7 +88,7 @@ static int __check_privilege_initialize() int ret = cynara_initialize(&p_cynara, NULL); if (CYNARA_API_SUCCESS != ret) SLOG(LOG_ERROR, TAG_VCC, "[ERROR] fail to initialize"); - + return ret == CYNARA_API_SUCCESS; } @@ -144,7 +152,7 @@ static int __vc_check_privilege() } g_privilege_allowed = 1; - return VC_ERROR_NONE; + return VC_ERROR_NONE; } static const char* __vc_get_error_code(vc_error_e err) @@ -334,6 +342,14 @@ int vc_initialize(void) return __vc_convert_config_error_code(ret); } + ret = vc_db_initialize(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to initialize DB : %d", ret); + vc_config_mgr_finalize(g_vc->handle); + vc_client_destroy(g_vc); + return ret; + } + SLOG(LOG_DEBUG, TAG_VCC, "[Success] pid(%d)", g_vc->handle); SLOG(LOG_DEBUG, TAG_VCC, "====="); @@ -361,8 +377,10 @@ static void __vc_internal_unprepare(void) SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request finalize : %s", __vc_get_error_code(ret)); } - vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_FOREGROUND); - vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_BACKGROUND); + + ret = vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_FOREGROUND); + if (0 != ret) + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to delete file, type(%d), ret(%d)", VC_COMMAND_TYPE_FOREGROUND, ret); return; } @@ -411,6 +429,10 @@ int vc_deinitialize(void) } SLOG(LOG_DEBUG, TAG_VCC, "Success: destroy"); + int ret = vc_db_finalize(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to finalize DB, ret(%d)", ret); + } if (0 != vc_dbus_close_connection()) { SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to close connection"); @@ -435,7 +457,12 @@ static Eina_Bool __vc_connect_daemon(void *data) int ret = -1; int mgr_pid = -1; int service_state = 0; - ret = vc_dbus_request_initialize(g_vc->handle, &mgr_pid, &service_state); + + ret = vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_FOREGROUND); + if (0 != ret) + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to delete file, type(%d), ret(%d)", VC_COMMAND_TYPE_FOREGROUND, ret); + + ret = vc_dbus_request_initialize(g_vc->handle, &mgr_pid, &service_state, &g_daemon_pid); if (VC_ERROR_ENGINE_NOT_FOUND == ret) { SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to initialize : %s", __vc_get_error_code(ret)); @@ -751,6 +778,103 @@ int vc_get_service_state(vc_service_state_e* state) return VC_ERROR_NONE; } +int vc_get_system_command_list(vc_cmd_list_h* vc_sys_cmd_list) +{ + if (0 != __vc_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + if (0 != __vc_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + + SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Get system command list"); + + if (NULL == vc_sys_cmd_list) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL"); + return VC_ERROR_INVALID_PARAMETER; + } + + vc_state_e state; + if (0 != vc_client_get_client_state(g_vc, &state)) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available"); + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'READY'"); + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + return VC_ERROR_INVALID_STATE; + } + + /* Check service state */ + vc_service_state_e service_state = -1; + vc_client_get_service_state(g_vc, &service_state); + if (service_state != VC_SERVICE_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: service state is not 'READY'"); + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + return VC_ERROR_INVALID_STATE; + } + + bool is_sys_cmd_valid = false; + int count = 0; + int ret = -1; + + do { + ret = vc_dbus_request_is_system_command_valid(g_vc->handle, &is_sys_cmd_valid); + if (0 != ret) { + if (VC_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to ask system command is : %s", __vc_get_error_code(ret)); + break; + } else { + SLOG(LOG_WARN, TAG_VCC, "[WARNING] retry to ask system command is : %s", __vc_get_error_code(ret)); + usleep(10000); + count++; + if (VC_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request"); + break; + } + } + } + } while (0 != ret); + + int mgr_pid = -1; + ret = vc_client_get_mgr_pid(g_vc, &mgr_pid); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get the manager pid"); + return VC_ERROR_OPERATION_FAILED; + } + + vc_cmd_list_s* list = NULL; + list = (vc_cmd_list_s*)(*vc_sys_cmd_list); + if (true == is_sys_cmd_valid) { + ret = vc_cmd_parser_get_commands(mgr_pid, VC_COMMAND_TYPE_SYSTEM, &(list->list)); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get parsing commands"); + return ret; + } + ret = vc_cmd_parser_get_commands(mgr_pid, VC_COMMAND_TYPE_SYSTEM_BACKGROUND, &(list->list)); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get parsing commands"); + return ret; + } + *vc_sys_cmd_list = (vc_cmd_list_h)list; + } else { + SLOG(LOG_WARN, TAG_VCC, "[WARNING] No system commands"); + *vc_sys_cmd_list = NULL; + return VC_ERROR_NONE; + } + + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + + return ret; +} + /** * @brief Checks whether the command format is supported. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif @@ -766,9 +890,15 @@ int vc_get_service_state(vc_service_state_e* state) * * @pre The state should be #VC_STATE_READY. */ -#if 0 int vc_is_command_format_supported(vc_cmd_format_e format, bool* support) { + if (0 != __vc_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + if (0 != __vc_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Is command format supported"); vc_state_e state; @@ -786,10 +916,12 @@ int vc_is_command_format_supported(vc_cmd_format_e format, bool* support) } switch (format) { - case VC_CMD_FORMAT_FIXED: *support = true; break; - case VC_CMD_FORMAT_FIXED_AND_EXTRA: *support = non_fixed_support; break; - case VC_CMD_FORMAT_EXTRA_AND_FIXED: *support = non_fixed_support; break; - default: *support = false; break; + case VC_CMD_FORMAT_FIXED: *support = true; break; + case VC_CMD_FORMAT_FIXED_AND_VFIXED: *support = true; break; + case VC_CMD_FORMAT_VFIXED_AND_FIXED: *support = true; break; + case VC_CMD_FORMAT_FIXED_AND_NONFIXED: *support = non_fixed_support; break; + case VC_CMD_FORMAT_NONFIXED_AND_FIXED: *support = non_fixed_support; break; + default: *support = false; break; } SLOG(LOG_ERROR, TAG_VCC, "[DEBUG] Format(%d) support(%s)", format, *support ? "true" : "false"); @@ -799,7 +931,73 @@ int vc_is_command_format_supported(vc_cmd_format_e format, bool* support) return VC_ERROR_NONE; } -#endif + +static int __vc_get_invocation_name(char** invocation_name) +{ + int ret = vc_client_get_invocation_name(g_vc, invocation_name); + if (0 != ret) { + SLOG(LOG_WARN, TAG_VCC, "Fail to get invocation name"); + return ret; + } + + if (NULL == *invocation_name) { + char* temp_label = NULL; + char* appid = NULL; + char* lang = NULL; + + ret = app_manager_get_app_id(getpid(), &appid); + if (0 != ret || NULL == appid) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get appid, ret(%d)", ret); + if (NULL != appid) { + free(appid); + appid = NULL; + } + return VC_ERROR_OPERATION_FAILED; + } + + ret = vc_get_current_language(&lang); + if (0 != ret || NULL == lang) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get current laguage, ret(%d)", ret); + free(appid); + appid = NULL; + if (NULL != lang) { + free(lang); + lang = NULL; + } + return VC_ERROR_OPERATION_FAILED; + } + + ret = app_info_get_localed_label(appid, lang, &temp_label); + if (0 != ret || NULL == temp_label) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get localed label, ret(%d) appid(%s) lang(%s)", ret, appid, lang); + free(appid); + appid = NULL; + free(lang); + lang = NULL; + if (NULL != temp_label) { + free(temp_label); + temp_label = NULL; + } + return VC_ERROR_OPERATION_FAILED; + } + + *invocation_name = strdup(temp_label); + if (NULL == *invocation_name) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to allocate memory"); + return VC_ERROR_OUT_OF_MEMORY; + } + + free(appid); + appid = NULL; + free(lang); + lang = NULL; + free(temp_label); + temp_label = NULL; + } + + SLOG(LOG_DEBUG, TAG_VCC, "Get invocation name(%s)", *invocation_name); + return VC_ERROR_NONE; +} int vc_set_command_list(vc_cmd_list_h vc_cmd_list, int type) { @@ -845,8 +1043,21 @@ int vc_set_command_list(vc_cmd_list_h vc_cmd_list, int type) list = (vc_cmd_list_s*)vc_cmd_list; int ret = 0; - if (0 != vc_cmd_parser_save_file(getpid(), (vc_cmd_type_e)type, list->list)) { - ret = VC_ERROR_INVALID_PARAMETER; + char* invocation_name = NULL; + if (VC_COMMAND_TYPE_BACKGROUND == type) { + ret = __vc_get_invocation_name(&invocation_name); + if (0 != ret || NULL == invocation_name) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get invocation name, ret(%d)", ret); + return ret; + } + } + + ret = vc_cmd_parser_delete_file(getpid(), type); + if (0 != ret) + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to delete file, type(%d), ret(%d)", type, ret); + + ret = vc_cmd_parser_save_file(getpid(), (vc_cmd_type_e)type, list->list, invocation_name); + if (0 != ret) { SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to save command list : %s", __vc_get_error_code(ret)); } else { int count = 0; @@ -869,6 +1080,11 @@ int vc_set_command_list(vc_cmd_list_h vc_cmd_list, int type) } while (0 != ret); } + if (NULL != invocation_name) { + free(invocation_name); + invocation_name = NULL; + } + SLOG(LOG_DEBUG, TAG_VCC, "====="); SLOG(LOG_DEBUG, TAG_VCC, " "); @@ -934,6 +1150,89 @@ int vc_unset_command_list(int type) return ret; } +int vc_set_command_list_from_file(const char* file_path, int type) +{ + if (0 != __vc_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + if (0 != __vc_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + + SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Set Command list from file"); + + vc_state_e state; + if (0 != vc_client_get_client_state(g_vc, &state)) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available"); + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'READY'"); + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + return VC_ERROR_INVALID_STATE; + } + + /* check type */ + if ((VC_COMMAND_TYPE_FOREGROUND != type) && (VC_COMMAND_TYPE_BACKGROUND != type)) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid command type: input type is %d", type); + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + return VC_ERROR_INVALID_PARAMETER; + } + + int ret = 0; + char* invocation_name = NULL; + if (VC_COMMAND_TYPE_BACKGROUND == type) { + ret = __vc_get_invocation_name(&invocation_name); + if (0 != ret || NULL == invocation_name) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get invocation name, ret(%d)", ret); + return ret; + } + } + + ret = vc_cmd_parser_delete_file(getpid(), type); + if (0 != ret) + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to delete file, type(%d), ret(%d)", type, ret); + + ret = vc_json_set_commands_from_file(file_path, (vc_cmd_type_e)type, invocation_name); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set commands from file : %s", __vc_get_error_code(ret)); + } else { + int count = 0; + do { + ret = vc_dbus_request_set_command(g_vc->handle, (vc_cmd_type_e)type); + if (0 != ret) { + if (VC_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request set command to daemon : %s", __vc_get_error_code(ret)); + break; + } else { + SLOG(LOG_WARN, TAG_VCC, "[WARNING] retry request set command : %s", __vc_get_error_code(ret)); + usleep(10000); + count++; + if (VC_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request"); + break; + } + } + } + } while (0 != ret); + } + + if (NULL != invocation_name) { + free(invocation_name); + invocation_name = NULL; + } + + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + return ret; +} + #if 0 int vc_get_exclusive_command_option(bool* value) { @@ -1234,13 +1533,33 @@ Eina_Bool __vc_notify_error(void *data) return EINA_FALSE; } -int __vc_cb_error(int pid, int reason) +int __vc_cb_error(int reason, int daemon_pid, char* msg) { - if (0 != vc_client_get_handle(pid, &g_vc)) { - SLOG(LOG_ERROR, TAG_VCC, "Handle is not valid : pid(%d)", pid); + vc_state_e state; + if (0 != vc_client_get_client_state(g_vc, &state)) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid client"); + return -1; + } + + /* check state */ + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] not connected client yet"); return -1; } + if (VC_ERROR_SERVICE_RESET == reason) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] VC daemon reset"); + + vc_client_set_client_state(g_vc, VC_STATE_INITIALIZED); + __vc_notify_state_changed(g_vc); + + if (0 != vc_prepare()) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to prepare"); + } + } + + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Error reason(%d), msg(%s)", reason, msg); + vc_client_set_error(g_vc, reason); ecore_timer_add(0, __vc_notify_error, g_vc); @@ -1321,6 +1640,59 @@ void __vc_cb_result(void) return; } +int vc_get_result(vc_result_cb callback, void* user_data) +{ + if (0 != __vc_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + if (0 != __vc_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + + SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Get result"); + + if (NULL == callback) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Client result callback is NULL"); + return VC_ERROR_INVALID_PARAMETER; + } + + char* temp_text = NULL; + int event = 0; + vc_cmd_list_h vc_cmd_list = NULL; + + if (0 != vc_cmd_list_create(&vc_cmd_list)) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to create command list"); + return VC_ERROR_INVALID_PARAMETER; + } + + int ret = vc_info_parser_get_result(&temp_text, &event, NULL, getpid(), vc_cmd_list, false); + if (0 != ret || NULL == temp_text) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get result, ret(%d) temp_text(%s)", ret, temp_text); + return ret; + } + + SLOG(LOG_DEBUG, TAG_VCC, "Result info : result text(%s) event(%d)", temp_text, event); + + vc_cmd_print_list(vc_cmd_list); + + vc_client_use_callback(g_vc); + callback(event, vc_cmd_list, temp_text, user_data); + vc_client_not_use_callback(g_vc); + + vc_cmd_list_destroy(vc_cmd_list, true); + + /* Release result */ + if (NULL != temp_text) { + free(temp_text); + temp_text = NULL; + } + + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + + return VC_ERROR_NONE; +} + int vc_set_result_cb(vc_result_cb callback, void* user_data) { if (0 != __vc_get_feature_enabled()) { @@ -1628,6 +2000,91 @@ int vc_unset_error_cb(void) return 0; } +int vc_set_invocation_name(const char* name) +{ + if (0 != __vc_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + if (0 != __vc_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + + vc_state_e state; + SLOG(LOG_DEBUG, TAG_VCC, "===== Set invocation name"); + + int ret = vc_client_get_client_state(g_vc, &state); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not valid"); + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + return ret; + } + + /* check state */ + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'READY'"); + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + return VC_ERROR_INVALID_STATE; + } + + ret = vc_client_set_invocation_name(g_vc, name); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set invocation name"); + } + return ret; +} + +int vc_dialog(const char* disp_text, const char* utt_text, bool continuous) +{ + vc_state_e state; + + SLOG(LOG_DEBUG, TAG_VCC, "===== Request dialog"); + if (0 != __vc_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + if (0 != __vc_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + + if (0 != vc_client_get_client_state(g_vc, &state)) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not valid"); + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'READY'"); + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + return VC_ERROR_INVALID_STATE; + } + + /* Check service state */ + vc_service_state_e service_state = -1; + vc_client_get_service_state(g_vc, &service_state); + if (service_state != VC_SERVICE_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: service state is not 'READY'"); + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + return VC_ERROR_INVALID_STATE; + } + + SLOG(LOG_DEBUG, TAG_VCC, "Request dialog : pid(%d) disp_text(%s), utt_text(%s), continuous(%d)", getpid(), disp_text, utt_text, continuous); + int ret = vc_dbus_request_dialog(getpid(), disp_text, utt_text, continuous); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set foreground (true) : %d", ret); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + + return VC_ERROR_NONE; +} + /* Authority */ int vc_auth_enable(void) { diff --git a/client/vc_client.c b/client/vc_client.c index 5f2d6b3..2602c1a 100644 --- a/client/vc_client.c +++ b/client/vc_client.c @@ -63,6 +63,9 @@ typedef struct { /* is foreground */ bool is_foreground; + + /* Invocation name */ + char* invocation_name; } vc_client_s; /* client list */ @@ -149,6 +152,7 @@ int vc_client_create(vc_h* vc) client->auth_state_changed_user_data = NULL; client->is_foreground = false; + client->invocation_name = NULL; g_client_list = g_slist_append(g_client_list, client); @@ -179,9 +183,14 @@ int vc_client_destroy(vc_h vc) while (0 != data->cb_ref_count) { /* wait for release callback function */ } + if (NULL != data->invocation_name) { + free(data->invocation_name); + data->invocation_name = NULL; + } free(data); free(vc); - + data = NULL; + vc = NULL; return 0; } } @@ -477,6 +486,37 @@ int vc_client_get_before_state(vc_h vc, vc_state_e* state, vc_state_e* before_st return 0; } +int vc_client_set_invocation_name(vc_h vc, const char* invocation_name) +{ + vc_client_s* client = __client_get(vc); + + /* check handle */ + if (NULL == client) + return VC_ERROR_INVALID_PARAMETER; + + if (NULL != invocation_name) { + client->invocation_name = strdup(invocation_name); + } else { + if (NULL != client->invocation_name) + free(client->invocation_name); + client->invocation_name = NULL; + } + return 0; +} + +int vc_client_get_invocation_name(vc_h vc, char** invocation_name) +{ + vc_client_s* client = __client_get(vc); + + /* check handle */ + if (NULL == client) + return VC_ERROR_INVALID_PARAMETER; + + if (NULL != client->invocation_name) + *invocation_name = strdup(client->invocation_name); + return 0; +} + int vc_client_set_xid(vc_h vc, int xid) { vc_client_s* client = __client_get(vc); @@ -721,4 +761,4 @@ int vc_client_get_mgr_pid(vc_h vc, int* mgr_pid) *mgr_pid = client->mgr_pid; return 0; -} \ No newline at end of file +} diff --git a/client/vc_client.h b/client/vc_client.h index 0067ec3..0d03bda 100644 --- a/client/vc_client.h +++ b/client/vc_client.h @@ -80,6 +80,10 @@ int vc_client_get_client_state_by_uid(int uid, vc_state_e* state); int vc_client_get_before_state(vc_h vc, vc_state_e* state, vc_state_e* before_state); +int vc_client_set_invocation_name(vc_h vc, const char* invocation_name); + +int vc_client_get_invocation_name(vc_h vc, char** invocation_name); + int vc_client_set_xid(vc_h vc, int xid); int vc_client_get_xid(vc_h vc, int* xid); diff --git a/client/vc_dbus.c b/client/vc_dbus.c index 22171c5..1cd3270 100644 --- a/client/vc_dbus.c +++ b/client/vc_dbus.c @@ -27,7 +27,7 @@ static Ecore_Fd_Handler* g_fd_handler = NULL; static DBusConnection* g_conn_sender = NULL; static DBusConnection* g_conn_listener = NULL; -extern int __vc_cb_error(int pid, int reason); +extern int __vc_cb_error(int reason, int daemon_pid, char* msg); extern void __vc_cb_result(); @@ -120,15 +120,15 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle } /* VCD_METHOD_RESULT */ - else if (dbus_message_is_method_call(msg, if_name, VCD_METHOD_ERROR)) { + else if (dbus_message_is_signal(msg, if_name, VCD_METHOD_ERROR)) { SLOG(LOG_DEBUG, TAG_VCC, "===== Get Error"); - int pid; int reason; + int daemon_pid; char* err_msg; dbus_message_get_args(msg, &err, - DBUS_TYPE_INT32, &pid, DBUS_TYPE_INT32, &reason, + DBUS_TYPE_INT32, &daemon_pid, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); @@ -136,8 +136,8 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle SLOG(LOG_ERROR, TAG_VCC, "<<<< vc Get Error message : Get arguments error (%s)", err.message); dbus_error_free(&err); } else { - SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc Get Error message : pid(%d), reason(%d), msg(%s)", pid, reason, err_msg); - __vc_cb_error(pid, reason); + SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc Get Error message : reason(%d), daemon_pid(%d), msg(%s)", reason, daemon_pid, err_msg); + __vc_cb_error(reason, daemon_pid, err_msg); } SLOG(LOG_DEBUG, TAG_VCC, "====="); @@ -360,7 +360,7 @@ int vc_dbus_request_hello() } -int vc_dbus_request_initialize(int pid, int* mgr_pid, int* service_state) +int vc_dbus_request_initialize(int pid, int* mgr_pid, int* service_state, int* daemon_pid) { if (0 != __dbus_check()) { return VC_ERROR_OPERATION_FAILED; @@ -402,10 +402,12 @@ int vc_dbus_request_initialize(int pid, int* mgr_pid, int* service_state) if (NULL != result_msg) { int tmp = -1; int tmp_service_state = 0; + int tmp_daemon_pid = 0; dbus_message_get_args(result_msg, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INT32, &tmp, DBUS_TYPE_INT32, &tmp_service_state, + DBUS_TYPE_INT32, &tmp_daemon_pid, DBUS_TYPE_INVALID); if (dbus_error_is_set(&err)) { @@ -419,7 +421,8 @@ int vc_dbus_request_initialize(int pid, int* mgr_pid, int* service_state) if (0 == result) { *mgr_pid = tmp; *service_state = tmp_service_state; - SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc initialize : result = %d mgr = %d service = %d", result, *mgr_pid, *service_state); + *daemon_pid = tmp_daemon_pid; + SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc initialize : result = %d mgr = %d service = %d daemon_pid = %d", result, *mgr_pid, *service_state, *daemon_pid); } else { SLOG(LOG_ERROR, TAG_VCC, "<<<< vc initialize : result = %d", result); } @@ -764,6 +767,152 @@ int vc_dbus_set_foreground(int pid, bool value) return 0; } +int vc_dbus_request_dialog(int pid, const char* disp_text, const char* utt_text, bool continuous) +{ + if (NULL == g_conn_sender) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] NULL connection"); + if (0 != vc_dbus_reconnect()) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to reconnect"); + } + } + + DBusMessage* msg; + int tmp_continue = 0; + + tmp_continue = (int)continuous; + + msg = dbus_message_new_method_call( + VC_SERVER_SERVICE_NAME, + VC_SERVER_SERVICE_OBJECT_PATH, + VC_SERVER_SERVICE_INTERFACE, + VC_METHOD_DIALOG); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCC, ">>>> vc request dialog to manager : Fail to make message"); + return VC_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc request dialog to manager : client pid(%d), disp_text(%s), utt_text(%s), continuous(%d)", getpid(), disp_text, utt_text, continuous); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &disp_text, + DBUS_TYPE_STRING, &utt_text, + DBUS_TYPE_INT32, &tmp_continue, + DBUS_TYPE_INVALID); + + DBusError err; + dbus_error_init(&err); + + DBusMessage* result_msg; + int result = VC_ERROR_OPERATION_FAILED; + + result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, g_waiting_time, &err); + dbus_message_unref(msg); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message); + dbus_error_free(&err); + } + + if (NULL != result_msg) { + dbus_message_get_args(result_msg, &err, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message); + dbus_error_free(&err); + result = VC_ERROR_OPERATION_FAILED; + } + dbus_message_unref(result_msg); + + if (0 == result) { + SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc set command : result = %d", result); + } else { + SLOG(LOG_ERROR, TAG_VCC, "<<<< vc set command : result = %d", result); + } + } else { + SLOG(LOG_ERROR, TAG_VCC, "<<<< Result message is NULL"); + vc_dbus_reconnect(); + result = VC_ERROR_TIMED_OUT; + } + + return result; +} + +int vc_dbus_request_is_system_command_valid(int pid, bool* is_sys_cmd_valid) +{ + if (NULL == g_conn_sender) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] NULL connection"); + if (0 != vc_dbus_reconnect()) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to reconnect"); + } + } + + DBusMessage* msg; + + msg = dbus_message_new_method_call( + VC_SERVER_SERVICE_NAME, + VC_SERVER_SERVICE_OBJECT_PATH, + VC_SERVER_SERVICE_INTERFACE, + VC_METHOD_IS_SYS_COMMAND_VALID); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCC, ">>>> vc is system command valid : Fail to make message"); + return VC_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc is system command valid : pid(%d)", pid); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INVALID); + + DBusError err; + dbus_error_init(&err); + int tmp_sys_cmd = 0; + + DBusMessage* result_msg; + int result = VC_ERROR_OPERATION_FAILED; + + result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, g_waiting_time, &err); + dbus_message_unref(msg); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message); + dbus_error_free(&err); + } + + if (NULL != result_msg) { + dbus_message_get_args(result_msg, &err, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_INT32, &tmp_sys_cmd, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message); + dbus_error_free(&err); + result = VC_ERROR_OPERATION_FAILED; + } + dbus_message_unref(result_msg); + + if (0 == result) { + *is_sys_cmd_valid = (bool)tmp_sys_cmd; + SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc is system command valid : result = %d, is_sys_cmd_valid = %d", result, *is_sys_cmd_valid); + } else { + SLOG(LOG_ERROR, TAG_VCC, "<<<< vc is system command valid : result = %d", result); + } + } else { + SLOG(LOG_ERROR, TAG_VCC, "<<<< Result message is NULL"); + vc_dbus_reconnect(); + result = VC_ERROR_TIMED_OUT; + } + + return result; +} + + #if 0 int vc_dbus_request_start(int pid, int silence) { diff --git a/client/vc_dbus.h b/client/vc_dbus.h index 7a6f811..a3fd996 100644 --- a/client/vc_dbus.h +++ b/client/vc_dbus.h @@ -30,7 +30,7 @@ int vc_dbus_close_connection(); int vc_dbus_request_hello(); -int vc_dbus_request_initialize(int pid, int* mgr_pid, int* service_state); +int vc_dbus_request_initialize(int pid, int* mgr_pid, int* service_state, int* daemon_pid); int vc_dbus_request_finalize(int pid); @@ -42,6 +42,10 @@ int vc_dbus_request_unset_command(int pid, vc_cmd_type_e cmd_type); int vc_dbus_set_foreground(int pid, bool value); +int vc_dbus_request_dialog(int pid, const char* disp_text, const char* utt_text, bool continuous); + +int vc_dbus_request_is_system_command_valid(int pid, bool* is_sys_cmd_valid); + #if 0 int vc_dbus_request_start(int pid, int silence); diff --git a/client/vc_mgr.c b/client/vc_mgr.c index e3a2f21..f7aed98 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -14,12 +14,15 @@ * limitations under the License. */ +#include #include #include -#include "vc_info_parser.h" +#include "vc_cmd_db.h" #include "vc_config_mgr.h" #include "vc_command.h" +#include "vc_info_parser.h" +#include "vc_json_parser.h" #include "vc_main.h" #include "vc_mgr_client.h" #include "vc_mgr_dbus.h" @@ -115,7 +118,7 @@ int vc_mgr_initialize() { SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Initialize"); - + if (0 != __vc_mgr_get_feature_enabled()) { SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] not supported"); return VC_ERROR_NOT_SUPPORTED; @@ -152,6 +155,14 @@ int vc_mgr_initialize() return VC_ERROR_OPERATION_FAILED; } + ret = vc_db_initialize(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to initialize DB : %d", ret); + vc_config_mgr_finalize(g_vc_m->handle + VC_MANAGER_CONFIG_HANDLE); + vc_mgr_client_destroy(g_vc_m); + return ret; + } + SLOG(LOG_DEBUG, TAG_VCM, "[Success] pid(%d)", g_vc_m->handle); SLOG(LOG_DEBUG, TAG_VCM, "====="); @@ -166,10 +177,6 @@ static void __vc_mgr_internal_unprepare() if (0 != ret) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request finalize : %s", __vc_mgr_get_error_code(ret)); } - - vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_SYSTEM); - vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_EXCLUSIVE); - return; } @@ -211,6 +218,18 @@ int vc_mgr_deinitialize() SLOG(LOG_DEBUG, TAG_VCM, "Success: destroy"); + int cnt = VC_COMMAND_TYPE_FOREGROUND; + do { + int ret = vc_cmd_parser_delete_file(getpid(), cnt); + if (0 != ret) + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to delete file, type(%d), ret(%d)", cnt, ret); + } while (VC_COMMAND_TYPE_EXCLUSIVE >= ++cnt); + + int ret = vc_db_finalize(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to finalize DB, ret(%d)", ret); + } + if (0 != vc_mgr_dbus_close_connection()) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to close connection"); } @@ -604,10 +623,12 @@ int vc_mgr_is_command_format_supported(vc_cmd_format_e format, bool* support) } switch (format) { - case VC_CMD_FORMAT_FIXED: *support = true; break; - case VC_CMD_FORMAT_FIXED_AND_EXTRA: *support = non_fixed_support; break; - case VC_CMD_FORMAT_EXTRA_AND_FIXED: *support = non_fixed_support; break; - default: *support = false; + case VC_CMD_FORMAT_FIXED: *support = true; break; + case VC_CMD_FORMAT_FIXED_AND_VFIXED: *support = true; break; + case VC_CMD_FORMAT_VFIXED_AND_FIXED: *support = true; break; + case VC_CMD_FORMAT_FIXED_AND_NONFIXED: *support = non_fixed_support; break; + case VC_CMD_FORMAT_NONFIXED_AND_FIXED: *support = non_fixed_support; break; + default: *support = false; break; } SLOG(LOG_ERROR, TAG_VCM, "[DEBUG] Format(%d) support(%s)", format, *support ? "true" : "false"); @@ -651,11 +672,24 @@ int vc_mgr_set_command_list(vc_cmd_list_h vc_cmd_list) vc_cmd_list_s* list = NULL; list = (vc_cmd_list_s*)vc_cmd_list; - int system_ret = vc_cmd_parser_save_file(getpid(), VC_COMMAND_TYPE_SYSTEM, list->list); - int exclsive_ret = vc_cmd_parser_save_file(getpid(), VC_COMMAND_TYPE_EXCLUSIVE, list->list); - int ret = 0; + int i; + int ret; + bool success_save = false; + for (i = VC_COMMAND_TYPE_FOREGROUND; i <= VC_COMMAND_TYPE_EXCLUSIVE; i++) { + ret = vc_cmd_parser_delete_file(getpid(), i); + if (0 != ret) + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to delete file, type(%d), ret(%d)", i, ret); + + ret = vc_cmd_parser_save_file(getpid(), i, list->list, NULL); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to save file, type(%d), ret(%d)", i, ret); + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Save file, type(%d)", i); + success_save = true; + } + } - if (0 != system_ret && 0 != exclsive_ret) { + if (true != success_save) { ret = VC_ERROR_INVALID_PARAMETER; SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to save command group : %s", __vc_mgr_get_error_code(ret)); } else { @@ -721,8 +755,12 @@ int vc_mgr_unset_command_list() } } - vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_SYSTEM); - vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_EXCLUSIVE); + int i; + for (i = VC_COMMAND_TYPE_FOREGROUND; i <= VC_COMMAND_TYPE_EXCLUSIVE; i++) { + ret = vc_cmd_parser_delete_file(getpid(), i); + if (0 != ret) + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to delete file, type(%d), ret(%d)", i, ret); + } SLOG(LOG_DEBUG, TAG_VCM, "====="); SLOG(LOG_DEBUG, TAG_VCM, " "); @@ -730,6 +768,113 @@ int vc_mgr_unset_command_list() return 0; } +int vc_mgr_set_command_list_from_file(const char* file_path, int type) +{ + SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Set Command list from file"); + + if (NULL == file_path) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter!!"); + return VC_ERROR_INVALID_PARAMETER; + } else { + SLOG(LOG_DEBUG, TAG_VCM, "===== File path: %s", file_path); + } + + /* check type */ + if (VC_COMMAND_TYPE_FOREGROUND > type || VC_COMMAND_TYPE_EXCLUSIVE < type) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid command type: input type is %d", type); + SLOG(LOG_DEBUG, TAG_VCC, "====="); + SLOG(LOG_DEBUG, TAG_VCC, " "); + return VC_ERROR_INVALID_PARAMETER; + } + + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'"); + return VC_ERROR_INVALID_STATE; + } + + /* Check service state */ + vc_service_state_e service_state = -1; + vc_mgr_client_get_service_state(g_vc_m, &service_state); + if (service_state != VC_SERVICE_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'READY'"); + return VC_ERROR_INVALID_STATE; + } + + int ret = vc_cmd_parser_delete_file(getpid(), type); + if (0 != ret) + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to delete file, type(4), ret(%d)", ret); + + if (0 != vc_json_set_commands_from_file(file_path, type, NULL)) { + ret = VC_ERROR_INVALID_PARAMETER; + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to save command list (%d)", ret); + } else { + int count = 0; + do { + ret = vc_mgr_dbus_request_set_command(g_vc_m->handle); + if (0 != ret) { + if (VC_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request set command to daemon : %s", __vc_mgr_get_error_code(ret)); + break; + } else { + SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry request set command : %s", __vc_mgr_get_error_code(ret)); + usleep(10000); + count++; + if (VC_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request"); + break; + } + } + } + } while (0 != ret); + } + + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + + return ret; +} + +int vc_mgr_set_preloaded_commands_from_file(const char* file_path) +{ + SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Set preloaded command list"); + + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'"); + return VC_ERROR_INVALID_STATE; + } + + /* Check service state */ + vc_service_state_e service_state = -1; + vc_mgr_client_get_service_state(g_vc_m, &service_state); + if (service_state != VC_SERVICE_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'READY'"); + return VC_ERROR_INVALID_STATE; + } + + /* Only support to set background commands for preloaded application */ + int ret = vc_json_set_commands_from_file(file_path, VC_COMMAND_TYPE_BACKGROUND, NULL); + if (0 != ret) + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to insert preloaded commands into db"); + + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + return ret; +} + int vc_mgr_set_audio_type(const char* audio_id) { SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Set audio type"); @@ -838,11 +983,6 @@ int vc_mgr_get_audio_type(char** audio_id) vc_mgr_client_get_audio_type(g_vc_m, &temp); - if (NULL != temp) { - free(temp); - temp = NULL; - } - if (NULL == temp) { /* Not initiallized */ int ret = -1; @@ -1126,9 +1266,14 @@ int vc_mgr_get_recognition_mode(vc_recognition_mode_e* mode) return 0; } -int vc_mgr_start(bool exclusive_command_option) +int vc_mgr_set_private_data(const char* key, const char* data) { - SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Request start"); + SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Set private data"); + + if (NULL == key) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter"); + return VC_ERROR_INVALID_PARAMETER; + } vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { @@ -1156,53 +1301,41 @@ int vc_mgr_start(bool exclusive_command_option) return VC_ERROR_INVALID_STATE; } - vc_mgr_client_set_exclusive_command(g_vc_m, exclusive_command_option); - - bool start_by_client = false; - if (0 != vc_mgr_client_get_start_by_client(g_vc_m, &start_by_client)) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get start by client"); - } - - int ret; + int ret = -1; int count = 0; - vc_recognition_mode_e recognition_mode = VC_RECOGNITION_MODE_STOP_BY_SILENCE; - if (0 != vc_mgr_get_recognition_mode(&recognition_mode)) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get recognition mode"); - } - - /* Request */ - ret = -1; - count = 0; while (0 != ret) { - ret = vc_mgr_dbus_request_start(g_vc_m->handle, (int)recognition_mode, exclusive_command_option, start_by_client); + ret = vc_mgr_dbus_request_set_private_data(g_vc_m->handle, key, data); if (0 != ret) { if (VC_ERROR_TIMED_OUT != ret) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to start request start : %s", __vc_mgr_get_error_code(ret)); + SLOG(LOG_DEBUG, TAG_VCM, "[ERROR] Fail to set private data request : %s", __vc_mgr_get_error_code(ret)); break; } else { - SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry start request start : %s", __vc_mgr_get_error_code(ret)); + SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry set private data request : %s", __vc_mgr_get_error_code(ret)); usleep(10000); count++; if (VC_RETRY_COUNT == count) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request"); - vc_mgr_client_set_exclusive_command(g_vc_m, false); break; } } } else { - SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] start recognition"); + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Set domain"); } } - SLOG(LOG_DEBUG, TAG_VCM, "====="); SLOG(LOG_DEBUG, TAG_VCM, " "); - return ret; + return 0; } -int vc_mgr_stop() +int vc_mgr_get_private_data(const char* key, char** data) { - SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Request stop"); + SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Get private data"); + + if (NULL == key || NULL == data) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter"); + return VC_ERROR_INVALID_PARAMETER; + } vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { @@ -1214,7 +1347,7 @@ int vc_mgr_stop() /* check state */ if (state != VC_STATE_READY) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: client state is not 'READY'"); + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'"); SLOG(LOG_DEBUG, TAG_VCM, "====="); SLOG(LOG_DEBUG, TAG_VCM, " "); return VC_ERROR_INVALID_STATE; @@ -1223,8 +1356,8 @@ int vc_mgr_stop() /* Check service state */ vc_service_state_e service_state = -1; vc_mgr_client_get_service_state(g_vc_m, &service_state); - if (service_state != VC_SERVICE_STATE_RECORDING) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'RECORDING'"); + if (service_state != VC_SERVICE_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'READY'"); SLOG(LOG_DEBUG, TAG_VCM, "====="); SLOG(LOG_DEBUG, TAG_VCM, " "); return VC_ERROR_INVALID_STATE; @@ -1232,15 +1365,16 @@ int vc_mgr_stop() int ret = -1; int count = 0; - /* do request */ + char* temp = NULL; + while (0 != ret) { - ret = vc_mgr_dbus_request_stop(g_vc_m->handle); + ret = vc_mgr_dbus_request_get_private_data(g_vc_m->handle, key, &temp); if (0 != ret) { if (VC_ERROR_TIMED_OUT != ret) { - SLOG(LOG_DEBUG, TAG_VCM, "[ERROR] Fail to stop request : %s", __vc_mgr_get_error_code(ret)); + SLOG(LOG_DEBUG, TAG_VCM, "[ERROR] Fail to get private data request : %s", __vc_mgr_get_error_code(ret)); break; } else { - SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry stop request : %s", __vc_mgr_get_error_code(ret)); + SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry get private data request : %s", __vc_mgr_get_error_code(ret)); usleep(10000); count++; if (VC_RETRY_COUNT == count) { @@ -1249,19 +1383,30 @@ int vc_mgr_stop() } } } else { - SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Stop recognition"); + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Get private data, key(%s), data(%s)", key, temp); } } + if (NULL != temp) { + *data = strdup(temp); + free(temp); + temp = NULL; + } + SLOG(LOG_DEBUG, TAG_VCM, "====="); SLOG(LOG_DEBUG, TAG_VCM, " "); - return ret; + return 0; } -int vc_mgr_cancel() +int vc_mgr_set_domain(const char* domain) { - SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Request cancel"); + SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Set domain"); + + if (NULL == domain) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter"); + return VC_ERROR_INVALID_PARAMETER; + } vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { @@ -1273,7 +1418,7 @@ int vc_mgr_cancel() /* check state */ if (state != VC_STATE_READY) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: client state is not 'READY'"); + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'"); SLOG(LOG_DEBUG, TAG_VCM, "====="); SLOG(LOG_DEBUG, TAG_VCM, " "); return VC_ERROR_INVALID_STATE; @@ -1282,8 +1427,8 @@ int vc_mgr_cancel() /* Check service state */ vc_service_state_e service_state = -1; vc_mgr_client_get_service_state(g_vc_m, &service_state); - if (service_state != VC_SERVICE_STATE_RECORDING && service_state != VC_SERVICE_STATE_PROCESSING) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'RECORDING' or 'PROCESSING'"); + if (service_state != VC_SERVICE_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'READY'"); SLOG(LOG_DEBUG, TAG_VCM, "====="); SLOG(LOG_DEBUG, TAG_VCM, " "); return VC_ERROR_INVALID_STATE; @@ -1292,13 +1437,13 @@ int vc_mgr_cancel() int ret = -1; int count = 0; while (0 != ret) { - ret = vc_mgr_dbus_request_cancel(g_vc_m->handle); + ret = vc_mgr_dbus_request_set_domain(g_vc_m->handle, domain); if (0 != ret) { if (VC_ERROR_TIMED_OUT != ret) { - SLOG(LOG_DEBUG, TAG_VCM, "[ERROR] Fail to cancel request : %s", __vc_mgr_get_error_code(ret)); + SLOG(LOG_DEBUG, TAG_VCM, "[ERROR] Fail to set domain request : %s", __vc_mgr_get_error_code(ret)); break; } else { - SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry cancel request : %s", __vc_mgr_get_error_code(ret)); + SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry set domain request : %s", __vc_mgr_get_error_code(ret)); usleep(10000); count++; if (VC_RETRY_COUNT == count) { @@ -1307,62 +1452,314 @@ int vc_mgr_cancel() } } } else { - SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Cancel recognition"); + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Set domain"); } } - - vc_mgr_client_set_exclusive_command(g_vc_m, false); - SLOG(LOG_DEBUG, TAG_VCM, "====="); SLOG(LOG_DEBUG, TAG_VCM, " "); - return ret; -} - -int __vc_mgr_cb_set_volume(float volume) -{ - g_volume_db = volume; - SLOG(LOG_DEBUG, TAG_VCM, "Set volume (%f)", g_volume_db); - return 0; } -int vc_mgr_get_recording_volume(float* volume) +int vc_mgr_do_action(vc_send_event_type_e type, char* send_event) { - if (NULL == volume) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL"); + SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] do action"); + + if (NULL == send_event) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter"); return VC_ERROR_INVALID_PARAMETER; } - vc_service_state_e service_state = -1; - if (0 != vc_mgr_client_get_service_state(g_vc_m, &service_state)) { + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available"); + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); return VC_ERROR_INVALID_STATE; } /* check state */ - if (VC_SERVICE_STATE_RECORDING != service_state) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Service state is not 'RECORDING'"); + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'"); + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); return VC_ERROR_INVALID_STATE; } - *volume = g_volume_db; + /* Check service state */ + vc_service_state_e service_state = -1; + vc_mgr_client_get_service_state(g_vc_m, &service_state); + if (service_state != VC_SERVICE_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'READY'"); + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + return VC_ERROR_INVALID_STATE; + } + + int ret = -1; + int count = 0; + while (0 != ret) { + ret = vc_mgr_dbus_request_do_action(g_vc_m->handle, type, send_event); + if (0 != ret) { + if (VC_ERROR_TIMED_OUT != ret) { + SLOG(LOG_DEBUG, TAG_VCM, "[ERROR] Fail to do action request : %s", __vc_mgr_get_error_code(ret)); + break; + } else { + SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry do action request : %s", __vc_mgr_get_error_code(ret)); + usleep(10000); + count++; + if (VC_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request"); + break; + } + } + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] do action"); + } + } + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); return 0; } -int __vc_mgr_cb_set_foreground(int pid, bool value) +int vc_mgr_start(bool exclusive_command_option) { - vc_mgr_client_set_foreground(g_vc_m, pid, value); + SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Request start"); - /* get authorized valid app */ - int tmp_pid; - if (0 != vc_mgr_client_get_valid_authorized_client(g_vc_m, &tmp_pid)) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get authorized valid app"); - return VC_ERROR_INVALID_PARAMETER; + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available"); + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + return VC_ERROR_INVALID_STATE; } - if (true == value) { + /* check state */ + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'"); + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + return VC_ERROR_INVALID_STATE; + } + + /* Check service state */ + vc_service_state_e service_state = -1; + vc_mgr_client_get_service_state(g_vc_m, &service_state); + if (service_state != VC_SERVICE_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'READY'"); + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + return VC_ERROR_INVALID_STATE; + } + + vc_mgr_client_set_exclusive_command(g_vc_m, exclusive_command_option); + + bool start_by_client = false; + if (0 != vc_mgr_client_get_start_by_client(g_vc_m, &start_by_client)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get start by client"); + } + + int ret; + int count = 0; + vc_recognition_mode_e recognition_mode = VC_RECOGNITION_MODE_STOP_BY_SILENCE; + if (0 != vc_mgr_get_recognition_mode(&recognition_mode)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get recognition mode"); + } + + /* Request */ + ret = -1; + count = 0; + while (0 != ret) { + ret = vc_mgr_dbus_request_start(g_vc_m->handle, (int)recognition_mode, exclusive_command_option, start_by_client); + if (0 != ret) { + if (VC_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to start request start : %s", __vc_mgr_get_error_code(ret)); + break; + } else { + SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry start request start : %s", __vc_mgr_get_error_code(ret)); + usleep(10000); + count++; + if (VC_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request"); + vc_mgr_client_set_exclusive_command(g_vc_m, false); + break; + } + } + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] start recognition"); + } + } + + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + + return ret; +} + +int vc_mgr_stop() +{ + SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Request stop"); + + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available"); + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: client state is not 'READY'"); + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + return VC_ERROR_INVALID_STATE; + } + + /* Check service state */ + vc_service_state_e service_state = -1; + vc_mgr_client_get_service_state(g_vc_m, &service_state); + if (service_state != VC_SERVICE_STATE_RECORDING) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'RECORDING'"); + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + return VC_ERROR_INVALID_STATE; + } + + int ret = -1; + int count = 0; + /* do request */ + while (0 != ret) { + ret = vc_mgr_dbus_request_stop(g_vc_m->handle); + if (0 != ret) { + if (VC_ERROR_TIMED_OUT != ret) { + SLOG(LOG_DEBUG, TAG_VCM, "[ERROR] Fail to stop request : %s", __vc_mgr_get_error_code(ret)); + break; + } else { + SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry stop request : %s", __vc_mgr_get_error_code(ret)); + usleep(10000); + count++; + if (VC_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request"); + break; + } + } + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Stop recognition"); + } + } + + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + + return ret; +} + +int vc_mgr_cancel() +{ + SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Request cancel"); + + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available"); + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: client state is not 'READY'"); + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + return VC_ERROR_INVALID_STATE; + } + + /* Check service state */ + vc_service_state_e service_state = -1; + vc_mgr_client_get_service_state(g_vc_m, &service_state); + if (service_state != VC_SERVICE_STATE_RECORDING && service_state != VC_SERVICE_STATE_PROCESSING) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'RECORDING' or 'PROCESSING'"); + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + return VC_ERROR_INVALID_STATE; + } + + int ret = -1; + int count = 0; + while (0 != ret) { + ret = vc_mgr_dbus_request_cancel(g_vc_m->handle); + if (0 != ret) { + if (VC_ERROR_TIMED_OUT != ret) { + SLOG(LOG_DEBUG, TAG_VCM, "[ERROR] Fail to cancel request : %s", __vc_mgr_get_error_code(ret)); + break; + } else { + SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry cancel request : %s", __vc_mgr_get_error_code(ret)); + usleep(10000); + count++; + if (VC_RETRY_COUNT == count) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request"); + break; + } + } + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Cancel recognition"); + } + } + + vc_mgr_client_set_exclusive_command(g_vc_m, false); + + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + + return ret; +} + +int __vc_mgr_cb_set_volume(float volume) +{ + g_volume_db = volume; + SLOG(LOG_DEBUG, TAG_VCM, "Set volume (%f)", g_volume_db); + + return 0; +} + +int vc_mgr_get_recording_volume(float* volume) +{ + if (NULL == volume) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL"); + return VC_ERROR_INVALID_PARAMETER; + } + + vc_service_state_e service_state = -1; + if (0 != vc_mgr_client_get_service_state(g_vc_m, &service_state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (VC_SERVICE_STATE_RECORDING != service_state) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Service state is not 'RECORDING'"); + return VC_ERROR_INVALID_STATE; + } + + *volume = g_volume_db; + + return 0; +} + +int __vc_mgr_cb_set_foreground(int pid, bool value) +{ + vc_mgr_client_set_foreground(g_vc_m, pid, value); + + /* get authorized valid app */ + int tmp_pid; + if (0 != vc_mgr_client_get_valid_authorized_client(g_vc_m, &tmp_pid)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get authorized valid app"); + return VC_ERROR_INVALID_PARAMETER; + } + + if (true == value) { /* compare & set valid */ if (tmp_pid != pid) { SLOG(LOG_DEBUG, TAG_VCM, "Authority(%d) changed to invalid", tmp_pid); @@ -1460,85 +1857,6 @@ static Eina_Bool __vc_mgr_set_select_result(void *data) return EINA_FALSE; } -int vc_mgr_get_nlp_info(char** info) -{ - SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Get nlp info"); - - vc_service_state_e service_state = -1; - vc_mgr_client_get_service_state(g_vc_m, &service_state); - if (service_state != VC_SERVICE_STATE_PROCESSING) { - vc_recognition_mode_e recognition_mode; - vc_mgr_get_recognition_mode(&recognition_mode); - - if (VC_RECOGNITION_MODE_RESTART_CONTINUOUSLY != recognition_mode) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'PROCESSING' and mode is not 'Restart continously'"); - SLOG(LOG_DEBUG, TAG_VCM, "====="); - SLOG(LOG_DEBUG, TAG_VCM, " "); - return VC_ERROR_INVALID_STATE; - } - } - - int ret = -1; - ret = vc_info_parser_get_nlp_info(info); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get nlp_info"); - } - - if (0 == strncmp(*info, "null", strlen("null"))) { - SLOG(LOG_DEBUG, TAG_VCM, "Get nlp info (NULL)"); - *info = NULL; - } - - SLOG(LOG_DEBUG, TAG_VCM, "====="); - SLOG(LOG_DEBUG, TAG_VCM, " "); - - return 0; -} - -int vc_mgr_set_pre_result_cb(vc_mgr_pre_result_cb callback, void* user_data) -{ - if (NULL == callback) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set error callback : callback is NULL"); - return VC_ERROR_INVALID_PARAMETER; - } - - vc_state_e state; - if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set error callback : A handle is not available"); - return VC_ERROR_INVALID_STATE; - } - - /* check state */ - if (state != VC_STATE_INITIALIZED) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set error callback : Current state is not 'Initialized'"); - return VC_ERROR_INVALID_STATE; - } - - vc_mgr_client_set_pre_result_cb(g_vc_m, callback, user_data); - - SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Set pre result callback"); - return 0; -} - -int vc_mgr_unset_pre_result_cb() -{ - vc_state_e state; - if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset error callback : A handle is not available"); - return VC_ERROR_INVALID_STATE; - } - - /* check state */ - if (state != VC_STATE_INITIALIZED) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset error callback : Current state is not 'Initialized'"); - return VC_ERROR_INVALID_STATE; - } - - vc_mgr_client_set_pre_result_cb(g_vc_m, NULL, NULL); - - return 0; -} - static void __vc_mgr_notify_all_result(vc_result_type_e result_type) { char* temp_text = NULL; @@ -1603,6 +1921,7 @@ static void __vc_mgr_notify_all_result(vc_result_type_e result_type) int count = 0; vc_cmd_list_get_count(vc_cmd_list, &count); if (0 < count) { + vc_mgr_client_set_all_result(g_vc_m, event, temp_text); if (true == cb_ret) { SLOG(LOG_DEBUG, TAG_VCM, "Callback result is true"); if (VC_RESULT_TYPE_NOTIFICATION != result_type) @@ -1610,8 +1929,6 @@ static void __vc_mgr_notify_all_result(vc_result_type_e result_type) } else { SLOG(LOG_DEBUG, TAG_VCM, "Callback result is false"); /* need to select conflicted result */ - - vc_mgr_client_set_all_result(g_vc_m, event, temp_text); } } else { if (VC_RESULT_TYPE_NOTIFICATION != result_type) @@ -1622,7 +1939,10 @@ static void __vc_mgr_notify_all_result(vc_result_type_e result_type) } /* Release result */ - if (NULL != temp_text) free(temp_text); + if (NULL != temp_text) { + free(temp_text); + temp_text = NULL; + } /* Release list */ vc_cmd_list_destroy(vc_cmd_list, true); @@ -1632,7 +1952,7 @@ static void __vc_mgr_notify_all_result(vc_result_type_e result_type) static Eina_Bool __vc_mgr_notify_result(void *data) { - char* temp_text; + char* temp_text = NULL; int event; vc_cmd_list_h vc_cmd_list = NULL; @@ -1669,53 +1989,32 @@ static Eina_Bool __vc_mgr_notify_result(void *data) return EINA_FALSE; } -static Eina_Bool __vc_mgr_notify_pre_result(void *data) +void __vc_mgr_cb_all_result(vc_result_type_e type) +{ + if (false == vc_mgr_client_get_exclusive_command(g_vc_m)) { + __vc_mgr_notify_all_result(type); + } else { + __vc_mgr_notify_result(0); + } + + return; +} + +void __vc_mgr_cb_pre_result(vc_pre_result_event_e event, const char* pre_result) { vc_mgr_pre_result_cb callback = NULL; void* user_data = NULL; - int event = -1; - char* pre_result = NULL; - vc_mgr_client_get_pre_resut_cb(g_vc_m, &callback, &user_data); + vc_mgr_client_get_pre_result_cb(g_vc_m, &callback, &user_data); if (NULL == callback) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Client speech detected callback is NULL"); - return EINA_FALSE; + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Client pre result callback is NULL"); + return; } - vc_mgr_client_get_pre_result(g_vc_m, &event, &pre_result); - vc_mgr_client_use_callback(g_vc_m); callback(event, pre_result, user_data); vc_mgr_client_not_use_callback(g_vc_m); - SLOG(LOG_DEBUG, TAG_VCM, "Speech detected callback called"); - - if (NULL != pre_result) { - free(pre_result); - } - - vc_mgr_client_unset_pre_result(g_vc_m); - - return EINA_FALSE; -} - -void __vc_mgr_cb_pre_result(int event, const char* pre_result) -{ - if (0 != vc_mgr_client_set_pre_result(g_vc_m, event, pre_result)) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Client speech detected callback is NULL"); - } - - ecore_timer_add(0, __vc_mgr_notify_pre_result, NULL); - - return; -} - -void __vc_mgr_cb_all_result(vc_result_type_e type) -{ - if (false == vc_mgr_client_get_exclusive_command(g_vc_m)) { - __vc_mgr_notify_all_result(type); - } else { - __vc_mgr_notify_result(0); - } + SLOG(LOG_DEBUG, TAG_VCM, "Pre result callback is called"); return; } @@ -1836,6 +2135,47 @@ int vc_mgr_unset_result_cb() return 0; } +int vc_mgr_set_pre_result_cb(vc_mgr_pre_result_cb callback, void* user_data) +{ + if (NULL == callback) + return VC_ERROR_INVALID_PARAMETER; + + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set pre result callback : A handle is not available"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_INITIALIZED) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set pre result callback : Current state is not 'Initialized'"); + return VC_ERROR_INVALID_STATE; + } + + vc_mgr_client_set_pre_result_cb(g_vc_m, callback, user_data); + + return 0; +} + +int vc_mgr_unset_pre_result_cb() +{ + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset pre result callback : A handle is not available"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_INITIALIZED) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset pre result callback : Current state is not 'Initialize'"); + return VC_ERROR_INVALID_STATE; + } + + vc_mgr_client_set_pre_result_cb(g_vc_m, NULL, NULL); + + return 0; +} + static Eina_Bool __vc_mgr_notify_error(void *data) { vc_h vc_m = (vc_h)data; @@ -1873,17 +2213,19 @@ int __vc_mgr_cb_error(int reason, int daemon_pid, char* msg) return -1; } - if ((daemon_pid == g_daemon_pid) && (VC_ERROR_SERVICE_RESET == reason)) { - SLOG(LOG_ERROR, TAG_VCM, "[WARNING] This is first initializing, not daemon reset"); - return -1; - } - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Error reason(%d), msg(%s)", reason, msg); - if (VC_ERROR_SERVICE_RESET == reason) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] VC daemon reset"); + vc_mgr_client_set_client_state(g_vc_m, VC_STATE_INITIALIZED); - __vc_mgr_notify_state_changed(NULL); + __vc_mgr_notify_state_changed(g_vc_m); + + if (0 != vc_mgr_prepare()) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to prepare"); + } } + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Error reason(%d), msg(%s)", reason, msg); + vc_mgr_client_set_error(g_vc_m, reason); __vc_mgr_notify_error(g_vc_m); @@ -2155,6 +2497,66 @@ int vc_mgr_unset_error_cb() return 0; } +int __vc_mgr_cb_dialog(int pid, const char* disp_text, const char* utt_text, bool continuous) +{ + vc_mgr_dialog_request_cb callback = NULL; + void* user_data = NULL; + + vc_mgr_client_get_dialog_request_cb(g_vc_m, &callback, &user_data); + + if (NULL != callback) { + vc_mgr_client_use_callback(g_vc_m); + callback(pid, disp_text, utt_text, continuous, user_data); + vc_mgr_client_not_use_callback(g_vc_m); + SLOG(LOG_DEBUG, TAG_VCM, "Error callback is called"); + } else { + SLOG(LOG_WARN, TAG_VCM, "[WARNING] Error callback is null"); + } + + return 0; +} + +int vc_mgr_set_dialog_request_cb(vc_mgr_dialog_request_cb callback, void* user_data) +{ + if (NULL == callback) + return VC_ERROR_INVALID_PARAMETER; + + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set error callback : A handle is not available"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_INITIALIZED) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set error callback : Current state is not 'Initialized'"); + return VC_ERROR_INVALID_STATE; + } + + vc_mgr_client_set_dialog_request_cb(g_vc_m, callback, user_data); + + return 0; +} + +int vc_mgr_unset_dialog_request_cb() +{ + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset error callback : A handle is not available"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_INITIALIZED) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset error callback : Current state is not 'Initialized'"); + return VC_ERROR_INVALID_STATE; + } + + vc_mgr_client_set_dialog_request_cb(g_vc_m, NULL, NULL); + + return 0; +} + static bool __vc_mgr_check_demandable_client(int pid) { if (0 == g_slist_length(g_demandable_client_list)) { diff --git a/client/vc_mgr_client.c b/client/vc_mgr_client.c index 68d0866..90d5b9e 100644 --- a/client/vc_mgr_client.c +++ b/client/vc_mgr_client.c @@ -28,6 +28,8 @@ typedef struct { void* all_result_user_data; vc_result_cb result_cb; void* result_user_data; + vc_mgr_pre_result_cb pre_result_cb; + void* pre_result_user_data; vc_error_cb error_cb; void* error_user_data; @@ -39,17 +41,13 @@ typedef struct { void* speech_detected_user_data; vc_current_language_changed_cb current_lang_changed_cb; void* current_lang_changed_user_data; - vc_mgr_pre_result_cb pre_result_cb; - void* pre_result_user_data; + vc_mgr_dialog_request_cb diaglog_requst_cb; + void* dialog_request_user_data; /* All result */ vc_result_event_e all_result_event; char* all_result_text; - /* Pre result */ - vc_pre_result_event_e pre_result_event; - char* pre_result_text; - /* exclusive command flag */ bool exclusive_cmd_option; @@ -150,6 +148,8 @@ int vc_mgr_client_create(vc_h* vc) client->all_result_user_data = NULL; client->result_cb = NULL; client->result_user_data = NULL; + client->pre_result_cb = NULL; + client->pre_result_user_data = NULL; client->error_cb = NULL; client->error_user_data = NULL; @@ -161,15 +161,13 @@ int vc_mgr_client_create(vc_h* vc) client->speech_detected_user_data = NULL; client->current_lang_changed_cb = NULL; client->current_lang_changed_user_data = NULL; - client->pre_result_cb = NULL; - client->pre_result_user_data = NULL; + client->diaglog_requst_cb = NULL; + client->dialog_request_user_data = NULL; client->exclusive_cmd_option = false; client->all_result_event = 0; client->all_result_text = NULL; - client->pre_result_event = 0; - client->pre_result_text = NULL; client->result_event = -1; client->result_text = NULL; @@ -376,6 +374,34 @@ int vc_mgr_client_get_result_cb(vc_h vc, vc_result_cb* callback, void** user_dat return 0; } +int vc_mgr_client_set_pre_result_cb(vc_h vc, vc_mgr_pre_result_cb callback, void* user_data) +{ + vc_mgr_client_s* client = __mgr_client_get(vc); + + /* check handle */ + if (NULL == client) + return VC_ERROR_INVALID_PARAMETER; + + client->pre_result_cb = callback; + client->pre_result_user_data = user_data; + + return 0; +} + +int vc_mgr_client_get_pre_result_cb(vc_h vc, vc_mgr_pre_result_cb* callback, void** user_data) +{ + vc_mgr_client_s* client = __mgr_client_get(vc); + + /* check handle */ + if (NULL == client) + return VC_ERROR_INVALID_PARAMETER; + + *callback = client->pre_result_cb; + *user_data = client->pre_result_user_data; + + return 0; +} + int vc_mgr_client_set_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb callback, void* user_data) { vc_mgr_client_s* client = __mgr_client_get(vc); @@ -516,7 +542,7 @@ int vc_mgr_client_get_error_cb(vc_h vc, vc_error_cb* callback, void** user_data) return 0; } -int vc_mgr_client_set_pre_result_cb(vc_h vc, vc_mgr_pre_result_cb callback, void* user_data) +int vc_mgr_client_set_dialog_request_cb(vc_h vc, vc_mgr_dialog_request_cb callback, void* user_data) { vc_mgr_client_s* client = __mgr_client_get(vc); @@ -524,13 +550,13 @@ int vc_mgr_client_set_pre_result_cb(vc_h vc, vc_mgr_pre_result_cb callback, void if (NULL == client) return VC_ERROR_INVALID_PARAMETER; - client->pre_result_cb = callback; - client->pre_result_user_data = user_data; + client->diaglog_requst_cb = callback; + client->dialog_request_user_data = user_data; return 0; } -int vc_mgr_client_get_pre_resut_cb(vc_h vc, vc_mgr_pre_result_cb* callback, void** user_data) +int vc_mgr_client_get_dialog_request_cb(vc_h vc, vc_mgr_dialog_request_cb* callback, void** user_data) { vc_mgr_client_s* client = __mgr_client_get(vc); @@ -538,9 +564,9 @@ int vc_mgr_client_get_pre_resut_cb(vc_h vc, vc_mgr_pre_result_cb* callback, void if (NULL == client) return VC_ERROR_INVALID_PARAMETER; - *callback = client->pre_result_cb; - *user_data = client->pre_result_user_data; - + *callback = client->diaglog_requst_cb; + *user_data = client->dialog_request_user_data; + return 0; } @@ -737,63 +763,6 @@ int vc_mgr_client_unset_all_result(vc_h vc) return 0; } -int vc_mgr_client_set_pre_result(vc_h vc, int event, const char* pre_result) -{ - vc_mgr_client_s* client = __mgr_client_get(vc); - - /* check handle */ - if (NULL == client) - return VC_ERROR_INVALID_PARAMETER; - - client->pre_result_event = event; - - if (NULL != client->pre_result_text) { - free(client->pre_result_text); - } - client->pre_result_text = strdup(pre_result); - - return 0; -} - -int vc_mgr_client_get_pre_result(vc_h vc, int* event, char** pre_result) -{ - vc_mgr_client_s* client = __mgr_client_get(vc); - - /* check handle */ - if (NULL == client) - return VC_ERROR_INVALID_PARAMETER; - - *event = client->pre_result_event; - - if (NULL != pre_result) { - if (NULL != client->pre_result_text) { - *pre_result = strdup(client->pre_result_text); - } else { - *pre_result = NULL; - } - } - - return 0; -} - -int vc_mgr_client_unset_pre_result(vc_h vc) -{ - vc_mgr_client_s* client = __mgr_client_get(vc); - - /* check handle */ - if (NULL == client) - return VC_ERROR_INVALID_PARAMETER; - - client->pre_result_event = -1; - - if (NULL != client->pre_result_text) { - free(client->pre_result_text); - client->pre_result_text = NULL; - } - - return 0; -} - int vc_mgr_client_set_audio_type(vc_h vc, const char* audio_id) { vc_mgr_client_s* client = __mgr_client_get(vc); diff --git a/client/vc_mgr_client.h b/client/vc_mgr_client.h index d29598e..15cd295 100644 --- a/client/vc_mgr_client.h +++ b/client/vc_mgr_client.h @@ -52,6 +52,10 @@ int vc_mgr_client_set_result_cb(vc_h vc, vc_result_cb callback, void* user_data) int vc_mgr_client_get_result_cb(vc_h vc, vc_result_cb* callback, void** user_data); +int vc_mgr_client_set_pre_result_cb(vc_h vc, vc_mgr_pre_result_cb callback, void* user_data); + +int vc_mgr_client_get_pre_result_cb(vc_h vc, vc_mgr_pre_result_cb* callback, void** user_data); + int vc_mgr_client_set_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb callback, void* user_data); int vc_mgr_client_get_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb* callback, void** user_data); @@ -72,9 +76,9 @@ int vc_mgr_client_set_error_cb(vc_h vc, vc_error_cb callback, void* user_data); int vc_mgr_client_get_error_cb(vc_h vc, vc_error_cb* callback, void** user_data); -int vc_mgr_client_set_pre_result_cb(vc_h vc, vc_mgr_pre_result_cb callback, void* user_data); +int vc_mgr_client_set_dialog_request_cb(vc_h vc, vc_mgr_dialog_request_cb callback, void* user_data); -int vc_mgr_client_get_pre_resut_cb(vc_h vc, vc_mgr_pre_result_cb* callback, void** user_data); +int vc_mgr_client_get_dialog_request_cb(vc_h vc, vc_mgr_dialog_request_cb* callback, void** user_data); /* * set/get option @@ -105,12 +109,6 @@ int vc_mgr_client_get_all_result(vc_h vc, int* event, char** result_text); int vc_mgr_client_unset_all_result(vc_h vc); -int vc_mgr_client_set_pre_result(vc_h vc, int event, const char* pre_result); - -int vc_mgr_client_get_pre_result(vc_h vc, int* event, char** pre_result); - -int vc_mgr_client_unset_pre_result(vc_h vc); - int vc_mgr_client_set_audio_type(vc_h vc, const char* audio_id); int vc_mgr_client_get_audio_type(vc_h vc, char** audio_id); diff --git a/client/vc_mgr_dbus.c b/client/vc_mgr_dbus.c index 93f4efd..a4339cb 100644 --- a/client/vc_mgr_dbus.c +++ b/client/vc_mgr_dbus.c @@ -30,10 +30,11 @@ static DBusConnection* g_m_conn_listener = NULL; static int g_volume_count = 0; -extern void __vc_mgr_cb_pre_result(int event, const char* pre_result); extern void __vc_mgr_cb_all_result(vc_result_type_e type); +extern void __vc_mgr_cb_pre_result(int event, const char* pre_result); + extern void __vc_mgr_cb_system_result(); extern void __vc_mgr_cb_speech_detected(); @@ -57,6 +58,8 @@ extern int __vc_mgr_request_auth_stop(int pid); extern int __vc_mgr_request_auth_cancel(int pid); +extern int __vc_mgr_cb_dialog(int pid, const char* disp_text, const char* utt_text, bool continuous); + static Eina_Bool vc_mgr_listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler) { if (NULL == g_m_conn_listener) return ECORE_CALLBACK_RENEW; @@ -165,6 +168,19 @@ static Eina_Bool vc_mgr_listener_event_callback(void* data, Ecore_Fd_Handler *fd } /* VCD_MANAGER_METHOD_SPEECH_DETECTED */ + else if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_ALL_RESULT)) { + SLOG(LOG_DEBUG, TAG_VCM, "===== Get All Result"); + int result_type = 0; + + dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &result_type, DBUS_TYPE_INVALID); + + __vc_mgr_cb_all_result((vc_result_type_e)result_type); + + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + + } /* VCD_MANAGER_METHOD_ALL_RESULT */ + else if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_PRE_RESULT)) { SLOG(LOG_DEBUG, TAG_VCM, "===== Get Pre Result"); int event; @@ -173,27 +189,13 @@ static Eina_Bool vc_mgr_listener_event_callback(void* data, Ecore_Fd_Handler *fd dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &event, DBUS_TYPE_STRING, &pre_result, DBUS_TYPE_INVALID); if (NULL != pre_result) { - __vc_mgr_cb_pre_result(event, pre_result); + __vc_mgr_cb_pre_result((vc_pre_result_event_e)event, pre_result); } SLOG(LOG_DEBUG, TAG_VCM, "====="); SLOG(LOG_DEBUG, TAG_VCM, " "); - } /* VCD_MANAGER_METHOD_PRE_RESULT */ - else if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_ALL_RESULT)) { - SLOG(LOG_DEBUG, TAG_VCM, "===== Get All Result"); - int result_type = 0; - - dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &result_type, DBUS_TYPE_INVALID); - - __vc_mgr_cb_all_result((vc_result_type_e)result_type); - - SLOG(LOG_DEBUG, TAG_VCM, "====="); - SLOG(LOG_DEBUG, TAG_VCM, " "); - - } /* VCD_MANAGER_METHOD_ALL_RESULT */ - else if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_RESULT)) { SLOG(LOG_DEBUG, TAG_VCM, "===== Get System Result"); @@ -225,6 +227,27 @@ static Eina_Bool vc_mgr_listener_event_callback(void* data, Ecore_Fd_Handler *fd SLOG(LOG_DEBUG, TAG_VCM, " "); } /* VCC_MANAGER_METHOD_SET_FOREGROUND */ + else if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_DIALOG)) { + SLOG(LOG_DEBUG, TAG_VCM, "===== Request Dialog"); + int pid = -1; + char* disp_text = NULL; + char* utt_text = NULL; + int tmp_continue; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &disp_text, + DBUS_TYPE_STRING, &utt_text, + DBUS_TYPE_INT32, &tmp_continue, + DBUS_TYPE_INVALID); + + __vc_mgr_cb_dialog(pid, disp_text, utt_text, (bool)tmp_continue); + + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + + } /* VCD_MANAGER_METHOD_ALL_RESULT */ + else if (dbus_message_is_signal(msg, if_name, VCD_MANAGER_METHOD_ERROR)) { SLOG(LOG_DEBUG, TAG_VCM, "===== Get Error"); int reason; @@ -739,7 +762,7 @@ int vc_mgr_dbus_request_initialize(int pid, int* service_state, int* foreground, *service_state = tmp_service_state; *foreground = tmp_foreground; *daemon_pid = tmp_daemon_pid; - SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc mgr initialize : result = %d, service state = %d, foreground = %d, daemon_pid = %d", + SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc mgr initialize : result = %d, service state = %d, foreground = %d, daemon_pid = %d", result, *service_state, *foreground, *daemon_pid); } else { SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr initialize : result = %d", result); @@ -1223,6 +1246,139 @@ int vc_mgr_dbus_request_get_audio_type(int pid, char** audio_type) return result; } +int vc_mgr_dbus_request_set_private_data(int pid, const char* key, const char* data) +{ + DBusMessage* msg; + + /* create a signal & check for errors */ + msg = dbus_message_new_method_call( + VC_SERVER_SERVICE_NAME, + VC_SERVER_SERVICE_OBJECT_PATH, /* object name of the signal */ + VC_SERVER_SERVICE_INTERFACE, /* interface name of the signal */ + VC_MANAGER_METHOD_SET_PRIVATE_DATA); /* name of the signal */ + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCM, ">>>> vc set private data : Fail to make message "); + return VC_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc set private data : pid(%d), data(%s)", pid, data); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &key, + DBUS_TYPE_STRING, &data, + DBUS_TYPE_INVALID); + + DBusError err; + dbus_error_init(&err); + + DBusMessage* result_msg; + int result = VC_ERROR_OPERATION_FAILED; + + result_msg = dbus_connection_send_with_reply_and_block(g_m_conn_sender, msg, g_m_waiting_time, &err); + dbus_message_unref(msg); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message); + dbus_error_free(&err); + } + + if (NULL != result_msg) { + dbus_message_get_args(result_msg, &err, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message); + dbus_error_free(&err); + result = VC_ERROR_OPERATION_FAILED; + } + dbus_message_unref(result_msg); + + if (0 == result) { + SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc set private data : result = %d", result); + } else { + SLOG(LOG_ERROR, TAG_VCM, "<<<< vc set private data : result = %d", result); + } + } else { + SLOG(LOG_DEBUG, TAG_VCM, "<<<< Result Message is NULL"); + vc_mgr_dbus_reconnect(); + result = VC_ERROR_TIMED_OUT; + } + + return result; +} + +int vc_mgr_dbus_request_get_private_data(int pid, const char* key, char** data) +{ + DBusMessage* msg; + + /* create a signal & check for errors */ + msg = dbus_message_new_method_call( + VC_SERVER_SERVICE_NAME, + VC_SERVER_SERVICE_OBJECT_PATH, + VC_SERVER_SERVICE_INTERFACE, + VC_MANAGER_METHOD_GET_PRIVATE_DATA); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr get private data : Fail to make message "); + return VC_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr get private data : pid(%d), key(%s)", pid, key); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &key, + DBUS_TYPE_INVALID); + + DBusError err; + dbus_error_init(&err); + + DBusMessage* result_msg; + int result = VC_ERROR_OPERATION_FAILED; + char* temp = NULL; + + result_msg = dbus_connection_send_with_reply_and_block(g_m_conn_sender, msg, g_m_waiting_time, &err); + dbus_message_unref(msg); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message); + dbus_error_free(&err); + } + + if (NULL != result_msg) { + dbus_message_get_args(result_msg, &err, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_STRING, &temp, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message); + dbus_error_free(&err); + result = VC_ERROR_OPERATION_FAILED; + } + dbus_message_unref(result_msg); + + if (0 == result) { + if (NULL != data && NULL != temp) { + *data = strdup(temp); + + SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc mgr get private data : result = %d private data = %s", result, *data); + } + } else { + SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr get private data : result = %d", result); + } + } else { + SLOG(LOG_DEBUG, TAG_VCM, "<<<< Result Message is NULL"); + vc_mgr_dbus_reconnect(); + result = VC_ERROR_TIMED_OUT; + } + + return result; +} + int vc_mgr_dbus_request_set_client_info(int pid) { DBusError err; @@ -1301,6 +1457,106 @@ int vc_mgr_dbus_request_set_client_info(int pid) return result; } +int vc_mgr_dbus_request_set_domain(int pid, const char* domain) +{ + DBusMessage* msg; + + /* create a signal & check for errors */ + msg = dbus_message_new_method_call( + VC_SERVER_SERVICE_NAME, + VC_SERVER_SERVICE_OBJECT_PATH, /* object name of the signal */ + VC_SERVER_SERVICE_INTERFACE, /* interface name of the signal */ + VC_MANAGER_METHOD_SET_DOMAIN); /* name of the signal */ + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCM, ">>>> vc set domain : Fail to make message "); + return VC_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc set domain : pid(%d), domain(%s)", pid, domain); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &domain, + DBUS_TYPE_INVALID); + + DBusError err; + dbus_error_init(&err); + + DBusMessage* result_msg; + int result = VC_ERROR_OPERATION_FAILED; + + result_msg = dbus_connection_send_with_reply_and_block(g_m_conn_sender, msg, g_m_waiting_time, &err); + dbus_message_unref(msg); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message); + dbus_error_free(&err); + } + + if (NULL != result_msg) { + dbus_message_get_args(result_msg, &err, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message); + dbus_error_free(&err); + result = VC_ERROR_OPERATION_FAILED; + } + dbus_message_unref(result_msg); + + if (0 == result) { + SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc set domain : result = %d", result); + } else { + SLOG(LOG_ERROR, TAG_VCM, "<<<< vc set domain : result = %d", result); + } + } else { + SLOG(LOG_DEBUG, TAG_VCM, "<<<< Result Message is NULL"); + vc_mgr_dbus_reconnect(); + result = VC_ERROR_TIMED_OUT; + } + + return result; +} + +int vc_mgr_dbus_request_do_action(int pid, vc_send_event_type_e type, char* send_event) +{ + DBusMessage* msg; + + /* create a signal & check for errors */ + msg = dbus_message_new_method_call( + VC_SERVER_SERVICE_NAME, + VC_SERVER_SERVICE_OBJECT_PATH, /* object name of the signal */ + VC_SERVER_SERVICE_INTERFACE, /* interface name of the signal */ + VC_MANAGER_METHOD_DO_ACTION); /* name of the signal */ + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCM, ">>>> vc set domain : Fail to make message "); + return VC_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc set domain : pid(%d), type(%d), send_event(%s)", pid, type, send_event); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &type, + DBUS_TYPE_STRING, &send_event, + DBUS_TYPE_INVALID); + + dbus_message_set_no_reply(msg, TRUE); + + if (1 != dbus_connection_send(g_m_conn_sender, msg, NULL)) { + SLOG(LOG_ERROR, TAG_VCM, "[Dbus ERROR] Fail to Send"); + return -1; + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[Dbus] SUCCESS Send"); + dbus_connection_flush(g_m_conn_sender); + } + + return 0; +} + int vc_mgr_dbus_request_start(int pid, int recognition_mode, bool exclusive_command_option, bool start_by_client) { DBusError err; diff --git a/client/vc_mgr_dbus.h b/client/vc_mgr_dbus.h index bd6215d..c12baa6 100644 --- a/client/vc_mgr_dbus.h +++ b/client/vc_mgr_dbus.h @@ -44,8 +44,16 @@ int vc_mgr_dbus_request_set_audio_type(int pid, const char* audio_type); int vc_mgr_dbus_request_get_audio_type(int pid, char** audio_type); +int vc_mgr_dbus_request_set_private_data(int pid, const char* key, const char* data); + +int vc_mgr_dbus_request_get_private_data(int pid, const char* key, char** data); + int vc_mgr_dbus_request_set_client_info(int pid); +int vc_mgr_dbus_request_set_domain(int pid, const char* domain); + +int vc_mgr_dbus_request_do_action(int pid, vc_send_event_type_e type, char* send_event); + int vc_mgr_dbus_request_start(int pid, int recognition_mode, bool exclusive_command_option, bool start_by_client); int vc_mgr_dbus_request_stop(int pid); diff --git a/client/vc_widget.c b/client/vc_widget.c old mode 100755 new mode 100644 index 40210a6..f05a6b6 --- a/client/vc_widget.c +++ b/client/vc_widget.c @@ -14,7 +14,7 @@ * limitations under the License. */ - +#include "vc_cmd_db.h" #include "vc_command.h" #include "vc_config_mgr.h" #include "vc_info_parser.h" @@ -35,6 +35,8 @@ static Ecore_Timer* g_w_tooltip_timer = NULL; static vc_h g_vc_w = NULL; +static int g_daemon_pid = 0; + static Eina_Bool __vc_widget_notify_state_changed(void *data); static Eina_Bool __vc_widget_notify_error(void *data); @@ -135,6 +137,14 @@ int vc_widget_initialize() return __vc_widget_convert_config_error_code(ret); } + ret = vc_db_initialize(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to initialize DB : %d", ret); + vc_config_mgr_finalize(g_vc_w->handle + VC_WIDGET_CONFIG_HANDLE); + vc_widget_client_destroy(g_vc_w); + return ret; + } + SLOG(LOG_DEBUG, TAG_VCW, "[Success] pid(%d)", g_vc_w->handle); SLOG(LOG_DEBUG, TAG_VCW, "====="); @@ -150,7 +160,9 @@ static void __vc_widget_internal_unprepare() SLOG(LOG_WARN, TAG_VCW, "[ERROR] Fail to request finalize : %s", __vc_widget_get_error_code(ret)); } - vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_WIDGET); + ret = vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_WIDGET); + if (0 != ret) + SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to delete file, type(%d), ret(%d)", VC_COMMAND_TYPE_WIDGET, ret); return; } @@ -193,6 +205,11 @@ int vc_widget_deinitialize() SLOG(LOG_DEBUG, TAG_VCW, "Success: destroy"); + int ret = vc_db_finalize(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to finalize DB, ret(%d)", ret); + } + if (0 != vc_widget_dbus_close_connection()) { SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to close connection"); } @@ -215,7 +232,7 @@ static Eina_Bool __vc_widget_connect_daemon(void *data) /* request initialization */ int ret = -1; int service_state = 0; - ret = vc_widget_dbus_request_initialize(g_vc_w->handle, &service_state); + ret = vc_widget_dbus_request_initialize(g_vc_w->handle, &service_state, &g_daemon_pid); if (VC_ERROR_ENGINE_NOT_FOUND == ret) { SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to initialize : %s", __vc_widget_get_error_code(ret)); @@ -485,7 +502,7 @@ int vc_widget_set_foreground(bool value) return VC_ERROR_NONE; } -#if 0 + int vc_widget_is_format_supported(vc_cmd_format_e format, bool* support) { SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Is command type supported"); @@ -505,10 +522,12 @@ int vc_widget_is_format_supported(vc_cmd_format_e format, bool* support) } switch (format) { - case VC_CMD_FORMAT_FIXED: *support = true; break; - case VC_CMD_FORMAT_FIXED_AND_EXTRA: *support = non_fixed_support; break; - case VC_CMD_FORMAT_EXTRA_AND_FIXED: *support = non_fixed_support; break; - default: *support = false; break; + case VC_CMD_FORMAT_FIXED: *support = true; break; + case VC_CMD_FORMAT_FIXED_AND_VFIXED: *support = true; break; + case VC_CMD_FORMAT_VFIXED_AND_FIXED: *support = true; break; + case VC_CMD_FORMAT_FIXED_AND_NONFIXED: *support = non_fixed_support; break; + case VC_CMD_FORMAT_NONFIXED_AND_FIXED: *support = non_fixed_support; break; + default: *support = false; break; } SLOG(LOG_ERROR, TAG_VCW, "[DEBUG] Format(%d) support(%s)", format, *support ? "true" : "false"); @@ -518,7 +537,7 @@ int vc_widget_is_format_supported(vc_cmd_format_e format, bool* support) return VC_ERROR_NONE; } -#endif + /** * @brief Starts recognition. * @@ -581,7 +600,7 @@ int vc_widget_start(bool stop_by_silence, vc_cmd_group_h vc_group) return ret; } - ret = vc_cmd_parser_save_file(getpid(), VC_COMMAND_GROUP_TYPE_WIDGET, list); + ret = vc_cmd_parser_save_file(getpid(), VC_COMMAND_GROUP_TYPE_WIDGET, list, NULL); if (0 != ret) { ret = vc_config_convert_error_code((vc_config_error_e)ret); SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to save command group : %s", __vc_widget_get_error_code(ret)); @@ -772,13 +791,33 @@ static Eina_Bool __vc_widget_notify_error(void *data) return EINA_FALSE; } -int __vc_widget_cb_error(int pid, int reason) +int __vc_widget_cb_error(int reason, int daemon_pid, char* msg) { - if (0 != vc_widget_client_get_handle(pid, &g_vc_w)) { - SLOG(LOG_ERROR, TAG_VCW, "Handle is not valid : pid(%d)", pid); + vc_state_e state; + if (0 != vc_widget_client_get_state(g_vc_w, &state)) { + SLOG(LOG_ERROR, TAG_VCW, "[WARNING] Invalid client"); + return -1; + } + + /* check state */ + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCW, "[WARNING] not connected client yet"); return -1; } + if (VC_ERROR_SERVICE_RESET == reason) { + SLOG(LOG_ERROR, TAG_VCW, "[ERROR] VC daemon reset"); + + vc_widget_client_set_state(g_vc_w, VC_STATE_INITIALIZED); + __vc_widget_notify_state_changed(g_vc_w); + + if (0 != vc_widget_prepare()) { + SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to prepare"); + } + } + + SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Error reason(%d), msg(%s)", reason, msg); + vc_widget_client_set_error(g_vc_w, reason); ecore_timer_add(0, __vc_widget_notify_error, g_vc_w); @@ -815,7 +854,11 @@ static Eina_Bool __vc_widget_start_recording(void *data) vc_cmd_list_s* list = NULL; list = (vc_cmd_list_s*)vc_cmd_list; - ret = vc_cmd_parser_save_file(getpid(), VC_COMMAND_TYPE_WIDGET, list->list); + ret = vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_WIDGET); + if (0 != ret) + SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to delete file, type(%d), ret(%d)", VC_COMMAND_TYPE_WIDGET, ret); + + ret = vc_cmd_parser_save_file(getpid(), VC_COMMAND_TYPE_WIDGET, list->list, NULL); if (0 == ret) { /* widget command is valid */ widget_command = true; diff --git a/client/vc_widget_dbus.c b/client/vc_widget_dbus.c index 2db6f72..a449df4 100644 --- a/client/vc_widget_dbus.c +++ b/client/vc_widget_dbus.c @@ -27,7 +27,7 @@ static Ecore_Fd_Handler* g_w_fd_handler = NULL; static DBusConnection* g_w_conn_sender = NULL; static DBusConnection* g_w_conn_listener = NULL; -extern int __vc_widget_cb_error(int pid, int reason); +extern int __vc_widget_cb_error(int reason, int daemon_pid, char* msg); extern void __vc_widget_cb_show_tooltip(int pid, bool show); @@ -166,15 +166,15 @@ static Eina_Bool widget_listener_event_callback(void* data, Ecore_Fd_Handler *fd } /* VCD_WIDGET_METHOD_RESULT */ - else if (dbus_message_is_method_call(msg, if_name, VCD_WIDGET_METHOD_ERROR)) { + else if (dbus_message_is_signal(msg, if_name, VCD_WIDGET_METHOD_ERROR)) { SLOG(LOG_DEBUG, TAG_VCW, "===== Get widget error"); - int pid; int reason; + int daemon_pid; char* err_msg; dbus_message_get_args(msg, &err, - DBUS_TYPE_INT32, &pid, DBUS_TYPE_INT32, &reason, + DBUS_TYPE_INT32, &daemon_pid, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); @@ -182,8 +182,8 @@ static Eina_Bool widget_listener_event_callback(void* data, Ecore_Fd_Handler *fd SLOG(LOG_ERROR, TAG_VCW, "<<<< vc widget get error message : Get arguments error (%s)", err.message); dbus_error_free(&err); } else { - SLOG(LOG_DEBUG, TAG_VCW, "<<<< vc widget get error message : pid(%d), reason(%d), msg(%s)", pid, reason, err_msg); - __vc_widget_cb_error(pid, reason); + SLOG(LOG_DEBUG, TAG_VCW, "<<<< vc widget get error message : reason(%d), daemon_pid(%d), msg(%s)", reason, daemon_pid, err_msg); + __vc_widget_cb_error(reason, daemon_pid, err_msg); } /* @@ -410,7 +410,7 @@ int vc_widget_dbus_request_hello() } -int vc_widget_dbus_request_initialize(int pid, int* service_state) +int vc_widget_dbus_request_initialize(int pid, int* service_state, int* daemon_pid) { DBusMessage* msg; @@ -447,9 +447,11 @@ int vc_widget_dbus_request_initialize(int pid, int* service_state) if (NULL != result_msg) { int tmp_service_state = 0; + int tmp_daemon_pid = 0; dbus_message_get_args(result_msg, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INT32, &tmp_service_state, + DBUS_TYPE_INT32, &tmp_daemon_pid, DBUS_TYPE_INVALID); if (dbus_error_is_set(&err)) { @@ -462,7 +464,8 @@ int vc_widget_dbus_request_initialize(int pid, int* service_state) if (0 == result) { *service_state = tmp_service_state; - SLOG(LOG_DEBUG, TAG_VCW, "<<<< vc widget initialize : result = %d service = %d", result, *service_state); + *daemon_pid = tmp_daemon_pid; + SLOG(LOG_DEBUG, TAG_VCW, "<<<< vc widget initialize : result = %d service = %d daemon_pid = %d", result, *service_state, *daemon_pid); } else { SLOG(LOG_ERROR, TAG_VCW, "<<<< vc widget initialize : result = %d", result); } diff --git a/client/vc_widget_dbus.h b/client/vc_widget_dbus.h index 00312dd..fe995c5 100644 --- a/client/vc_widget_dbus.h +++ b/client/vc_widget_dbus.h @@ -30,7 +30,7 @@ int vc_widget_dbus_close_connection(); int vc_widget_dbus_request_hello(); -int vc_widget_dbus_request_initialize(int pid, int* service_state); +int vc_widget_dbus_request_initialize(int pid, int* service_state, int* daemon_pid); int vc_widget_dbus_request_finalize(int pid); diff --git a/common/vc_cmd_db.c b/common/vc_cmd_db.c new file mode 100644 index 0000000..3b627df --- /dev/null +++ b/common/vc_cmd_db.c @@ -0,0 +1,1583 @@ +/* +* Copyright (c) 2011-2016 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 "vc_cmd_db.h" +#include "vc_main.h" +#include "voice_control_command.h" +#include "voice_control_command_expand.h" + + +const char* vc_db_tag() +{ + return TAG_VCDB; +} + +/*! + * \note + * DB Table schema + * + * vc_info + * +-----+------+------+--------+--------+---------+-----------+-------+-----------------+-------+ + * | id | pid | type | format | domain | command | parameter | appid | invocation_name | fixed | + * +-----+------+------+--------+--------+---------+-----------+-------+-----------------+-------+ + * + * CREATE TABLE vc_info (id INTEGER PRIMARY KEY AUTOINCREMENT, pid INTEGER, type INTEGER, format INTEGER, domain INTEGER, command TEXT, appid TEXT); + * + * vc_result + * +-----+--------+-------+-----+-----------+-----+------+--------+--------+---------+-----------+-------+-----------------+-------+ + * | id | result | event | msg | exclusive | pid | type | format | domain | command | parameter | appid | invocation_name | fixed | + * +-----+--------+-------+-----+-----------+-----+------+--------+--------+---------+-----------+-------+-----------------+-------+ + * + * CREATE TABLE vc_result (id INTEGER PRIMARY KEY AUTOINCREMENT, result TEXT, event INTEGER, msg TEXT, exclusive INTEGER, + * pid INTEGER, type INTEGER, format INTEGER, domain INTEGER, command TEXT, parameter TEXT, appid TEXT,\ + * + */ + +#define FREE_MEM(X) {if (NULL != X) {free(X); X = NULL;}} + + +//#define DB_PATH tzplatform_mkpath(TZ_USER_DB, ".vc_info.db") +static sqlite3* db_handle = NULL; +char* path = NULL; +int g_fpid = -1; + +static int __vc_db_transaction(const char* transaction) +{ + sqlite3_stmt* pStmt = NULL; + + int ret = sqlite3_prepare_v2(db_handle, transaction, -1, &pStmt, NULL); + if (ret != SQLITE_OK) + { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_prepare_v2: transaction(%s), ret(%d), err(%s)", transaction, ret, sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + + if (sqlite3_step(pStmt) != SQLITE_DONE) + { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_step: transaction(%s), ret(%d), err(%s)", transaction, ret, sqlite3_errmsg(db_handle)); + sqlite3_finalize(pStmt); + return VC_DB_ERROR_OPERATION_FAILED; + } + + sqlite3_finalize(pStmt); + return VC_DB_ERROR_NONE; +} + +static int __vc_db_begin_transaction(void) +{ + int ret = __vc_db_transaction("BEGIN TRANSACTION"); + return ret; +} + +static int __vc_db_rollback_transaction(void) +{ + int ret = __vc_db_transaction("ROLLBACK TRANSACTION"); + return ret; +} + +static int __vc_db_commit_transaction(void) +{ + int ret = __vc_db_transaction("COMMIT TRANSACTION"); + return ret; +} + +static int __vc_db_exec_query(const char* sql) +{ + char* err_msg = NULL; + + int ret = sqlite3_exec(db_handle, sql, NULL, NULL, &err_msg); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] sqlite3_exec return fail, ret(%d), err(%s)", ret, err_msg); + sqlite3_free(err_msg); + return VC_DB_ERROR_OPERATION_FAILED; + } + return VC_DB_ERROR_NONE; +} + +static int __vc_db_delete_commands(int pid, vc_cmd_type_e type, const char* appid) +{ + sqlite3_stmt* stmt = NULL; + char* sql = NULL; + + if (VC_COMMAND_TYPE_BACKGROUND != type && -1 == pid) + sql = strdup("DELETE FROM vc_info WHERE type = ?;"); + else if (NULL != appid) + sql = strdup("DELETE FROM vc_info WHERE type = ? AND appid = ?;"); + else + sql = strdup("DELETE FROM vc_info WHERE type = ? AND pid = ?;"); + + if (NULL == sql) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory"); + return VC_DB_ERROR_OUT_OF_MEMORY; + } + + int ret = 0; + ret = sqlite3_prepare_v2(db_handle, sql, -1, &stmt, NULL); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] sqlite3_prepare_v2: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_int(stmt, 1, (int)type); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + + if (VC_COMMAND_TYPE_BACKGROUND != type && -1 == pid) { + SLOG(LOG_DEBUG, vc_db_tag(), "[SQL] DELETE FROM vc_info WHERE type = %d;", type); + } else if (NULL != appid) { + ret = sqlite3_bind_text(stmt, 2, appid, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + SLOG(LOG_DEBUG, vc_db_tag(), "[SQL] DELETE FROM vc_info WHERE type = %d AND appid = %s", type, appid); + } else { + ret = sqlite3_bind_int(stmt, 2, pid); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + SLOG(LOG_DEBUG, vc_db_tag(), "[SQL] DELETE FROM vc_info WHERE type = %d AND pid = %d", type, pid); + } + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_step: fail returned, sql(%s), ret(%d), err(%s)", sql, ret, sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + sqlite3_finalize(stmt); + + free(sql); + sql = NULL; + return VC_DB_ERROR_NONE; +} + +static int __vc_db_insert_commands(int pid, vc_cmd_type_e type, vc_cmd_s* cmd) +{ + SLOG(LOG_DEBUG, vc_db_tag(), "pid(%d), type(%d)", pid, type); + + sqlite3_stmt* stmt = NULL; + const char* sql = "INSERT INTO vc_info (id, pid, type, format, domain, command, parameter, appid, invocation_name, fixed) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"; + int ret = 0; + ret = sqlite3_prepare_v2(db_handle, sql, -1, &stmt, NULL); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] sqlite3_prepare_v2: err(%s)", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_int(stmt, 2, pid); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: err(%s)", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_int(stmt, 3, cmd->type); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: err(%s)", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_int(stmt, 4, cmd->format); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: err(%s)", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_int(stmt, 5, cmd->domain); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: err(%s)", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_text(stmt, 6, cmd->command, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_text: err(%s)", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + + char* appid = NULL; + if (NULL == cmd->appid) { + // Get appid by pid using app control + ret = app_manager_get_app_id(pid, &appid); + if (APP_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] fail to get app id, ret(%d), pid(%d)", ret, pid); + } + if (NULL != appid) { + cmd->appid = strdup(appid); + FREE_MEM(appid); + } + } + ret = sqlite3_bind_text(stmt, 8, cmd->appid, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_text: err(%s)", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + if (VC_COMMAND_TYPE_BACKGROUND == type && NULL != cmd->invocation_name) { + ret = sqlite3_bind_text(stmt, 9, cmd->invocation_name, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_text: err(%s)", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + } + ret = sqlite3_bind_text(stmt, 10, cmd->fixed, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_text: err(%s)", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_step: fail returned %d, %s", ret, sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_ERROR, vc_db_tag(), "[SQL] INSERT INTO vc_info (id, pid(%d), type(%d), format(%d), domain(%d), command(%s)", pid, cmd->type, cmd->format, cmd->domain, cmd->command); + SLOG(LOG_ERROR, vc_db_tag(), "[SQL] ==== appid(%s), invocation(%s), fixed(%s)", cmd->appid, cmd->invocation_name, cmd->fixed); + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + sqlite3_finalize(stmt); + return VC_DB_ERROR_NONE; +} + +static int __vc_db_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list) +{ + SLOG(LOG_DEBUG, vc_db_tag(), "pid(%d), type(%d)", pid, type); + + int ret = 0; + sqlite3_stmt* stmt = NULL; + char* sql = NULL; + char* appid = NULL; + + if (VC_COMMAND_TYPE_BACKGROUND == type) { + /* For background command */ + sql = strdup("SELECT * FROM vc_info WHERE type = ?;"); + } else { + sql = strdup("SELECT * FROM vc_info WHERE type = ? AND pid = ?;"); + } + + if (NULL == sql) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory"); + return VC_DB_ERROR_OUT_OF_MEMORY; + } + ret = sqlite3_prepare_v2(db_handle, sql, -1, &stmt, NULL); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] sqlite3_prepare_v2: %s", sqlite3_errmsg(db_handle)); + free(sql); + sql = NULL; + return VC_DB_ERROR_OPERATION_FAILED; + } + + ret = sqlite3_bind_int(stmt, 1, (int)type); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + if (VC_COMMAND_TYPE_BACKGROUND != type ) { + ret = sqlite3_bind_int(stmt, 2, pid); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + } + + if (VC_COMMAND_TYPE_BACKGROUND == type) + SLOG(LOG_DEBUG, vc_db_tag(), "[SQL] SELECT * FROM vc_info WHERE type = %d", type); + else + SLOG(LOG_DEBUG, vc_db_tag(), "[SQL] SELECT * FROM vc_info WHERE type = %d and pid = %d", type, pid); + + ret = sqlite3_step(stmt); + if (ret == SQLITE_DONE) { + SLOG(LOG_DEBUG, vc_db_tag(), "No matched commands"); + return VC_DB_ERROR_NONE; + } + + if (VC_COMMAND_TYPE_BACKGROUND == type && -1 != pid) { + if (APP_MANAGER_ERROR_NONE != app_manager_get_app_id(pid, &appid)) { + SLOG(LOG_WARN, vc_db_tag(), "[WARN] fail to get app id, pid(%d)", pid); + } + } + + while (SQLITE_ROW == ret) { + int temp = 0; + char* temp_text = NULL; + vc_cmd_s* temp_cmd = NULL; + temp_cmd = (vc_cmd_s*)calloc(1, sizeof(vc_cmd_s)); + if (NULL == temp_cmd) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory"); + if (NULL != appid) { + free(appid); + appid = NULL; + } + return VC_DB_ERROR_OUT_OF_MEMORY; + } + + temp_text = (char*)sqlite3_column_text(stmt, 7); + if (NULL != temp_text) + temp_cmd->appid = strdup(temp_text); + + if (NULL != appid && NULL != temp_cmd->appid) { + if (VC_COMMAND_TYPE_BACKGROUND == type && 0 == strncmp(appid, temp_cmd->appid, strlen(appid))) { + SLOG(LOG_DEBUG, vc_db_tag(), "Skip get background commands when app is foreground, appid(%s)", appid); + + ret = sqlite3_step(stmt); + if (SQLITE_DONE == ret) + break; + + continue; + } + } + + temp = sqlite3_column_int(stmt, 0); + temp_cmd->id = temp; + + temp = sqlite3_column_int(stmt, 1); + temp_cmd->pid = temp; + + temp = sqlite3_column_int(stmt, 2); + temp_cmd->type = temp; + + temp = sqlite3_column_int(stmt, 3); + temp_cmd->format = temp; + + temp = sqlite3_column_int(stmt, 4); + temp_cmd->domain = temp; + + temp_text = (char*)sqlite3_column_text(stmt, 5); + if (NULL != temp_text) + temp_cmd->command = strdup(temp_text); + + temp_text = (char*)sqlite3_column_text(stmt, 6); + if (NULL != temp_text) + temp_cmd->parameter = strdup(temp_text); + + temp_text = (char*)sqlite3_column_text(stmt, 8); + if (NULL != temp_text) + temp_cmd->invocation_name = strdup(temp_text); + + temp_text = (char*)sqlite3_column_text(stmt, 9); + if (NULL != temp_text) + temp_cmd->fixed = strdup(temp_text); + + if (type == temp_cmd->type) { + *cmd_list = g_slist_append(*cmd_list, temp_cmd); + } else { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Command type(%d) is NOT valid : request type(%d)", temp_cmd->type, type); + } + ret = sqlite3_step(stmt); + if (SQLITE_DONE == ret) + break; + } + + if (NULL != appid) { + free(appid); + appid = NULL; + } + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + sqlite3_finalize(stmt); + + free(sql); + sql = NULL; + return VC_DB_ERROR_NONE; +} + +static int __vc_db_get_pid(const char* appid, int* pid) +{ + bool running = false; + int ret = app_manager_is_running(appid, &running); + if (APP_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to check running with appid(%s)", appid); + return VC_DB_ERROR_OPERATION_FAILED; + } + if (true == running) { + app_context_h app_context = NULL; + ret = app_manager_get_app_context(appid, &app_context); + if (APP_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to get app_context, ret(%d), appid(%s)", ret, appid); + return VC_DB_ERROR_OPERATION_FAILED; + } + + ret = app_context_get_pid(app_context, pid); + if (APP_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to get pid, ret(%d), appid(%s)", ret, appid); + return VC_DB_ERROR_OPERATION_FAILED; + } + + ret = app_context_destroy(app_context); + if (APP_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to destroy app context, ret(%d), appid(%s)", ret, appid); + return VC_DB_ERROR_OPERATION_FAILED; + } + } else { + SLOG(LOG_ERROR, vc_db_tag(), "app is not running, appid(%s)", appid); + } + return VC_DB_ERROR_NONE; +} + +static int __vc_db_insert_result(const char* result_text, int event, const char* msg, bool exclusive, vc_cmd_s* cmd) +{ + SLOG(LOG_DEBUG, vc_db_tag(), "result_text(%s), event(%d), msg(%s), exclusive(%d), cmd(%p)", result_text, event, msg, exclusive, cmd); + + sqlite3_stmt* stmt = NULL; + const char* sql = "INSERT INTO vc_result (id, result, event, msg, exclusive, pid, type, format, domain, command, parameter, appid, invocation_name, fixed) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"; + int ret = 0; + ret = sqlite3_prepare_v2(db_handle, sql, -1, &stmt, NULL); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] sqlite3_prepare_v2: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_text(stmt, 2, result_text, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_text: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_int(stmt, 3, event); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_text(stmt, 4, msg, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_text: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_int(stmt, 5, exclusive); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + + if (NULL == cmd) { + SLOG(LOG_DEBUG, vc_db_tag(), "[SQL] INSERT INTO vc_result result(%s), event(%d), msg(%s), exclusive(%d))", result_text, event, msg, exclusive); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_step: fail returned %d, %s", ret, sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + sqlite3_finalize(stmt); + return VC_DB_ERROR_NONE; + } + + if (VC_COMMAND_TYPE_BACKGROUND == cmd->type) { + int pid = -1; + ret = __vc_db_get_pid(cmd->appid, &pid); + if (0 != ret) { + SLOG(LOG_WARN, vc_db_tag(), "Fail to get pid, appid(%s) ret(%d)", cmd->appid, ret); + } else { + SLOG(LOG_ERROR, vc_db_tag(), "pid(%d)", pid); + if (-1 != pid) + cmd->pid = pid; + } + } + ret = sqlite3_bind_int(stmt, 6, cmd->pid); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_int(stmt, 7, cmd->type); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_int(stmt, 8, cmd->format); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_int(stmt, 9, cmd->domain); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_text(stmt, 10, cmd->command, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_text: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_text(stmt, 11, cmd->parameter, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_text: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_text(stmt, 12, cmd->appid, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_text: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_text(stmt, 13, cmd->invocation_name, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_text: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_text(stmt, 14, cmd->fixed, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_text: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_step: fail returned %d, %s", ret, sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, vc_db_tag(), "[SQL] INSERT INTO vc_result result(%s), event(%d), msg(%s), exclusive(%d), pid(%d), type(%d), format(%d), domain(%d), command(%s), parameter(%s), appid(%s), invocation(%s), fixed(%s)", + result_text, event, msg, exclusive, cmd->pid, cmd->type, cmd->format, cmd->domain, cmd->command, cmd->parameter, cmd->appid, cmd->invocation_name, cmd->fixed); + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + sqlite3_finalize(stmt); + + return VC_DB_ERROR_NONE; +} + +static int __vc_db_remove_invocation_name(char* org_cmd, const char* invocation_name, char** new_cmd) +{ + if (NULL == org_cmd || NULL == new_cmd) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Invalid parameter"); + return VC_DB_ERROR_INVALID_PARAMETER; + } + + if (NULL == invocation_name) { + SLOG(LOG_WARN, vc_db_tag(), "[WARNING] Invalid parameter, invocation name is NULL, org_cmd(%s)", org_cmd); + return VC_DB_ERROR_INVALID_PARAMETER; + } + + if (strlen(org_cmd) <= strlen(invocation_name)) { + SLOG(LOG_WARN, vc_db_tag(), "[WARNING] No need to remove invocation name, org_cmd(%s) invocation(%s)", org_cmd, invocation_name); + return VC_DB_ERROR_INVALID_PARAMETER; + } + + if (0 == strncasecmp(org_cmd, invocation_name, strlen(invocation_name))) { + *new_cmd = strdup(org_cmd + strlen(invocation_name) + 1); + } + SLOG(LOG_DEBUG, vc_db_tag(), "Original cmd[%s], New cmd[%s], Invocation name[%s]", org_cmd, *new_cmd, invocation_name); + return VC_DB_ERROR_NONE; +} + +static int __vc_db_extract_unfixed_command(char* command, char* fixed, char** temp_unfixed) +{ + if (NULL == command || NULL == temp_unfixed) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Invalid parameter"); + return VC_DB_ERROR_INVALID_PARAMETER; + } + + if (NULL == fixed) { + SLOG(LOG_WARN, vc_db_tag(), "[WARNING] Invalid parameter, fixed cmd is NULL, org_cmd(%s)", command); + return VC_DB_ERROR_INVALID_PARAMETER; + } + + if (strlen(command) <= strlen(fixed)) { + SLOG(LOG_WARN, vc_db_tag(), "[WARNING] No need to extract unfixed command, cmd(%s) fixed(%s)", command, fixed); + return VC_DB_ERROR_INVALID_PARAMETER; + } + + char* temp = (char*)calloc(256, sizeof(char)); + if (0 == strncasecmp(command, fixed, strlen(fixed))) { + strncpy(temp, command + strlen(fixed) + 1, strlen(command) - strlen(fixed) - 1); + SLOG(LOG_WARN, vc_db_tag(), "=="); + } else if (0 == strncasecmp(command + strlen(command) - strlen(fixed), fixed, strlen(fixed))) { + strncpy(temp, command, strlen(command) - strlen(fixed) - 1); + SLOG(LOG_WARN, vc_db_tag(), "=="); + } + + SLOG(LOG_WARN, vc_db_tag(), "Command(%s) Fixed(%s) Unfixed(%s)", command, fixed, temp); + if (NULL != temp) { + *temp_unfixed = strdup(temp); + free(temp); + temp = NULL; + } + return VC_DB_ERROR_NONE; +} + +static int __vc_db_get_result(char** result_text, int* event, char** msg, int pid, char* appid, vc_cmd_list_h vc_cmd_list, bool exclusive) +{ + int ret = 0; + sqlite3_stmt* stmt = NULL; + char* sql = NULL; + if (-1 == pid) + sql = strdup("SELECT * FROM vc_result;"); + else if (NULL != appid) + sql = strdup("SELECT * FROM vc_result WHERE appid = ?;"); + else + sql = strdup("SELECT * FROM vc_result WHERE pid = ?;"); + + if (NULL == sql) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory"); + return VC_DB_ERROR_OUT_OF_MEMORY; + } + + ret = sqlite3_prepare_v2(db_handle, sql, -1, &stmt, NULL); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] sqlite3_prepare_v2: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + if (NULL != appid) { + ret = sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + } else if (-1 != pid) { + ret = sqlite3_bind_int(stmt, 1, pid); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + } + ret = sqlite3_step(stmt); + if (ret == SQLITE_DONE) { + SLOG(LOG_DEBUG, vc_db_tag(), "No matched commands"); + return VC_DB_ERROR_NONE; + } + + if (-1 == pid) + SLOG(LOG_DEBUG, vc_db_tag(), "[SQL] %s", sql); + else if (NULL != appid) + SLOG(LOG_DEBUG, vc_db_tag(), "[SQL] SELECT * FROM vc_result WHERE appid = %d;", appid); + + else + SLOG(LOG_DEBUG, vc_db_tag(), "[SQL] SELECT * FROM vc_result WHERE pid = %d;", pid); + + vc_cmd_h temp_cmd = NULL; + while (SQLITE_ROW == ret) { + int temp = 0; + char* temp_text = NULL; + const char* invocation_name = NULL; + + temp_text = (char*)sqlite3_column_text(stmt, 1); + if (NULL != temp_text) + *result_text = strdup(temp_text); + + temp = sqlite3_column_int(stmt, 2); + *event = temp; + + if (NULL != msg) { + temp_text = (char*)sqlite3_column_text(stmt, 3); + if (NULL != temp_text) + *msg = strdup(temp_text); + } + + if (0 != vc_cmd_create(&temp_cmd)) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to create command!!"); + if (NULL != *result_text) { + free(*result_text); + *result_text = NULL; + } + + if (NULL != msg && NULL != *msg) { + free(*msg); + *msg = NULL; + } + return -1; + } + + temp = sqlite3_column_int(stmt, 0); + vc_cmd_set_id(temp_cmd, temp); + + temp = sqlite3_column_int(stmt, 5); + vc_cmd_set_pid(temp_cmd, temp); + + temp = sqlite3_column_int(stmt, 6); + vc_cmd_set_type(temp_cmd, temp); + + temp = sqlite3_column_int(stmt, 7); + vc_cmd_set_format(temp_cmd, temp); + + temp = sqlite3_column_int(stmt, 8); + vc_cmd_set_domain(temp_cmd, temp); + + // invocation name + invocation_name = (char*)sqlite3_column_text(stmt, 12); + // command name + temp_text = (char*)sqlite3_column_text(stmt, 9); + SLOG(LOG_DEBUG, vc_db_tag(), "org command (%s)", temp_text); + + if (NULL != temp_text) { + char* temp_command = NULL; + char* temp_unfixed = NULL; + char* temp_fixed = NULL; + + if (NULL != invocation_name) + __vc_db_remove_invocation_name(*result_text, invocation_name, &temp_command); + + if (NULL == temp_command) { + temp_command = strdup(temp_text); + } else { + // remove invocation name from result_text + free(*result_text); + *result_text = strdup(temp_command); + } + + // fixed + temp_fixed = (char*)sqlite3_column_text(stmt, 13); + if (NULL != temp_fixed) + vc_cmd_set_fixed_command(temp_cmd, temp_fixed); + + // unfixed + temp_unfixed = (char*)sqlite3_column_text(stmt, 10); + + if (NULL != temp_unfixed) { + char merge_result[256] = {0, }; + vc_cmd_set_command(temp_cmd, temp_command); + vc_cmd_set_unfixed_command(temp_cmd, temp_unfixed); + snprintf(merge_result, 256, "%s %s", temp_command, temp_unfixed); + if (NULL != *result_text) + free(*result_text); + *result_text = strdup(merge_result); + } else if (NULL != temp_fixed) { + __vc_db_extract_unfixed_command(*result_text, temp_fixed, &temp_unfixed); + vc_cmd_set_command(temp_cmd, temp_fixed); + vc_cmd_set_unfixed_command(temp_cmd, temp_unfixed); + if (NULL != temp_unfixed) { + free(temp_unfixed); + temp_unfixed = NULL; + } + } else { + vc_cmd_set_command(temp_cmd, temp_command); + } + free(temp_command); + temp_command = NULL; + } + + temp_text = (char*)sqlite3_column_text(stmt, 11); + if (NULL != temp_text) + vc_cmd_set_appid(temp_cmd, temp_text); + + if (0 != vc_cmd_list_add(vc_cmd_list, temp_cmd)) { + SLOG(LOG_DEBUG, vc_db_tag(), "Fail to add command to list"); + vc_cmd_destroy(temp_cmd); + vc_cmd_list_destroy(vc_cmd_list, true); + if (NULL != *result_text) { + free(*result_text); + *result_text = NULL; + } + + if (NULL != msg && NULL != *msg) { + free(*msg); + *msg = NULL; + } + + return VC_DB_ERROR_OPERATION_FAILED; + } + + ret = sqlite3_step(stmt); + if (SQLITE_DONE == ret) + break; + } + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + sqlite3_finalize(stmt); + + free(sql); + sql = NULL; + return VC_DB_ERROR_NONE; +} + +static int __vc_db_get_appid(const char* result, GSList** app_list) +{ + GSList* temp_app_list = NULL; + + int ret = 0; + sqlite3_stmt* stmt = NULL; + const char* sql = "SELECT * FROM vc_result WHERE type = ? AND result = ? COLLATE NOCASE;"; + + ret = sqlite3_prepare_v2(db_handle, sql, -1, &stmt, NULL); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] sqlite3_prepare_v2: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_int(stmt, 1, VC_COMMAND_TYPE_BACKGROUND); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_text(stmt, 2, result, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + SLOG(LOG_DEBUG, vc_db_tag(), "[SQL] SELECT * FROM vc_result WHERE type = 2 and result = %s", result); + ret = sqlite3_step(stmt); + if (ret == SQLITE_DONE) { + SLOG(LOG_DEBUG, vc_db_tag(), "No matched commands"); + return VC_DB_ERROR_NONE; + } + + while (SQLITE_ROW == ret) { + char* temp_text = NULL; + vc_deactivated_app_s* temp_app = NULL; + temp_app = (vc_deactivated_app_s*)calloc(1, sizeof(vc_deactivated_app_s)); + if (NULL == temp_app) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] memory allcation fail"); + return VC_DB_ERROR_OUT_OF_MEMORY; + } + + temp_text = (char*)sqlite3_column_text(stmt, 11); + if (NULL != temp_text) + temp_app->appid = strdup(temp_text); + + temp_app_list = g_slist_append(temp_app_list, temp_app); + + ret = sqlite3_step(stmt); + if (SQLITE_DONE == ret) + break; + } + + *app_list = temp_app_list; + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + sqlite3_finalize(stmt); + return VC_DB_ERROR_NONE; +} + +int __vc_db_get_result_pid_list(const char* result, GSList** pid_list) +{ + GSList* temp_pid_list = NULL; + + int ret = 0; + sqlite3_stmt* stmt = NULL; + const char* sql = "SELECT * FROM vc_result WHERE result = ? COLLATE NOCASE;"; + + ret = sqlite3_prepare_v2(db_handle, sql, -1, &stmt, NULL); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] sqlite3_prepare_v2: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_text(stmt, 1, result, -1, SQLITE_TRANSIENT); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_step(stmt); + if (ret == SQLITE_DONE) { + SLOG(LOG_DEBUG, vc_db_tag(), "No matched commands"); + return VC_DB_ERROR_NONE; + } + + SLOG(LOG_DEBUG, vc_db_tag(), "[SQL] SELECT * FROM vc_result result = %s", result); + + while (SQLITE_ROW == ret) { + int temp = 0; + vc_cmd_s* temp_cmd = NULL; + temp_cmd = (vc_cmd_s*)calloc(1, sizeof(vc_cmd_s)); + if (NULL == temp_cmd) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] memory allcation fail"); + return VC_DB_ERROR_OUT_OF_MEMORY; + } + + temp = sqlite3_column_int(stmt, 0); + temp_cmd->id = temp; + + temp = sqlite3_column_int(stmt, 5); + temp_cmd->pid = temp; + + temp = sqlite3_column_int(stmt, 6); + temp_cmd->type = temp; + + temp_pid_list = g_slist_append(temp_pid_list, temp_cmd); + + ret = sqlite3_step(stmt); + if (SQLITE_DONE == ret) + break; + } + + *pid_list = temp_pid_list; + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + sqlite3_finalize(stmt); + return VC_DB_ERROR_NONE; +} + +static int __vc_db_append_commands(int pid, int type, vc_cmd_list_h vc_cmd_list) +{ + SLOG(LOG_ERROR, vc_db_tag(), "pid(%d), type(%d)", pid, type); + + int ret = 0; + sqlite3_stmt* stmt = NULL; + const char* sql = "SELECT * FROM vc_info WHERE pid = ? AND type = ?;"; + + ret = sqlite3_prepare_v2(db_handle, sql, -1, &stmt, NULL); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] sqlite3_prepare_v2: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_int(stmt, 1, pid); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_bind_int(stmt, 2, type); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_bind_int: %s", sqlite3_errmsg(db_handle)); + return VC_DB_ERROR_OPERATION_FAILED; + } + ret = sqlite3_step(stmt); + if (ret == SQLITE_DONE) { + SLOG(LOG_DEBUG, vc_db_tag(), "No matched commands"); + return VC_DB_ERROR_NONE; + } + + SLOG(LOG_DEBUG, vc_db_tag(), "[SQL] SELECT * FROM vc_info WHERE pid = %d and type = %d", pid, type); + + vc_cmd_h temp_cmd = NULL; + + while (SQLITE_ROW == ret) { + int temp = 0; + char* temp_text = NULL; + + if (0 != vc_cmd_create(&temp_cmd)) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to create command!!"); + return -1; + } + temp = sqlite3_column_int(stmt, 0); + vc_cmd_set_id(temp_cmd, temp); + + temp = sqlite3_column_int(stmt, 1); + vc_cmd_set_pid(temp_cmd, temp); + + temp = sqlite3_column_int(stmt, 2); + vc_cmd_set_type(temp_cmd, temp); + + temp = sqlite3_column_int(stmt, 3); + vc_cmd_set_format(temp_cmd, temp); + + temp = sqlite3_column_int(stmt, 4); + vc_cmd_set_domain(temp_cmd, temp); + + temp_text = (char*)sqlite3_column_text(stmt, 5); + if (NULL != temp_text) + vc_cmd_set_command(temp_cmd, temp_text); + + temp_text = (char*)sqlite3_column_text(stmt, 6); + if (NULL != temp_text) + vc_cmd_set_unfixed_command(temp_cmd, temp_text); + + temp_text = (char*)sqlite3_column_text(stmt, 7); + if (NULL != temp_text) + vc_cmd_set_appid(temp_cmd, temp_text); + + temp_text = (char*)sqlite3_column_text(stmt, 8); + if (NULL != temp_text) + vc_cmd_set_invocation_name(temp_cmd, temp_text); + + temp_text = (char*)sqlite3_column_text(stmt, 9); + if (NULL != temp_text) + vc_cmd_set_fixed_command(temp_cmd, temp_text); + + if (0 != vc_cmd_list_add(vc_cmd_list, temp_cmd)) { + SLOG(LOG_DEBUG, vc_db_tag(), "Fail to add command to list"); + vc_cmd_destroy(temp_cmd); + vc_cmd_list_destroy(vc_cmd_list, true); + return VC_DB_ERROR_OPERATION_FAILED; + } + + ret = sqlite3_step(stmt); + if (SQLITE_DONE == ret) + break; + } + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + sqlite3_finalize(stmt); + return VC_DB_ERROR_NONE; +} + +int vc_db_initialize(void) +{ + SLOG(LOG_ERROR, vc_db_tag(), "DB initialization"); + + path = (char*)calloc(256, sizeof(char)); + if (NULL == path) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory"); + return VC_DB_ERROR_OUT_OF_MEMORY; + } + + /* This should be changed to general DB space - TZ_USER_DB */ + snprintf(path, 256, "%s/.vc_info.db", VC_RUNTIME_INFO_ROOT); + + struct stat stat; + int ret = db_util_open(path, &db_handle, DB_UTIL_REGISTER_HOOK_METHOD); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to open db, path = %s, ret %d: %s", path, ret, sqlite3_errmsg(db_handle)); + if (db_handle) { + db_util_close(db_handle); + db_handle = NULL; + } + return VC_DB_ERROR_OPERATION_FAILED; + } + + if (lstat(path, &stat) < 0) { + char buf_err[256]; + SLOG(LOG_ERROR, vc_db_tag(), "%s", strerror_r(errno, buf_err, sizeof (buf_err))); + if (db_handle) + db_util_close(db_handle); + db_handle = NULL; + return VC_DB_ERROR_OPERATION_FAILED; + } + + if (!S_ISREG(stat.st_mode)) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] S_ISREG failed"); + if (db_handle) + db_util_close(db_handle); + db_handle = NULL; + return VC_DB_ERROR_OPERATION_FAILED; + } + + if (!stat.st_size) { + vc_db_create_table(); + } + + if (db_handle) { + char* err_msg = NULL; + static const const char* sql = "PRAGMA journal_mode = WAL"; + int ret = sqlite3_exec(db_handle, sql, NULL, NULL, &err_msg); + if (ret != SQLITE_OK) { + SLOG(LOG_ERROR, vc_db_tag(), "sqlite3_exec returned %d: %s", ret, err_msg); + } + } + + return VC_DB_ERROR_NONE; +} + +int vc_db_finalize(void) +{ + if (NULL != path) { + free(path); + path = NULL; + } + + if (!db_handle) + return 0; + + db_util_close(db_handle); + + db_handle = NULL; + return VC_DB_ERROR_NONE; +} + +int vc_db_create_table(void) +{ + __vc_db_begin_transaction(); + + const char* vc_info_sql = "CREATE TABLE IF NOT EXISTS vc_info (id INTEGER PRIMARY KEY AUTOINCREMENT, pid INTEGER, type INTEGER, format INTEGER, domain INTEGER, \ + command TEXT, parameter TEXT, appid TEXT, invocation_name TEXT, fixed TEXT);"; + const char* vc_result_sql = "CREATE TABLE IF NOT EXISTS vc_result (id INTEGER PRIMARY KEY AUTOINCREMENT, result TEXT, event INTEGER, msg TEXT, exclusive INTEGER,\ + pid INTEGER, type INTEGER, format INTEGER, domain INTEGER, command TEXT, parameter TEXT, appid TEXT, invocation_name TEXT, fixed TEXT);"; + + int ret = __vc_db_exec_query(vc_info_sql); + if (ret != VC_DB_ERROR_NONE) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to create table, %d", ret); + __vc_db_rollback_transaction(); + return VC_DB_ERROR_OPERATION_FAILED; + } + SLOG(LOG_WARN, vc_db_tag(), "[SQL] %s", vc_info_sql); + + ret = __vc_db_exec_query(vc_result_sql); + if (ret != VC_DB_ERROR_NONE) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to create table, %d", ret); + __vc_db_rollback_transaction(); + return ret; + } + SLOG(LOG_WARN, vc_db_tag(), "[SQL] %s", vc_result_sql); + + __vc_db_commit_transaction(); + return VC_DB_ERROR_NONE; +} + +int vc_db_delete_table(const char* table) +{ + char* sql = NULL; + if (0 == strncmp(table, "result", strlen(table))) { + sql = strdup("DELETE FROM vc_result;"); + } else if (0 == strncmp(table, "command", strlen(table))) { + sql = strdup("DELETE_FROM vc_info;"); + } else { + return VC_DB_ERROR_INVALID_PARAMETER; + } + + if (NULL == sql) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory"); + return VC_DB_ERROR_OUT_OF_MEMORY; + } + + __vc_db_begin_transaction(); + + int ret = __vc_db_exec_query(sql); + if (ret != VC_DB_ERROR_NONE) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to delete table, %d", ret); + __vc_db_rollback_transaction(); + free(sql); + sql = NULL; + return ret; + } + + free(sql); + sql = NULL; + + if (0 == strncmp(table, "result", strlen(table))) { + sql = strdup("UPDATE SQLITE_SEQUENCE SET SEQ=0 WHERE NAME='vc_result';"); + } else if (0 == strncmp(table, "command", strlen(table))) { + sql = strdup("UPDATE SQLITE_SEQUENCE SET SEQ=0 WHERE NAME='vc_info';"); + } + + if (NULL == sql) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory"); + return VC_DB_ERROR_OUT_OF_MEMORY; + } + + ret = __vc_db_exec_query(sql); + if (ret != VC_DB_ERROR_NONE) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to delete table, %d", ret); + __vc_db_rollback_transaction(); + free(sql); + sql = NULL; + return ret; + } + + SLOG(LOG_WARN, vc_db_tag(), "[SQL] %s", sql); + __vc_db_commit_transaction(); + + free(sql); + sql = NULL; + return VC_DB_ERROR_NONE; +} + +static void __vc_db_remove_space(char** string) +{ + if (NULL == string || NULL == *string) + return; + + char* temp = *string; + + //remove previous space + if (' ' == temp[0]) + strncpy(temp, temp + 1, strlen(temp)); + + // remove next space + if (' ' == temp[strlen(temp) - 1]) + temp[strlen(temp) - 1] = '\0'; +} + +static bool __vc_db_is_valid_vfixed_string(char* string) +{ + char* temp = strchr(string, '}'); + if (NULL == temp) + return false; + + temp = strchr(string, '{'); + if (NULL == temp) + return false; + + temp = strchr(string, '|'); + if (NULL == temp) + return false; + return true; +} + +static int __vc_db_generate_command(vc_cmd_s* cmd, char** fixed_cmd, GSList** cmd_list) +{ + if (NULL == cmd || NULL == cmd->command) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Invalid parameter"); + return VC_DB_ERROR_INVALID_PARAMETER; + } + + GSList* temp_list = NULL; + char* temp = NULL; + char* src_cmd = strdup(cmd->command); + char* dst_cmd = NULL; + char merge_cmd[256] = {0, }; + + if (NULL == src_cmd) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory"); + return VC_DB_ERROR_OUT_OF_MEMORY; + } + + if (VC_CMD_FORMAT_FIXED_AND_VFIXED == cmd->format) { + // check string validation + if (false == __vc_db_is_valid_vfixed_string(src_cmd)) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Invalid parameter, cmd->command(%s)", src_cmd); + free(src_cmd); + src_cmd = NULL; + return VC_DB_ERROR_INVALID_PARAMETER; + } + + // remove close brace, '}' + char* temp_close = strchr(src_cmd, '}'); + temp_close[0] = '\0'; + + // extract fixed command and remove space in front of '{' + temp = strtok(src_cmd, "{"); + __vc_db_remove_space(&temp); + *fixed_cmd = strdup(temp); + + // merge command with fixed and vfixed + while (NULL != (temp = strtok(NULL, "|"))) { + __vc_db_remove_space(&temp); + + snprintf(merge_cmd, 256, "%s %s", *fixed_cmd, temp); + dst_cmd = strdup(merge_cmd); + temp_list = g_slist_append(temp_list, dst_cmd); + SLOG(LOG_ERROR, vc_db_tag(), "New generated cmd: %s", dst_cmd); + } + } else if (VC_CMD_FORMAT_VFIXED_AND_FIXED == cmd->format) { + // check string validation + if (false == __vc_db_is_valid_vfixed_string(src_cmd)) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Invalid parameter, cmd->command(%s)", src_cmd); + free(src_cmd); + src_cmd = NULL; + return VC_DB_ERROR_INVALID_PARAMETER; + } + + // extract fixed command + char* temp_fixed = strchr(src_cmd, '}') + 1; + __vc_db_remove_space(&temp_fixed); + *fixed_cmd = strdup(temp_fixed); + + // remove close brace, '}' + temp = strtok(src_cmd, "}"); + + // remove open brace, '{' + temp = strchr(src_cmd, '{') + 1; + + temp = strtok(temp, "|"); + __vc_db_remove_space(&temp); + + // merge command with fixed and vfixed + snprintf(merge_cmd, 256, "%s %s", temp, *fixed_cmd); + dst_cmd = strdup(merge_cmd); + temp_list = g_slist_append(temp_list, dst_cmd); + SLOG(LOG_ERROR, vc_db_tag(), "New generated cmd: %s", dst_cmd); + + while (NULL != (temp = strtok(NULL, "|"))) { + __vc_db_remove_space(&temp); + + // merge command with fixed and vfixed + snprintf(merge_cmd, 256, "%s %s", temp, *fixed_cmd); + dst_cmd = strdup(merge_cmd); + temp_list = g_slist_append(temp_list, dst_cmd); + SLOG(LOG_ERROR, vc_db_tag(), "New generated cmd: %s", dst_cmd); + } + } else if (VC_CMD_FORMAT_FIXED_AND_NONFIXED == cmd->format || VC_CMD_FORMAT_NONFIXED_AND_FIXED == cmd->format) { + dst_cmd = strdup(src_cmd); + temp_list = g_slist_append(temp_list, dst_cmd); + *fixed_cmd = strdup(src_cmd); + + } else { + dst_cmd = strdup(src_cmd); + temp_list = g_slist_append(temp_list, dst_cmd); + } + + *cmd_list = temp_list; + + free(src_cmd); + src_cmd = NULL; + return VC_DB_ERROR_NONE; +} + +int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd) +{ + GSList* cmd_list = NULL; + char* fixed_cmd = NULL; + + int ret = __vc_db_generate_command(cmd, &fixed_cmd, &cmd_list); + if (0 != ret) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to generate command, %d", ret); + return ret; + } + + __vc_db_begin_transaction(); + + if (0 != g_slist_length(cmd_list)) { + GSList *iter = NULL; + char* temp_command = NULL; + iter = g_slist_nth(cmd_list, 0); + + while (NULL != iter) { + temp_command = iter->data; + + if (NULL != temp_command) { + if (NULL != cmd->command) { + free(cmd->command); + cmd->command = NULL; + } + cmd->command = strdup(temp_command); + if (NULL != fixed_cmd) + cmd->fixed = strdup(fixed_cmd); + else + cmd->fixed = NULL; + + int ret = __vc_db_insert_commands(pid, type, cmd); + if (ret != VC_DB_ERROR_NONE) { + __vc_db_rollback_transaction(); + if (NULL != fixed_cmd) { + free(fixed_cmd); + fixed_cmd = NULL; + } + return ret; + } + + if (VC_COMMAND_TYPE_BACKGROUND == type && NULL != cmd->invocation_name) { + char temp[256] = {0, }; + snprintf(temp, 256, "%s %s", cmd->invocation_name, cmd->command); + if (NULL != cmd->command) + free(cmd->command); + + cmd->command = strdup(temp); + + ret = __vc_db_insert_commands(pid, type, cmd); + if (ret != VC_DB_ERROR_NONE) { + __vc_db_rollback_transaction(); + if (NULL != fixed_cmd) { + free(fixed_cmd); + fixed_cmd = NULL; + } + return ret; + } + } + + } + if (NULL != temp_command) { + free(temp_command); + temp_command = NULL; + } + iter = g_slist_next(iter); + } + cmd_list = NULL; + } + + __vc_db_commit_transaction(); + + if (NULL != fixed_cmd) { + free(fixed_cmd); + fixed_cmd = NULL; + } + return VC_DB_ERROR_NONE; +} + +int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name) +{ + GSList *iter = NULL; + vc_cmd_s *temp_cmd; + + int i; + int count = g_slist_length(cmd_list); + iter = g_slist_nth(cmd_list, 0); + + SLOG(LOG_DEBUG, vc_db_tag(), "list count : %d", count); + + for (i = 0; i < count; i++) { + if (NULL == iter) + break; + + temp_cmd = iter->data; + + if (NULL == temp_cmd) { + SLOG(LOG_ERROR, vc_db_tag(), "comamnd is NULL"); + break; + } + + if (type == temp_cmd->type) { + if (NULL != invocation_name) + temp_cmd->invocation_name = strdup(invocation_name); + + int ret = vc_db_insert_command(pid, type, temp_cmd); + if (ret != VC_DB_ERROR_NONE) { + SLOG(LOG_ERROR, vc_db_tag(), "Fail to insert command, ret(%d)", ret); + return ret; + } + } else { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Command type(%d) is NOT valid : request type(%d)", temp_cmd->type, type); + } + iter = g_slist_next(iter); + } + + return VC_DB_ERROR_NONE; +} + +int vc_db_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list) +{ + __vc_db_begin_transaction(); + + int ret = __vc_db_get_commands(pid, type, cmd_list); + if (ret != VC_DB_ERROR_NONE) { + __vc_db_rollback_transaction(); + return ret; + } + + __vc_db_commit_transaction(); + return VC_DB_ERROR_NONE; +} + +int vc_db_insert_result(const char* result_text, int event, const char* msg, vc_cmd_list_h vc_cmd_list, bool exclusive) +{ + if (NULL == result_text) { + SLOG(LOG_ERROR, vc_db_tag(), "Invalid parameter, result_text is NULL"); + return VC_DB_ERROR_INVALID_PARAMETER; + } + + int ret = vc_db_delete_table("result"); + if (0 != ret) + LOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to delete table"); + + if (NULL == vc_cmd_list) { + __vc_db_begin_transaction(); + int ret = __vc_db_insert_result(result_text, event, msg, exclusive, NULL); + if (ret != VC_DB_ERROR_NONE) { + __vc_db_rollback_transaction(); + return ret; + } + __vc_db_commit_transaction(); + return VC_DB_ERROR_NONE; + } + + /* Make client list node */ + vc_cmd_h vc_command = NULL; + vc_cmd_list_first(vc_cmd_list); + + while (VC_ERROR_ITERATION_END != ret) { + if (0 != vc_cmd_list_get_current(vc_cmd_list, &vc_command)) { + LOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to get command"); + break; + } + + if (NULL == vc_command) { + LOG(LOG_ERROR, vc_db_tag(), "[ERROR] No vc command any more"); + break; + } + + vc_cmd_s* temp_cmd = NULL; + temp_cmd = (vc_cmd_s*)vc_command; + + __vc_db_begin_transaction(); + ret = __vc_db_insert_result(result_text, event, msg, exclusive, temp_cmd); + if (ret != VC_DB_ERROR_NONE) { + __vc_db_rollback_transaction(); + return ret; + } + __vc_db_commit_transaction(); + + ret = vc_cmd_list_next(vc_cmd_list); + } + + return VC_DB_ERROR_NONE; +} + +int vc_db_get_result(char** result_text, int* event, char** msg, int pid, vc_cmd_list_h vc_cmd_list, bool exclusive) +{ + __vc_db_begin_transaction(); + + int ret = __vc_db_get_result(result_text, event, msg, pid, NULL, vc_cmd_list, exclusive); + if (ret != VC_DB_ERROR_NONE) { + __vc_db_rollback_transaction(); + return VC_DB_ERROR_OPERATION_FAILED; + } + + if (NULL == msg) { + int count = 0; + ret = vc_cmd_list_get_count(vc_cmd_list, &count); + if (ret != VC_DB_ERROR_NONE) { + LOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to get count"); + } + if (0 == count) { + char* appid = NULL; + // Get appid by pid using app control + ret = app_manager_get_app_id(pid, &appid); + if (APP_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] fail to get app id, ret(%d), pid(%d)", ret, pid); + } + ret = __vc_db_get_result(result_text, event, msg, pid, appid, vc_cmd_list, exclusive); + if (ret != VC_DB_ERROR_NONE) { + __vc_db_rollback_transaction(); + return ret; + } + if (NULL != appid) { + free(appid); + appid = NULL; + } + } + } + __vc_db_commit_transaction(); + return VC_DB_ERROR_NONE; +} + +int vc_db_get_appid_list(const char* result, GSList** app_list) +{ + __vc_db_begin_transaction(); + + int ret = __vc_db_get_appid(result, app_list); + if (ret != VC_DB_ERROR_NONE) { + __vc_db_rollback_transaction(); + return ret; + } + + __vc_db_commit_transaction(); + return VC_DB_ERROR_NONE; +} + +int vc_db_get_result_pid_list(const char* result, GSList** pid_list) +{ + __vc_db_begin_transaction(); + + int ret = __vc_db_get_result_pid_list(result, pid_list); + if (ret != VC_DB_ERROR_NONE) { + __vc_db_rollback_transaction(); + return ret; + } + + __vc_db_commit_transaction(); + return VC_DB_ERROR_NONE; +} + +int vc_db_append_commands(int pid, int type, vc_cmd_list_h vc_cmd_list) +{ + __vc_db_begin_transaction(); + + int ret = __vc_db_append_commands(pid, type, vc_cmd_list); + if (ret != VC_DB_ERROR_NONE) { + __vc_db_rollback_transaction(); + return ret; + } + + __vc_db_commit_transaction(); + return VC_DB_ERROR_NONE; +} + +int vc_db_delete_commands(int pid, vc_cmd_type_e type, char* appid) +{ + __vc_db_begin_transaction(); + + int ret = 0; + ret = __vc_db_delete_commands(pid, type, appid); + if (ret != VC_DB_ERROR_NONE) { + __vc_db_rollback_transaction(); + return ret; + } + + __vc_db_commit_transaction(); + return VC_DB_ERROR_NONE; +} diff --git a/common/vc_cmd_db.h b/common/vc_cmd_db.h new file mode 100644 index 0000000..c8133e7 --- /dev/null +++ b/common/vc_cmd_db.h @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2011-2016 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. +*/ + + +#ifndef __VC_CMD_DB_H_ +#define __VC_CMD_DB_H_ + +#include "vc_command.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + VC_DB_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + VC_DB_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of Memory */ + VC_DB_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */ + VC_DB_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + VC_DB_ERROR_TIMED_OUT = TIZEN_ERROR_TIMED_OUT, /**< No answer from service */ + VC_DB_ERROR_RECORDER_BUSY = TIZEN_ERROR_RESOURCE_BUSY, /**< Busy recorder */ + VC_DB_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + VC_DB_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< VC NOT supported */ + VC_DB_ERROR_INVALID_STATE = TIZEN_ERROR_VOICE_CONTROL | 0x011, /**< Invalid state */ + VC_DB_ERROR_INVALID_LANGUAGE = TIZEN_ERROR_VOICE_CONTROL | 0x012, /**< Invalid language */ + VC_DB_ERROR_ENGINE_NOT_FOUND = TIZEN_ERROR_VOICE_CONTROL | 0x013, /**< No available engine */ + VC_DB_ERROR_OPERATION_FAILED = TIZEN_ERROR_VOICE_CONTROL | 0x014, /**< Operation failed */ + VC_DB_ERROR_OPERATION_REJECTED = TIZEN_ERROR_VOICE_CONTROL | 0x015, /**< Operation rejected */ + VC_DB_ERROR_ITERATION_END = TIZEN_ERROR_VOICE_CONTROL | 0x016, /**< List reached end */ + VC_DB_ERROR_EMPTY = TIZEN_ERROR_VOICE_CONTROL | 0x017, /**< List empty */ + VC_DB_ERROR_SERVICE_RESET = TIZEN_ERROR_VOICE_CONTROL | 0x018 /**< Service Damon reset */ +} vc_db_error_e; + +typedef struct _deactivated_app_s { + char* appid; +} vc_deactivated_app_s; + +int vc_db_initialize(void); + +int vc_db_finalize(void); + +int vc_db_create_table(void); + +int vc_db_delete_table(const char* table); + +int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd); + +int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name); + +int vc_db_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list); + +int vc_db_insert_result(const char* result_text, int event, const char* msg, vc_cmd_list_h vc_cmd_list, bool exclusive); + +int vc_db_get_result(char** result_text, int* event, char** result_message, int pid, vc_cmd_list_h vc_cmd_list, bool exclusive); + +int vc_db_get_appid_list(const char* result, GSList** app_list); + +int vc_db_get_result_pid_list(const char* result, GSList** pid_list); + +int vc_db_append_commands(int pid, int type, vc_cmd_list_h vc_cmd_list); + +int vc_db_select_by_pid(int pid); + +int vc_db_delete_commands(int pid, vc_cmd_type_e type, char* appid); + + +#ifdef __cplusplus +} +#endif + +#endif /* __VC_CMD_DB_H_ */ diff --git a/common/vc_command.c b/common/vc_command.c index 4d5fa9f..e728fb5 100644 --- a/common/vc_command.c +++ b/common/vc_command.c @@ -22,6 +22,7 @@ #include #include "vc_command.h" +#include "vc_info_parser.h" #include "vc_main.h" #include "voice_control_command.h" #include "voice_control_command_expand.h" @@ -68,7 +69,7 @@ static int __check_privilege_initialize() int ret = cynara_initialize(&p_cynara, NULL); if (CYNARA_API_SUCCESS != ret) SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] fail to initialize"); - + return ret == CYNARA_API_SUCCESS; } @@ -679,6 +680,7 @@ int vc_cmd_create(vc_cmd_h* vc_command) command->command = NULL; command->parameter = NULL; command->domain = 0; + command->priority = 0; command->key = VC_KEY_NONE; command->modifier = VC_MODIFIER_NONE; @@ -768,6 +770,58 @@ int vc_cmd_get_id(vc_cmd_h vc_command, int* id) return 0; } +int vc_cmd_set_appid(vc_cmd_h vc_command, const char* appid) +{ + if (0 != __vc_cmd_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + + if (NULL == vc_command) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, vc_command is NULL"); + return VC_ERROR_INVALID_PARAMETER; + } + + if (NULL == appid) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, appid is NULL"); + return VC_ERROR_INVALID_PARAMETER; + } + + vc_cmd_s* cmd = NULL; + cmd = (vc_cmd_s*)vc_command; + + if (NULL != cmd->appid) { + free(cmd->appid); + cmd->appid = NULL; + } + + cmd->appid = strdup(appid); + + SLOG(LOG_DEBUG, TAG_VCCMD, "[Set appid][%p] appid(%s)", vc_command, cmd->appid); + return 0; +} + +int vc_cmd_get_appid(vc_cmd_h vc_command, char** appid) +{ + if (0 != __vc_cmd_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + + if (NULL == vc_command || NULL == appid) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle "); + return VC_ERROR_INVALID_PARAMETER; + } + + vc_cmd_s* cmd = NULL; + cmd = (vc_cmd_s*)vc_command; + + if (NULL != cmd->appid) { + *appid = strdup(gettext(cmd->appid)); + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "[Get appid][%p] appid(%s)", vc_command, *appid); + return 0; +} + int vc_cmd_set_command(vc_cmd_h vc_command, const char* command) { if (0 != __vc_cmd_get_feature_enabled()) { @@ -851,7 +905,7 @@ int vc_cmd_set_unfixed_command(vc_cmd_h vc_command, const char* command) if (NULL != command) { cmd->parameter = strdup(command); - SLOG(LOG_DEBUG, TAG_VCCMD, "[Set parameter][%p] parameter(%s)", vc_command, cmd->parameter); + SLOG(LOG_DEBUG, TAG_VCCMD, "[Set unfixed command][%p] unfixed command(%s)", vc_command, cmd->parameter); } return 0; @@ -876,9 +930,113 @@ int vc_cmd_get_unfixed_command(vc_cmd_h vc_command, char** command) if (NULL != cmd->parameter) { *command = strdup(gettext(cmd->parameter)); - SLOG(LOG_DEBUG, TAG_VCCMD, "[Get nonfixed command][%p] nonfixed command(%s)", vc_command, *command); + SLOG(LOG_DEBUG, TAG_VCCMD, "[Get unfixed command][%p] unfixed command(%s)", vc_command, *command); + } + + return 0; +} + +int vc_cmd_set_fixed_command(vc_cmd_h vc_command, const char* fixed) +{ + if (0 != __vc_cmd_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + + if (NULL == vc_command) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter "); + return VC_ERROR_INVALID_PARAMETER; } + if (NULL == fixed) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, fixed is NULL"); + return VC_ERROR_INVALID_PARAMETER; + } + + vc_cmd_s* cmd = NULL; + cmd = (vc_cmd_s*)vc_command; + + if (NULL != cmd->fixed) { + free(cmd->fixed); + cmd->fixed = NULL; + } + + cmd->fixed = strdup(fixed); + + SLOG(LOG_DEBUG, TAG_VCCMD, "[Set parameter][%p] fixed command(%s)", vc_command, cmd->fixed); + return 0; +} + +int vc_cmd_get_fixed_command(vc_cmd_h vc_command, char** fixed) +{ + if (0 != __vc_cmd_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + + if (NULL == vc_command || NULL == fixed) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle "); + return VC_ERROR_INVALID_PARAMETER; + } + + vc_cmd_s* cmd = NULL; + cmd = (vc_cmd_s*)vc_command; + + if (NULL != cmd->fixed) { + *fixed = strdup(gettext(cmd->fixed)); + SLOG(LOG_DEBUG, TAG_VCCMD, "[Get fixed command][%p] fixed command(%s)", vc_command, *fixed); + } + + return 0; +} + +int vc_cmd_set_invocation_name(vc_cmd_h vc_command, const char* invocation_name) +{ + if (0 != __vc_cmd_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + + if (NULL == vc_command) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, vc_command is NULL"); + return VC_ERROR_INVALID_PARAMETER; + } + + if (NULL == invocation_name) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter, invocation_name is NULL"); + return VC_ERROR_INVALID_PARAMETER; + } + + vc_cmd_s* cmd = NULL; + cmd = (vc_cmd_s*)vc_command; + + if (NULL != cmd->invocation_name) { + free(cmd->invocation_name); + cmd->invocation_name = NULL; + } + + cmd->invocation_name = strdup(invocation_name); + + SLOG(LOG_DEBUG, TAG_VCCMD, "[Set invocation name][%p] invocation_name(%s)", vc_command, cmd->invocation_name); + return 0; +} + +int vc_cmd_get_invocation_name(vc_cmd_h vc_command, char** invocation_name) +{ + if (0 != __vc_cmd_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + + if (NULL == vc_command || NULL == invocation_name) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid handle "); + return VC_ERROR_INVALID_PARAMETER; + } + + vc_cmd_s* cmd = NULL; + cmd = (vc_cmd_s*)vc_command; + + if (NULL != cmd->invocation_name) { + *invocation_name = strdup(gettext(cmd->invocation_name)); + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "[Get invocation name][%p] invocation_name(%s)", vc_command, *invocation_name); return 0; } @@ -1159,14 +1317,14 @@ int vc_cmd_print_list(vc_cmd_list_h vc_cmd_list) int count = g_slist_length(list->list); int i; - vc_cmd_s *temp_cmd = NULL; + vc_cmd_s *cmd = NULL; for (i = 0; i < count ; i++) { - temp_cmd = g_slist_nth_data(list->list, i); + cmd = g_slist_nth_data(list->list, i); - if (NULL != temp_cmd) { - SLOG(LOG_DEBUG, TAG_VCCMD, " [%d][%p] PID(%d) ID(%d) Type(%d) Format(%d) Domain(%d) Command(%s) Param(%s)", - i, temp_cmd, temp_cmd->pid, temp_cmd->index, temp_cmd->type, temp_cmd->format, temp_cmd->domain, temp_cmd->command, temp_cmd->parameter); + if (NULL != cmd) { + SLOG(LOG_DEBUG, TAG_VCCMD, " [%d][%p] PID(%d) ID(%d) Type(%d) Format(%d) Command(%s) Param(%s) Appid(%s) Invocation(%s) Fixed(%s)", + i, cmd, cmd->pid, cmd->index, cmd->type, cmd->format, cmd->command, cmd->parameter, cmd->appid, cmd->invocation_name, cmd->fixed); } } @@ -1175,3 +1333,30 @@ int vc_cmd_print_list(vc_cmd_list_h vc_cmd_list) return 0; } + +int vc_cmd_get_nlu_json(vc_cmd_h vc_cmd, char** json) +{ + if (0 != __vc_cmd_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + + if (NULL == vc_cmd || NULL == json) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] NULL parameter"); + return VC_ERROR_INVALID_PARAMETER; + } + + vc_cmd_s* cmd = NULL; + cmd = (vc_cmd_s*)vc_cmd; + + if (VC_CMD_FORMAT_ACTION != cmd->format) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Not Action format"); + return VC_ERROR_INVALID_PARAMETER; + } + + if (0 != vc_info_parser_get_nlu_result(json)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get nlu result"); + return VC_ERROR_OPERATION_FAILED; + } + + return 0; +} diff --git a/common/vc_command.h b/common/vc_command.h old mode 100755 new mode 100644 index 236c8af..2791f01 --- a/common/vc_command.h +++ b/common/vc_command.h @@ -35,6 +35,11 @@ typedef struct _command_s { int domain; char* command; char* parameter; + char* appid; + + int priority; + char* invocation_name; + char* fixed; /* not used */ int key; @@ -56,9 +61,17 @@ typedef enum { VC_COMMAND_TYPE_BACKGROUND = 2, /**< Background command by client */ VC_COMMAND_TYPE_WIDGET = 3, /**< Widget command by widget client */ VC_COMMAND_TYPE_SYSTEM = 4, /**< System command by manager client */ - VC_COMMAND_TYPE_EXCLUSIVE = 5 /**< exclusive command by manager client */ + VC_COMMAND_TYPE_SYSTEM_BACKGROUND = 5, /**< System Background command by manager client */ + VC_COMMAND_TYPE_EXCLUSIVE = 6 /**< exclusive command by manager client */ } vc_cmd_type_e; +typedef enum { + VC_COMMAND_PRIORITY_SYSTEM = 1, + VC_COMMAND_PRIORITY_EXCLUSIVE = 2, + VC_COMMAND_PRIORITY_FOREGROUND = 3, + VC_COMMAND_PRIORITY_SYSTEM_BACKGROUND = 4, + VC_COMMAND_PRIORITY_BACKGROUND = 5 +} vc_cmd_priority_e; int vc_cmd_set_id(vc_cmd_h vc_command, int id); @@ -67,11 +80,12 @@ int vc_cmd_get_id(vc_cmd_h vc_command, int* id); int vc_cmd_print_list(vc_cmd_list_h vc_cmd_list); /** -* @brief Sets extra unfixed command. +* @brief Remove all commands from command list. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * -* @param[in] vc_command The command handle -* @param[in] command The unfixed command +* @param[in] vc_cmd_list The command list handle +* @param[in] free_command The command free option @c true = release each commands in list, +* @c false = remove command from list * * @return 0 on success, otherwise a negative error value * @retval #VC_CMD_ERROR_NONE Successful @@ -79,22 +93,22 @@ int vc_cmd_print_list(vc_cmd_list_h vc_cmd_list); * @retval #VC_CMD_ERROR_PERMISSION_DENIED Permission denied * @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature * -* @see vc_cmd_get_non_fixed_command() +* @see vc_cmd_list_add() */ -int vc_cmd_set_unfixed_command(vc_cmd_h vc_command, const char* command); +int vc_cmd_list_remove_all(vc_cmd_list_h vc_cmd_list, bool free_command); /** * @brief Sets pid. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * * @param[in] vc_command The command handle -* @param[in] pid process id +* @param[in] pid Process id * * @return 0 on success, otherwise a negative error value * @retval #VC_CMD_ERROR_NONE Successful * @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter * -* @see vc_cmd_set_pid() +* @see vc_cmd_get_pid() */ int vc_cmd_set_pid(vc_cmd_h vc_command, int pid); @@ -103,7 +117,7 @@ int vc_cmd_set_pid(vc_cmd_h vc_command, int pid); * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * * @param[in] vc_command The command handle -* @param[in] domain domain +* @param[out] pid Process id * * @return 0 on success, otherwise a negative error value * @retval #VC_CMD_ERROR_NONE Successful @@ -111,10 +125,137 @@ int vc_cmd_set_pid(vc_cmd_h vc_command, int pid); * @retval #VC_CMD_ERROR_PERMISSION_DENIED Permission denied * @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature * -* @see vc_cmd_get_domain() +* @see vc_cmd_set_pid() */ int vc_cmd_get_pid(vc_cmd_h vc_command, int* pid); +/** +* @brief Sets app id. +* @since_tizen 3.0 +* +* @param[in] vc_command The command handle +* @param[in] appid App id +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_CMD_ERROR_NONE Successful +* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature +* +* @see vc_cmd_get_appid() +*/ +int vc_cmd_set_appid(vc_cmd_h vc_command, const char* appid); + +/** +* @brief Gets app id +* @since_tizen 3.0 +* +* @param[in] vc_command The command handle +* @param[out] appid App id +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_CMD_ERROR_NONE Successful +* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature +* +* @see vc_cmd_set_appid() +*/ +int vc_cmd_get_appid(vc_cmd_h vc_command, char** appid); + +/** +* @brief Sets fixed command +* @since_tizen 3.0 +* +* @param[in] vc_command The command handle +* @param[in] fixed Fixed command +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_CMD_ERROR_NONE Successful +* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature +* +* @see vc_cmd_get_fixed_command() +*/ +int vc_cmd_set_fixed_command(vc_cmd_h vc_command, const char* fixed); + +/** +* @brief Gets fixed command +* @since_tizen 3.0 +* +* @param[in] vc_command The command handle +* @param[out] fixed Fixed command +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_CMD_ERROR_NONE Successful +* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature +* +* @see vc_cmd_set_fixed_command() +*/ +int vc_cmd_get_fixed_command(vc_cmd_h vc_command, char** fixed); + +/** +* @brief Sets unfixed command. +* @since_tizen 3.0 +* +* @param[in] vc_command The command handle +* @param[in] command The unfixed command +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_CMD_ERROR_NONE Successful +* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature +* +* @see vc_cmd_get_unfixed_command() +*/ +int vc_cmd_set_unfixed_command(vc_cmd_h vc_command, const char* command); + +/** +* @brief Gets fixed command +* @since_tizen 3.0 +* +* @param[in] vc_command The command handle +* @param[out] fixed Fixed command +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_CMD_ERROR_NONE Successful +* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature +* +* @see vc_cmd_set_unfixed_command() +*/ +int vc_cmd_get_unfixed_command(vc_cmd_h vc_command, char** command); + +/** +* @brief Sets invocation name. +* @since_tizen 3.0 +* +* @param[in] vc_command The command handle +* @param[in] invocation Invocation name +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_CMD_ERROR_NONE Successful +* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature +* +* @see vc_cmd_get_invocation_name() +*/ +int vc_cmd_set_invocation_name(vc_cmd_h vc_command, const char* invocation); + +/** +* @brief Gets invocation name +* @since_tizen 3.0 +* +* @param[in] vc_command The command handle +* @param[out] invocation Invocation Name +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_CMD_ERROR_NONE Successful +* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature +* +* @see vc_cmd_set_invocation_name() +*/ +int vc_cmd_get_invocation_name(vc_cmd_h vc_command, char** invocation); #ifdef __cplusplus } diff --git a/common/vc_config_mgr.c b/common/vc_config_mgr.c index f8caf11..822f81d 100644 --- a/common/vc_config_mgr.c +++ b/common/vc_config_mgr.c @@ -27,8 +27,8 @@ #include #include "vc_config_mgr.h" -#include "vc_defs.h" #include "vc_config_parser.h" +#include "vc_defs.h" #include "vc_main.h" #include "voice_control_command.h" @@ -53,8 +53,6 @@ static GSList* g_config_client_list = NULL; static vc_config_s* g_config_info; -static int g_foreground_pid; - static int g_lang_ref_count; static Ecore_Fd_Handler* g_fd_handler_lang = NULL; static int g_fd_lang; @@ -387,7 +385,7 @@ int __vc_config_set_auto_language() SLOG(LOG_ERROR, vc_config_tag(), "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(), "Current config language is NULL"); @@ -651,13 +649,6 @@ int vc_config_mgr_initialize(int uid) SLOG(LOG_DEBUG, vc_config_tag(), " language : %s", g_config_info->language); SLOG(LOG_DEBUG, vc_config_tag(), "==================="); - if (0 != vc_parser_get_foreground(&g_foreground_pid)) { - SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get foreground pid"); - return VC_CONFIG_ERROR_OPERATION_FAILED; - } - - SLOG(LOG_DEBUG, vc_config_tag(), "Current foreground pid : %d", g_foreground_pid); - g_lang_ref_count = 0; /* Register to detect display language change */ diff --git a/common/vc_defs.h b/common/vc_defs.h index 6b580da..7b6294d 100644 --- a/common/vc_defs.h +++ b/common/vc_defs.h @@ -63,6 +63,8 @@ extern "C" { #define VC_METHOD_SET_COMMAND "vc_method_set_command" #define VC_METHOD_UNSET_COMMAND "vc_method_unset_command" #define VC_METHOD_SET_FOREGROUND "vc_method_set_foreground" +#define VC_METHOD_DIALOG "vc_method_dialog" +#define VC_METHOD_IS_SYS_COMMAND_VALID "vc_method_is_system_command_valid" #define VCD_METHOD_RESULT "vcd_method_result" #define VCD_METHOD_ERROR "vcd_method_error" @@ -119,11 +121,15 @@ extern "C" { #define VC_MANAGER_METHOD_SET_AUDIO_TYPE "vc_manager_method_set_audio_type" #define VC_MANAGER_METHOD_GET_AUDIO_TYPE "vc_manager_method_get_audio_type" #define VC_MANAGER_METHOD_SET_CLIENT_INFO "vc_manager_method_set_client_info" +#define VC_MANAGER_METHOD_SET_PRIVATE_DATA "vc_manager_method_set_private_data" +#define VC_MANAGER_METHOD_GET_PRIVATE_DATA "vc_manager_method_get_private_data" #define VC_MANAGER_METHOD_START "vc_manager_method_request_start" #define VC_MANAGER_METHOD_STOP "vc_manager_method_request_stop" #define VC_MANAGER_METHOD_CANCEL "vc_manager_method_request_cancel" #define VC_MANAGER_METHOD_RESULT_SELECTION "vc_manager_method_result_selection" +#define VC_MANAGER_METHOD_SET_DOMAIN "vc_manager_method_set_domain" +#define VC_MANAGER_METHOD_DO_ACTION "vc_manager_method_do_action" #define VCD_MANAGER_METHOD_HELLO "vcd_manager_method_hello" #define VCD_MANAGER_METHOD_SPEECH_DETECTED "vcd_manager_method_speech_detected" @@ -132,6 +138,7 @@ extern "C" { #define VCD_MANAGER_METHOD_RESULT "vcd_manager_method_result" #define VCD_MANAGER_METHOD_SET_VOLUME "vcd_manager_method_set_volume" #define VCD_MANAGER_METHOD_SET_SERVICE_STATE "vcd_manager_method_set_service_state" +#define VCD_MANAGER_METHOD_DIALOG "vcd_manager_method_dialog" #define VCD_MANAGER_METHOD_ERROR "vcd_manager_method_error" @@ -168,11 +175,11 @@ extern "C" { #define VC_RUNTIME_INFO_EX_RESULT tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-ex-result.xml") -#define VC_RUNTIME_INFO_CLIENT tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-client-info.xml") +#define VC_RUNTIME_INFO_NLU_RESULT tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-nlu-result.xml") -#define VC_RUNTIME_INFO_NLP_INFO tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-nlp-info.xml") +#define VC_RUNTIME_INFO_CLIENT tzplatform_mkpath(TZ_USER_HOME, "share/.voice/vc/vc-client-info.xml") -#define VC_NO_FOREGROUND_PID 0 +#define VC_NO_FOREGROUND_PID -1 #define VC_BASE_LANGUAGE "en_US" #define VC_RETRY_COUNT 5 #define VC_RUNTIME_INFO_NO_FOREGROUND -1 diff --git a/common/vc_info_parser.c b/common/vc_info_parser.c index 1f098f1..882779d 100644 --- a/common/vc_info_parser.c +++ b/common/vc_info_parser.c @@ -14,12 +14,13 @@ * limitations under the License. */ - +#include #include #include #include #include +#include "vc_cmd_db.h" #include "vc_defs.h" #include "vc_info_parser.h" #include "vc_main.h" @@ -40,6 +41,7 @@ #define VC_TAG_CMD_DOMAIN "cmd_domain" #define VC_TAG_CMD_KEY "cmd_key" #define VC_TAG_CMD_MODIFIER "cmd_modifier" +#define VC_TAG_CMD_IS_ACTION "cmd_is_action" #define VC_TAG_RESULT_BASE_TAG "vc_results" #define VC_TAG_RESULT_TEXT "result_text" @@ -79,207 +81,82 @@ static int __vc_info_parser_set_file_mode(const char* filename) SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to change file mode"); return -1; } - -#if 0 /*Does not need to change owner on Tizen 3.0*/ - if (0 > chown(filename, 5000, 5000)) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to change file owner"); - return -1; - } -#endif - - return 0; -} - -int __vc_cmd_parser_make_filepath(int pid, vc_cmd_type_e type, char** path) -{ - if (NULL == path) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Input parameter is NULL"); - return -1; - } - - *path = (char*)calloc(256, sizeof(char)); - if (NULL == *path) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to allocate memory"); - return VC_ERROR_OUT_OF_MEMORY; - } - - snprintf(*path, 256, "%s/vc_%d_%d.xml", VC_RUNTIME_INFO_ROOT, (int)type, pid); - return 0; } -int vc_cmd_parser_save_file(int pid, vc_cmd_type_e type, GSList* cmd_list) +int vc_cmd_parser_save_file(int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name) { if (0 >= g_slist_length(cmd_list)) { SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Command list is invalid"); return -1; } - /* Check file */ - char* filepath = NULL; - __vc_cmd_parser_make_filepath(pid, type, &filepath); - - if (NULL == filepath) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to create file path"); - return -1; + int ret = vc_db_insert_commands_list(pid, type, cmd_list, invocation_name); + if (0 != ret) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Insert db is failed, ret = %d", ret); } + return ret; +} - remove(filepath); - - xmlDocPtr doc; - xmlNodePtr root_node; - xmlNodePtr cmd_node; - xmlNodePtr tmp_node; - - doc = xmlNewDoc((const xmlChar*)"1.0"); - doc->encoding = (const xmlChar*)"utf-8"; - doc->charset = 1; - - root_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_BASE_TAG); - xmlDocSetRootElement(doc, root_node); - - GSList *iter = NULL; - vc_cmd_s *temp_cmd; - - int i; - int count = g_slist_length(cmd_list); - iter = g_slist_nth(cmd_list, 0); - - SLOG(LOG_DEBUG, vc_info_tag(), "list count : %d", count); - char temp[16] = {0, }; - int selected_count = 0; - - for (i = 0; i < count; i++) { - if (NULL == iter) - break; - - temp_cmd = iter->data; - - if (NULL == temp_cmd) { - SLOG(LOG_ERROR, vc_info_tag(), "comamnd is NULL"); - break; - } - - if (type == temp_cmd->type) { - SLOG(LOG_DEBUG, vc_info_tag(), "[%dth] type(%d) format(%d) domain(%d) cmd(%s) param(%s)", - i, temp_cmd->type, temp_cmd->format, temp_cmd->domain, temp_cmd->command, temp_cmd->parameter); - - /* Make new command node */ - cmd_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_COMMAND); - - /* ID */ - memset(temp, 0, 16); - snprintf(temp, 16, "%d", i); - - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_ID); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp); - xmlAddChild(cmd_node, tmp_node); - - /* PID */ - memset(temp, 0, 16); - snprintf(temp, 16, "%d", getpid()); - - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_PID); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp); - xmlAddChild(cmd_node, tmp_node); - - /* TYPE */ - memset(temp, 0, 16); - snprintf(temp, 16, "%d", temp_cmd->type); - - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_TYPE); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp); - xmlAddChild(cmd_node, tmp_node); - - /* FORMAT */ - memset(temp, 0, 16); - snprintf(temp, 16, "%d", temp_cmd->format); - - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_FORMAT); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp); - xmlAddChild(cmd_node, tmp_node); - - /* DOMAIN */ - memset(temp, 0, 16); - snprintf(temp, 16, "%d", temp_cmd->domain); - - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_DOMAIN); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp); - xmlAddChild(cmd_node, tmp_node); - - /* COMMAND */ - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_COMMAND_TEXT); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp_cmd->command); - xmlAddChild(cmd_node, tmp_node); - - /* PARAMETER */ - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_PARAMETER_TEXT); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp_cmd->parameter); - xmlAddChild(cmd_node, tmp_node); - - xmlAddChild(root_node, cmd_node); +int vc_cmd_parser_delete_file(int pid, vc_cmd_type_e type) +{ + int ret = 0; + char* appid = NULL; - selected_count++; + if (-1 != pid) { + // Get appid by pid using app control + ret = app_manager_get_app_id(pid, &appid); + if (APP_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] fail to get app id, ret(%d)", ret); } else { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Command type(%d) is NOT valid : request type(%d)", temp_cmd->type, type); + SLOG(LOG_ERROR, vc_info_tag(), "Background cmd: appid = %s", appid); } - iter = g_slist_next(iter); } - if (0 < selected_count) { - int ret = xmlSaveFormatFile(filepath, doc, 1); - if (0 >= ret) { - SLOG(LOG_DEBUG, vc_info_tag(), "[ERROR] Fail to save command file : %d, filepath(%s)", ret, filepath); - free(filepath); - return -1; - } - - if (0 != __vc_info_parser_set_file_mode(filepath)) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to set file mode - %s", filepath); - } else { - SLOG(LOG_DEBUG, vc_info_tag(), "[Success] Save command file"); - } - free(filepath); - } else { - free(filepath); - - SLOG(LOG_DEBUG, vc_info_tag(), "No command"); - return -1; + ret = vc_db_delete_commands(pid, type, appid); + if (0 != ret) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] get commands from db is failed, ret = %d", ret); } - - return 0; + if (NULL != appid) { + free(appid); + appid = NULL; + } + return ret; } -int vc_cmd_parser_delete_file(int pid, vc_cmd_type_e type) +int vc_cmd_parser_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list) { - /* Check file */ - char* filepath = NULL; - __vc_cmd_parser_make_filepath(pid, type, &filepath); + int ret = vc_db_get_commands(pid, type, cmd_list); + if (0 != ret) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] get commands from db is failed, ret = %d", ret); + } + __vc_cmd_parser_print_commands(*cmd_list); + return ret; +} - if (NULL != filepath) { - remove(filepath); - free(filepath); +int vc_cmd_parser_append_commands(int pid, vc_cmd_type_e type, vc_cmd_list_h vc_cmd_list) +{ + int ret = vc_db_append_commands(pid, type, vc_cmd_list); + if (0 != ret) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] get commands from db is failed, ret = %d", ret); } - return 0; + vc_cmd_print_list(vc_cmd_list); + return ret; } -int vc_cmd_parser_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list) +int vc_info_parser_get_demandable_clients(GSList** client_list) { /* Check file */ - char* filepath = NULL; - __vc_cmd_parser_make_filepath(pid, type, &filepath); - xmlDocPtr doc = NULL; xmlNodePtr cur = NULL; xmlChar *key; - doc = xmlParseFile(filepath); + doc = xmlParseFile(VC_RUNTIME_INFO_DEMANDABLE_LIST); if (doc == NULL) { - SECURE_SLOG(LOG_WARN, vc_info_tag(), "[WARNING] Fail to parse file error : %s", filepath); + SECURE_SLOG(LOG_WARN, vc_info_tag(), "[WARNING] Fail to parse file error : %s", VC_RUNTIME_INFO_FOREGROUND); return -1; } - if (NULL != filepath) free(filepath); cur = xmlDocGetRootElement(doc); if (cur == NULL) { @@ -288,8 +165,8 @@ int vc_cmd_parser_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list) return -1; } - if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CMD_BASE_TAG)) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_CMD_BASE_TAG); + if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_BASE_TAG)) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_DEMANDABLE_CLIENT_BASE_TAG); xmlFreeDoc(doc); return -1; } @@ -301,177 +178,59 @@ int vc_cmd_parser_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list) return -1; } - GSList* temp_cmd_list = NULL; + GSList* temp_client_list = NULL; while (cur != NULL) { - cur = cur->next; - - if (NULL == cur) { - break; - } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)"text")) { - continue; - } - - xmlNodePtr command_node = NULL; - command_node = cur->xmlChildrenNode; - command_node = command_node->next; - - vc_cmd_s* temp_cmd; - temp_cmd = (vc_cmd_s*)calloc(1, sizeof(vc_cmd_s)); - - if (NULL == temp_cmd) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Memory alloc error!!"); - return -1; - } - - /* ID */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_ID)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "ID : %s", (char *)key); - temp_cmd->index = atoi((char*)key); - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_ID); - free(temp_cmd); - break; - } - } - - command_node = command_node->next; - command_node = command_node->next; - - /* PID */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_PID)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "PID : %s", (char *)key); - temp_cmd->pid = atoi((char*)key); - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_PID); - free(temp_cmd); - break; - } - } - - command_node = command_node->next; - command_node = command_node->next; - - /* Type */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_TYPE)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "Type : %s", (char *)key); - temp_cmd->type = atoi((char*)key); - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_TYPE); - free(temp_cmd); - break; - } - } - - command_node = command_node->next; - command_node = command_node->next; - - /* Format */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_FORMAT)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "Format : %s", (char *)key); - temp_cmd->format = atoi((char*)key); - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_FORMAT); - free(temp_cmd); - break; - } - } - - command_node = command_node->next; - command_node = command_node->next; - - /* Domain */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_DOMAIN)) { - key = xmlNodeGetContent(command_node); + if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_APPID)) { + key = xmlNodeGetContent(cur); if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "Domain : %s", (char *)key); - temp_cmd->domain = atoi((char*)key); - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_DOMAIN); - free(temp_cmd); - break; - } - } + SLOG(LOG_DEBUG, vc_info_tag(), "App id : %s", (char *)key); - command_node = command_node->next; - command_node = command_node->next; + vc_demandable_client_s* temp_client; + temp_client = (vc_demandable_client_s*)calloc(1, sizeof(vc_demandable_client_s)); - /* Command */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_COMMAND_TEXT)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "Command : %s", (char *)key); - if (0 < xmlStrlen(key)) { - temp_cmd->command = strdup((char*)key); - } else { - temp_cmd->command = NULL; + if (NULL == temp_client) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Memory alloc error!!"); + return -1; } - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_COMMAND_TEXT); - free(temp_cmd); - break; - } - } - command_node = command_node->next; - command_node = command_node->next; - - /* Parameter */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_PARAMETER_TEXT)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "Parameter : %s", (char *)key); if (0 < xmlStrlen(key)) { - temp_cmd->parameter = strdup((char*)key); + temp_client->appid = strdup((char*)key); } else { - temp_cmd->parameter = NULL; + /* NULL for appid is available */ + temp_client->appid = NULL; } xmlFree(key); + + temp_client_list = g_slist_append(temp_client_list, temp_client); } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_PARAMETER_TEXT); - if (NULL != temp_cmd->command) free(temp_cmd->command); - free(temp_cmd); - break; + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] enable is NULL"); } } - - if (type == temp_cmd->type) { - temp_cmd_list = g_slist_append(temp_cmd_list, temp_cmd); - } else { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Command type(%d) is NOT valid : request type(%d)", temp_cmd->type, type); - vc_cmd_destroy((vc_cmd_h)temp_cmd); - } + cur = cur->next; } xmlFreeDoc(doc); - *cmd_list = temp_cmd_list; + *client_list = temp_client_list; - __vc_cmd_parser_print_commands(temp_cmd_list); + if (0 != remove(VC_RUNTIME_INFO_DEMANDABLE_LIST)) { + SLOG(LOG_WARN, vc_info_tag(), "[WARNING] remove file(%s) is failed", VC_RUNTIME_INFO_DEMANDABLE_LIST); + } return 0; } -int vc_cmd_parser_append_commands(int pid, vc_cmd_type_e type, vc_cmd_list_h vc_cmd_list) +int vc_info_parser_set_demandable_client(const char* filepath) { - /* Check file */ - char* filepath = NULL; - __vc_cmd_parser_make_filepath(pid, type, &filepath); + if (NULL == filepath) { + if (0 != remove(VC_RUNTIME_INFO_DEMANDABLE_LIST)) { + SLOG(LOG_WARN, vc_info_tag(), "[WARNING] remove file(%s) is failed", VC_RUNTIME_INFO_DEMANDABLE_LIST); + } + return 0; + } + /* Check file */ xmlDocPtr doc = NULL; xmlNodePtr cur = NULL; xmlChar *key; @@ -481,7 +240,6 @@ int vc_cmd_parser_append_commands(int pid, vc_cmd_type_e type, vc_cmd_list_h vc_ SECURE_SLOG(LOG_WARN, vc_info_tag(), "[WARNING] Fail to parse file error : %s", filepath); return -1; } - if (NULL != filepath) free(filepath); cur = xmlDocGetRootElement(doc); if (cur == NULL) { @@ -490,8 +248,8 @@ int vc_cmd_parser_append_commands(int pid, vc_cmd_type_e type, vc_cmd_list_h vc_ return -1; } - if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CMD_BASE_TAG)) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_CMD_BASE_TAG); + if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_BASE_TAG)) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_DEMANDABLE_CLIENT_BASE_TAG); xmlFreeDoc(doc); return -1; } @@ -503,740 +261,87 @@ int vc_cmd_parser_append_commands(int pid, vc_cmd_type_e type, vc_cmd_list_h vc_ return -1; } - vc_cmd_h temp_command = NULL; - while (cur != NULL) { - cur = cur->next; - - if (NULL == cur) { - break; - } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)"text")) { - continue; - } - - xmlNodePtr command_node = NULL; - command_node = cur->xmlChildrenNode; - command_node = command_node->next; - - if (0 != vc_cmd_create(&temp_command)) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to create command!!"); - return -1; - } - - /* ID */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_ID)) { - key = xmlNodeGetContent(command_node); + if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_APPID)) { + key = xmlNodeGetContent(cur); if (NULL != key) { - /*SLOG(LOG_DEBUG, vc_info_tag(), "ID : %s", (char *)key); */ - vc_cmd_set_id(temp_command, atoi((char*)key)); + SLOG(LOG_DEBUG, vc_info_tag(), "App id : %s", (char *)key); xmlFree(key); } else { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_ID); - vc_cmd_destroy(temp_command); - break; + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] enable is NULL"); + xmlFreeDoc(doc); + return -1; } } + cur = cur->next; + } - command_node = command_node->next; - command_node = command_node->next; + int ret = xmlSaveFormatFile(VC_RUNTIME_INFO_DEMANDABLE_LIST, doc, 1); + SLOG(LOG_DEBUG, vc_info_tag(), "Save demandable file info : %d", ret); - /* PID */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_PID)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - /*SLOG(LOG_DEBUG, vc_info_tag(), "PID : %s", (char *)key); */ - vc_cmd_set_pid(temp_command, atoi((char*)key)); - xmlFree(key); - } else { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_PID); - vc_cmd_destroy(temp_command); - break; - } - } + return 0; +} - command_node = command_node->next; - command_node = command_node->next; +int vc_info_parser_set_result(const char* result_text, int event, const char* msg, vc_cmd_list_h vc_cmd_list, bool exclusive) +{ + int ret = vc_db_insert_result(result_text, event, msg, vc_cmd_list, exclusive); + if (0 != ret) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Insert db is failed, ret = %d", ret); + } + SLOG(LOG_DEBUG, vc_info_tag(), "[Success] Save result command file"); + return ret; +} - /* TYPE */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_TYPE)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - /*SLOG(LOG_DEBUG, vc_info_tag(), "Type : %s", (char *)key); */ - vc_cmd_set_type(temp_command, atoi((char*)key)); - xmlFree(key); - } else { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_TYPE); - vc_cmd_destroy(temp_command); - break; - } - } +int vc_info_parser_get_result(char** result_text, int* event, char** result_message, int pid, vc_cmd_list_h vc_cmd_list, bool exclusive) +{ + if (NULL == result_text || NULL == event || NULL == vc_cmd_list) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Input parameter is NULL"); + return -1; + } - command_node = command_node->next; - command_node = command_node->next; + int ret = vc_db_get_result(result_text, event, result_message, pid, vc_cmd_list, exclusive); + if (0 != ret) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Insert db is failed, ret = %d", ret); + } + return ret; +} - /* FORMAT */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_FORMAT)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - /*SLOG(LOG_DEBUG, vc_info_tag(), "Format : %s", (char *)key); */ - vc_cmd_set_format(temp_command, atoi((char*)key)); - xmlFree(key); - } else { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_FORMAT); - vc_cmd_destroy(temp_command); - break; - } - } - - command_node = command_node->next; - command_node = command_node->next; - - /* DOMAIN */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_DOMAIN)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - /*SLOG(LOG_DEBUG, vc_info_tag(), "Domain : %s", (char *)key); */ - vc_cmd_set_domain(temp_command, atoi((char*)key)); - xmlFree(key); - } else { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_DOMAIN); - vc_cmd_destroy(temp_command); - break; - } - } - - command_node = command_node->next; - command_node = command_node->next; - - /* Command */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_COMMAND_TEXT)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - /*SLOG(LOG_DEBUG, vc_info_tag(), "Command : %s, size : %d", (char *)key, strlen(key)); */ - vc_cmd_set_command(temp_command, (char*)key); - - xmlFree(key); - } else { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_COMMAND_TEXT); - vc_cmd_destroy(temp_command); - break; - } - } - - command_node = command_node->next; - command_node = command_node->next; - - /* Parameter */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_PARAMETER_TEXT)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - /*SLOG(LOG_DEBUG, vc_info_tag(), "Parameter : %s , size : %d", (char *)key, strlen(key)); */ - /*vc_cmd_set_parameter(temp_command, (char*)key); */ - vc_cmd_set_unfixed_command(temp_command, (char*)key); - xmlFree(key); - } else { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_PARAMETER_TEXT); - vc_cmd_destroy(temp_command); - break; - } - } - - if (0 != vc_cmd_list_add(vc_cmd_list, temp_command)) { - SLOG(LOG_DEBUG, vc_info_tag(), "Fail to add command to list"); - vc_cmd_destroy(temp_command); - vc_cmd_list_destroy(vc_cmd_list, true); - return -1; - } - } - - xmlFreeDoc(doc); - - vc_cmd_print_list(vc_cmd_list); - - return 0; -} - -int vc_info_parser_get_demandable_clients(GSList** client_list) -{ - /* Check file */ - xmlDocPtr doc = NULL; - xmlNodePtr cur = NULL; - xmlChar *key; - - doc = xmlParseFile(VC_RUNTIME_INFO_DEMANDABLE_LIST); - if (doc == NULL) { - SECURE_SLOG(LOG_WARN, vc_info_tag(), "[WARNING] Fail to parse file error : %s", VC_RUNTIME_INFO_FOREGROUND); - return -1; - } - - cur = xmlDocGetRootElement(doc); - if (cur == NULL) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document"); - xmlFreeDoc(doc); - return -1; - } - - if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_BASE_TAG)) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_DEMANDABLE_CLIENT_BASE_TAG); - xmlFreeDoc(doc); - return -1; - } - - cur = cur->xmlChildrenNode; - if (cur == NULL) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document"); - xmlFreeDoc(doc); - return -1; - } - - GSList* temp_client_list = NULL; - - while (cur != NULL) { - if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_APPID)) { - key = xmlNodeGetContent(cur); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "App id : %s", (char *)key); - - vc_demandable_client_s* temp_client; - temp_client = (vc_demandable_client_s*)calloc(1, sizeof(vc_demandable_client_s)); - - if (NULL == temp_client) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Memory alloc error!!"); - return -1; - } - - if (0 < xmlStrlen(key)) { - temp_client->appid = strdup((char*)key); - } else { - /* NULL for appid is available */ - temp_client->appid = NULL; - } - xmlFree(key); - - temp_client_list = g_slist_append(temp_client_list, temp_client); - } else { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] enable is NULL"); - } - } - cur = cur->next; - } - - xmlFreeDoc(doc); - - *client_list = temp_client_list; - - remove(VC_RUNTIME_INFO_DEMANDABLE_LIST); - - return 0; -} - -int vc_info_parser_set_demandable_client(const char* filepath) -{ - if (NULL == filepath) { - remove(VC_RUNTIME_INFO_DEMANDABLE_LIST); - return 0; - } - - /* Check file */ - xmlDocPtr doc = NULL; - xmlNodePtr cur = NULL; - xmlChar *key; - - doc = xmlParseFile(filepath); - if (doc == NULL) { - SECURE_SLOG(LOG_WARN, vc_info_tag(), "[WARNING] Fail to parse file error : %s", filepath); - return -1; - } - - cur = xmlDocGetRootElement(doc); - if (cur == NULL) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document"); - xmlFreeDoc(doc); - return -1; - } - - if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_BASE_TAG)) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_DEMANDABLE_CLIENT_BASE_TAG); - xmlFreeDoc(doc); - return -1; - } - - cur = cur->xmlChildrenNode; - if (cur == NULL) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document"); - xmlFreeDoc(doc); - return -1; - } - - while (cur != NULL) { - if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_APPID)) { - key = xmlNodeGetContent(cur); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "App id : %s", (char *)key); - xmlFree(key); - } else { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] enable is NULL"); - xmlFreeDoc(doc); - return -1; - } - } - cur = cur->next; - } - - int ret = xmlSaveFormatFile(VC_RUNTIME_INFO_DEMANDABLE_LIST, doc, 1); - SLOG(LOG_DEBUG, vc_info_tag(), "Save demandable file info : %d", ret); - - return 0; -} - -int vc_info_parser_set_result(const char* result_text, int event, const char* msg, vc_cmd_list_h vc_cmd_list, bool exclusive) +int vc_info_parser_unset_result(bool exclusive) { - char filepath[256] = {'\0',}; - - if (false == exclusive) { - snprintf(filepath, 256, "%s", VC_RUNTIME_INFO_RESULT); - } else { - snprintf(filepath, 256, "%s", VC_RUNTIME_INFO_EX_RESULT); - } - - SLOG(LOG_DEBUG, vc_info_tag(), "Result file path : %s", filepath); - - /* Check file */ - remove(filepath); - - xmlDocPtr doc; - xmlNodePtr root_node; - xmlNodePtr cmd_node; - xmlNodePtr tmp_node; - char temp[16]; int ret = 0; - - doc = xmlNewDoc((const xmlChar*)"1.0"); - doc->encoding = (const xmlChar*)"utf-8"; - doc->charset = 1; - - root_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_RESULT_BASE_TAG); - xmlDocSetRootElement(doc, root_node); - - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_RESULT_TEXT); - xmlNodeSetContent(tmp_node, (const xmlChar *)result_text); - xmlAddChild(root_node, tmp_node); - - memset(temp, 0, 16); - snprintf(temp, 16, "%d", event); - - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_RESULT_EVENT); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp); - xmlAddChild(root_node, tmp_node); - - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_RESULT_MESSAGE); - xmlNodeSetContent(tmp_node, (const xmlChar *)msg); - xmlAddChild(root_node, tmp_node); - - /* Make client list node */ - vc_cmd_h vc_command = NULL; - - vc_cmd_list_first(vc_cmd_list); - - while (VC_ERROR_ITERATION_END != ret) { - if (0 != vc_cmd_list_get_current(vc_cmd_list, &vc_command)) { - LOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to get command"); - break; - } - - if (NULL == vc_command) { - break; - } - - vc_cmd_s* temp_cmd = NULL; - temp_cmd = (vc_cmd_s*)vc_command; - - /* Make new command node */ - cmd_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_COMMAND); - - SLOG(LOG_DEBUG, vc_info_tag(), "[Result info] ID(%d) PID(%d) type(%d) format(%d) domain(%d) cmd(%s) param(%s)", - temp_cmd->id, temp_cmd->pid, temp_cmd->type, temp_cmd->format, temp_cmd->domain, temp_cmd->command, temp_cmd->parameter); - - - /* ID */ - memset(temp, 0, 16); - snprintf(temp, 16, "%d", temp_cmd->id); - - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_ID); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp); - xmlAddChild(cmd_node, tmp_node); - - /* PID */ - memset(temp, 0, 16); - snprintf(temp, 16, "%d", temp_cmd->pid); - - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_PID); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp); - xmlAddChild(cmd_node, tmp_node); - - /* TYPE */ - memset(temp, 0, 16); - snprintf(temp, 16, "%d", temp_cmd->type); - - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_TYPE); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp); - xmlAddChild(cmd_node, tmp_node); - - /* FORMAT */ - memset(temp, 0, 16); - snprintf(temp, 16, "%d", temp_cmd->format); - - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_FORMAT); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp); - xmlAddChild(cmd_node, tmp_node); - - /* DOMAIN */ - memset(temp, 0, 16); - snprintf(temp, 16, "%d", temp_cmd->domain); - - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_DOMAIN); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp); - xmlAddChild(cmd_node, tmp_node); - - /* COMMAND */ - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_COMMAND_TEXT); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp_cmd->command); - xmlAddChild(cmd_node, tmp_node); - - /* PARAMETER */ - tmp_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_PARAMETER_TEXT); - xmlNodeSetContent(tmp_node, (const xmlChar *)temp_cmd->parameter); - xmlAddChild(cmd_node, tmp_node); - - xmlAddChild(root_node, cmd_node); - - ret = vc_cmd_list_next(vc_cmd_list); + ret = vc_db_delete_table("result"); + if (0 != ret) { + SLOG(LOG_DEBUG, vc_info_tag(), "[ERROR] Fail to delete result table"); } - - ret = xmlSaveFormatFile(filepath, doc, 1); - if (0 >= ret) { - SLOG(LOG_DEBUG, vc_info_tag(), "[ERROR] Fail to save result command file : %d", ret); - return -1; - } - - SLOG(LOG_DEBUG, vc_info_tag(), "[Success] Save result command file"); - - return 0; + return ret; } -int vc_info_parser_get_result(char** result_text, int* event, char** result_message, int pid, vc_cmd_list_h vc_cmd_list, bool exclusive) +int vc_info_parser_set_nlu_result(const char* nlu_result) { - if (NULL == result_text || NULL == event || NULL == vc_cmd_list) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Input parameter is NULL"); - return -1; - } - - char filepath[256] = {'\0',}; - - if (false == exclusive) { - snprintf(filepath, 256, "%s", VC_RUNTIME_INFO_RESULT); - } else { - snprintf(filepath, 256, "%s", VC_RUNTIME_INFO_EX_RESULT); - } - - SLOG(LOG_DEBUG, vc_info_tag(), "Result file path : %s", filepath); - - xmlDocPtr doc = NULL; - xmlNodePtr cur = NULL; - xmlChar *key; - - doc = xmlParseFile(filepath); - if (doc == NULL) { - SLOG(LOG_ERROR, vc_info_tag(), "[WARNING] Fail to parse file error : %s", filepath); - return -1; - } - - cur = xmlDocGetRootElement(doc); - if (cur == NULL) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document"); - xmlFreeDoc(doc); - return -1; - } - - if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_RESULT_BASE_TAG)) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_RESULT_BASE_TAG); - xmlFreeDoc(doc); - return -1; - } - - cur = cur->xmlChildrenNode; - if (cur == NULL) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document"); - xmlFreeDoc(doc); - return -1; - } - - cur = cur->next; - if (NULL == cur) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document"); - xmlFreeDoc(doc); - return -1; - } - - /* Result text */ - if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_RESULT_TEXT)) { - key = xmlNodeGetContent(cur); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "Result text : %s", (char *)key); - *result_text = strdup((char*)key); - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_RESULT_TEXT); - return -1; - } - } - - cur = cur->next; - cur = cur->next; - if (NULL == cur) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document"); - xmlFreeDoc(doc); - return -1; - } - - /* Result event */ - if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_RESULT_EVENT)) { - key = xmlNodeGetContent(cur); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "Result event : %s", (char *)key); - *event = atoi((char*)key); - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_RESULT_EVENT); - return -1; - } - } - - cur = cur->next; - cur = cur->next; - if (NULL == cur) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document"); - xmlFreeDoc(doc); + if (NULL == nlu_result) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] nlu result is NULL"); return -1; } - /* Result Message */ - if (result_message != NULL) { - if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_RESULT_MESSAGE)) { - key = xmlNodeGetContent(cur); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "Result message : %s", (char *)key); - *result_message = strdup((char*)key); - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_RESULT_MESSAGE); - return -1; - } - } + if (0 != remove(VC_RUNTIME_INFO_NLU_RESULT)) { + SLOG(LOG_WARN, vc_info_tag(), "[WARNING] remove file(%s) is failed", VC_RUNTIME_INFO_NLU_RESULT); } - vc_cmd_h vc_command = NULL; - - while (cur != NULL) { - - cur = cur->next; - if (NULL == cur) { - break; - } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)"text")) { - continue; - } - - SLOG(LOG_ERROR, vc_info_tag(), "111 : %s", cur->name); - - /* Check Command tag */ - if (0 != xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CMD_COMMAND)) { - break; - } - - if (0 != vc_cmd_create(&vc_command)) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to create command!!"); - return -1; - } - - vc_cmd_s* temp_cmd = NULL; - temp_cmd = (vc_cmd_s*)vc_command; - - if (NULL == temp_cmd) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Memory alloc error!!"); - return -1; - } - - xmlNodePtr command_node = NULL; - command_node = cur->xmlChildrenNode; - command_node = command_node->next; - - - SLOG(LOG_ERROR, vc_info_tag(), "222 : %s", command_node->name); - - /* ID */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_ID)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "ID : %s", (char *)key); - temp_cmd->id = atoi((char*)key); - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_ID); - free(temp_cmd); - break; - } - } - - command_node = command_node->next; - command_node = command_node->next; - - /* PID */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_PID)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "PID : %s", (char *)key); - temp_cmd->pid = atoi((char*)key); - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_PID); - free(temp_cmd); - break; - } - } - - command_node = command_node->next; - command_node = command_node->next; - - /* Type */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_TYPE)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "Type : %s", (char *)key); - temp_cmd->type = atoi((char*)key); - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_TYPE); - free(temp_cmd); - return -1; - } - } - - command_node = command_node->next; - command_node = command_node->next; - - /* Format */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_FORMAT)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "Format : %s", (char *)key); - temp_cmd->format = atoi((char*)key); - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_FORMAT); - free(temp_cmd); - return -1; - } - } - - command_node = command_node->next; - command_node = command_node->next; - - /* Domain */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_DOMAIN)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "Command domain : %s", (char *)key); - temp_cmd->domain = atoi((char*)key); - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_DOMAIN); - free(temp_cmd); - return -1; - } - } - - command_node = command_node->next; - command_node = command_node->next; - - /* Command */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_COMMAND_TEXT)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "Command text : %s, size : %d", (char *)key, xmlStrlen(key)); - if (0 < xmlStrlen(key)) { - temp_cmd->command = strdup((char*)key); - } else { - temp_cmd->command = NULL; - } - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_COMMAND_TEXT); - free(temp_cmd); - return -1; - } - } - - command_node = command_node->next; - command_node = command_node->next; - - /* Parameter */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_PARAMETER_TEXT)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "Parameter text : %s , size : %d", (char *)key, xmlStrlen(key)); - if (0 < xmlStrlen(key)) { - temp_cmd->parameter = strdup((char*)key); - } else { - temp_cmd->parameter = NULL; - } - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_PARAMETER_TEXT); - if (NULL != temp_cmd->command) free(temp_cmd->command); - free(temp_cmd); - return -1; - } - } - - if (0 < pid && pid != temp_cmd->pid) { - SLOG(LOG_DEBUG, vc_info_tag(), "Current command is NOT valid"); - vc_cmd_destroy(vc_command); - } else { - if (0 != vc_cmd_list_add(vc_cmd_list, vc_command)) { - SLOG(LOG_DEBUG, vc_info_tag(), "Fail to add command to list"); - vc_cmd_destroy(vc_command); - return -1; - } - } - } - - xmlFreeDoc(doc); - - return 0; -} - -int vc_info_parser_set_nlp_info(const char* nlp_info) -{ - if (NULL == nlp_info) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] nlp info is NULL"); - return -1; - } - - remove(VC_RUNTIME_INFO_NLP_INFO); + SLOG(LOG_DEBUG, vc_info_tag(), "[RESULT] %s", nlu_result); FILE* fp = NULL; int write_size = -1; - fp = fopen(VC_RUNTIME_INFO_NLP_INFO, "w+"); + fp = fopen(VC_RUNTIME_INFO_NLU_RESULT, "w+"); if (NULL == fp) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to open file %s", VC_RUNTIME_INFO_NLP_INFO); + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to open file %s", VC_RUNTIME_INFO_NLU_RESULT); return -1; } /* Write size */ - fprintf(fp, "size(%d)\n", (int)strlen(nlp_info)); + fprintf(fp, "size(%d)\n", strlen(nlu_result)); - write_size = fwrite(nlp_info, 1, strlen(nlp_info), fp); + write_size = fwrite(nlu_result, 1, strlen(nlu_result), fp); fclose(fp); if (0 >= write_size) { @@ -1244,28 +349,28 @@ int vc_info_parser_set_nlp_info(const char* nlp_info) return -1; } - if (0 != __vc_info_parser_set_file_mode(VC_RUNTIME_INFO_NLP_INFO)) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to set file mode - %s", VC_RUNTIME_INFO_NLP_INFO); + if (0 != __vc_info_parser_set_file_mode(VC_RUNTIME_INFO_NLU_RESULT)) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to set file mode - %s", VC_RUNTIME_INFO_NLU_RESULT); } - SLOG(LOG_DEBUG, vc_info_tag(), "[SUCCESS] Write file (%s) size (%d)", VC_RUNTIME_INFO_NLP_INFO, strlen(nlp_info)); + SLOG(LOG_DEBUG, vc_info_tag(), "[SUCCESS] Write file (%s) size (%d)", VC_RUNTIME_INFO_NLU_RESULT, strlen(nlu_result)); return 0; } -int vc_info_parser_get_nlp_info(char** nlp_info) +int vc_info_parser_get_nlu_result(char** nlu_result) { - if (NULL == nlp_info) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] nlp info is NULL"); + if (NULL == nlu_result) { + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] nlu_result is NULL"); return -1; } FILE* fp = NULL; int readn = 0; - fp = fopen(VC_RUNTIME_INFO_NLP_INFO, "r"); + fp = fopen(VC_RUNTIME_INFO_NLU_RESULT, "r"); if (NULL == fp) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to open file %s", VC_RUNTIME_INFO_NLP_INFO); + SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to open file %s", VC_RUNTIME_INFO_NLU_RESULT); return -1; } @@ -1285,170 +390,30 @@ int vc_info_parser_get_nlp_info(char** nlp_info) } int tmp_readn = readn + 10; - *nlp_info = (char*)calloc(tmp_readn, sizeof(char)); - if (NULL == *nlp_info) { + *nlu_result = (char*)calloc(tmp_readn, sizeof(char)); + if (NULL == *nlu_result) { SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Out of memory"); fclose(fp); return -1; } - readn = fread(*nlp_info, 1, readn, fp); + readn = fread(*nlu_result, 1, readn, fp); fclose(fp); SLOG(LOG_DEBUG, vc_info_tag(), "[DEBUG] Read buffer (%d)", readn); - /* remove(VC_RUNTIME_INFO_NLP_INFO); */ + /* remove(VC_RUNTIME_INFO_NLU_RESULT); */ return 0; } - -int vc_info_parser_unset_result(bool exclusive) +int vc_info_parser_get_result_pid_list(GSList** pid_list, const char* result) { - if (false == exclusive) { - remove(VC_RUNTIME_INFO_RESULT); - } else { - remove(VC_RUNTIME_INFO_EX_RESULT); - } - - return 0; -} - -int vc_info_parser_get_result_pid_list(GSList** pid_list) -{ - char filepath[256] = {'\0', }; - snprintf(filepath, 256, "%s", VC_RUNTIME_INFO_RESULT); - - SLOG(LOG_DEBUG, vc_info_tag(), "Result file path : %s", filepath); - - xmlDocPtr doc = NULL; - xmlNodePtr cur = NULL; - xmlChar *key; - - doc = xmlParseFile(filepath); - if (doc == NULL) { - SLOG(LOG_ERROR, vc_info_tag(), "[WARNING] Fail to parse file error : %s", filepath); + int ret = vc_db_get_result_pid_list(result, pid_list); + if (0 != ret) { + SLOG(LOG_DEBUG, vc_info_tag(), "[ERROR] Fail to delete result table"); return -1; } - - cur = xmlDocGetRootElement(doc); - if (cur == NULL) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document"); - xmlFreeDoc(doc); - return -1; - } - - if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_RESULT_BASE_TAG)) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_RESULT_BASE_TAG); - xmlFreeDoc(doc); - return -1; - } - - cur = cur->xmlChildrenNode; - cur = cur->next; - - cur = cur->next; - cur = cur->next; - - cur = cur->next; - cur = cur->next; - - GSList* iter = NULL; - vc_cmd_s* temp_cmd = NULL; - vc_cmd_s* check_cmd = NULL; - - while (cur != NULL) { - - cur = cur->next; - if (NULL == cur) { - break; - } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)"text")) { - continue; - } - - /* Check Command tag */ - if (0 != xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CMD_COMMAND)) { - break; - } - - temp_cmd = (vc_cmd_s*)calloc(1, sizeof(vc_cmd_s)); - if (NULL == temp_cmd) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to alloc command"); - break; - } - - xmlNodePtr command_node = NULL; - command_node = cur->xmlChildrenNode; - command_node = command_node->next; - - /* ID */ - if (0 != xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_ID)) { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_ID); - free(temp_cmd); - break; - } - - command_node = command_node->next; - command_node = command_node->next; - - /* PID */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_PID)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "PID : %s", (char *)key); - temp_cmd->pid = atoi((char*)key); - xmlFree(key); - } else { - SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_PID); - free(temp_cmd); - break; - } - } - - command_node = command_node->next; - command_node = command_node->next; - - /* Type */ - if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_TYPE)) { - key = xmlNodeGetContent(command_node); - if (NULL != key) { - SLOG(LOG_DEBUG, vc_info_tag(), "Type : %s", (char *)key); - temp_cmd->type = atoi((char*)key); - xmlFree(key); - } else { - SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_TYPE); - free(temp_cmd); - return -1; - } - } - - /* check pid in gslist */ - iter = g_slist_nth(*pid_list, 0); - while (NULL != iter) { - check_cmd = iter->data; - - if (NULL == check_cmd) { - free(temp_cmd); - temp_cmd = NULL; - break; - } - - if (check_cmd->pid == temp_cmd->pid && check_cmd->type == temp_cmd->type) { - free(temp_cmd); - temp_cmd = NULL; - break; - } - iter = g_slist_next(iter); - } - - if (NULL != temp_cmd) { - /* add pid to gslist */ - *pid_list = g_slist_append(*pid_list, temp_cmd); - } - } - - xmlFreeDoc(doc); - return 0; } @@ -1460,7 +425,9 @@ int vc_info_parser_set_client_info(GSList* client_info_list) } /* Remove file */ - remove(VC_RUNTIME_INFO_CLIENT); + if (0 != remove(VC_RUNTIME_INFO_CLIENT)) { + SLOG(LOG_WARN, vc_info_tag(), "[WARNING] remove file(%s) is failed", VC_RUNTIME_INFO_CLIENT); + } xmlDocPtr doc; xmlNodePtr root_node; @@ -1677,7 +644,7 @@ int __vc_cmd_parser_print_commands(GSList* cmd_list) int count = g_slist_length(cmd_list); int i ; GSList *iter = NULL; - vc_cmd_s *temp_cmd; + vc_cmd_s *cmd; iter = g_slist_nth(cmd_list, 0); @@ -1685,17 +652,16 @@ int __vc_cmd_parser_print_commands(GSList* cmd_list) if (NULL == iter) break; - temp_cmd = iter->data; + cmd = iter->data; - if (NULL == temp_cmd) { + if (NULL == cmd) { SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] NULL data from command list"); iter = g_slist_next(iter); continue; } - SLOG(LOG_DEBUG, vc_info_tag(), " [%d][%p] PID(%d) ID(%d) Type(%d) Format(%d) Domain(%d) Command(%s) Param(%s)", - i, temp_cmd, temp_cmd->pid, temp_cmd->index, temp_cmd->type, temp_cmd->format, temp_cmd->domain, - temp_cmd->command, temp_cmd->parameter); + SLOG(LOG_DEBUG, vc_info_tag(), " [%d][%p] PID(%d) ID(%d) Type(%d) Format(%d) Command(%s) Param(%s), Appid(%s), Invocation(%s), Fixed(%s)", + i, cmd, cmd->pid, cmd->id, cmd->type, cmd->format, cmd->command, cmd->parameter, cmd->appid, cmd->invocation_name, cmd->fixed); iter = g_slist_next(iter); } diff --git a/common/vc_info_parser.h b/common/vc_info_parser.h index 910e936..d1532a6 100644 --- a/common/vc_info_parser.h +++ b/common/vc_info_parser.h @@ -40,14 +40,12 @@ typedef struct _client_s { } vc_client_info_s; -int vc_cmd_parser_save_file(int pid, vc_cmd_type_e type, GSList* cmd_list); +int vc_cmd_parser_save_file(int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name); int vc_cmd_parser_delete_file(int pid, vc_cmd_type_e type); int vc_cmd_parser_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list); -int vc_cmd_parser_get_command_info(int pid, vc_cmd_type_e type, int index, vc_cmd_s** info); - int vc_cmd_parser_append_commands(int pid, vc_cmd_type_e type, vc_cmd_list_h vc_cmd_list); @@ -62,13 +60,13 @@ int vc_info_parser_set_result(const char* result_text, int event, const char* ms int vc_info_parser_get_result(char** result_text, int* event, char** result_message, int pid, vc_cmd_list_h vc_cmd_list, bool exclusive); -int vc_info_parser_set_nlp_info(const char* nlp_info); +int vc_info_parser_unset_result(bool exclusive); -int vc_info_parser_get_nlp_info(char** nlp_info); +int vc_info_parser_get_result_pid_list(GSList** pid_list, const char* result); -int vc_info_parser_unset_result(bool exclusive); +int vc_info_parser_set_nlu_result(const char* nlu_result); -int vc_info_parser_get_result_pid_list(GSList** pid_list); +int vc_info_parser_get_nlu_result(char** nlu_result); /* Client info */ diff --git a/common/vc_json_parser.c b/common/vc_json_parser.c new file mode 100644 index 0000000..f49d6d6 --- /dev/null +++ b/common/vc_json_parser.c @@ -0,0 +1,422 @@ +/* +* Copyright (c) 2011-2016 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 "vc_cmd_db.h" +#include "vc_command.h" +#include "vc_main.h" +#include "voice_control_common.h" +#include "vc_config_mgr.h" + + +const char* vc_json_tag() +{ + return TAG_VCINFO; +} + +static int __vc_json_get_invocation_name(const char* appid, char** invocation_name) +{ + int ret = VC_ERROR_NONE; + if (NULL == *invocation_name) { + char* temp_lable = NULL; + char* lang = NULL; + + ret = vc_config_mgr_get_default_language(&lang); + if (0 != ret || NULL == lang) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to get current laguage, ret(%d) lang(%s)", ret, lang); + return ret; + } + ret = app_info_get_localed_label(appid, lang, &temp_lable); + if (0 != ret || NULL == temp_lable) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to get localed label, ret(%d) label(%s)", ret, temp_lable); + free(lang); + lang = NULL; + return ret; + } + + *invocation_name = strdup(temp_lable); + if (NULL == *invocation_name) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to allocate memory"); + } + free(temp_lable); + temp_lable = NULL; + free(lang); + lang = NULL; + } + + SLOG(LOG_DEBUG, vc_json_tag(), "Get invocation name(%s)", *invocation_name); + return ret; +} + + +static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocation_name) +{ + if (NULL == root_obj) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Invalid paramget"); + return VC_ERROR_INVALID_PARAMETER; + } + + if (VC_COMMAND_TYPE_NONE > type || VC_COMMAND_TYPE_EXCLUSIVE < type) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Invalid paramget, type(%d)", type); + return VC_ERROR_INVALID_PARAMETER; + } + + char* temp_type = NULL; + if (VC_COMMAND_TYPE_FOREGROUND == type) { + temp_type = strdup("foreground"); + } else if (VC_COMMAND_TYPE_BACKGROUND == type) { + temp_type = strdup("background"); + } else if (VC_COMMAND_TYPE_WIDGET == type) { + temp_type = strdup("widget"); + } else if (VC_COMMAND_TYPE_SYSTEM == type) { + temp_type = strdup("system"); + } else if (VC_COMMAND_TYPE_EXCLUSIVE == type) { + temp_type = strdup("exclusive"); + } + + if (NULL == temp_type) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to allocate memory"); + return VC_ERROR_OUT_OF_MEMORY; + } + + JsonArray *array = NULL; + array = json_object_get_array_member(root_obj, temp_type); + if (NULL == array) { + SLOG(LOG_WARN, vc_json_tag(), "[WARNING] There's no matched type(%s)", temp_type); + free(temp_type); + temp_type = NULL; + return VC_ERROR_NONE; + } + + int ret = 0; + int array_size = json_array_get_length(array); + int i = 0; + char* prev_appid = strdup("NULL"); + if (NULL == prev_appid) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to allocate memory"); + free(temp_type); + temp_type = NULL; + return VC_ERROR_OUT_OF_MEMORY; + } + + if (VC_COMMAND_TYPE_BACKGROUND != type) { + ret = vc_db_delete_commands(getpid(), type, NULL); + if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to delete command, ret(%d) pid(%d) type(%d)", ret, getpid(), type); + free(temp_type); + free(prev_appid); + temp_type = NULL; + prev_appid = NULL; + return ret; + } + } + + for (i = 0; i < array_size; i++) { + int temp = 0; + const char* temp_text = NULL; + vc_cmd_s* cmd = NULL; + cmd = (vc_cmd_s*)calloc(1, sizeof(vc_cmd_s)); + if (NULL == cmd) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to allocate memory"); + free(temp_type); + free(prev_appid); + temp_type = NULL; + prev_appid = NULL; + return VC_ERROR_OUT_OF_MEMORY; + } + + JsonObject *object = NULL; + object = json_array_get_object_element(array, i); + if (NULL == object) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to get object element"); + free(temp_type); + free(prev_appid); + free(cmd); + temp_type = NULL; + prev_appid = NULL; + cmd = NULL; + return VC_ERROR_OPERATION_FAILED; + } + + cmd->pid = getpid(); + cmd->type = type; + temp = json_object_get_int_member(object, "format"); + cmd->format = temp; + + temp = json_object_get_int_member(object, "domain"); + cmd->domain = temp; + + temp_text = json_object_get_string_member(object, "cmd"); + cmd->command = strdup(temp_text); + if (NULL == cmd->command) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to allocate memory"); + free(temp_type); + free(prev_appid); + free(cmd); + temp_type = NULL; + prev_appid = NULL; + cmd = NULL; + return VC_ERROR_OUT_OF_MEMORY; + } + + if (VC_COMMAND_TYPE_BACKGROUND == type) { + // Get appid when background command is + char* appid = NULL;; + temp_text = json_object_get_string_member(object, "appid"); + if (NULL == temp_text) { + ret = app_manager_get_app_id(cmd->pid, &appid); + if (APP_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] fail to get app id, ret(%d)", ret); + } else { + SLOG(LOG_ERROR, vc_json_tag(), "Background cmd: appid = %s", appid); + } + } else { + appid = strdup(temp_text); + } + + if (NULL != appid) { + cmd->appid = strdup(appid); + + free(appid); + appid = NULL; + if (NULL == cmd->appid) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to allocate memory"); + free(temp_type); + free(prev_appid); + free(cmd->command); + cmd->command = NULL; + temp_type = NULL; + prev_appid = NULL; + free(cmd); + cmd = NULL; + + return VC_ERROR_OUT_OF_MEMORY; + } + } else { + free(cmd->command); + cmd->command = NULL; + free(cmd); + cmd = NULL; + continue; + } + + if (NULL == invocation_name) { + ret = __vc_json_get_invocation_name(cmd->appid, &invocation_name); + if (0 != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] fail to get invocation name, ret(%d) appid(%s)", ret, cmd->appid); + } + } + if (NULL != invocation_name) + cmd->invocation_name = strdup(invocation_name); + + if (NULL == cmd->invocation_name) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to allocate memory"); + free(temp_type); + free(prev_appid); + free(cmd->command); + free(cmd->appid); + temp_type = NULL; + prev_appid = NULL; + cmd->command = NULL; + cmd->appid = NULL; + + free(cmd); + cmd = NULL; + return VC_ERROR_OUT_OF_MEMORY; + } + + if (0 != strncmp(cmd->appid, prev_appid, strlen(cmd->appid))) { + //delete bacground commands with appid and type + ret = vc_db_delete_commands(cmd->pid, type, cmd->appid); + if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to insert command into db, ret(%d) pid(%d) type(%d), appid(%s)", ret, cmd->pid, type, cmd->appid); + free(temp_type); + free(prev_appid); + free(cmd->command); + free(cmd->appid); + free(cmd->invocation_name); + temp_type = NULL; + prev_appid = NULL; + cmd->command = NULL; + cmd->appid = NULL; + cmd->invocation_name = NULL; + + free(cmd); + cmd = NULL; + return ret; + } + + free(prev_appid); + prev_appid = strdup(cmd->appid); + + if (NULL == prev_appid) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to allocate memory"); + free(temp_type); + free(cmd->command); + free(cmd->appid); + free(cmd->invocation_name); + temp_type = NULL; + cmd->command = NULL; + cmd->appid = NULL; + cmd->invocation_name = NULL; + + free(cmd); + cmd = NULL; + + return VC_ERROR_OUT_OF_MEMORY; + } + } + } + + ret = vc_db_insert_command(cmd->pid, type, cmd); + if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to insert command into db, type(%s), command(%s)", temp_type, temp_text); + if (NULL != cmd->command) free(cmd->command); + if (NULL != cmd->appid) free(cmd->appid); + if (NULL != cmd->invocation_name) free(cmd->invocation_name); + free(temp_type); + free(prev_appid); + cmd->command = NULL; + cmd->appid = NULL; + cmd->invocation_name = NULL; + temp_type = NULL; + prev_appid = NULL; + free(cmd); + cmd = NULL; + return ret; + } + SLOG(LOG_WARN, vc_json_tag(), "[INFO] pid(%d), type(%d), format(%d), domain(%d), cmd(%s), appid(%s)", cmd->pid, type, cmd->format, cmd->domain, cmd->command, cmd->appid); + + if (NULL != cmd->appid) { + free(cmd->appid); + cmd->appid = NULL; + } + if (NULL != cmd->invocation_name) { + free(cmd->invocation_name); + cmd->invocation_name = NULL; + } + + free(cmd->command); + cmd->command = NULL; + free(cmd); + cmd = NULL; + } + + free(temp_type); + free(prev_appid); + temp_type = NULL; + prev_appid = NULL; + return VC_ERROR_NONE; +} + +int vc_json_set_commands_from_file(const char* file_path, vc_cmd_type_e type, char* invocation_name) +{ + JsonParser* parser = NULL; + JsonNode* root = NULL; + GError* err_msg = NULL; + JsonObject *root_obj = NULL; + + // Create a new json parser + parser = json_parser_new(); + json_parser_load_from_file(parser, file_path, &err_msg); + if (err_msg) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to load json file, file_path(%s), err_msg(%s)", file_path, err_msg); + g_error_free(err_msg); + g_object_unref(parser); + return VC_ERROR_OPERATION_FAILED; + } + + // Retrieves top level node + root = json_parser_get_root(parser); + if (NULL == root) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to get root node"); + g_object_unref(parser); + return VC_ERROR_OPERATION_FAILED; + } + + // Retrieves the Json object inside a node + root_obj = json_node_get_object(root); + if (NULL == root_obj) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to get object from root node"); + g_object_unref(parser); + return VC_ERROR_OPERATION_FAILED; + } + + // Inserts commands to + int ret = VC_ERROR_NONE; + ret = __vc_json_set_commands(root_obj, type, invocation_name); + if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to set commands into db, ret(%d)", ret); + } + + g_object_unref(parser); + return ret; +} + +int vc_json_set_all_commands_from_file(const char* file_path) +{ + JsonParser* parser = NULL; + JsonNode* root = NULL; + GError* err_msg = NULL; + JsonObject *root_obj = NULL; + + // Create a new json parser + parser = json_parser_new(); + + json_parser_load_from_file(parser, file_path, &err_msg); + if (err_msg) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to load json file"); + g_error_free(err_msg); + g_object_unref(parser); + return VC_ERROR_OPERATION_FAILED; + } + + // Retrieves top level node + root = json_parser_get_root(parser); + if (NULL == root) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to get root node"); + g_object_unref(parser); + return VC_ERROR_OPERATION_FAILED; + } + + // Retrieves the Json object inside a node + root_obj = json_node_get_object(root); + if (NULL == root_obj) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to get object from root node"); + g_object_unref(parser); + return VC_ERROR_OPERATION_FAILED; + } + + int type = 1; + int ret = VC_ERROR_NONE; + do { + // Inserts commands to + ret = __vc_json_set_commands(root_obj, type++, NULL); + if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to set commands into db, type(%d), ret(%d)", type - 1, ret); + g_object_unref(parser); + return ret; + } + } while (VC_COMMAND_TYPE_EXCLUSIVE >= type); + + g_object_unref(parser); + return ret; +} + diff --git a/common/vc_json_parser.h b/common/vc_json_parser.h new file mode 100644 index 0000000..c097ef0 --- /dev/null +++ b/common/vc_json_parser.h @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2011-2015 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. +*/ + + +#ifndef __VC_JSON_PARSER_H_ +#define __VC_JSON_PARSER_H_ + +#include "vc_command.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int vc_json_set_commands_from_file(const char* file_path, vc_cmd_type_e type, char* invocation_name); + +int vc_json_set_all_commands_from_file(const char* file_path); + + +#ifdef __cplusplus +} +#endif + +#endif /* __VC_JSON_PARSER_H_ */ diff --git a/common/vc_main.h b/common/vc_main.h index f203bfe..061155e 100644 --- a/common/vc_main.h +++ b/common/vc_main.h @@ -42,6 +42,7 @@ extern "C" { #define TAG_VCINFO "vcinfo" /* info lib log tag */ #define TAG_VCCONFIG "vcinfo" /* config lib log tag */ #define TAG_VCCMD "vccmd" /* Command log tag */ +#define TAG_VCDB "vcdb" /* DB log tag */ /** * @brief A structure of handle for identification diff --git a/include/voice_control.h b/include/voice_control.h old mode 100755 new mode 100644 index 8bf4d15..ef6cf50 --- a/include/voice_control.h +++ b/include/voice_control.h @@ -58,6 +58,18 @@ extern "C" */ #define VC_COMMAND_TYPE_BACKGROUND 2 +/** +* @brief Definitions for ended dialog. +* @since_tizen 3.0 +*/ +#define VC_DIALOG_END 0 + +/** +* @brief Definitions for continued dialog. +* @since_tizen 3.0 +*/ +#define VC_DIALOG_CONTINUE 1 + /** * @brief Initializes voice control. @@ -232,6 +244,77 @@ int vc_get_state(vc_state_e* state); int vc_get_service_state(vc_service_state_e* state); /** +* @brief Get system command list. +* @since_tizen 3.0 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @remarks If system command is set by system voice app, the system command list can be retreived. +* +* @param[out] vc_sys_cmd_list System command list handle +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_INVALID_STATE Invalid state +* @retval #VC_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ERROR_NOT_SUPPORTED Not supported +* +* @pre The service state should be #VC_SERVICE_STATE_READY. +* +* @see vc_unset_command_list() +*/ +int vc_get_system_command_list(vc_cmd_list_h* vc_sys_cmd_list); + +/** +* @brief Sets invocation name. +* @since_tizen 3.0 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @remarks The invocation name will be combined with background command. +* This function should be called before vc_set_command_list() or vc_set_command_list_from_file(). +* +* @param[in] name App name that wants to be invoked +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_INVALID_STATE Invalid state +* @retval #VC_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ERROR_NOT_SUPPORTED Not supported +* +* @pre The state should be #VC_STATE_READY. +* +* @see vc_set_command_list() +* @see vc_set_command_list_from_file() +*/ +int vc_set_invocation_name(const char* name); + +/** +* @brief Request to display text and to speak text what app want. +* @since_tizen 3.0 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @remarks If continue is true, the recognition will start again. In this case, 4 times can be restarted. +* +* @param[in] disp_text Text hat wants to be displayed +* @param[in] utt_text Text that wants to be spoken +* @param[in] continue Continue dialog session +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_INVALID_STATE Invalid state +* @retval #VC_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ERROR_NOT_SUPPORTED Not supported +* +* @pre The service state should be #VC_SERVICE_STATE_READY. +*/ +int vc_dialog(const char* disp_text, const char* utt_text, bool continuous); + +/** * @brief Sets command list. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * @privlevel public @@ -257,6 +340,31 @@ int vc_get_service_state(vc_service_state_e* state); int vc_set_command_list(vc_cmd_list_h vc_cmd_list, int type); /** +* @brief Sets command list from file. +* @since_tizen 3.0 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @remarks The command type is valid for #VC_COMMAND_TYPE_FOREGROUND or #VC_COMMAND_TYPE_BACKGROUND. \n +* The matched commands of command list should be set and they should include type and command text at least. +* +* @param[in] file_path The file path including commands +* @param[in] type Command type +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_INVALID_STATE Invalid state +* @retval #VC_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ERROR_NOT_SUPPORTED Not supported +* +* @pre The state should be #VC_STATE_READY. +* +* @see vc_unset_command_list() +*/ +int vc_set_command_list_from_file(const char* file_path, int type); + +/** * @brief Unsets command list. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * @privlevel public @@ -274,9 +382,30 @@ int vc_set_command_list(vc_cmd_list_h vc_cmd_list, int type); * @pre The state should be #VC_STATE_READY. * * @see vc_set_command_list() +* @see vc_set_command_list_from_file */ int vc_unset_command_list(int type); +/** +* @brief Get recognition result using a callback function. +* @since_tizen 3.0 +* @privlevel public +* @privilege %http://tizen.org/privilege/recorder +* +* @param[in] callback Callback function to get recognition result +* @param[in] user_data The user data to be passed to the callback function +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_INVALID_STATE Invalid state +* @retval #VC_ERROR_NOT_SUPPORTED Not supported +* +* @pre The state should be #VC_STATE_READY. +* +* @see vc_result_cb() +*/ +int vc_get_result(vc_result_cb callback, void* user_data); /** * @brief Registers a callback function for getting recognition result. diff --git a/include/voice_control_command.h b/include/voice_control_command.h old mode 100755 new mode 100644 index 82a7849..188675d --- a/include/voice_control_command.h +++ b/include/voice_control_command.h @@ -48,6 +48,20 @@ typedef struct vc_cmd_s* vc_cmd_h; typedef struct vc_cmd_list_s* vc_cmd_list_h; /** +* @brief Enumerations of command format. +* @since_tizen 3.0 +*/ +typedef enum { + VC_CMD_FORMAT_FIXED = 0, /**< fixed command only */ + VC_CMD_FORMAT_FIXED_AND_VFIXED, /**< Fixed + variable fixed command */ + VC_CMD_FORMAT_VFIXED_AND_FIXED, /**< Variable fixed + fixed command */ + VC_CMD_FORMAT_FIXED_AND_NONFIXED, /**< Fixed + non fixed command */ + VC_CMD_FORMAT_NONFIXED_AND_FIXED, /**< Non fixed + fixed command */ + VC_CMD_FORMAT_ACTION, /**< Action command */ + VC_CMD_FORMAT_PARTIAL /**< Partial matched command */ +} vc_cmd_format_e; + +/** * @brief Called to retrieve The commands in list. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * @@ -169,6 +183,25 @@ int vc_cmd_list_remove(vc_cmd_list_h vc_cmd_list, vc_cmd_h vc_command); int vc_cmd_list_foreach_commands(vc_cmd_list_h vc_cmd_list, vc_cmd_list_cb callback, void* user_data); /** +* @brief Retrieves all commands of system command list using callback function. +* @since_tizen 3.0 +* +* @param[in] callback Callback function to invoke +* @param[in] user_data The user data to be passed to the callback function +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ERROR_NOT_SUPPORTED Not supported +* +* @post This function invokes vc_cmd_list_cb() repeatedly for getting commands. +* +* @see vc_cmd_list_cb() +*/ +int vc_cmd_list_foreach_system_commands(vc_cmd_list_cb callback, void* user_data); + +/** * @brief Moves index to first command. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * @@ -298,11 +331,11 @@ int vc_cmd_create(vc_cmd_h* vc_command); int vc_cmd_destroy(vc_cmd_h vc_command); /** -* @brief Sets command. +* @brief Sets command or action. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * * @param[in] vc_command The command handle -* @param[in] command The command text +* @param[in] command The command or action text * * @return 0 on success, otherwise a negative error value * @retval #VC_ERROR_NONE Successful @@ -334,6 +367,25 @@ int vc_cmd_set_command(vc_cmd_h vc_command, const char* command); int vc_cmd_get_command(vc_cmd_h vc_command, char** command); /** +* @brief Gets extra unfixed command. +* @since_tizen 3.0 +* +* @remark If the function succeeds, @a The command must be released with free() by you if they are not NULL. +* If you get the result command list in result callback and the command type of commands has non-fixed format, +* you should check non-fixed result using this function. +* +* @param[in] vc_command The command handle +* @param[out] command The unfixed command text +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ERROR_NOT_SUPPORTED Not supported feature +*/ +int vc_cmd_get_unfixed_command(vc_cmd_h vc_command, char** command); + +/** * @brief Sets command type. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * @@ -371,6 +423,57 @@ int vc_cmd_set_type(vc_cmd_h vc_command, int type); int vc_cmd_get_type(vc_cmd_h vc_command, int* type); +/** +* @brief Sets command format. +* @since_tizen 3.0 +* +* @param[in] vc_command The command handle +* @param[in] format The command format +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ERROR_NOT_SUPPORTED Not supported feature +* +* @see vc_cmd_get_format() +*/ +int vc_cmd_set_format(vc_cmd_h vc_command, vc_cmd_format_e format); + +/** +* @brief Gets command format. +* @since_tizen 3.0 +* +* @remark If you do not set the format, the default format is #VC_CMD_FORMAT_FIXED. +* +* @param[in] vc_command The command handle +* @param[out] format The command format +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ERROR_NOT_SUPPORTED Not supported feature +* +* @see vc_cmd_set_format() +*/ +int vc_cmd_get_format(vc_cmd_h vc_command, vc_cmd_format_e* format); + +/** +* @brief Gets nlu json data. +* @since_tizen 3.0 +* +* @param[in] vc_command The command handle +* @param[out] json The nlu json data +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_NOT_SUPPORTED Not supported feature +* +*/ +int vc_cmd_get_nlu_json(vc_cmd_h vc_cmd, char** json); + #ifdef __cplusplus } #endif diff --git a/include/voice_control_command_expand.h b/include/voice_control_command_expand.h old mode 100755 new mode 100644 index 98fe563..14539f8 --- a/include/voice_control_command_expand.h +++ b/include/voice_control_command_expand.h @@ -27,38 +27,6 @@ extern "C" { #endif - -/** -* @brief Enumerations of command format. -* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif -*/ -typedef enum { - VC_CMD_FORMAT_FIXED = 0, /**< fixed command only */ - VC_CMD_FORMAT_FIXED_AND_EXTRA, /**< Fixed + extra unfixed command */ - VC_CMD_FORMAT_EXTRA_AND_FIXED, /**< Extra unfixed + fixed command */ - VC_CMD_FORMAT_UNFIXED_ONLY /**< Unfixed command */ -} vc_cmd_format_e; - - -/** -* @brief Gets extra unfixed command. -* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif -* -* @remark If the function succeeds, @a The command must be released with free() by you if they are not NULL. -* If you get the result command list in result callback and the command type of commands has non-fixed format, -* you should check non-fixed result using this function. -* -* @param[in] vc_command The command handle -* @param[out] command The unfixed command text -* -* @return 0 on success, otherwise a negative error value -* @retval #VC_ERROR_NONE Successful -* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VC_ERROR_PERMISSION_DENIED Permission denied -* @retval #VC_ERROR_NOT_SUPPORTED Not supported feature -*/ -int vc_cmd_get_unfixed_command(vc_cmd_h vc_command, char** command); - /** * @brief Sets command format. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif diff --git a/include/voice_control_manager.h b/include/voice_control_manager.h index e6d80a4..bdef272 100644 --- a/include/voice_control_manager.h +++ b/include/voice_control_manager.h @@ -71,7 +71,13 @@ extern "C" * @brief Definition for exclusive command type. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif */ -#define VC_COMMAND_TYPE_EXCLUSIVE 5 +#define VC_COMMAND_TYPE_SYSTEM_BACKGROUND 5 + +/** +* @brief Definitions for exclusive command type. +* @since_tizen 2.4 +*/ +#define VC_COMMAND_TYPE_EXCLUSIVE 6 /** * @brief Definition for none message. @@ -94,6 +100,24 @@ typedef enum { } vc_recognition_mode_e; /** +* @brief Enumerations of send event type. +*/ +typedef enum { + VC_SEND_EVENT_TYPE_TEXT, /**< send text event to vc engine*/ + VC_SEND_EVENT_TYPE_LIST_EVENT, /**< send list event to vc engine */ + VC_SEND_EVENT_TYPE_HAPTIC_EVENT /**< send haptic event to vc engine */ +} vc_send_event_type_e; + +/** +* @brief Enumerations of pre result event. +*/ +typedef enum { + VC_PRE_RESULT_EVENT_FINAL_RESULT = 0, + VC_PRE_RESULT_EVENT_PARTIAL_RESULT, + VC_PRE_RESULT_EVENT_ERROR +} vc_pre_result_event_e; + +/** * @brief Called when client gets the all recognition results from vc-daemon. * * @remark temp_command is valid in callback function. @@ -113,14 +137,19 @@ typedef enum { typedef bool (*vc_mgr_all_result_cb)(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char* result, const char* msg, void *user_data); -typedef enum { - VC_PRE_RESULT_EVENT_FINAL_RESULT = 0, - VC_PRE_RESULT_EVENT_PARTIAL_RESULT, - VC_PRE_RESULT_EVENT_ERROR -} vc_pre_result_event_e; - -// support pre-result -typedef bool(*vc_mgr_pre_result_cb)(vc_pre_result_event_e event, const char* result, void *user_data); +/** +* @brief Called when client gets the pre recognition results(partial ASR) from vc-daemon. +* +* @param[in] event The pre result event +* @param[in] result ASR text +* @param[in] user_data The user data passed from the callback registration function +* +* @pre An application registers callback function using vc_mgr_set_pre_result_cb(). +* +* @see vc_mgr_set_pre_result_cb() +* @see vc_mgr_unset_pre_result_cb() +*/ +typedef void (*vc_mgr_pre_result_cb)(vc_pre_result_event_e event, const char* result, void *user_data); /** * @brief Called when user speaking is detected. @@ -136,6 +165,23 @@ typedef void (*vc_mgr_begin_speech_detected_cb)(void *user_data); /** +* @brief Called when user request dialog +* +* @param[in] pid Pid of VC client to request dialog +* @param[in] disp_text Text that wants to be displayed +* @param[in] utt_text Text that wants to be spoken +* @param[in] continuous Continue dialog session +* @param[in] user_data The user data passed from the callback registration function +* +* @pre An application registers callback function using vc_mgr_set_dialog_request_cb(). +* +* @see vc_mgr_set_dialog_request_cb() +* @see vc_mgr_unset_dialog_request_cb() +*/ +typedef void (*vc_mgr_dialog_request_cb)(int pid, const char* disp_text, const char* utt_text, bool continuous, void *user_data); + + +/** * @brief Initialize voice control manager. * * @remarks If the function succeeds, @a vc mgr must be released with vc_mgr_deinitialize(). @@ -350,6 +396,46 @@ int vc_mgr_set_command_list(vc_cmd_list_h vc_cmd_list); int vc_mgr_unset_command_list(); /** +* @brief Sets commands from file. +* +* @remarks The commands should include type, command text, format. +* +* @param[in] vc_cmd_list The command list handle +* @param[in] type Command type +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_INVALID_STATE Invalid state +* @retval #VC_ERROR_OPERATION_FAILED Operation failure +* +* @pre The state should be #VC_STATE_READY. +* +* @see vc_mgr_unset_command_list() +*/ +int vc_mgr_set_command_list_from_file(const char* file_path, int type); + +/** +* @brief Sets background commands of preloaded app from file. +* +* @remarks The command type is valid for VC_COMMAND_TYPE_BACKGROUND +* The commands should include type, command text, format. +* +* @param[in] vc_cmd_list The command list handle +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_INVALID_STATE Invalid state +* @retval #VC_ERROR_OPERATION_FAILED Operation failure +* +* @pre The state should be #VC_STATE_READY. +* +* @see vc_mgr_unset_command_list() +*/ +int vc_mgr_set_preloaded_commands_from_file(const char* file_path); + +/** * @brief Retrieves all available commands. * * @remarks If the function succeeds, @a vc_cmd_list must be released with vc_cmd_list_destroy(vc_cmd_list, true). @@ -435,6 +521,71 @@ int vc_mgr_set_recognition_mode(vc_recognition_mode_e mode); int vc_mgr_get_recognition_mode(vc_recognition_mode_e* mode); /** +* @brief Sets private data between app and engine. +* +* @param[in] key Private key +* @param[in] data Private data +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_OUT_OF_MEMORY Not enough memory +* @retval #VC_ERROR_INVALID_STATE Invalid state +* @retval #VC_ERROR_OPERATION_FAILED Operation failure +* +* @pre The service state should be #VC_SERVICE_STATE_READY. +*/ +int vc_mgr_set_private_data(const char* key, const char* data); + +/** +* @brief Gets private data between app and engine. +* +* @remarks data must be released using free() when it is no longer required. +* +* @param[in] key Private key +* @param[out] data Private data +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_OUT_OF_MEMORY Not enough memory +* @retval #VC_ERROR_INVALID_STATE Invalid state +* @retval #VC_ERROR_OPERATION_FAILED Operation failure +* +* @pre The service state should be #VC_SERVICE_STATE_READY. +*/ +int vc_mgr_get_private_data(const char* key, char** data); + +/** +* @brief Sets domain such as agent or device type. +* +* @param[in] domain Available agent or device type +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_OUT_OF_MEMORY Not enough memory +* @retval #VC_ERROR_INVALID_STATE Invalid state +* @retval #VC_ERROR_OPERATION_FAILED Operation failure +* +* @pre The service state should be #VC_SERVICE_STATE_READY. +*/ +int vc_mgr_set_domain(const char* domain); + +/** +* @brief Request to do action as if utterence is spoken. +* +* @param[in] type Event type +* @param[in] send_event The string for send event +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_OUT_OF_MEMORY Not enough memory +* @retval #VC_ERROR_INVALID_STATE Invalid state +* @retval #VC_ERROR_OPERATION_FAILED Operation failure +* +* @pre The service state should be #VC_SERVICE_STATE_READY. +*/ +int vc_mgr_do_action(vc_send_event_type_e type, char* send_event); + +/** * @brief Starts recognition. * * @remarks The default recognition mode is #VC_RECOGNITION_MODE_STOP_BY_SILENCE. \n @@ -533,12 +684,6 @@ int vc_mgr_get_recording_volume(float* volume); int vc_mgr_set_selected_results(vc_cmd_list_h vc_cmd_list); -int vc_mgr_get_nlp_info(char** info); - -int vc_mgr_set_pre_result_cb(vc_mgr_pre_result_cb callback, void* user_data); - -int vc_mgr_unset_pre_result_cb(); - /** * @brief Registers a callback function for getting recognition result. * @@ -571,6 +716,37 @@ int vc_mgr_set_all_result_cb(vc_mgr_all_result_cb callback, void* user_data); int vc_mgr_unset_all_result_cb(); /** +* @brief Registers a callback function for getting pre recognition result. +* +* @param[in] callback Callback function to register +* @param[in] user_data The user data to be passed to the callback function +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_INVALID_STATE Invalid state +* +* @pre The state should be #VC_STATE_INITIALIZED. +* +* @see vc_mgr_pre_result_cb() +* @see vc_mgr_unset_pre_result_cb() +*/ +int vc_mgr_set_pre_result_cb(vc_mgr_pre_result_cb callback, void* user_data); + +/** +* @brief Unregisters the callback function. +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_STATE Invalid state +* +* @pre The state should be #VC_STATE_INITIALIZED. +* +* @see vc_mgr_set_pre_result_cb() +*/ +int vc_mgr_unset_pre_result_cb(); + +/** * @brief Registers a callback function for getting system or exclusive recognition result. * * @param[in] callback Callback function to register @@ -757,6 +933,37 @@ int vc_mgr_set_error_cb(vc_error_cb callback, void* user_data); int vc_mgr_unset_error_cb(); +/** +* @brief Registers a callback function to be called when dialog requests. +* +* @param[in] callback Callback function to register +* @param[in] user_data The user data to be passed to the callback function +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_INVALID_STATE Invalid state +* +* @pre The state should be #VC_STATE_INITIALIZED. +* +* @see vc_mgr_unset_dialog_request_cb() +*/ +int vc_mgr_set_dialog_request_cb(vc_mgr_dialog_request_cb callback, void* user_data); + +/** +* @brief Unregisters the callback function. +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_STATE Invalid state +* +* @pre The state should be #VC_STATE_INITIALIZED. +* +* @see vc_mgr_set_dialog_request_cb() +*/ +int vc_mgr_unset_dialog_request_cb(); + + #ifdef __cplusplus } #endif diff --git a/include/voice_control_plugin_engine.h b/include/voice_control_plugin_engine.h index 0524a8c..a9d573b 100644 --- a/include/voice_control_plugin_engine.h +++ b/include/voice_control_plugin_engine.h @@ -65,10 +65,51 @@ typedef enum { * @brief Enumerations of command type. */ typedef enum { - VCP_COMMAND_TYPE_FIXED = 0, /**< Fixed command */ - VCP_COMMAND_TYPE_FIXED_AND_NON_FIXED, /**< Fixed command + Non-fixed command */ - VCP_COMMAND_TYPE_NON_FIXED_AND_FIXED /**< Non-fixed command + Fixed command */ -} vcp_command_type_e; + VCP_COMMAND_FORMAT_FIXED = 0, /**< Fixed command */ + VCP_COMMAND_FORMAT_FIXED_AND_VFIXED, /**< Fixed command + variable-fixed command */ + VCP_COMMAND_FORMAT_VFIXED_AND_FIXED, /**< variable-fixed command + Fixed command */ + VCP_COMMAND_FORMAT_FIXED_AND_NONFIXED, /**< Fixed command + Non-fixed command */ + VCP_COMMAND_FORMAT_NONFIXED_AND_FIXED, /**< Non-fixed command + Fixed command */ + VCP_COMMAND_FORMAT_ACTION, + VCP_COMMAND_FORMAT_PARTIAL +} vcp_command_format_e; + +/** +* @brief Definition for foreground command type. +* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif +*/ +#define VCP_COMMAND_TYPE_FOREGROUND 1 + +/** +* @brief Definition for background command type. +* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif +*/ +#define VCP_COMMAND_TYPE_BACKGROUND 2 + +/** +* @brief Definition for widget command type. +* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif +*/ +#define VCP_COMMAND_TYPE_WIDGET 3 + +/** +* @brief Definition for system command type. +* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif +*/ +#define VCP_COMMAND_TYPE_SYSTEM 4 + +/** +* @brief Definition for exclusive command type. +* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif +*/ +#define VCP_COMMAND_TYPE_SYSTEM_BACKGROUND 5 + +/** +* @brief Definitions for exclusive command type. +* @since_tizen 2.4 +*/ +#define VCP_COMMAND_TYPE_EXCLUSIVE 6 + /** * @brief Enumerations of speech detect. @@ -79,6 +120,12 @@ typedef enum { VCP_SPEECH_DETECT_END, /**< End of speech detected */ } vcp_speech_detect_e; +typedef enum { + VCP_ASR_RESULT_EVENT_FINAL_RESULT = 0, + VCP_ASR_RESULT_EVENT_PARTIAL_RESULT, + VCP_ASR_RESULT_EVENT_ERROR +}vcp_asr_result_event_e; + /** * @brief A structure of handle for VC command */ @@ -113,24 +160,36 @@ typedef int vcp_cmd_h; * @param[in] count Result count * @param[in] all_result All result text * @param[in] non_fixed_result Non-fixed command result text +* @param[in] nlu_result NLU result text * @param[in] msg Engine message (e.g. #VC_RESULT_MESSAGE_NONE, #VC_RESULT_MESSAGE_ERROR_TOO_LOUD) -* @param[in] user_data The user data passed from the start synthesis function +* @param[in] user_data The user data passed from set callback function * * @pre vcpe_stop() will invoke this callback. * * @see vcpe_stop() */ typedef void (*vcpe_result_cb)(vcp_result_event_e event, int* result_id, int count, - const char* all_result, const char* non_fixed_result, const char* msg, void *user_data); + const char* all_result, const char* non_fixed_result, const char* nlu_result, const char* msg, void *user_data); -typedef enum { - VCP_PRE_RESULT_EVENT_FINAL_RESULT = 0, - VCP_PRE_RESULT_EVENT_PARTIAL_RESULT, - VCP_PRE_RESULT_EVENT_ERROR -} vcp_pre_result_event_e; -// Add new -typedef void (*vcpe_pre_result_cb)(vcp_pre_result_event_e event, const char* pre_result, void *user_data); +/** +* @brief Called when the daemon gets ASR result. +* +* @param[in] event A asr result event +* @param[in] pre_result result text +* @param[in] user_data The user data passed from the start +*/ +typedef void (*vcpe_asr_result_cb)(vcp_asr_result_event_e event, const char* asr_result, void *user_data); + +/** +* @brief Called when the daemon gets error. +* +* @param[in] error Error type +* @param[in] msg Error message +* @param[in] user_data The user data passed from set callback function +* +*/ +typedef void (*vcpe_error_cb)(vcp_error_e error, const char* msg, void *user_data); /** * @brief Called to retrieve the supported languages. @@ -190,6 +249,19 @@ typedef void (*vcpe_deinitialize)(void); typedef int (*vcpe_set_result_cb)(vcpe_result_cb callback, void* user_data); /** +* @brief Registers a callback function for getting ASR recognition result. +* +* @param[in] callback Callback function to register +* @param[in] user_data The user data to be passed to the callback function +* +* @return 0 on success, otherwise a negative error value +* +* @see vcpe_asr_result_cb() +*/ +typedef int (*vcpe_set_asr_result_cb)(vcpe_asr_result_cb callback, void* user_data); + +#if 0 +/** * @brief Registers a callback function for getting partial recognition result. * * @param[in] callback Callback function to register @@ -200,7 +272,31 @@ typedef int (*vcpe_set_result_cb)(vcpe_result_cb callback, void* user_data); * @see vcpe_pre_result_cb() */ typedef int (*vcpe_set_pre_result_cb)(vcpe_pre_result_cb callback, void* user_data); +#endif +/** +* @brief Registers a callback function for error. +* +* @param[in] callback Callback function to register +* @param[in] user_data The user data to be passed to the callback function +* +* @return 0 on success, otherwise a negative error value +* +*/ +typedef int (*vcpe_set_error_cb)(vcpe_error_cb callback, void* user_data); + +#if 0 +/** +* @brief Registers a callback function for getting NLU result. +* +* @param[in] callback Callback function to register +* @param[in] user_data The user data to be passed to the callback function +* +* @return 0 on success, otherwise a negative error value +* +*/ +typedef int (*vcpe_set_nlu_result_cb)(vcpe_nlu_result_cb, void* user_data); +#endif /** * @brief Gets recording format of the engine. @@ -289,9 +385,6 @@ typedef int (*vcpe_set_commands)(vcp_cmd_h vcp_command); */ typedef int (*vcpe_unset_commands)(); -// Add new -typedef int (*vcpe_get_nlp_info)(char** info); - /** * @brief Start recognition. * @@ -366,6 +459,78 @@ typedef int (*vcpe_stop)(void); */ typedef int (*vcpe_cancel)(void); +/** +* @brief Sets domain (Agent or device type) +* +* @param[in] domain available Agent or device type +* +* @return 0 on success, otherwise a negative error value. +* +*/ +typedef int (*vcpe_set_domain)(const char* domain); + +/** +* @brief Gets essential value from nlu result. This function is available inside vcpe_nlu_result_cb() +* +* @param[in] key NLU base info key +* @parma[out] value NLU base info value +* +* @return 0 on success, otherwise a negative error value. +* +*/ +typedef int (*vcpe_get_nlu_base_info)(const char* key, char** value); + +/** +* @brief Sets private data between app and engine. +* +* @param[in] key Private key +* @param[in] data Private data +* +* @return 0 on success, otherwise a negative error value. +* +*/ +typedef int (*vcpe_set_private_data)(const char* key, const char* data); + +/** +* @brief Gets private data between app and engine. +* +* @param[in] key Private key +* @param[out] data Private data +* +* @return 0 on success, otherwise a negative error value. +* +*/ +typedef int (*vcpe_get_private_data)(const char* key, char** data); + +/** +* @brief Request process text. +* +* @param[in] text Requested text +* +* @return 0 on success, otherwise a negative error value. +* +*/ +typedef int (*vcpe_process_text)(const char* text); + +/** +* @brief Request list event. +* +* @param[in] event Requested list event +* +* @return 0 on success, otherwise a negative error value. +* +*/ +typedef int (*vcpe_process_list_event)(const char* event); + +/** +* @brief Request haptic event. +* +* @param[in] event Requested haptic event +* +* @return 0 on success, otherwise a negative error value. +* +*/ +typedef int (*vcpe_process_haptic_event)(const char* event); /** * Daemon API. @@ -376,6 +541,7 @@ typedef int (*vcpe_cancel)(void); * * @param[in] id command id * @param[in] type command type +* @param[in] format command format * @param[in] command command text * @param[in] param parameter text * @param[in] domain command domain @@ -386,7 +552,7 @@ typedef int (*vcpe_cancel)(void); * * @see vcpd_foreach_command() */ -typedef bool (*vcpd_foreach_command_cb)(int id, int type, const char* command, const char* param, int domain, void* user_data); +typedef bool (*vcpd_foreach_command_cb)(int id, int type, int format, const char* command, const char* param, int domain, void* user_data); /** * @brief Retrieves all commands using callback function. @@ -447,18 +613,28 @@ typedef struct { vcpe_is_language_supported is_lang_supported; /**< Check language */ /* Set info */ - vcpe_set_pre_result_cb set_pre_result_cb; /**< Set pre result callback */ vcpe_set_result_cb set_result_cb; /**< Set result callback */ vcpe_set_language set_language; /**< Set language */ vcpe_set_commands set_commands; /**< Request to set current commands */ vcpe_unset_commands unset_commands; /**< Request to unset current commands */ - vcpe_get_nlp_info get_nlp_info; /**< Get nlp info */ /* Control recognition */ vcpe_start start; /**< Start recognition */ vcpe_set_recording_data set_recording; /**< Set recording data */ vcpe_stop stop; /**< Stop recording for getting result */ vcpe_cancel cancel; /**< Cancel recording and processing */ + + //vcpe_set_pre_result_cb set_pre_result_cb; /**< Set pre result callback */ + vcpe_set_asr_result_cb set_asr_result_cb; /**< Set asr result callback */ + vcpe_set_error_cb set_error_cb; /**< Set error callback */ + vcpe_set_domain set_domain; /**< Set domain */ + vcpe_get_nlu_base_info get_nlu_base_info; /**< Get essential info */ + //vcpe_set_nlu_result_cb set_nlu_result_cb; /**< Set nlu result callback */ + vcpe_set_private_data set_private_data; /**< Set private data */ + vcpe_get_private_data get_private_data; /**< Get private data */ + vcpe_process_text process_text; /**< Request to process text */ + vcpe_process_list_event process_list_event; /**< Request to process list event */ + vcpe_process_haptic_event process_haptic_event; /**< Request to process haptic event */ } vcpe_funcs_s; /** diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index 168f3ec..f724a9e 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -11,6 +11,8 @@ Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig BuildRequires: pkgconfig(aul) +BuildRequires: pkgconfig(capi-appfw-application) +BuildRequires: pkgconfig(capi-appfw-app-manager) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(capi-media-audio-io) BuildRequires: pkgconfig(capi-media-sound-manager) @@ -19,11 +21,14 @@ BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(cynara-client) BuildRequires: pkgconfig(cynara-session) BuildRequires: pkgconfig(dbus-1) +BuildRequires: pkgconfig(db-util) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(ecore) BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(json-glib-1.0) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(libxml-2.0) +BuildRequires: pkgconfig(sqlite3) %if "%{PRODUCT_TYPE}" == "TV" #BuildRequires: pkgconfig(msfapi) #not be applied yet. %endif diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index c986dcc..d2cf638 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -1,8 +1,10 @@ SET(SRCS + ../common/vc_cmd_db.c ../common/vc_command.c ../common/vc_config_mgr.c ../common/vc_config_parser.c ../common/vc_info_parser.c + ../common/vc_json_parser.c vcd_client_data.c vcd_config.c vcd_dbus_server.c diff --git a/server/vcd_client_data.c b/server/vcd_client_data.c index 69bac43..d307a13 100644 --- a/server/vcd_client_data.c +++ b/server/vcd_client_data.c @@ -36,7 +36,7 @@ static GSList* g_demandable_client = NULL; /* Runtime info */ static bool g_silence_detection; static vcd_recognition_mode_e g_recognition_mode; - +static char* g_result_text = NULL; /* Function definitions */ widget_info_s* __widget_get_element(int pid); @@ -94,6 +94,19 @@ int vcd_client_manager_unset_command(int pid) return 0; } +bool vcd_client_manager_is_system_command_valid(int pid) +{ + if (pid != g_manager.pid) { + SLOG(LOG_WARN, TAG_VCD, "[Client Data WARNING] pid(%d) is NOT valid", pid); + return false; + } + + if (true == g_manager.manager_cmd) + return true; + + return false; +} + int vcd_client_manager_set_demandable_client(int pid, GSList* client_list) { if (0 != g_slist_length(g_demandable_client)) { @@ -184,112 +197,78 @@ int vcd_client_manager_get_pid() return g_manager.pid; } -int __vcd_client_release_commands() +int vcd_client_manager_set_result_text(const char* result) { - g_cur_cmd_list.total_cmd_count = 0; - g_cur_cmd_list.foreground = VC_NO_FOREGROUND_PID; - - GSList *iter = NULL; - vc_cmd_s* temp_cmd; - - if (0 < g_slist_length(g_cur_cmd_list.widget_cmds)) { - iter = g_slist_nth(g_cur_cmd_list.widget_cmds, 0); - while (NULL != iter) { - temp_cmd = iter->data; - - if (NULL != temp_cmd) { - if (NULL != temp_cmd->command) free(temp_cmd->command); - if (NULL != temp_cmd->parameter) free(temp_cmd->parameter); - free(temp_cmd); - } - - iter = g_slist_next(iter); - } - g_cur_cmd_list.widget_cmds = NULL; + if (NULL != g_result_text) { + free(g_result_text); + g_result_text = NULL; } - if (0 < g_slist_length(g_cur_cmd_list.foreground_cmds)) { - iter = g_slist_nth(g_cur_cmd_list.foreground_cmds, 0); - while (NULL != iter) { - temp_cmd = iter->data; - - if (NULL != temp_cmd) { - if (NULL != temp_cmd->command) free(temp_cmd->command); - if (NULL != temp_cmd->parameter) free(temp_cmd->parameter); - free(temp_cmd); - } - - iter = g_slist_next(iter); - } - g_cur_cmd_list.foreground_cmds = NULL; + if (NULL != result) { + g_result_text = strdup(result); } - if (0 < g_slist_length(g_cur_cmd_list.system_cmds)) { - iter = g_slist_nth(g_cur_cmd_list.system_cmds, 0); - while (NULL != iter) { - temp_cmd = iter->data; + return 0; +} - if (NULL != temp_cmd) { - if (NULL != temp_cmd->command) free(temp_cmd->command); - if (NULL != temp_cmd->parameter) free(temp_cmd->parameter); - free(temp_cmd); - } +char* vcd_client_manager_get_result_text() +{ + return g_result_text; +} - iter = g_slist_next(iter); - } - g_cur_cmd_list.system_cmds = NULL; - } +static void __vcd_client_release_each_commands(GSList** cmds) +{ + GSList *iter = NULL; + vc_cmd_s* temp_cmd; - if (0 < g_slist_length(g_cur_cmd_list.exclusive_system_cmds)) { - iter = g_slist_nth(g_cur_cmd_list.exclusive_system_cmds, 0); + if (0 < g_slist_length(*cmds)) { + iter = g_slist_nth(*cmds, 0); while (NULL != iter) { temp_cmd = iter->data; if (NULL != temp_cmd) { - if (NULL != temp_cmd->command) free(temp_cmd->command); - if (NULL != temp_cmd->parameter) free(temp_cmd->parameter); + if (NULL != temp_cmd->command) { + free(temp_cmd->command); + temp_cmd->command = NULL; + } + if (NULL != temp_cmd->appid) { + free(temp_cmd->appid); + temp_cmd->appid = NULL; + } + if (NULL != temp_cmd->parameter) { + free(temp_cmd->parameter); + temp_cmd->parameter = NULL; + } + if (NULL != temp_cmd->invocation_name) { + free(temp_cmd->invocation_name); + temp_cmd->invocation_name = NULL; + } + if (NULL != temp_cmd->fixed) { + free(temp_cmd->fixed); + temp_cmd->fixed = NULL; + } free(temp_cmd); + temp_cmd = NULL; } + *cmds = g_slist_remove_link(*cmds, iter); - iter = g_slist_next(iter); + iter = g_slist_nth(*cmds, 0); } - g_cur_cmd_list.exclusive_system_cmds = NULL; + *cmds = NULL; } +} - if (0 < g_slist_length(g_cur_cmd_list.background_cmds)) { - background_command_s* back_cmd_info; - iter = g_slist_nth(g_cur_cmd_list.background_cmds, 0); - - GSList* back_iter = NULL; - - while (NULL != iter) { - back_cmd_info = iter->data; - - if (NULL != back_cmd_info) { - back_iter = g_slist_nth(back_cmd_info->cmds, 0); - - while (NULL != back_iter) { - temp_cmd = back_iter->data; - - if (NULL != temp_cmd) { - if (NULL != temp_cmd->command) free(temp_cmd->command); - if (NULL != temp_cmd->parameter) free(temp_cmd->parameter); - free(temp_cmd); - } - - back_iter = g_slist_next(back_iter); - } - - back_cmd_info->cmds = NULL; - } - - iter = g_slist_next(iter); - } - - g_cur_cmd_list.background_cmds = NULL; - } +int __vcd_client_release_commands() +{ + g_cur_cmd_list.total_cmd_count = 0; + g_cur_cmd_list.foreground = VC_NO_FOREGROUND_PID; - g_cur_cmd_list.bg_cmd_count = 0; + __vcd_client_release_each_commands(&(g_cur_cmd_list.widget_cmds)); + __vcd_client_release_each_commands(&(g_cur_cmd_list.system_cmds)); + __vcd_client_release_each_commands(&(g_cur_cmd_list.system_background_cmds)); + __vcd_client_release_each_commands(&(g_cur_cmd_list.exclusive_system_cmds)); + __vcd_client_release_each_commands(&(g_cur_cmd_list.foreground_cmds)); + __vcd_client_release_each_commands(&(g_cur_cmd_list.background_cmds)); return 0; } @@ -341,12 +320,21 @@ int vcd_client_command_collect_command() SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No system commands"); } - vc_client_info_s* client_info = NULL; - GSList *iter = NULL; + GSList* sys_back_cmd_list = NULL; + if (true == g_manager.manager_cmd) { + ret = vc_cmd_parser_get_commands(g_manager.pid, VC_COMMAND_TYPE_SYSTEM_BACKGROUND, &sys_back_cmd_list); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to get the system command list"); + } else { + g_cur_cmd_list.system_background_cmds = sys_back_cmd_list; + } + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No system background commands"); + } /* 4. Set foreground commands and widget */ + GSList* fg_cmd_list = NULL; if (VC_NO_FOREGROUND_PID != fg_pid) { - GSList* fg_cmd_list = NULL; GSList* widget_cmd_list = NULL; g_cur_cmd_list.foreground = fg_pid; @@ -367,95 +355,35 @@ int vcd_client_command_collect_command() SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No widget commands"); } - /* Get handle */ - client_info = __client_get_element(fg_pid); - if (NULL != client_info) { - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] fore cmd(%d)", client_info->fg_cmd); - - /* 4-2. Set foreground command */ - if (true == client_info->fg_cmd) { - ret = vc_cmd_parser_get_commands(fg_pid, VC_COMMAND_TYPE_FOREGROUND, &fg_cmd_list); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to get the fg command list"); - } else { - g_cur_cmd_list.foreground_cmds = fg_cmd_list; - } - } else { - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No foreground commands"); - } - - /* 4-3. Check exclusive option */ - if (true == client_info->exclusive_cmd) { - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Exclusive command is ON"); - - /* 4-4. Set background command for exclusive option */ - if (true == client_info->bg_cmd) { - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Set background command"); - GSList* bg_cmd_list = NULL; - ret = vc_cmd_parser_get_commands(client_info->pid, VC_COMMAND_TYPE_BACKGROUND, &bg_cmd_list); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to get the bg command list : pid(%d)", client_info->pid); - } else { - background_command_s* bg_cmd = (background_command_s*)calloc(1, sizeof(background_command_s)); - if (NULL == bg_cmd) { - SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory"); - return VCD_ERROR_OUT_OF_MEMORY; - } - - bg_cmd->pid = client_info->pid; - bg_cmd->cmds = bg_cmd_list; - bg_cmd->cmd_count = g_slist_length(bg_cmd_list); - - /* Add item to global command list */ - g_cur_cmd_list.background_cmds = g_slist_append(g_cur_cmd_list.background_cmds, bg_cmd); - } - } - return 0; - } + /* 4-2. Set foreground command of foreground app */ + ret = vc_cmd_parser_get_commands(fg_pid, VC_COMMAND_TYPE_FOREGROUND, &fg_cmd_list); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to get the fg command list"); } else { - SLOG(LOG_WARN, TAG_VCD, "[Client Data] No foreground client : pid(%d)", fg_pid); + g_cur_cmd_list.foreground_cmds = fg_cmd_list; } } else { SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No foreground app"); } + if (true == g_manager.manager_cmd) { + /* 4-3. Set foreground command by manager */ + ret = vc_cmd_parser_get_commands(g_manager.pid, VC_COMMAND_TYPE_FOREGROUND, &fg_cmd_list); + if (0 != ret) { + SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No foreground commands of manager app"); + } else { + g_cur_cmd_list.foreground_cmds = fg_cmd_list; + } + } /* 5. Set background commands */ - if (0 < g_slist_length(g_client_list)) { - iter = g_slist_nth(g_client_list, 0); - - while (NULL != iter) { - client_info = iter->data; - GSList* bg_cmd_list = NULL; - - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Pid(%d) Back cmd(%d)", client_info->pid, client_info->bg_cmd); - - if (true == client_info->bg_cmd) { - ret = vc_cmd_parser_get_commands(client_info->pid, VC_COMMAND_TYPE_BACKGROUND, &bg_cmd_list); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to get the bg command list : pid(%d)", client_info->pid); - } else { - background_command_s* bg_cmd = (background_command_s*)calloc(1, sizeof(background_command_s)); - if (NULL == bg_cmd) { - SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory"); - return VCD_ERROR_OUT_OF_MEMORY; - } - - bg_cmd->pid = client_info->pid; - bg_cmd->cmds = bg_cmd_list; - bg_cmd->cmd_count = g_slist_length(bg_cmd_list); - - /* Add item to global command list */ - g_cur_cmd_list.background_cmds = g_slist_append(g_cur_cmd_list.background_cmds, bg_cmd); - } - } - - iter = g_slist_next(iter); - } + GSList* bg_cmd_list = NULL; + ret = vc_cmd_parser_get_commands(fg_pid, VC_COMMAND_TYPE_BACKGROUND, &bg_cmd_list); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to get the bg command list"); } else { - /* NO client */ - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No background commands"); + /* Add item to global command list */ + g_cur_cmd_list.background_cmds = bg_cmd_list; } - return 0; } @@ -463,34 +391,15 @@ int vcd_client_get_length() { int command_count = 0; command_count += g_slist_length(g_cur_cmd_list.widget_cmds); - command_count += g_slist_length(g_cur_cmd_list.foreground_cmds); command_count += g_slist_length(g_cur_cmd_list.system_cmds); command_count += g_slist_length(g_cur_cmd_list.exclusive_system_cmds); - - GSList *iter = NULL; - background_command_s* back_cmd_info; - - if (0 < g_slist_length(g_cur_cmd_list.background_cmds)) { - iter = g_slist_nth(g_cur_cmd_list.background_cmds, 0); - - while (NULL != iter) { - back_cmd_info = iter->data; - - command_count += g_slist_length(back_cmd_info->cmds); - - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] background commands count : %d", g_slist_length(back_cmd_info->cmds)); - - iter = g_slist_next(iter); - } - } else { - /* NO client */ - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No background commands"); - } + command_count += g_slist_length(g_cur_cmd_list.system_background_cmds); + command_count += g_slist_length(g_cur_cmd_list.foreground_cmds); + command_count += g_slist_length(g_cur_cmd_list.background_cmds); g_cur_cmd_list.total_cmd_count = command_count; SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Command count : %d ", g_cur_cmd_list.total_cmd_count); - return command_count; } @@ -501,7 +410,7 @@ int vcd_client_foreach_command(client_foreach_command_cb callback, void* user_da return VCD_ERROR_INVALID_PARAMETER; } - int id_count = 1; +// int id_count = 1; GSList *iter = NULL; vc_cmd_s* temp_cmd; @@ -510,13 +419,10 @@ int vcd_client_foreach_command(client_foreach_command_cb callback, void* user_da while (NULL != iter) { temp_cmd = iter->data; - temp_cmd->id = id_count; - id_count++; + SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Widget : id(%d) type(%d) format(%d) command(%s) domain(%d)" + , temp_cmd->id, temp_cmd->type, temp_cmd->format, temp_cmd->command, temp_cmd->domain); - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Widget : id(%d) index(%d) format(%d) command(%s) param(%s) domain(%d)" - , temp_cmd->id, temp_cmd->index, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain); - - callback(temp_cmd->id, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data); + callback(temp_cmd->id, temp_cmd->type, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data); iter = g_slist_next(iter); } @@ -529,13 +435,10 @@ int vcd_client_foreach_command(client_foreach_command_cb callback, void* user_da while (NULL != iter) { temp_cmd = iter->data; - temp_cmd->id = id_count; - id_count++; - - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Foreground : id(%d) index(%d) format(%d) command(%s) param(%s) domain(%d)" - , temp_cmd->id, temp_cmd->index, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain); + SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Fore : id(%d) type(%d) format(%d) command(%s) param(%s) domain(%d) fixed(%s)" + , temp_cmd->id, temp_cmd->type, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, temp_cmd->fixed); - callback(temp_cmd->id, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data); + callback(temp_cmd->id, temp_cmd->type, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data); iter = g_slist_next(iter); } @@ -548,13 +451,10 @@ int vcd_client_foreach_command(client_foreach_command_cb callback, void* user_da while (NULL != iter) { temp_cmd = iter->data; - temp_cmd->id = id_count; - id_count++; - - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] System : id(%d) index(%d) format(%d) domain(%d) command(%s) param(%s)" - , temp_cmd->id, temp_cmd->index, temp_cmd->format, temp_cmd->domain, temp_cmd->command, temp_cmd->parameter); + SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] System : id(%d) type(%d) format(%d) command(%s) param(%s) domain(%d)" + , temp_cmd->id, temp_cmd->type, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain); - callback(temp_cmd->id, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data); + callback(temp_cmd->id, temp_cmd->type, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data); iter = g_slist_next(iter); } @@ -562,18 +462,31 @@ int vcd_client_foreach_command(client_foreach_command_cb callback, void* user_da SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No system commands"); } + if (0 < g_slist_length(g_cur_cmd_list.system_background_cmds)) { + iter = g_slist_nth(g_cur_cmd_list.system_background_cmds, 0); + while (NULL != iter) { + temp_cmd = iter->data; + + SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] System background : id(%d) type(%d) format(%d) command(%s) param(%s) domain(%d)" + , temp_cmd->id, temp_cmd->type, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain); + + callback(temp_cmd->id, temp_cmd->type, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data); + + iter = g_slist_next(iter); + } + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No system background commands"); + } + if (0 < g_slist_length(g_cur_cmd_list.exclusive_system_cmds)) { iter = g_slist_nth(g_cur_cmd_list.exclusive_system_cmds, 0); while (NULL != iter) { temp_cmd = iter->data; - temp_cmd->id = id_count; - id_count++; + SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Exclusive system : id(%d) type(%d) format(%d) command(%s) param(%s) domain(%d)" + , temp_cmd->id, temp_cmd->type, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain); - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Exclusive system : id(%d) index(%d) format(%d) command(%s) param(%s) domain(%d)" - , temp_cmd->id, temp_cmd->index, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain); - - callback(temp_cmd->id, temp_cmd->type, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data); + callback(temp_cmd->id, temp_cmd->type, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data); iter = g_slist_next(iter); } @@ -582,37 +495,20 @@ int vcd_client_foreach_command(client_foreach_command_cb callback, void* user_da } if (0 < g_slist_length(g_cur_cmd_list.background_cmds)) { - background_command_s* back_cmd_info; iter = g_slist_nth(g_cur_cmd_list.background_cmds, 0); - while (NULL != iter) { - back_cmd_info = iter->data; - - GSList* back_iter = NULL; - back_iter = g_slist_nth(back_cmd_info->cmds, 0); - - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] pid(%d) command count(%d)", back_cmd_info->pid, back_cmd_info->cmd_count); - - while (NULL != back_iter) { - temp_cmd = back_iter->data; - - temp_cmd->id = id_count; - id_count++; - - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Background : id(%d) index(%d) format(%d) command(%s) param(%s) domain(%d)" - , temp_cmd->id, temp_cmd->index, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain); + temp_cmd = iter->data; - callback(temp_cmd->id, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data); + SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Back : id(%d) format(%d) type(%d) command(%s) param(%s) domain(%d) appid(%s) invocation(%s) fixed(%s)" + , temp_cmd->id, temp_cmd->type, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, temp_cmd->appid, temp_cmd->invocation_name, temp_cmd->fixed); - back_iter = g_slist_next(back_iter); - } + callback(temp_cmd->id, temp_cmd->type, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data); iter = g_slist_next(iter); } } else { SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No background commands"); } - return 0; } @@ -637,6 +533,13 @@ static vc_cmd_s* __command_copy(vc_cmd_s* src_cmd) temp_cmd->format = src_cmd->format; temp_cmd->domain = src_cmd->domain; + if (VC_COMMAND_TYPE_SYSTEM == temp_cmd->type) temp_cmd->priority = VC_COMMAND_PRIORITY_SYSTEM; + else if (VC_COMMAND_TYPE_EXCLUSIVE == temp_cmd->type) temp_cmd->priority = VC_COMMAND_PRIORITY_EXCLUSIVE; + else if (VC_COMMAND_TYPE_FOREGROUND == temp_cmd->type) temp_cmd->priority = VC_COMMAND_PRIORITY_FOREGROUND; + else if (VC_COMMAND_TYPE_WIDGET == temp_cmd->type) temp_cmd->priority = VC_COMMAND_PRIORITY_FOREGROUND; + else if (VC_COMMAND_TYPE_SYSTEM_BACKGROUND == temp_cmd->type) temp_cmd->priority = VC_COMMAND_PRIORITY_SYSTEM_BACKGROUND; + else if (VC_COMMAND_TYPE_BACKGROUND == temp_cmd->type) temp_cmd->priority = VC_COMMAND_PRIORITY_BACKGROUND; + if (NULL != src_cmd->command) { temp_cmd->command = strdup(src_cmd->command); } @@ -645,6 +548,18 @@ static vc_cmd_s* __command_copy(vc_cmd_s* src_cmd) temp_cmd->parameter = strdup(src_cmd->parameter); } + if (NULL != src_cmd->appid) { + temp_cmd->appid = strdup(src_cmd->appid); + } + + if (NULL != src_cmd->invocation_name) { + temp_cmd->invocation_name = strdup(src_cmd->invocation_name); + } + + if (NULL != src_cmd->fixed) { + temp_cmd->fixed = strdup(src_cmd->fixed); + } + temp_cmd->key = src_cmd->key; temp_cmd->modifier = src_cmd->modifier; @@ -722,6 +637,26 @@ int vcd_client_get_cmd_from_result_id(int result_id, vc_cmd_s** result) SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No system commands"); } + if (0 < g_slist_length(g_cur_cmd_list.system_background_cmds)) { + iter = g_slist_nth(g_cur_cmd_list.system_background_cmds, 0); + while (NULL != iter) { + temp_cmd = iter->data; + + if (result_id == temp_cmd->id) { + /**pid = g_manager.pid; */ + /**cmd_type = VCD_CLIENT_COMMAND_GROUP_TYPE_SYSTEM_BACKGROUND; */ + /*SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Find result pid(%d) type(%d)", *pid, *cmd_type); */ + + *result = __command_copy(temp_cmd); + return 0; + } + + iter = g_slist_next(iter); + } + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No system background commands"); + } + if (0 < g_slist_length(g_cur_cmd_list.exclusive_system_cmds)) { iter = g_slist_nth(g_cur_cmd_list.exclusive_system_cmds, 0); while (NULL != iter) { @@ -743,28 +678,16 @@ int vcd_client_get_cmd_from_result_id(int result_id, vc_cmd_s** result) } if (0 < g_slist_length(g_cur_cmd_list.background_cmds)) { - background_command_s* back_cmd_info; iter = g_slist_nth(g_cur_cmd_list.background_cmds, 0); while (NULL != iter) { - back_cmd_info = iter->data; - - GSList* back_iter = NULL; - back_iter = g_slist_nth(back_cmd_info->cmds, 0); - - SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] pid(%d) command count(%d)", back_cmd_info->pid, back_cmd_info->cmd_count); - - while (NULL != back_iter) { - temp_cmd = back_iter->data; + temp_cmd = iter->data; - if (result_id == temp_cmd->id) { - /**pid = back_cmd_info->pid; */ - /**cmd_type = VCD_CLIENT_COMMAND_GROUP_TYPE_BACKGROUND; */ + SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] command id (%d)", temp_cmd->id); - *result = __command_copy(temp_cmd); - return 0; - } - back_iter = g_slist_next(back_iter); + if (result_id == temp_cmd->id) { + *result = __command_copy(temp_cmd); + return 0; } iter = g_slist_next(iter); @@ -774,7 +697,6 @@ int vcd_client_get_cmd_from_result_id(int result_id, vc_cmd_s** result) } SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Not find matched result"); - return -1; } @@ -1213,10 +1135,9 @@ widget_info_s* __widget_get_element(int pid) if (0 < count) { iter = g_slist_nth(g_widget_list, 0); - for (i = 0; i < count; i++) { - if (NULL == iter) - break; + i = 0; + while (iter && i < count) { data = iter->data; if (NULL != data) { @@ -1225,6 +1146,8 @@ widget_info_s* __widget_get_element(int pid) } iter = g_slist_next(iter); + + i++; } } diff --git a/server/vcd_client_data.h b/server/vcd_client_data.h index 10a381d..6985a1f 100644 --- a/server/vcd_client_data.h +++ b/server/vcd_client_data.h @@ -31,7 +31,7 @@ typedef struct { int cmd_count; GSList* cmds; -} background_command_s; +} command_list_s; typedef struct { int total_cmd_count; @@ -44,6 +44,7 @@ typedef struct { /* Manager application */ GSList* system_cmds; GSList* exclusive_system_cmds; + GSList* system_background_cmds; /* Other applications */ int bg_cmd_count; @@ -73,7 +74,7 @@ typedef enum { /* * Command API */ -typedef bool (* client_foreach_command_cb)(int id, int type, const char* command, const char* param, int domain, void* user_data); +typedef bool (* client_foreach_command_cb)(int id, int type, int format, const char* command, const char* param, int domain, void* user_data); int vcd_client_command_collect_command(); @@ -116,6 +117,11 @@ int vcd_client_manager_set_exclusive(bool value); int vcd_client_manager_get_pid(); +int vcd_client_manager_set_result_text(const char* result); + +char* vcd_client_manager_get_result_text(); + +bool vcd_client_manager_is_system_command_valid(int pid); /* * client API diff --git a/server/vcd_config.c b/server/vcd_config.c index 7060d3a..7c46573 100644 --- a/server/vcd_config.c +++ b/server/vcd_config.c @@ -14,7 +14,7 @@ * limitations under the License. */ - +#include "vc_cmd_db.h" #include "vc_config_mgr.h" #include "vcd_config.h" #include "vcd_main.h" @@ -58,6 +58,12 @@ int vcd_config_initialize(vcd_config_lang_changed_cb lang_cb, vcd_config_foregro return VCD_ERROR_OPERATION_FAILED; } + ret = vc_db_initialize(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to initialize DB : %d", ret); + return ret; + } + g_lang_cb = lang_cb; g_user_data = user_data; @@ -70,7 +76,12 @@ int vcd_config_finalize() { vc_config_mgr_unset_lang_cb(getpid()); vc_config_mgr_finalize(getpid()); - return 0; + + int ret = vc_db_finalize(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to finalize DB, ret(%d)", ret); + } + return ret; } int vcd_config_get_default_language(char** language) diff --git a/server/vcd_dbus.c b/server/vcd_dbus.c index 6dbc6e6..58f3bdf 100644 --- a/server/vcd_dbus.c +++ b/server/vcd_dbus.c @@ -207,7 +207,7 @@ int vcdc_send_set_volume(int manger_pid, float volume) return 0; } -int vcdc_send_result(int pid, int cmd_type) +int vcdc_send_result(int pid, int manager_pid, int cmd_type) { DBusMessage* msg = NULL; @@ -215,15 +215,18 @@ int vcdc_send_result(int pid, int cmd_type) switch (cmd_type) { case VC_COMMAND_TYPE_FOREGROUND: - msg = __get_message(pid, VCD_METHOD_RESULT, VCD_CLIENT_TYPE_NORMAL); - break; case VC_COMMAND_TYPE_BACKGROUND: - msg = __get_message(pid, VCD_METHOD_RESULT, VCD_CLIENT_TYPE_NORMAL); + if (pid == manager_pid) { + msg = __get_message(pid, VCD_MANAGER_METHOD_RESULT, VCD_CLIENT_TYPE_MANAGER); + } else { + msg = __get_message(pid, VCD_METHOD_RESULT, VCD_CLIENT_TYPE_NORMAL); + } break; case VC_COMMAND_TYPE_WIDGET: msg = __get_message(pid, VCD_WIDGET_METHOD_RESULT, VCD_CLIENT_TYPE_WIDGET); break; case VC_COMMAND_TYPE_SYSTEM: + case VC_COMMAND_TYPE_SYSTEM_BACKGROUND: case VC_COMMAND_TYPE_EXCLUSIVE: msg = __get_message(pid, VCD_MANAGER_METHOD_RESULT, VCD_CLIENT_TYPE_MANAGER); break; @@ -253,14 +256,14 @@ int vcdc_send_result(int pid, int cmd_type) return 0; } -int vcdc_send_pre_result_to_manager(int manger_pid, int event, const char* pre_result) +int vcdc_send_pre_result_to_manager(int manager_pid, int event, const char* pre_result) { DBusError err; dbus_error_init(&err); DBusMessage* msg = NULL; - msg = __get_message(manger_pid, VCD_MANAGER_METHOD_PRE_RESULT, VCD_CLIENT_TYPE_MANAGER); + msg = __get_message(manager_pid, VCD_MANAGER_METHOD_PRE_RESULT, VCD_CLIENT_TYPE_MANAGER); if (NULL == msg) { SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Message is NULL"); @@ -427,6 +430,44 @@ int vcdc_send_service_state(vcd_state_e state) return 0; } +int vcdc_send_dialog(int manger_pid, int pid, const char* disp_text, const char* utt_text, int continuous) +{ + DBusError err; + dbus_error_init(&err); + + DBusMessage* msg = NULL; + + msg = __get_message(manger_pid, VCD_MANAGER_METHOD_DIALOG, VCD_CLIENT_TYPE_MANAGER); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Message is NULL"); + return VCD_ERROR_OUT_OF_MEMORY; + } + + SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] send dialog : pid(%d), disp_text(%s), utt_text(%s), continue(%d)", pid, disp_text, utt_text, continuous); + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &disp_text, + DBUS_TYPE_STRING, &utt_text, + DBUS_TYPE_INT32, &continuous, + DBUS_TYPE_INVALID); + + dbus_message_set_no_reply(msg, TRUE); + + if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to Send"); + return VCD_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] SUCCESS Send"); + dbus_connection_flush(g_conn_sender); + } + + dbus_message_unref(msg); + + return 0; +} + int vcdc_send_error_signal_to_manager(int manager_pid, int reason, char *err_msg) { SLOG(LOG_ERROR, TAG_VCD, ">>>> Send error signal to manager"); @@ -599,6 +640,12 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_SET_CLIENT_INFO)) vcd_dbus_server_mgr_set_client_info(g_conn_listener, msg); + else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_SET_PRIVATE_DATA)) + vcd_dbus_server_mgr_set_private_data(g_conn_listener, msg); + + else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_GET_PRIVATE_DATA)) + vcd_dbus_server_mgr_get_private_data(g_conn_listener, msg); + else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_START)) vcd_dbus_server_mgr_start(g_conn_listener, msg); @@ -611,6 +658,11 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_RESULT_SELECTION)) vcd_dbus_server_mgr_result_selection(g_conn_listener, msg); + else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_SET_DOMAIN)) + vcd_dbus_server_mgr_set_domain(g_conn_listener, msg); + + else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_DO_ACTION)) + vcd_dbus_server_mgr_do_action(g_conn_listener, msg); /* client event */ else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_INITIALIZE)) @@ -630,6 +682,13 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_SET_FOREGROUND)) vcd_dbus_server_set_foreground(g_conn_listener, msg); + + else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_DIALOG)) + vcd_dbus_server_dialog(g_conn_listener, msg); + + else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_IS_SYS_COMMAND_VALID)) + vcd_dbus_server_is_system_command_valid(g_conn_listener, msg); + #if 0 else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_REQUEST_START)) vcd_dbus_server_start_request(g_conn_listener, msg); diff --git a/server/vcd_dbus.h b/server/vcd_dbus.h index f83e97d..a1abc46 100644 --- a/server/vcd_dbus.h +++ b/server/vcd_dbus.h @@ -41,9 +41,9 @@ int vcdc_send_show_tooltip(int pid, bool show); int vcdc_send_set_volume(int manger_pid, float volume); -int vcdc_send_result(int pid, int cmd_type); +int vcdc_send_result(int pid, int manager_pid, int cmd_type); -int vcdc_send_pre_result_to_manager(int manger_pid, int event, const char* pre_result); +int vcdc_send_pre_result_to_manager(int manager_pid, int event, const char* pre_result); int vcdc_send_result_to_manager(int manger_pid, int result_type); @@ -55,6 +55,8 @@ int vcdc_send_error_signal_to_manager(int manager_pid, int reason, char *err_msg int vcdc_send_service_state(vcd_state_e state); +int vcdc_send_dialog(int manger_pid, int pid, const char* disp_text, const char* utt_text, int continuous); + #ifdef __cplusplus } diff --git a/server/vcd_dbus_server.c b/server/vcd_dbus_server.c index 2929eb0..dafeadb 100644 --- a/server/vcd_dbus_server.c +++ b/server/vcd_dbus_server.c @@ -516,6 +516,232 @@ int vcd_dbus_server_mgr_set_client_info(DBusConnection* conn, DBusMessage* msg) return 0; } +int vcd_dbus_server_mgr_set_private_data(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid = 0; + char* key = NULL; + char* data = NULL; + + int ret = VCD_ERROR_OPERATION_FAILED; + + SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager set private data"); + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &key, + DBUS_TYPE_STRING, &data, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr set private data : get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = VCD_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr set domain : pid(%d), key(%s), data(%s)", pid, key, data); + ret = vcd_server_mgr_set_private_data(pid, key, data); + } + + DBusMessage* reply; + reply = dbus_message_new_method_return(msg); + + if (NULL != reply) { + dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID); + + if (0 == ret) { + SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret); + } + + if (!dbus_connection_send(conn, reply, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!"); + } + + dbus_connection_flush(conn); + dbus_message_unref(reply); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!"); + } + + SLOG(LOG_DEBUG, TAG_VCD, "<<<<<"); + SLOG(LOG_DEBUG, TAG_VCD, " "); + + return 0; +} + +int vcd_dbus_server_mgr_get_private_data(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid = 0; + char* key = NULL; + char* data = NULL; + + int ret = VCD_ERROR_OPERATION_FAILED; + + SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager get private data"); + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &key, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr set audio type : get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = VCD_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr get private data : pid(%d), key(%s)", pid, key); + ret = vcd_server_mgr_get_private_data(pid, key, &data); + } + + DBusMessage* reply; + reply = dbus_message_new_method_return(msg); + + if (NULL != reply) { + dbus_message_append_args(reply, + DBUS_TYPE_INT32, &ret, + DBUS_TYPE_STRING, &data, + DBUS_TYPE_INVALID); + + if (0 == ret) { + SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d), private data(%s)", ret, data); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret); + } + + if (!dbus_connection_send(conn, reply, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!"); + } + + dbus_connection_flush(conn); + dbus_message_unref(reply); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!"); + } + + SLOG(LOG_DEBUG, TAG_VCD, "<<<<<"); + SLOG(LOG_DEBUG, TAG_VCD, " "); + + if (NULL != data) free(data); + + return 0; +} + +int vcd_dbus_server_mgr_set_domain(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid = 0; + char* domain = NULL; + + int ret = VCD_ERROR_OPERATION_FAILED; + + SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager set audio type"); + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &domain, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr set domain : get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = VCD_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr set domain : pid(%d), domain(%s)", pid, domain); + ret = vcd_server_mgr_set_domain(pid, domain); + } + + DBusMessage* reply; + reply = dbus_message_new_method_return(msg); + + if (NULL != reply) { + dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID); + + if (0 == ret) { + SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret); + } + + if (!dbus_connection_send(conn, reply, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!"); + } + + dbus_connection_flush(conn); + dbus_message_unref(reply); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!"); + } + + SLOG(LOG_DEBUG, TAG_VCD, "<<<<<"); + SLOG(LOG_DEBUG, TAG_VCD, " "); + + return 0; +} + +int vcd_dbus_server_mgr_do_action(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid = 0; + int type = 0; + char* send_event = NULL; + + int ret = VCD_ERROR_OPERATION_FAILED; + + SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager request to do action"); + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &type, + DBUS_TYPE_STRING, &send_event, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr request to do action : get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = VCD_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr request to do action : pid(%d), type(%d) send_event(%s)", pid, type, send_event); + ret = vcd_server_mgr_do_action(pid, type, send_event); + } + + DBusMessage* reply; + reply = dbus_message_new_method_return(msg); + + if (NULL != reply) { + dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID); + + if (0 == ret) { + SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret); + } + + if (!dbus_connection_send(conn, reply, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!"); + } + + dbus_connection_flush(conn); + dbus_message_unref(reply); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!"); + } + + SLOG(LOG_DEBUG, TAG_VCD, "<<<<<"); + SLOG(LOG_DEBUG, TAG_VCD, " "); + + return 0; +} + int vcd_dbus_server_mgr_start(DBusConnection* conn, DBusMessage* msg) { DBusError err; @@ -729,6 +955,7 @@ int vcd_dbus_server_initialize(DBusConnection* conn, DBusMessage* msg) int pid; int service_state = 0; + int daemon_pid; int ret = VCD_ERROR_OPERATION_FAILED; dbus_message_get_args(msg, &err, @@ -742,9 +969,10 @@ int vcd_dbus_server_initialize(DBusConnection* conn, DBusMessage* msg) dbus_error_free(&err); ret = VCD_ERROR_OPERATION_FAILED; } else { - SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd initialize : pid(%d)", pid); ret = vcd_server_initialize(pid); service_state = vcd_server_get_service_state(); + daemon_pid = getpid(); + SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd initialize : pid(%d) daemon_pid(%d)", pid, daemon_pid); } int mgr_pid = vcd_client_manager_get_pid(); @@ -757,6 +985,7 @@ int vcd_dbus_server_initialize(DBusConnection* conn, DBusMessage* msg) DBUS_TYPE_INT32, &ret, DBUS_TYPE_INT32, &mgr_pid, DBUS_TYPE_INT32, &service_state, + DBUS_TYPE_INT32, &daemon_pid, DBUS_TYPE_INVALID); if (0 == ret) { @@ -1019,6 +1248,121 @@ int vcd_dbus_server_set_foreground(DBusConnection* conn, DBusMessage* msg) return 0; } +int vcd_dbus_server_dialog(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid; + char* disp_text = NULL; + char* utt_text = NULL; + int continuous; + int ret = VCD_ERROR_OPERATION_FAILED; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &disp_text, + DBUS_TYPE_STRING, &utt_text, + DBUS_TYPE_INT32, &continuous, + DBUS_TYPE_INVALID); + + SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD request dialog"); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd request dialog : get arguments error (%s)", err.message); + dbus_error_free(&err); + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd dialog : pid(%d), disp_text(%s), utt_text(%s), continuous(%d)", pid, disp_text, utt_text, continuous); + ret = vcd_server_dialog(pid, disp_text, utt_text, continuous); + } + + DBusMessage* reply; + reply = dbus_message_new_method_return(msg); + + if (NULL != reply) { + if (0 == ret) { + /* Append result and language */ + dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID); + + SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret); + } else { + dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID); + + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret); + } + + if (!dbus_connection_send(conn, reply, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!"); + } + + dbus_connection_flush(conn); + dbus_message_unref(reply); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!"); + } + + + SLOG(LOG_DEBUG, TAG_VCD, "<<<<<"); + SLOG(LOG_DEBUG, TAG_VCD, " "); + + return 0; +} + +int vcd_dbus_server_is_system_command_valid(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid; + int is_sys_cmd_valid; + + int ret = VCD_ERROR_OPERATION_FAILED; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INVALID); + + SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD request to check system command is valid"); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd request to check system command is valid : get arguments error (%s)", err.message); + dbus_error_free(&err); + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd dialog : pid(%d)", pid); + vcd_server_is_system_command_valid(pid, &is_sys_cmd_valid); + } + + DBusMessage* reply; + reply = dbus_message_new_method_return(msg); + + if (NULL != reply) { + dbus_message_append_args(reply, + DBUS_TYPE_INT32, &ret, + DBUS_TYPE_STRING, &is_sys_cmd_valid, + DBUS_TYPE_INVALID); + + if (0 == ret) { + SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d), is_sys_cmd_valid (%d)", ret, is_sys_cmd_valid); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret); + } + + if (!dbus_connection_send(conn, reply, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!"); + } + + dbus_connection_flush(conn); + dbus_message_unref(reply); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!"); + } + + SLOG(LOG_DEBUG, TAG_VCD, "<<<<<"); + SLOG(LOG_DEBUG, TAG_VCD, " "); + + return 0; +} + #if 0 int vcd_dbus_server_start_request(DBusConnection* conn, DBusMessage* msg) { @@ -1178,6 +1522,7 @@ int vcd_dbus_server_widget_initialize(DBusConnection* conn, DBusMessage* msg) int pid; int service_state = 0; + int daemon_pid; int ret = VCD_ERROR_OPERATION_FAILED; dbus_message_get_args(msg, &err, @@ -1191,9 +1536,10 @@ int vcd_dbus_server_widget_initialize(DBusConnection* conn, DBusMessage* msg) dbus_error_free(&err); ret = VCD_ERROR_OPERATION_FAILED; } else { - SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd widget initialize : pid(%d)", pid); ret = vcd_server_widget_initialize(pid); service_state = vcd_server_get_service_state(); + daemon_pid = getpid(); + SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd widget initialize : pid(%d) daemon_pid(%d)", pid, daemon_pid); } DBusMessage* reply; @@ -1203,6 +1549,7 @@ int vcd_dbus_server_widget_initialize(DBusConnection* conn, DBusMessage* msg) dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INT32, &service_state, + DBUS_TYPE_INT32, &daemon_pid, DBUS_TYPE_INVALID); if (0 == ret) { diff --git a/server/vcd_dbus_server.h b/server/vcd_dbus_server.h index 4011693..b29fc5d 100644 --- a/server/vcd_dbus_server.h +++ b/server/vcd_dbus_server.h @@ -47,6 +47,14 @@ int vcd_dbus_server_mgr_get_audio_type(DBusConnection* conn, DBusMessage* msg); int vcd_dbus_server_mgr_set_client_info(DBusConnection* conn, DBusMessage* msg); +int vcd_dbus_server_mgr_set_private_data(DBusConnection* conn, DBusMessage* msg); + +int vcd_dbus_server_mgr_get_private_data(DBusConnection* conn, DBusMessage* msg); + +int vcd_dbus_server_mgr_set_domain(DBusConnection* conn, DBusMessage* msg); + +int vcd_dbus_server_mgr_do_action(DBusConnection* conn, DBusMessage* msg); + int vcd_dbus_server_mgr_start(DBusConnection* conn, DBusMessage* msg); int vcd_dbus_server_mgr_stop(DBusConnection* conn, DBusMessage* msg); @@ -73,6 +81,10 @@ int vcd_dbus_server_unset_command(DBusConnection* conn, DBusMessage* msg); int vcd_dbus_server_set_foreground(DBusConnection* conn, DBusMessage* msg); +int vcd_dbus_server_dialog(DBusConnection* conn, DBusMessage* msg); + +int vcd_dbus_server_is_system_command_valid(DBusConnection* conn, DBusMessage* msg); + #if 0 int vcd_dbus_server_start_request(DBusConnection* conn, DBusMessage* msg); diff --git a/server/vcd_engine_agent.c b/server/vcd_engine_agent.c index 0100ac1..0863583 100644 --- a/server/vcd_engine_agent.c +++ b/server/vcd_engine_agent.c @@ -69,8 +69,17 @@ static vcengine_s g_dynamic_engine; static char* g_default_lang; /** callback functions */ -static pre_result_callback g_pre_result_cb; -static result_callback g_result_cb; +static result_callback g_result_cb = NULL; + +static asr_result_callback g_asr_result_cb = NULL; + +#if 0 +static pre_result_callback g_pre_result_cb = NULL; + +static nlu_result_callback g_nlu_result_cb = NULL; +#endif + +static error_callback g_error_cb = NULL; bool __supported_language_cb(const char* language, void* user_data); @@ -100,9 +109,10 @@ int __log_enginelist(); /* * VCS Engine Agent Interfaces */ -int vcd_engine_agent_init(pre_result_callback pre_cb, result_callback result_cb) +//int vcd_engine_agent_init(pre_result_callback pre_result_cb, result_callback result_cb, nlu_result_callback nlu_result_cb, error_callback error_cb) +int vcd_engine_agent_init(asr_result_callback asr_result_cb, result_callback result_cb, error_callback error_cb) { - if (NULL == pre_cb || NULL == result_cb) { + if (/*NULL == pre_result_cb*/ NULL == asr_result_cb || NULL == result_cb /*|| NULL == nlu_result_cb*/ || NULL == error_cb) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Input parameter is NULL"); return VCD_ERROR_OPERATION_FAILED; } @@ -121,8 +131,11 @@ int vcd_engine_agent_init(pre_result_callback pre_cb, result_callback result_cb) g_agent_init = true; - g_pre_result_cb = pre_cb; + //g_pre_result_cb = pre_result_cb; + g_asr_result_cb = asr_result_cb; g_result_cb = result_cb; + //g_nlu_result_cb = nlu_result_cb; + g_error_cb = error_cb; if (0 != vcd_config_get_default_language(&g_default_lang)) { SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] There is No default voice in config"); @@ -163,11 +176,23 @@ int vcd_engine_agent_release() g_list_free(iter); /* release current engine data */ - if (NULL != g_dynamic_engine.pefuncs) free(g_dynamic_engine.pefuncs); - if (NULL != g_dynamic_engine.pdfuncs) free(g_dynamic_engine.pdfuncs); + if (NULL != g_dynamic_engine.pefuncs) { + free(g_dynamic_engine.pefuncs); + g_dynamic_engine.pefuncs = NULL; + } + if (NULL != g_dynamic_engine.pdfuncs) { + free(g_dynamic_engine.pdfuncs); + g_dynamic_engine.pdfuncs = NULL; + } g_agent_init = false; + //g_pre_result_cb = NULL; + g_asr_result_cb = NULL; + g_result_cb = NULL; + //g_nlu_result_cb = NULL; + g_error_cb = NULL; + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Engine Agent release"); return 0; @@ -297,6 +322,9 @@ int __internal_get_engine_info(const char* filepath, vcengine_info_s** info) handle = dlopen(filepath, RTLD_LAZY); if (!handle) { SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Invalid engine : %s", filepath); + if ((error = dlerror()) != NULL) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] %s", error); + } return -1; } @@ -462,46 +490,40 @@ int __get_audio_type(char** audio_type) return vcd_recorder_get(audio_type); } -void __pre_result_cb(vcp_pre_result_event_e event, const char* pre_result, void* user_data) +void __result_cb(vcp_result_event_e event, int* result_id, int count, const char* all_result, const char* non_fixed, const char* nlu_result, const char* msg, void *user_data) { - SLOG(LOG_DEBUG, TAG_VCD, "[Engine agent] Pre result(%s)", pre_result); + SLOG(LOG_DEBUG, TAG_VCD, "[Engine agent] Event(%d), Count(%d) Text(%s) Nonfixed(%s) NLU result(%s) Msg(%s)", event, count, all_result, non_fixed, nlu_result, msg); - if (NULL != g_pre_result_cb) { - g_pre_result_cb(event, pre_result, user_data); + if (NULL != g_result_cb) { + g_result_cb(event, result_id, count, all_result, non_fixed, nlu_result, msg, user_data); } else { SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent ERROR] Result callback function is NOT valid"); } + return; } -void __result_cb(vcp_result_event_e event, int* result_id, int count, const char* all_result, const char* non_fixed, const char* msg, void *user_data) +void __asr_result_cb(vcp_asr_result_event_e event, const char* asr_result, void *user_data) { - SLOG(LOG_DEBUG, TAG_VCD, "[Engine agent] Event(%d), Count(%d) Text(%s) Nonfixed(%s) Msg(%s)", event, count, all_result, non_fixed, msg); + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] ASR result - Event(%d), Result(%s)", event, asr_result); - // Need to nlp info handle or true false value - int ret = 0; - char* temp_nlp = NULL; - - if (true == g_dynamic_engine.is_loaded) { - if (NULL != g_dynamic_engine.pefuncs->get_nlp_info) { - ret = g_dynamic_engine.pefuncs->get_nlp_info(&temp_nlp); - if (0 != ret) { - SLOG(LOG_WARN, TAG_VCD, "[Engine Agent ERROR] Fail to get nlp info : error(%d)", ret); - } else { - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Get nlp info : %s", temp_nlp); - } - } else { - SLOG(LOG_WARN, TAG_VCD, "[Engine Agent ERROR] Not support to get nlp info"); - } + if (NULL != g_asr_result_cb) { + g_asr_result_cb(event, asr_result, user_data); + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent ERROR] ASR result callback function is NOT valid"); } - if (NULL == temp_nlp) - temp_nlp = "null"; + return; +} - if (NULL != g_result_cb) { - g_result_cb(event, result_id, count, all_result, non_fixed, msg, temp_nlp, user_data); +void __error_cb(vcp_error_e error, const char* msg, void *user_data) +{ + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] ERROR(%d)", error); + + if (NULL != g_error_cb) { + g_error_cb(error, msg, user_data); } else { - SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent ERROR] Result callback function is NOT valid"); + SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent ERROR] Error callback function is NOT vaild"); } return; @@ -565,13 +587,28 @@ int __load_engine(vcengine_s* engine) /* Check all engine functions */ if (NULL == engine->pefuncs->initialize || NULL == engine->pefuncs->deinitialize || + NULL == engine->pefuncs->get_recording_format || NULL == engine->pefuncs->foreach_langs || NULL == engine->pefuncs->is_lang_supported || NULL == engine->pefuncs->set_result_cb || NULL == engine->pefuncs->set_language || + NULL == engine->pefuncs->set_commands || + NULL == engine->pefuncs->unset_commands || + NULL == engine->pefuncs->start || NULL == engine->pefuncs->set_recording || NULL == engine->pefuncs->stop || - NULL == engine->pefuncs->cancel) { + NULL == engine->pefuncs->cancel || + NULL == engine->pefuncs->set_asr_result_cb || + //NULL == engine->pefuncs->set_pre_result_cb || + NULL == engine->pefuncs->set_error_cb || + NULL == engine->pefuncs->set_domain || + NULL == engine->pefuncs->get_nlu_base_info || + //NULL == engine->pefuncs->set_nlu_result_cb || + NULL == engine->pefuncs->set_private_data || + NULL == engine->pefuncs->get_private_data || + NULL == engine->pefuncs->process_text || + NULL == engine->pefuncs->process_list_event || + NULL == engine->pefuncs->process_haptic_event) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The current engine is NOT valid"); return VCD_ERROR_OPERATION_FAILED; } @@ -587,9 +624,13 @@ int __load_engine(vcengine_s* engine) return VCD_ERROR_OPERATION_FAILED; } - // temp - if (0 != engine->pefuncs->set_pre_result_cb(__pre_result_cb, NULL)) { - SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set pre result callback of vc-engine"); + if (0 != engine->pefuncs->set_asr_result_cb(__asr_result_cb, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set asr result callback of vc-engine"); + return VCD_ERROR_OPERATION_FAILED; + } + + if (0 != engine->pefuncs->set_error_cb(__error_cb, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set error callback of vc-engine"); return VCD_ERROR_OPERATION_FAILED; } @@ -770,12 +811,155 @@ int vcd_engine_recognize_cancel() ret = g_dynamic_engine.pefuncs->cancel(); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to cancel dynamic engine error(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + } + + return 0; +} + +int vcd_engine_set_domain(int pid, const char* domain) +{ + if (false == g_agent_init) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); + return VCD_ERROR_OPERATION_FAILED; + } + + int ret = -1; + if (true == g_dynamic_engine.is_loaded) { + ret = g_dynamic_engine.pefuncs->set_domain(domain); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set domain (%d)", ret); + return VCD_ERROR_OPERATION_FAILED; } } return 0; } +int vcd_engine_get_nlu_base_info(int pid, const char* key, char** value) +{ + if (NULL == value) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter"); + return VCD_ERROR_INVALID_PARAMETER; + } + + if (false == g_agent_init) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); + return VCD_ERROR_OPERATION_FAILED; + } + + int ret = -1; + if (true == g_dynamic_engine.is_loaded) { + ret = g_dynamic_engine.pefuncs->get_nlu_base_info(key, value); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get nlu base info (%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + } + + return 0; +} + +int vcd_engine_set_private_data(int pid, const char* key, const char* data) +{ + if (false == g_agent_init) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); + return VCD_ERROR_OPERATION_FAILED; + } + + int ret = -1; + if (true == g_dynamic_engine.is_loaded) { + ret = g_dynamic_engine.pefuncs->set_private_data(key, data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set private data (%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + } + + return 0; +} + +int vcd_engine_get_private_data(int pid, const char* key, char** data) +{ + if (NULL == data) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter"); + return VCD_ERROR_INVALID_PARAMETER; + } + + if (false == g_agent_init) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); + return VCD_ERROR_OPERATION_FAILED; + } + + int ret = -1; + if (true == g_dynamic_engine.is_loaded) { + ret = g_dynamic_engine.pefuncs->get_private_data(key, data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get private data (%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + } + + return 0; +} + +int vcd_engine_process_text(int pid, const char* text) +{ + if (false == g_agent_init) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); + return VCD_ERROR_OPERATION_FAILED; + } + + int ret = -1; + if (true == g_dynamic_engine.is_loaded) { + ret = g_dynamic_engine.pefuncs->process_text(text); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to process text (%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + } + + return 0; +} + +int vcd_engine_process_list_event(int pid, const char* event) +{ + if (false == g_agent_init) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); + return VCD_ERROR_OPERATION_FAILED; + } + + int ret = -1; + if (true == g_dynamic_engine.is_loaded) { + ret = g_dynamic_engine.pefuncs->process_list_event(event); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to process list event (%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + } + + return 0; +} + +int vcd_engine_process_haptic_event(int pid, const char* event) +{ + if (false == g_agent_init) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); + return VCD_ERROR_OPERATION_FAILED; + } + + int ret = -1; + if (true == g_dynamic_engine.is_loaded) { + ret = g_dynamic_engine.pefuncs->process_haptic_event(event); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to process haptic event (%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + } + + return 0; +} /* * VCS Engine Interfaces for client and setting diff --git a/server/vcd_engine_agent.h b/server/vcd_engine_agent.h index 4bfcaf1..8e50ff9 100644 --- a/server/vcd_engine_agent.h +++ b/server/vcd_engine_agent.h @@ -31,17 +31,26 @@ extern "C" { #define ENGINE_PATH_SIZE 256 -typedef void (*pre_result_callback)(vcp_pre_result_event_e event, const char* pre_result, void* user_data); - typedef void (*result_callback)(vcp_result_event_e event, int* result_id, int count, const char* all_result, - const char* non_fixed_result, const char* msg, const char* nlp_info, void *user_data); + const char* non_fixed_result, const char* nlu_result, const char* msg, void *user_data); + +typedef void (*asr_result_callback)(vcp_asr_result_event_e event, const char* asr_result, void *user_data); + +#if 0 +typedef void (*pre_result_callback)(vcp_pre_result_event_e event, const char* pre_result, void *user_data); + +typedef void (*nlu_result_callback)(vcp_result_event_e event, const char* nlu_result, void *user_data); +#endif + +typedef void (*error_callback)(vcp_error_e error, const char* msg, void *user_data); typedef void (*silence_dectection_callback)(void *user_data); /** Init engine agent */ -int vcd_engine_agent_init(pre_result_callback pre_cb, result_callback result_cb); +//int vcd_engine_agent_init(pre_result_callback pre_result_cb, result_callback result_cb, nlu_result_callback nlu_result_cb, error_callback error_cb); +int vcd_engine_agent_init(asr_result_callback asr_result_cb, result_callback result_cb, error_callback error_cb); /** Release engine agent */ int vcd_engine_agent_release(); @@ -80,6 +89,21 @@ int vcd_engine_recognize_stop(); int vcd_engine_recognize_cancel(); +int vcd_engine_set_domain(int pid, const char* domain); + +int vcd_engine_get_nlu_base_info(int pid, const char* key, char** value); + +// int vcd_engine_set_private_data(const char* data); +int vcd_engine_set_private_data(int pid, const char* key, const char* data); + +// int vcd_engine_get_private_data(char** data); +int vcd_engine_get_private_data(int pid, const char* key, char** data); + +int vcd_engine_process_text(int pid, const char* text); + +int vcd_engine_process_list_event(int pid, const char* event); + +int vcd_engine_process_haptic_event(int pid, const char* event); #ifdef __cplusplus diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index 52a9f3a..764a7a4 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -454,7 +454,7 @@ static float get_volume_decibel(char* data, int size) if (0 == count) rms = 0.0; else - rms = sqrt(square_sum/count); + rms = sqrt((float)square_sum/count); db = 20 * log10(rms/MAX_AMPLITUDE_MEAN_16); return db; @@ -523,7 +523,7 @@ int vcd_recorder_start() bool started = false; SLOG(LOG_ERROR, TAG_VCD, "[Recorder] audio type : %s", g_current_audio_type); - + if (NULL != g_current_audio_type) { if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) { #ifdef TV_BT_MODE @@ -562,7 +562,7 @@ int vcd_recorder_start() SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start MSF(wifi) audio"); return VCD_ERROR_OPERATION_FAILED; } -#endif +#endif } } diff --git a/server/vcd_server.c b/server/vcd_server.c index e8ea19e..95b81f1 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -14,9 +14,12 @@ * limitations under the License. */ +#include +#include #include #include +#include "vc_cmd_db.h" #include "vc_info_parser.h" #include "vcd_main.h" #include "vcd_server.h" @@ -38,6 +41,15 @@ static GList *g_proc_list = NULL; static Ecore_Timer *g_restart_timer = NULL; +/** +* @brief Enumerations of send event type. +*/ +typedef enum { + VCD_SEND_EVENT_TYPE_TEXT, /**< send text event to vc engine*/ + VCD_SEND_EVENT_TYPE_LIST_EVENT, /**< send list event to vc engine */ + VCD_SEND_EVENT_TYPE_HAPTIC_EVENT /**< send haptic event to vc engine */ +} vcd_send_event_type_e; + /* * VC Server Internal Functions */ @@ -63,6 +75,17 @@ static Eina_Bool __cancel_by_interrupt(void *data) return EINA_FALSE; } +static void __cancel_by_error(void *data) +{ + SLOG(LOG_DEBUG, TAG_VCD, "===== Cancel by error"); + + vcd_server_mgr_cancel(); + + SLOG(LOG_DEBUG, TAG_VCD, "====="); + SLOG(LOG_DEBUG, TAG_VCD, " "); + return; +} + static Eina_Bool __restart_engine(void *data) { SLOG(LOG_DEBUG, TAG_VCD, "===== Restart by no result"); @@ -93,9 +116,10 @@ static Eina_Bool __restart_engine(void *data) static int __server_recorder_callback(const void* data, const unsigned int length) { vcd_state_e state = vcd_config_get_service_state(); - if (VCD_STATE_RECORDING != state) { - SLOG(LOG_DEBUG, TAG_VCD, "[Server] Not recording state, but recording"); -// return 0; + if (VCD_STATE_READY == state) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Ready state, but recording"); + } else if (VCD_STATE_PROCESSING == state) { + return 0; } vcp_speech_detect_e speech_detected = VCP_SPEECH_DETECT_NONE; @@ -203,43 +227,186 @@ static void __config_foreground_changed_cb(int previous, int current, void* user return; } +static int __vcd_activate_app_by_appcontrol(const char* appid) +{ + if (NULL == appid) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter"); + return VCD_ERROR_INVALID_PARAMETER; + } + + int ret = -1; + app_control_h app_control = NULL; + ret = app_control_create(&app_control); + if (APP_CONTROL_ERROR_NONE == ret) { + // Set extra data + ret = app_control_add_extra_data(app_control, "voice_launch", "get_result"); + if (APP_CONTROL_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to add extra data, ret(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + // Set an app ID. + ret = app_control_set_app_id(app_control, appid); + if (APP_CONTROL_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set app id, ret(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + // Sent launch request + ret = app_control_send_launch_request(app_control, NULL, NULL); + if(APP_CONTROL_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send launch request, ret(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + // Destroy app control + ret = app_control_destroy(app_control); + if (APP_CONTROL_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to destroy, ret(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + } + return VCD_ERROR_NONE; +} + +static int __vcd_resume_app(const char* appid) +{ + app_context_h app_context = NULL; + int ret = app_manager_get_app_context(appid, &app_context); + if (APP_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get app_context, ret(%d), appid(%s)", ret, appid); + return VCD_ERROR_OPERATION_FAILED; + } + + ret = app_manager_resume_app(app_context); + if (APP_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to resume app, ret(%d), appid(%s)", ret, appid); + return VCD_ERROR_OPERATION_FAILED; + } + return VCD_ERROR_NONE; +} + +static bool __vcd_is_package_installed(const char* appid) +{ + app_info_h app_info = NULL; + int ret = app_manager_get_app_info(appid, &app_info); + if (APP_MANAGER_ERROR_NONE != ret || NULL == app_info) + return false; + ret = app_info_destroy(app_info); + if (APP_MANAGER_ERROR_NONE != ret) + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to destroy app_info, ret(%d)", ret); + return true; +} + +static bool __vcd_launch_app(const char* result) +{ + if (NULL == result) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter"); + return VCD_ERROR_INVALID_PARAMETER; + } + + GSList* app_list = NULL; + if (0 != vc_db_get_appid_list(result, &app_list)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] result text is NULL"); + return VCD_ERROR_INVALID_PARAMETER; + } + + if (0 != g_slist_length(app_list)) { + /* releaes data */ + GSList *iter = NULL; + vc_deactivated_app_s* temp_app = NULL; + iter = g_slist_nth(app_list, 0); + + while (NULL != iter) { + temp_app = iter->data; + + if (NULL != temp_app) { + if (NULL != temp_app->appid) { + int ret = -1; + bool running = false; + ret = app_manager_is_running(temp_app->appid, &running); + if (APP_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to check running with appid(%s)", temp_app->appid); + free(temp_app->appid); + temp_app->appid = NULL; + free(temp_app); + temp_app = NULL; + return VCD_ERROR_OPERATION_FAILED; + } + if (false == running) { + int tmp_ret = __vcd_is_package_installed(temp_app->appid); + if (false == tmp_ret) { + SLOG(LOG_WARN, TAG_VCD, "[WARNING] app is not installed, appid(%s)", temp_app->appid); + } else { + ret = __vcd_activate_app_by_appcontrol(temp_app->appid); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to activate app"); + free(temp_app->appid); + temp_app->appid = NULL; + free(temp_app); + temp_app = NULL; + return ret; + } + SLOG(LOG_ERROR, TAG_VCD, "Launch app: appid(%s) result(%s)", temp_app->appid, result); + } + } else { + ret = __vcd_resume_app(temp_app->appid); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to resume app"); + free(temp_app->appid); + temp_app->appid = NULL; + free(temp_app); + temp_app = NULL; + return ret; + } + SLOG(LOG_ERROR, TAG_VCD, "Resume app: appid(%s) result(%s)", temp_app->appid, result); + } + free(temp_app->appid); + temp_app->appid = NULL; + } + free(temp_app); + temp_app = NULL; + } + iter = g_slist_next(iter); + } + app_list = NULL; + } + + return VCD_ERROR_NONE; +} + static Eina_Bool __vcd_send_selected_result(void *data) { GSList* pid_list = NULL; - if (0 != vc_info_parser_get_result_pid_list(&pid_list)) { + const char* result = vcd_client_manager_get_result_text(); + + if (0 != vc_info_parser_get_result_pid_list(&pid_list, result)) { SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to get pid list. No result"); } else { if (0 < g_slist_length(pid_list)) { GSList* iter = NULL; vc_cmd_s* temp_cmd = NULL; int ret = 0; - int count = 0; iter = g_slist_nth(pid_list, 0); while (NULL != iter) { temp_cmd = iter->data; if (NULL != temp_cmd) { - count = 0; - do { + /* Launch deactivated several apps that is matched with result */ + ret = __vcd_launch_app(result); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "Fail to launch or resume app, ret(%d) result(%s)", ret, result); + } else { /* send result noti */ - ret = vcdc_send_result(temp_cmd->pid, temp_cmd->type); + ret = vcdc_send_result(temp_cmd->pid, vcd_client_manager_get_pid(), temp_cmd->type); if (0 != ret) { - SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); - if (VCD_ERROR_TIMED_OUT != ret) { - break; - } + SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result, ret(%d)", ret); + break; } else { SLOG(LOG_DEBUG, TAG_VCD, "[Server] Send result : pid(%d) type(%d)", temp_cmd->pid, temp_cmd->type); } - count++; - - if (100 == count) break; - /* While is retry code */ - } while (0 != ret); + } free(temp_cmd); + temp_cmd = NULL; } - pid_list = g_slist_remove_link(pid_list, iter); iter = g_slist_nth(pid_list, 0); } @@ -254,28 +421,25 @@ static Eina_Bool __vcd_send_selected_result(void *data) return EINA_FALSE; } -static int __convert_type_to_priority(vc_cmd_type_e type) +//static void __vcd_server_pre_result_cb(vcp_pre_result_event_e event, const char* pre_result, void *user_data) +static void __vcd_server_asr_result_cb(vcp_asr_result_event_e event, const char* asr_result, void *user_data) { - switch (type) { - case VC_COMMAND_TYPE_NONE: return 0; - case VC_COMMAND_TYPE_BACKGROUND: return 1; - case VC_COMMAND_TYPE_FOREGROUND: return 2; - case VC_COMMAND_TYPE_WIDGET: return 2; - case VC_COMMAND_TYPE_SYSTEM: return 3; - case VC_COMMAND_TYPE_EXCLUSIVE: return 3; - default: return 0; + if (NULL != asr_result) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] ASR result - Event(%d), Text(%s)", event, asr_result); + vcdc_send_pre_result_to_manager(vcd_client_manager_get_pid(), event, asr_result); } + + return; } -static void __vcd_server_pre_result_cb(vcp_pre_result_event_e event, const char* pre_result, void* user_data) +static void* __recorder_stop(void *data) { - if (NULL != pre_result) { - vcdc_send_pre_result_to_manager(vcd_client_manager_get_pid(), event, pre_result); - } + vcd_recorder_stop(); + return NULL; } static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int count, const char* all_result, - const char* non_fixed_result, const char* msg, const char* nlp_info, void *user_data) + const char* non_fixed_result, const char* nlu_result, const char* msg, void *user_data) { if (VCD_STATE_PROCESSING != vcd_config_get_service_state()) { if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY != vcd_client_get_recognition_mode()) { @@ -284,14 +448,8 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int } } - // temp - if (NULL != nlp_info) { - if (0 != vc_info_parser_set_nlp_info(nlp_info)) { - SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to save nlp info"); - } - } - vc_info_parser_unset_result(vcd_client_manager_get_exclusive()); + vcd_client_manager_set_result_text(all_result); SLOG(LOG_DEBUG, TAG_VCD, "[Server] Event(%d), Text(%s) Nonfixed(%s) Msg(%s) Result count(%d)", event, all_result, non_fixed_result, msg, count); @@ -311,7 +469,8 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int return; } SLOG(LOG_DEBUG, TAG_VCD, "[Server] Stop recorder due to success"); - vcd_recorder_stop(); + //vcd_recorder_stop(); + ecore_main_loop_thread_safe_call_sync(__recorder_stop, NULL); } else if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY == vcd_client_get_recognition_mode()) { SLOG(LOG_DEBUG, TAG_VCD, "[Server] Restart continuously"); /* Restart option is ON */ @@ -325,7 +484,197 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int return; } } +#if 1 + /* if nlu_result is exist, Add command handle(is_action) into result list */ + /* Normal result */ + SLOG(LOG_DEBUG, TAG_VCD, "[Server] === Get engine result ==="); + + int ret = -1; + vc_cmd_s* temp_cmd = NULL; + vc_cmd_list_h vc_cmd_list = NULL; + + if (0 != vc_cmd_list_create(&vc_cmd_list)) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to create command list"); + vcd_client_manager_set_exclusive(false); + vcd_config_set_service_state(VCD_STATE_READY); + vcdc_send_service_state(VCD_STATE_READY); + return; + } + + /* priority filter */ + /* system > exclusive > foreground = widget > system_background > background */ + int i = 0; + int* filtered_id = (int*)calloc(count, sizeof(int)); + int filtered_count = 0; + int top_priority = VC_COMMAND_PRIORITY_BACKGROUND; + for (i = 0; i < count; i++) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] [%d] Result id(%d)", i, result_id[i]); + + if (0 > result_id[i]) { + SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Result ID(%d) is NOT valid", result_id[i]); + continue; + } + + ret = vcd_client_get_cmd_from_result_id(result_id[i], &temp_cmd); + if (0 == ret && NULL != temp_cmd) { + if (top_priority == temp_cmd->priority) { + filtered_id[filtered_count] = result_id[i]; + filtered_count++; + } else if (top_priority < temp_cmd->priority) { + continue; + } else { + filtered_id[0] = result_id[i]; + filtered_count = 1; + top_priority = temp_cmd->priority; + } + } + } + + int is_action = 0; + for (i = 0; i < filtered_count; i++) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] [%d] Filtered Result id(%d)", i, filtered_id[i]); + + if (filtered_id[i] < 0) { + SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Filtered ID(%d) is NOT valid", filtered_id[i]); + continue; + } + + ret = vcd_client_get_cmd_from_result_id(filtered_id[i], &temp_cmd); + if (0 == ret && NULL != temp_cmd) { + switch (temp_cmd->format) { + case VC_CMD_FORMAT_FIXED: + case VC_CMD_FORMAT_FIXED_AND_VFIXED: + case VC_CMD_FORMAT_VFIXED_AND_FIXED: + case VC_CMD_FORMAT_PARTIAL: + case VC_CMD_FORMAT_FIXED_AND_NONFIXED: + case VC_CMD_FORMAT_NONFIXED_AND_FIXED: + break; + case VC_CMD_FORMAT_ACTION: + is_action = 1; + break; + default: + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Unknown command type : %d", temp_cmd->type); + } + + temp_cmd->id = i; + if (0 != vc_cmd_list_add(vc_cmd_list, (vc_cmd_h)temp_cmd)) { + SLOG(LOG_DEBUG, TAG_VCD, "Fail to add command to list"); + vc_cmd_destroy((vc_cmd_h)temp_cmd); + } + } else { + SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] NOT found matached result(%d)", filtered_id[i]); + } + } + + if (NULL != filtered_id) { + free(filtered_id); + filtered_id = NULL; + } + + if (NULL != nlu_result) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] NLU (%s)", nlu_result); + vc_info_parser_set_nlu_result(nlu_result); + if (0 == is_action) { + vc_cmd_h nlu_cmd; + if (0 != vc_cmd_create(&nlu_cmd)) { + SLOG(LOG_ERROR, TAG_VCD, "Fail to nlu cmd create"); + } else { + if (0 != vc_cmd_set_type(nlu_cmd, VC_COMMAND_TYPE_SYSTEM)) { + SLOG(LOG_ERROR, TAG_VCD, "Fail to set type"); + } + if (0 != vc_cmd_set_pid(nlu_cmd, vcd_client_manager_get_pid())) { + SLOG(LOG_ERROR, TAG_VCD, "Fail to set pid"); + } + if (0 != vc_cmd_set_format(nlu_cmd, VC_CMD_FORMAT_ACTION)) { + SLOG(LOG_ERROR, TAG_VCD, "Fail to set format"); + } + if (0 != vc_cmd_list_add(vc_cmd_list, nlu_cmd)) { + SLOG(LOG_ERROR, TAG_VCD, "Fail to add nlu cmd to list"); + vc_cmd_destroy(nlu_cmd); + } + } + } + } + + vc_cmd_print_list(vc_cmd_list); + + SLOG(LOG_DEBUG, TAG_VCD, "[Server] ========================="); + + int result_count = 0; + vc_cmd_list_get_count(vc_cmd_list, &result_count); + + if (0 == result_count) { + /* No result */ + if (NULL != all_result) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Engine result is no command : %s", all_result); + bool temp = vcd_client_manager_get_exclusive(); + vc_info_parser_set_result(all_result, event, msg, NULL, temp); + } + + int pid = vcd_client_widget_get_foreground_pid(); + if (-1 != pid) { + if (NULL != all_result) { + /* Send result text to widget */ + vcdc_send_result(pid, vcd_client_manager_get_pid(), VC_COMMAND_TYPE_WIDGET); + } + + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide"); + /* Send to hide tooltip */ + vcdc_send_show_tooltip(pid, false); + } + + if (-1 != vcd_client_manager_get_pid()) { + /* Manager client is available */ + if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) { + SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); + } + } + + vcd_client_manager_set_exclusive(false); + + return; + } else { + if (false == vcd_client_manager_get_exclusive()) { + int pid = vcd_client_widget_get_foreground_pid(); + if (-1 != pid) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide"); + vcdc_send_show_tooltip(pid, false); + } + + vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, false); + + if (-1 != vcd_client_manager_get_pid()) { + /* Manager client is available */ + if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) { + SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); + } + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available. Send result to client directly"); + /* Send result to client */ + ecore_timer_add(0, __vcd_send_selected_result, NULL); + } + } else { + /* exclusive command */ + vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, true); + + if (-1 != vcd_client_manager_get_pid()) { + /* Manager client is available */ + if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid(), VC_RESULT_TYPE_NORMAL)) { + SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result"); + } + } else { + SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Manager is NOT available"); + } + + vcd_client_manager_set_exclusive(false); + } + } + vc_cmd_list_destroy(vc_cmd_list, true); + + return; + +#else /* No result */ if (NULL == result_id) { /* No result */ @@ -339,7 +688,7 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int if (-1 != pid) { if (NULL != all_result) { /* Send result text to widget */ - vcdc_send_result(pid, VC_COMMAND_TYPE_WIDGET); + vcdc_send_result(pid, vcd_client_manager_get_pid(), VC_COMMAND_TYPE_WIDGET); } SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide"); @@ -375,7 +724,6 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int } int i = 0; - int priority = 0; for (i = 0; i < count; i++) { SLOG(LOG_DEBUG, TAG_VCD, "[Server] [%d] Result ID(%d)", i, result_id[i]); @@ -386,25 +734,14 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int ret = vcd_client_get_cmd_from_result_id(result_id[i], &temp_cmd); if (0 == ret && NULL != temp_cmd) { - /* Add priority filter */ - int temp_priority = __convert_type_to_priority(temp_cmd->type); - if (priority > temp_priority) { - SLOG(LOG_DEBUG, TAG_VCD, "[Server] Ignore result by priority"); - continue; - } else if (priority < temp_priority) { - SLOG(LOG_DEBUG, TAG_VCD, "[Server] High priority result!!"); - priority = temp_priority; - - if (0 != vc_cmd_list_remove_all(vc_cmd_list, true)) { - SLOG(LOG_ERROR, TAG_VCD, "[Server] Fail to list remove all"); - } - } - switch (temp_cmd->format) { case VC_CMD_FORMAT_FIXED: + case VC_CMD_FORMAT_FIXED_AND_VFIXED: + case VC_CMD_FORMAT_VFIXED_AND_FIXED: + case VC_CMD_FORMAT_PARTIAL: /* Nonfixed result is NOT valid */ break; - case VC_CMD_FORMAT_FIXED_AND_EXTRA: + case VC_CMD_FORMAT_FIXED_AND_NONFIXED: if (NULL == temp_cmd->parameter) { if (NULL != non_fixed_result) { temp_cmd->parameter = strdup(non_fixed_result); @@ -413,7 +750,7 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Command type is NOT vaild. Parameter (%s)", temp_cmd->parameter); } break; - case VC_CMD_FORMAT_EXTRA_AND_FIXED: + case VC_CMD_FORMAT_NONFIXED_AND_FIXED: if (NULL == temp_cmd->command) { if (NULL != non_fixed_result) { temp_cmd->command = strdup(non_fixed_result); @@ -482,6 +819,42 @@ static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int vc_cmd_list_destroy(vc_cmd_list, true); return; +#endif +} + +#if 0 +static void __vcd_server_nlu_result_cb(vcp_result_event_e event, const char* nlu_result, void *user_data) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Server] NLU result cb - event(%d)", event); + SLOG(LOG_DEBUG, TAG_VCD, "[Server] result (%s)", nlu_result); + + int ret = vc_info_parser_set_nlu_result(nlu_result); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set nlu result (%d)", ret); + } + + return; +} +#endif + +static void __vcd_server_error_cb(vcp_error_e error, const char* msg, void *user_data) +{ + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Engine Error cb - reason(%d), msg(%s)", error, msg); + ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL); + + char* error_msg = NULL; + error_msg = strdup(msg); + + if (0 != vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), error, error_msg)) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send error signal"); + } + + if (NULL != error_msg) { + free(error_msg); + error_msg = NULL; + } + + return; } /* @@ -530,14 +903,47 @@ static void __vcd_file_clean_up() return; } +static int __vcd_db_clean_up() +{ + int ret = 0; + int cnt = VC_COMMAND_TYPE_FOREGROUND; + do { + if (VC_COMMAND_TYPE_BACKGROUND != cnt) + ret = vc_db_delete_commands(-1, cnt, NULL); + } while (VC_COMMAND_TYPE_EXCLUSIVE >= ++cnt); + + return ret; +} + +static void __sig_handler(int signo) +{ + /* restore signal handler */ + signal(signo, SIG_DFL); + + /* Send error signal for notifying that daemon is reset*/ + vcdc_send_error_signal(VCD_ERROR_SERVICE_RESET, "Daemon reset"); + + /* invoke signal again */ + raise(signo); +} + +static void __register_sig_handler() +{ + signal(SIGSEGV, __sig_handler); + signal(SIGABRT, __sig_handler); + signal(SIGTERM, __sig_handler); + signal(SIGINT, __sig_handler); + signal(SIGQUIT, __sig_handler); +} + int vcd_initialize() { int ret = 0; + __register_sig_handler(); + /* Remove old file */ __vcd_file_clean_up(); - /* Send error signal for notifying that daemon is reset*/ - vcdc_send_error_signal(VCD_ERROR_SERVICE_RESET, "Daemon reset"); /* initialize modules */ ret = vcd_config_initialize(__config_lang_changed_cb, __config_foreground_changed_cb, NULL); @@ -545,9 +951,16 @@ int vcd_initialize() SLOG(LOG_ERROR, TAG_VCD, "[Server WARNING] Fail to initialize config."); } + /* Remove db data */ + ret = __vcd_db_clean_up(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server WARNING] Fail to remove db data"); + } + vcd_config_set_service_state(VCD_STATE_NONE); - ret = vcd_engine_agent_init(__vcd_server_pre_result_cb, __vcd_server_result_cb); + //ret = vcd_engine_agent_init(__vcd_server_pre_result_cb, __vcd_server_result_cb, __vcd_server_nlu_result_cb, __vcd_server_error_cb); + ret = vcd_engine_agent_init(__vcd_server_asr_result_cb, __vcd_server_result_cb, __vcd_server_error_cb); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret); return ret; @@ -1063,6 +1476,8 @@ static int __start_internal_recognition() stop_by_silence = false; } + vcd_client_manager_set_result_text(NULL); + /* 4. start recognition */ ret = vcd_engine_recognize_start(stop_by_silence); if (0 != ret) { @@ -1222,6 +1637,113 @@ int vcd_server_mgr_result_select() return VCD_ERROR_NONE; } +int vcd_server_mgr_set_domain(int pid, const char* domain) +{ + /* check if pid is valid */ + if (false == vcd_client_manager_is_valid(pid)) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid); + return VCD_ERROR_INVALID_PARAMETER; + } + + vcd_state_e state = vcd_config_get_service_state(); + if (VCD_STATE_READY != state) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready"); + return VCD_ERROR_INVALID_STATE; + } + + /* Set domain to engine */ + int ret = vcd_engine_set_domain(pid, domain); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set domain : %d", ret); + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] Set domain"); + } + + return ret; +} + +int vcd_server_mgr_set_private_data(int pid, const char* key, const char* data) +{ + /* check if pid is valid */ + if (false == vcd_client_manager_is_valid(pid)) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid); + return VCD_ERROR_INVALID_PARAMETER; + } + + vcd_state_e state = vcd_config_get_service_state(); + if (VCD_STATE_READY != state) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready"); + return VCD_ERROR_INVALID_STATE; + } + + /* Set private data to engine */ + int ret = vcd_engine_set_private_data(pid, key, data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set private data : %d", ret); + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] Set private data"); + } + + return ret; +} + +int vcd_server_mgr_get_private_data(int pid, const char* key, char** data) +{ + /* check if pid is valid */ + if (false == vcd_client_manager_is_valid(pid)) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid); + return VCD_ERROR_INVALID_PARAMETER; + } + vcd_state_e state = vcd_config_get_service_state(); + if (VCD_STATE_READY != state) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready"); + return VCD_ERROR_INVALID_STATE; + } + + /* Get private data to engine */ + int ret = vcd_engine_get_private_data(pid, key, data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get private data : %d", ret); + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] Set private data"); + } + + return ret; +} + +int vcd_server_mgr_do_action(int pid, int type, const char* action) +{ + int ret = -1; + + /* check if pid is valid */ + if (false == vcd_client_manager_is_valid(pid)) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid); + return VCD_ERROR_INVALID_PARAMETER; + } + + vcd_state_e state = vcd_config_get_service_state(); + if (VCD_STATE_READY != state) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready"); + return VCD_ERROR_INVALID_STATE; + } + + /* Reqeust do action to engine */ + if (VCD_SEND_EVENT_TYPE_TEXT == type) + ret = vcd_engine_process_text(pid, action); + else if (VCD_SEND_EVENT_TYPE_LIST_EVENT == type) + ret = vcd_engine_process_list_event(pid, action); + else if (VCD_SEND_EVENT_TYPE_HAPTIC_EVENT == type) + ret = vcd_engine_process_haptic_event(pid, action); + + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to process do action : %d", ret); + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] Process do action"); + } + + return ret; +} + /* * VC Server Functions for Client */ @@ -1332,6 +1854,39 @@ int vcd_server_set_foreground(int pid, bool value) return 0; } +int vcd_server_dialog(int pid, const char* disp_text, const char* utt_text, int continuous) +{ + /* check if pid is valid */ + if (false == vcd_client_is_available(pid) && false == vcd_client_widget_is_available(pid)) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid "); + return VCD_ERROR_INVALID_PARAMETER; + } + + if (0 != vcdc_send_dialog(vcd_client_manager_get_pid(), pid, disp_text, utt_text, continuous)) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send dialog : mgr_pid(%d), pid(%d), disp_text(%s), utt_text(%s), continue(%d)", vcd_client_manager_get_pid(), pid, disp_text, utt_text, continuous); + return VCD_ERROR_OPERATION_FAILED; + } + + return 0; +} + +int vcd_server_is_system_command_valid(int pid, int* is_sys_cmd_valid) +{ + /* check if pid is valid */ + if (false == vcd_client_is_available(pid) && false == vcd_client_widget_is_available(pid)) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid "); + return VCD_ERROR_INVALID_PARAMETER; + } + + /* check if system command is valid */ + if (true == vcd_client_manager_is_system_command_valid(vcd_client_manager_get_pid())) + *is_sys_cmd_valid = true; + else + *is_sys_cmd_valid = false; + + return 0; +} + #if 0 int vcd_server_set_exclusive_command(int pid, bool value) { @@ -1523,7 +2078,7 @@ int vcd_server_widget_start_recording(int pid, bool widget_command) SLOG(LOG_DEBUG, TAG_VCD, "[Server] widget command is available"); } else { vcd_client_widget_unset_command(pid); - SLOG(LOG_DEBUG, TAG_VCD, "[Server] widget command is NOT available"); + SLOG(LOG_WARN, TAG_VCD, "[Server] widget command is NOT available"); } int ret = __start_internal_recognition(); diff --git a/server/vcd_server.h b/server/vcd_server.h index fc7217d..5166ccb 100644 --- a/server/vcd_server.h +++ b/server/vcd_server.h @@ -66,6 +66,14 @@ int vcd_server_mgr_cancel(); int vcd_server_mgr_result_select(); +int vcd_server_mgr_set_domain(int pid, const char* domain); + +int vcd_server_mgr_set_private_data(int pid, const char* key, const char* data); + +int vcd_server_mgr_get_private_data(int pid, const char* key, char** data); + +int vcd_server_mgr_do_action(int pid, int type, const char* action); + /* * For client */ @@ -79,6 +87,10 @@ int vcd_server_unset_command(int pid, vc_cmd_type_e cmd_type); int vcd_server_set_foreground(int pid, bool value); +int vcd_server_dialog(int pid, const char* disp_text, const char* utt_text, int continuous); + +int vcd_server_is_system_command_valid(int pid, int* is_sys_cmd_valid); + #if 0 int vcd_server_set_exclusive_command(int pid, bool value); diff --git a/vc-config.xml b/vc-config.xml index 5e222e8..733b8b6 100644 --- a/vc-config.xml +++ b/vc-config.xml @@ -3,5 +3,5 @@ C7AEDE1D-90F7-41ea-9AB4-FD99966D2654 on en_US - off + on -- 2.7.4 From 8740929c2dc1bb7ffabcf43d7ea931dc9cef742f Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Fri, 23 Sep 2016 10:11:23 +0900 Subject: [PATCH 08/16] Type casting for 64 bit build and add internal api Change-Id: I611c103deb6f46ddef086bc8604b4a345d4cf37e Signed-off-by: Wonnam Jang --- common/vc_command.h | 48 ---------------------------------- common/vc_info_parser.c | 2 +- include/voice_control_command_expand.h | 48 ++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/common/vc_command.h b/common/vc_command.h index 2791f01..c010c65 100644 --- a/common/vc_command.h +++ b/common/vc_command.h @@ -98,38 +98,6 @@ int vc_cmd_print_list(vc_cmd_list_h vc_cmd_list); int vc_cmd_list_remove_all(vc_cmd_list_h vc_cmd_list, bool free_command); /** -* @brief Sets pid. -* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif -* -* @param[in] vc_command The command handle -* @param[in] pid Process id -* -* @return 0 on success, otherwise a negative error value -* @retval #VC_CMD_ERROR_NONE Successful -* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter -* -* @see vc_cmd_get_pid() -*/ -int vc_cmd_set_pid(vc_cmd_h vc_command, int pid); - -/** -* @brief Sets command domain -* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif -* -* @param[in] vc_command The command handle -* @param[out] pid Process id -* -* @return 0 on success, otherwise a negative error value -* @retval #VC_CMD_ERROR_NONE Successful -* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VC_CMD_ERROR_PERMISSION_DENIED Permission denied -* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature -* -* @see vc_cmd_set_pid() -*/ -int vc_cmd_get_pid(vc_cmd_h vc_command, int* pid); - -/** * @brief Sets app id. * @since_tizen 3.0 * @@ -194,22 +162,6 @@ int vc_cmd_set_fixed_command(vc_cmd_h vc_command, const char* fixed); int vc_cmd_get_fixed_command(vc_cmd_h vc_command, char** fixed); /** -* @brief Sets unfixed command. -* @since_tizen 3.0 -* -* @param[in] vc_command The command handle -* @param[in] command The unfixed command -* -* @return 0 on success, otherwise a negative error value -* @retval #VC_CMD_ERROR_NONE Successful -* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature -* -* @see vc_cmd_get_unfixed_command() -*/ -int vc_cmd_set_unfixed_command(vc_cmd_h vc_command, const char* command); - -/** * @brief Gets fixed command * @since_tizen 3.0 * diff --git a/common/vc_info_parser.c b/common/vc_info_parser.c index 882779d..83847cf 100644 --- a/common/vc_info_parser.c +++ b/common/vc_info_parser.c @@ -339,7 +339,7 @@ int vc_info_parser_set_nlu_result(const char* nlu_result) } /* Write size */ - fprintf(fp, "size(%d)\n", strlen(nlu_result)); + fprintf(fp, "size(%d)\n", (int)strlen(nlu_result)); write_size = fwrite(nlu_result, 1, strlen(nlu_result), fp); fclose(fp); diff --git a/include/voice_control_command_expand.h b/include/voice_control_command_expand.h index 14539f8..1e9b1b1 100644 --- a/include/voice_control_command_expand.h +++ b/include/voice_control_command_expand.h @@ -135,6 +135,54 @@ int vc_cmd_list_remove_all(vc_cmd_list_h vc_cmd_list, bool free_command); */ int vc_cmd_list_filter_by_type(vc_cmd_list_h original, int type, vc_cmd_list_h* filtered); +/** +* @brief Sets pid. +* @since_tizen 3.0 +* +* @param[in] vc_command The command handle +* @param[in] pid Process id +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_CMD_ERROR_NONE Successful +* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter +* +* @see vc_cmd_get_pid() +*/ +int vc_cmd_set_pid(vc_cmd_h vc_command, int pid); + +/** +* @brief Sets command domain +* @since_tizen 3.0 +* +* @param[in] vc_command The command handle +* @param[out] pid Process id +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_CMD_ERROR_NONE Successful +* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_CMD_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature +* +* @see vc_cmd_set_pid() +*/ +int vc_cmd_get_pid(vc_cmd_h vc_command, int* pid); + +/** +* @brief Sets unfixed command. +* @since_tizen 3.0 +* +* @param[in] vc_command The command handle +* @param[in] command The unfixed command +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_CMD_ERROR_NONE Successful +* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature +* +* @see vc_cmd_get_unfixed_command() +*/ +int vc_cmd_set_unfixed_command(vc_cmd_h vc_command, const char* command); + #ifdef __cplusplus } #endif -- 2.7.4 From 8ef3a6e9de6368b5909acefde1ece56421684138 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Mon, 26 Sep 2016 21:36:15 +0900 Subject: [PATCH 09/16] Update dialog and api Change-Id: Iae4c6190c631a78e5ea75aaa8c3d546155b99476 Signed-off-by: Wonnam Jang --- client/vc.c | 6 ++-- client/vc_mgr.c | 2 +- common/vc_cmd_db.c | 29 ++++++++++++---- common/vc_cmd_db.h | 6 ++++ common/vc_json_parser.c | 54 +++++++++++++++++++++++++++-- include/voice_control.h | 2 +- include/voice_control_command.h | 14 -------- include/voice_control_command_expand.h | 16 +++++++++ server/vcd_client_data.c | 34 +++++++++++++++++-- server/vcd_client_data.h | 5 +++ server/vcd_server.c | 62 ++++++++++++++++++++++++++++++++-- 11 files changed, 199 insertions(+), 31 deletions(-) diff --git a/client/vc.c b/client/vc.c index 327db61..e6b4de9 100644 --- a/client/vc.c +++ b/client/vc.c @@ -2035,7 +2035,7 @@ int vc_set_invocation_name(const char* name) return ret; } -int vc_dialog(const char* disp_text, const char* utt_text, bool continuous) +int vc_dialog(const char* disp_text, const char* utt_text, bool auto_start) { vc_state_e state; @@ -2072,8 +2072,8 @@ int vc_dialog(const char* disp_text, const char* utt_text, bool continuous) return VC_ERROR_INVALID_STATE; } - SLOG(LOG_DEBUG, TAG_VCC, "Request dialog : pid(%d) disp_text(%s), utt_text(%s), continuous(%d)", getpid(), disp_text, utt_text, continuous); - int ret = vc_dbus_request_dialog(getpid(), disp_text, utt_text, continuous); + SLOG(LOG_DEBUG, TAG_VCC, "Request dialog : pid(%d) disp_text(%s), utt_text(%s), auto_start(%d)", getpid(), disp_text, utt_text, auto_start); + int ret = vc_dbus_request_dialog(getpid(), disp_text, utt_text, auto_start); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set foreground (true) : %d", ret); return VC_ERROR_OPERATION_FAILED; diff --git a/client/vc_mgr.c b/client/vc_mgr.c index f7aed98..603e112 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -2508,7 +2508,7 @@ int __vc_mgr_cb_dialog(int pid, const char* disp_text, const char* utt_text, boo vc_mgr_client_use_callback(g_vc_m); callback(pid, disp_text, utt_text, continuous, user_data); vc_mgr_client_not_use_callback(g_vc_m); - SLOG(LOG_DEBUG, TAG_VCM, "Error callback is called"); + SLOG(LOG_DEBUG, TAG_VCM, "Dialog callback is called"); } else { SLOG(LOG_WARN, TAG_VCM, "[WARNING] Error callback is null"); } diff --git a/common/vc_cmd_db.c b/common/vc_cmd_db.c index 3b627df..0168129 100644 --- a/common/vc_cmd_db.c +++ b/common/vc_cmd_db.c @@ -1167,6 +1167,24 @@ int vc_db_delete_table(const char* table) return VC_DB_ERROR_NONE; } +int vc_db_begin_transaction(void) +{ + int ret = __vc_db_begin_transaction(); + return ret; +} + +int vc_db_rollback_transaction(void) +{ + int ret = __vc_db_rollback_transaction(); + return ret; +} + +int vc_db_commit_transaction(void) +{ + int ret = __vc_db_commit_transaction(); + return ret; +} + static void __vc_db_remove_space(char** string) { if (NULL == string || NULL == *string) @@ -1310,8 +1328,6 @@ int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd) return ret; } - __vc_db_begin_transaction(); - if (0 != g_slist_length(cmd_list)) { GSList *iter = NULL; char* temp_command = NULL; @@ -1333,7 +1349,6 @@ int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd) int ret = __vc_db_insert_commands(pid, type, cmd); if (ret != VC_DB_ERROR_NONE) { - __vc_db_rollback_transaction(); if (NULL != fixed_cmd) { free(fixed_cmd); fixed_cmd = NULL; @@ -1351,7 +1366,6 @@ int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd) ret = __vc_db_insert_commands(pid, type, cmd); if (ret != VC_DB_ERROR_NONE) { - __vc_db_rollback_transaction(); if (NULL != fixed_cmd) { free(fixed_cmd); fixed_cmd = NULL; @@ -1370,8 +1384,6 @@ int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd) cmd_list = NULL; } - __vc_db_commit_transaction(); - if (NULL != fixed_cmd) { free(fixed_cmd); fixed_cmd = NULL; @@ -1390,6 +1402,8 @@ int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, ch SLOG(LOG_DEBUG, vc_db_tag(), "list count : %d", count); + __vc_db_begin_transaction(); + for (i = 0; i < count; i++) { if (NULL == iter) break; @@ -1408,6 +1422,7 @@ int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, ch int ret = vc_db_insert_command(pid, type, temp_cmd); if (ret != VC_DB_ERROR_NONE) { SLOG(LOG_ERROR, vc_db_tag(), "Fail to insert command, ret(%d)", ret); + __vc_db_rollback_transaction(); return ret; } } else { @@ -1416,6 +1431,8 @@ int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, ch iter = g_slist_next(iter); } + __vc_db_commit_transaction(); + return VC_DB_ERROR_NONE; } diff --git a/common/vc_cmd_db.h b/common/vc_cmd_db.h index c8133e7..c0028b6 100644 --- a/common/vc_cmd_db.h +++ b/common/vc_cmd_db.h @@ -55,6 +55,12 @@ int vc_db_create_table(void); int vc_db_delete_table(const char* table); +int vc_db_begin_transaction(void); + +int vc_db_rollback_transaction(void); + +int vc_db_commit_transaction(void); + int vc_db_insert_command(int pid, vc_cmd_type_e type, vc_cmd_s* cmd); int vc_db_insert_commands_list(int pid, vc_cmd_type_e type, GSList* cmd_list, char* invocation_name); diff --git a/common/vc_json_parser.c b/common/vc_json_parser.c index f49d6d6..6d50d51 100644 --- a/common/vc_json_parser.c +++ b/common/vc_json_parser.c @@ -128,6 +128,12 @@ static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocati } } + ret = vc_db_begin_transaction(); + if (0 != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to begin transaction for db"); + return ret; + } + for (i = 0; i < array_size; i++) { int temp = 0; const char* temp_text = NULL; @@ -139,6 +145,11 @@ static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocati free(prev_appid); temp_type = NULL; prev_appid = NULL; + ret = vc_db_rollback_transaction(); + if (0 != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to begin transaction for db"); + return ret; + } return VC_ERROR_OUT_OF_MEMORY; } @@ -152,6 +163,11 @@ static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocati temp_type = NULL; prev_appid = NULL; cmd = NULL; + ret = vc_db_rollback_transaction(); + if (0 != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to begin transaction for db"); + return ret; + } return VC_ERROR_OPERATION_FAILED; } @@ -173,6 +189,11 @@ static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocati temp_type = NULL; prev_appid = NULL; cmd = NULL; + ret = vc_db_rollback_transaction(); + if (0 != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to begin transaction for db"); + return ret; + } return VC_ERROR_OUT_OF_MEMORY; } @@ -206,7 +227,11 @@ static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocati prev_appid = NULL; free(cmd); cmd = NULL; - + ret = vc_db_rollback_transaction(); + if (0 != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to begin transaction for db"); + return ret; + } return VC_ERROR_OUT_OF_MEMORY; } } else { @@ -239,6 +264,11 @@ static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocati free(cmd); cmd = NULL; + ret = vc_db_rollback_transaction(); + if (0 != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to begin transaction for db"); + return ret; + } return VC_ERROR_OUT_OF_MEMORY; } @@ -260,6 +290,11 @@ static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocati free(cmd); cmd = NULL; + ret = vc_db_rollback_transaction(); + if (0 != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to begin transaction for db"); + return ret; + } return ret; } @@ -279,7 +314,11 @@ static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocati free(cmd); cmd = NULL; - + ret = vc_db_rollback_transaction(); + if (0 != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to begin transaction for db"); + return ret; + } return VC_ERROR_OUT_OF_MEMORY; } } @@ -300,6 +339,11 @@ static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocati prev_appid = NULL; free(cmd); cmd = NULL; + ret = vc_db_rollback_transaction(); + if (0 != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to begin transaction for db"); + return ret; + } return ret; } SLOG(LOG_WARN, vc_json_tag(), "[INFO] pid(%d), type(%d), format(%d), domain(%d), cmd(%s), appid(%s)", cmd->pid, type, cmd->format, cmd->domain, cmd->command, cmd->appid); @@ -319,6 +363,12 @@ static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocati cmd = NULL; } + ret = vc_db_commit_transaction(); + if (0 != ret) { + SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to commit transaction for db"); + return ret; + } + free(temp_type); free(prev_appid); temp_type = NULL; diff --git a/include/voice_control.h b/include/voice_control.h index ef6cf50..205a39a 100644 --- a/include/voice_control.h +++ b/include/voice_control.h @@ -312,7 +312,7 @@ int vc_set_invocation_name(const char* name); * * @pre The service state should be #VC_SERVICE_STATE_READY. */ -int vc_dialog(const char* disp_text, const char* utt_text, bool continuous); +int vc_dialog(const char* disp_text, const char* utt_text, bool auto_start); /** * @brief Sets command list. diff --git a/include/voice_control_command.h b/include/voice_control_command.h index 188675d..f913caa 100644 --- a/include/voice_control_command.h +++ b/include/voice_control_command.h @@ -459,20 +459,6 @@ int vc_cmd_set_format(vc_cmd_h vc_command, vc_cmd_format_e format); */ int vc_cmd_get_format(vc_cmd_h vc_command, vc_cmd_format_e* format); -/** -* @brief Gets nlu json data. -* @since_tizen 3.0 -* -* @param[in] vc_command The command handle -* @param[out] json The nlu json data -* -* @return 0 on success, otherwise a negative error value -* @retval #VC_ERROR_NONE Successful -* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VC_ERROR_NOT_SUPPORTED Not supported feature -* -*/ -int vc_cmd_get_nlu_json(vc_cmd_h vc_cmd, char** json); #ifdef __cplusplus } diff --git a/include/voice_control_command_expand.h b/include/voice_control_command_expand.h index 1e9b1b1..8bd196c 100644 --- a/include/voice_control_command_expand.h +++ b/include/voice_control_command_expand.h @@ -183,6 +183,22 @@ int vc_cmd_get_pid(vc_cmd_h vc_command, int* pid); */ int vc_cmd_set_unfixed_command(vc_cmd_h vc_command, const char* command); +/** +* @brief Gets nlu json data. +* @since_tizen 3.0 +* +* @param[in] vc_command The command handle +* @param[out] json The nlu json data +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_NOT_SUPPORTED Not supported feature +* +*/ +int vc_cmd_get_nlu_json(vc_cmd_h vc_cmd, char** json); + + #ifdef __cplusplus } #endif diff --git a/server/vcd_client_data.c b/server/vcd_client_data.c index d307a13..70f3749 100644 --- a/server/vcd_client_data.c +++ b/server/vcd_client_data.c @@ -14,8 +14,9 @@ * limitations under the License. */ - +#include #include + #include "vcd_client_data.h" #include "vcd_config.h" #include "vcd_main.h" @@ -46,14 +47,26 @@ vc_client_info_s* __client_get_element(int pid); int vcd_client_manager_set(int pid) { - if (-1 != g_manager.pid) { + if (-1 != g_manager.pid && NULL != g_manager.appid) { SLOG(LOG_DEBUG, TAG_VCD, "Manager has already registered"); return -1; } g_manager.pid = pid; g_manager.manager_cmd = false; g_manager.exclusive_cmd_option = false; + g_manager.appid = NULL; + + // Get appid by pid using app control + char* appid = NULL; + int ret = app_manager_get_app_id(pid, &appid); + if (0 != ret || NULL == appid) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] fail to get app id, ret(%d), pid(%d)", ret, pid); + return -1; + } + g_manager.appid = strdup(appid); + free(appid); + appid = NULL; return 0; } @@ -66,6 +79,15 @@ int vcd_client_manager_unset() return 0; } +int vcd_client_manager_unset_appid() +{ + if (NULL != g_manager.appid) { + free(g_manager.appid); + g_manager.appid = NULL; + } + return 0; +} + bool vcd_client_manager_is_valid(int pid) { if (-1 == g_manager.pid || pid == g_manager.pid) { @@ -197,6 +219,14 @@ int vcd_client_manager_get_pid() return g_manager.pid; } +int vcd_client_manager_get_appid(char** appid) +{ + if (NULL != g_manager.appid) + *appid = strdup(g_manager.appid); + + return 0; +} + int vcd_client_manager_set_result_text(const char* result) { if (NULL != g_result_text) { diff --git a/server/vcd_client_data.h b/server/vcd_client_data.h index 6985a1f..62f3120 100644 --- a/server/vcd_client_data.h +++ b/server/vcd_client_data.h @@ -54,6 +54,7 @@ typedef struct { typedef struct { int pid; + char* appid; bool manager_cmd; bool exclusive_cmd_option; } manager_info_s; @@ -101,6 +102,8 @@ int vcd_client_manager_set(int pid); int vcd_client_manager_unset(); +int vcd_client_manager_unset_appid(); + bool vcd_client_manager_is_valid(int pid); int vcd_client_manager_set_command(int pid); @@ -117,6 +120,8 @@ int vcd_client_manager_set_exclusive(bool value); int vcd_client_manager_get_pid(); +int vcd_client_manager_get_appid(char** appid); + int vcd_client_manager_set_result_text(const char* result); char* vcd_client_manager_get_result_text(); diff --git a/server/vcd_server.c b/server/vcd_server.c index 95b81f1..843b587 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -1036,6 +1036,8 @@ void vcd_finalize() SLOG(LOG_DEBUG, TAG_VCD, "[Server] release engine"); } + vcd_client_manager_unset_appid(); + vcd_config_set_service_state(VCD_STATE_NONE); vcdc_send_service_state(VCD_STATE_NONE); @@ -1854,6 +1856,55 @@ int vcd_server_set_foreground(int pid, bool value) return 0; } +static int __vcd_server_launch_manager_app() +{ + int ret = -1; + bool running = false; + char* appid = NULL; + + ret = vcd_client_manager_get_appid(&appid); + if (0 != ret || NULL == appid) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to get manager appid"); + return VCD_ERROR_OPERATION_FAILED; + } + ret = app_manager_is_running(appid, &running); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to check running with appid(%s)", appid); + free(appid); + appid = NULL; + return VCD_ERROR_OPERATION_FAILED; + } + if (false == running) { + int tmp_ret = __vcd_is_package_installed(appid); + if (false == tmp_ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] manager app is not installed, appid(%s)", appid); + } else { + ret = __vcd_activate_app_by_appcontrol(appid); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to activate app"); + free(appid); + appid = NULL; + return ret; + } + SLOG(LOG_ERROR, TAG_VCD, "Launch vc manager app: appid(%s)", appid); + } + } else { + ret = __vcd_resume_app(appid); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to resume app"); + free(appid); + appid = NULL; + return ret; + } + SLOG(LOG_ERROR, TAG_VCD, "Resume vc manager app: appid(%s)", appid); + } + + free(appid); + appid = NULL; + + return VCD_ERROR_NONE; +} + int vcd_server_dialog(int pid, const char* disp_text, const char* utt_text, int continuous) { /* check if pid is valid */ @@ -1862,9 +1913,16 @@ int vcd_server_dialog(int pid, const char* disp_text, const char* utt_text, int return VCD_ERROR_INVALID_PARAMETER; } - if (0 != vcdc_send_dialog(vcd_client_manager_get_pid(), pid, disp_text, utt_text, continuous)) { + int ret = __vcd_server_launch_manager_app(); + if (0 != ret){ SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send dialog : mgr_pid(%d), pid(%d), disp_text(%s), utt_text(%s), continue(%d)", vcd_client_manager_get_pid(), pid, disp_text, utt_text, continuous); - return VCD_ERROR_OPERATION_FAILED; + return ret; + } + + ret = vcdc_send_dialog(vcd_client_manager_get_pid(), pid, disp_text, utt_text, continuous); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send dialog : mgr_pid(%d), pid(%d), disp_text(%s), utt_text(%s), continue(%d)", vcd_client_manager_get_pid(), pid, disp_text, utt_text, continuous); + return ret; } return 0; -- 2.7.4 From b4a01fc7783a1f5f58c56508b3d315c5316bec92 Mon Sep 17 00:00:00 2001 From: "stom.hwang" Date: Fri, 23 Sep 2016 17:43:47 +0900 Subject: [PATCH 10/16] Add API that gets the timestamp data from the sentence Change-Id: Ie89ca887c005df4295ef53a035e0f915f9fd98f6 Signed-off-by: stom.hwang --- common/vc_command.c | 916 ++++++++++++++++++++++++++++++++- common/vc_regex_rule.h | 57 ++ include/voice_control_command_expand.h | 21 + 3 files changed, 991 insertions(+), 3 deletions(-) mode change 100644 => 100755 common/vc_command.c create mode 100755 common/vc_regex_rule.h mode change 100644 => 100755 include/voice_control_command_expand.h diff --git a/common/vc_command.c b/common/vc_command.c old mode 100644 new mode 100755 index e728fb5..61053a9 --- a/common/vc_command.c +++ b/common/vc_command.c @@ -14,6 +14,8 @@ * limitations under the License. */ +#define _GNU_SOURCE + #include #include #include @@ -24,6 +26,8 @@ #include "vc_command.h" #include "vc_info_parser.h" #include "vc_main.h" +#include "vc_regex_rule.h" +#include "vc_config_mgr.h" #include "voice_control_command.h" #include "voice_control_command_expand.h" #include "voice_control_common.h" @@ -34,6 +38,17 @@ static int g_feature_enabled = -1; static int g_privilege_allowed = 1; /* Always True */ static cynara *p_cynara = NULL; +// For getting timestamp using regular expression +static regex_t reg[MAX_NUM_REGEX]; +static time_t t_now; //time_t is based on UTC +static struct tm *td_now; //if use localtime function, the value follows the local time zone, otherwise it follows the UTC. + +static int g_time_flag; +static int g_date_flag; + +static int g_data_sidx; +static int g_data_eidx; + static int __vc_cmd_get_feature_enabled() { if (0 == g_feature_enabled) { @@ -1341,7 +1356,7 @@ int vc_cmd_get_nlu_json(vc_cmd_h vc_cmd, char** json) } if (NULL == vc_cmd || NULL == json) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] NULL parameter"); + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] NULL parameter"); return VC_ERROR_INVALID_PARAMETER; } @@ -1349,14 +1364,909 @@ int vc_cmd_get_nlu_json(vc_cmd_h vc_cmd, char** json) cmd = (vc_cmd_s*)vc_cmd; if (VC_CMD_FORMAT_ACTION != cmd->format) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Not Action format"); + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not Action format"); return VC_ERROR_INVALID_PARAMETER; } if (0 != vc_info_parser_get_nlu_result(json)) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get nlu result"); + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get nlu result"); return VC_ERROR_OPERATION_FAILED; } return 0; } + +static void __vc_cmd_regex_deinit(int num_regex) +{ + SLOG(LOG_DEBUG, TAG_VCCMD, "==== Start Deinitialize regex ===="); + int i; + + for (i = 0; i < num_regex; i++) { + regfree(®[i]); + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "===="); + SLOG(LOG_DEBUG, TAG_VCCMD, ""); +} + +static int __vc_cmd_regex_init() +{ + SLOG(LOG_DEBUG, TAG_VCCMD, "==== Initialize regular expression ===="); + + int cflags = REG_EXTENDED | REG_ICASE; + int ret; + char errStr[128]; + char *lang = NULL; + int lang_type = 1; + + vc_config_mgr_get_default_language(&lang); + if (NULL == lang) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language"); + return VC_ERROR_OPERATION_FAILED; + } + + if (!strcmp("en_US", lang)) { + lang_type = 1; + } else if (!strcmp("ko_KR", lang)) { + lang_type = 0; + } else { + free(lang); + lang = NULL; + + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not supported language type"); + return VC_ERROR_INVALID_LANGUAGE; + } + + free(lang); + lang = NULL; + + SLOG(LOG_DEBUG, TAG_VCCMD, "==== lang type > %d ====", lang_type); + + re_syntax_options = RE_SYNTAX_POSIX_EXTENDED; + + SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s" , TIME_ABS1_REGEX[lang_type]); + ret = regcomp(®[0], TIME_ABS1_REGEX[lang_type], cflags); + if (0 != ret) { + regerror(ret, ®[0], errStr, sizeof(errStr)); + + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_ABS2_REGEX[lang_type]); + ret = regcomp(®[1], TIME_ABS2_REGEX[lang_type], cflags); + if (0 != ret) { + regerror(ret, ®[1], errStr, sizeof(errStr)); + __vc_cmd_regex_deinit(1); + + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_ABS3_REGEX[lang_type]); + ret = regcomp(®[2], TIME_ABS3_REGEX[lang_type], cflags); + if (0 != ret) { + regerror(ret, ®[2], errStr, sizeof(errStr)); + __vc_cmd_regex_deinit(2); + + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL1_REGEX[lang_type]); + ret = regcomp(®[3], TIME_REL1_REGEX[lang_type], cflags); + if (0 != ret) { + regerror(ret, ®[3], errStr, sizeof(errStr)); + __vc_cmd_regex_deinit(3); + + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL2_REGEX[lang_type]); + ret = regcomp(®[4], TIME_REL2_REGEX[lang_type], cflags); + if (0 != ret) { + regerror(ret, ®[4], errStr, sizeof(errStr)); + __vc_cmd_regex_deinit(4); + + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_REL3_REGEX[lang_type]); + ret = regcomp(®[5], TIME_REL3_REGEX[lang_type], cflags); + if (0 != ret) { + regerror(ret, ®[5], errStr, sizeof(errStr)); + __vc_cmd_regex_deinit(5); + + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", TIME_PHR_REGEX[lang_type]); + ret = regcomp(®[6], TIME_PHR_REGEX[lang_type], cflags); + if (0 != ret) { + regerror(ret, ®[6], errStr, sizeof(errStr)); + __vc_cmd_regex_deinit(6); + + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS1_REGEX[lang_type]); + ret = regcomp(®[7], DATE_ABS1_REGEX[lang_type], cflags); + if (0 != ret) { + regerror(ret, ®[7], errStr, sizeof(errStr)); + __vc_cmd_regex_deinit(7); + + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS2_REGEX[lang_type]); + ret = regcomp(®[8], DATE_ABS2_REGEX[lang_type], cflags); + if (0 != ret) { + regerror(ret, ®[8], errStr, sizeof(errStr)); + __vc_cmd_regex_deinit(8); + + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_ABS3_REGEX[lang_type]); + ret = regcomp(®[9], DATE_ABS3_REGEX[lang_type], cflags); + if (0 != ret) { + regerror(ret, ®[9], errStr, sizeof(errStr)); + __vc_cmd_regex_deinit(9); + + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_PHR1_REGEX[lang_type]); + ret = regcomp(®[10], DATE_PHR1_REGEX[lang_type], cflags); + if (0 != ret) { + regerror(ret, ®[10], errStr, sizeof(errStr)); + __vc_cmd_regex_deinit(10); + + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "Regular expression > %s", DATE_PHR2_REGEX[lang_type]); + ret = regcomp(®[11], DATE_PHR2_REGEX[lang_type], cflags); + if (0 != ret) { + regerror(ret, ®[11], errStr, sizeof(errStr)); + __vc_cmd_regex_deinit(11); + + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] regcomp() error > %s", errStr); + return VC_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "===="); + SLOG(LOG_DEBUG, TAG_VCCMD, ""); + + return VC_ERROR_NONE; +} + +static void __vc_cmd_add_year(struct tm *td, int year) +{ + td->tm_year += year; +} + +static void __vc_cmd_add_mon(struct tm *td, int mon) +{ + int year = 0; + + mon = td->tm_mon + mon; + year = mon / 12; + + if (0 < year) { + __vc_cmd_add_year(td, year); + } + + td->tm_mon = mon % 12; +} + +static void __vc_cmd_add_mday(struct tm *td, int mday) +{ + int max_day[12] = {31, 28, 31, 30, 31, 30, 31, 30, 30, 31, 30, 31}; + int year = td->tm_year + 1900; + + int mon = 0; + + if ((0 == year % 4 && 0 != year % 100) || 0 == year % 400) max_day[1] = 29; + + mday = td->tm_mday + mday; + + for (mon = td->tm_mon; mday >= max_day[mon % 12]; mon++) { + mday -= max_day[mon % 12]; + + if (mon % 12 == 11) { + year++; + + if ((0 == year % 4 && 0 != year % 100) || 0 == year % 400) { + max_day[1] = 29; + } else { + max_day[1] = 28; + } + } + } + + mon = mon - td->tm_mon; + + if (0 < mon) { + __vc_cmd_add_mon(td, mon); + } + + td->tm_mday = mday; +} + +static void __vc_cmd_add_hour(struct tm *td, int hour) +{ + int day = 0; + + hour = td->tm_hour + hour; + day = hour / 24; + + if (0 < day) { + __vc_cmd_add_mday(td, day); + } + + td->tm_hour = hour % 24; +} + +static void __vc_cmd_add_min(struct tm *td, int min) +{ + int hour = 0; + + min = td->tm_min + min; + hour = min / 60; + + if (0 < hour) { + __vc_cmd_add_hour(td, hour); + } + + td->tm_min = min % 60; +} + +static void __copy_struct_tm(struct tm *des, struct tm *src) +{ + SLOG(LOG_DEBUG, TAG_VCCMD, "==== Start to copy struct tm ===="); + + des->tm_sec = src->tm_sec; + des->tm_min = src->tm_min; + des->tm_hour = src->tm_hour; + des->tm_mday = src->tm_mday; + des->tm_mon = src->tm_mon; + des->tm_year = src->tm_year; + des->tm_wday = src->tm_wday; + des->tm_yday = src->tm_yday; + des->tm_isdst = src->tm_isdst; + + des->tm_gmtoff = src->tm_gmtoff; + des->tm_zone = src->tm_zone; +} + +static void __update_data_sidx(int idx) +{ + if (g_data_sidx < 0 || g_data_sidx > idx) g_data_sidx = idx; +} + +static void __update_data_eidx(int idx) +{ + if (g_data_eidx < 0 || g_data_eidx < idx) g_data_eidx = idx; +} + +static int __vc_cmd_tphrase_check(const char *str, struct tm *td, int *exist) +{ + regmatch_t pmatch[3]; + int ret; + int len; + int idx; + + *exist = 0; + ret = regexec(®[6], str, 3, pmatch, 0); + if (0 == ret) { + idx = 1; + len = pmatch[idx].rm_eo - pmatch[idx].rm_so; + if (0 < len) { + if (12 < td->tm_hour) { + __vc_cmd_add_mday(td, 1); + } + + td->tm_hour = 12; + } else { + idx = 2; + len = pmatch[idx].rm_eo - pmatch[idx].rm_so; + + __vc_cmd_add_mday(td, 1); + } + + td->tm_min = 0; + td->tm_sec = 0; + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[idx].rm_so); + + __update_data_sidx(pmatch[0].rm_so); + __update_data_eidx(pmatch[0].rm_eo); + + *exist = 1; + return VC_ERROR_NONE; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string"); + return VC_ERROR_NONE; +} + +static int __vc_cmd_trelative_check(const char *str, struct tm *td, int *exist) +{ + regmatch_t pmatch[2]; + int ret; + int len; + int sidx = -1; + int eidx = -1; + int hour = -1; + int min = -1; + + char *tempstr = NULL; + + *exist = 0; + ret = regexec(®[3], str, 1, pmatch, 0); + if (0 == ret) { + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[0].rm_eo - pmatch[0].rm_so, str+pmatch[0].rm_so); + hour = min = -1; + + if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; + if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + + ret = regexec(®[4], str, 2, pmatch, 0); + if (0 == ret) { + len = pmatch[1].rm_eo - pmatch[1].rm_so; + tempstr = strndup(str + pmatch[1].rm_so, len); + + if (NULL == tempstr) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed"); + return VC_ERROR_OUT_OF_MEMORY; + } + + hour = atoi(tempstr); + + free(tempstr); + tempstr = NULL; + + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[1].rm_so); + + if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; + if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + } + + ret = regexec(®[5], str, 2, pmatch, 0); + if (0 == ret) { + len = pmatch[1].rm_eo - pmatch[1].rm_so; + tempstr = strndup(str + pmatch[1].rm_so, len); + + if (NULL == tempstr) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed"); + return VC_ERROR_OUT_OF_MEMORY; + } + + min = atoi(tempstr); + + free(tempstr); + tempstr = NULL; + + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[1].rm_so); + + if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; + if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + } + + if (hour < 0 && min < 0) { + SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string"); + return VC_ERROR_NONE; + } + + hour = hour < 0 ? 0 : hour; + min = min < 0 ? 0 : min; + + min = min + (hour * 60); + + __vc_cmd_add_min(td, min); + td->tm_sec = 0; + + __update_data_sidx(sidx); + __update_data_eidx(eidx); + + *exist = 1; + return VC_ERROR_NONE; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string"); + return VC_ERROR_NONE; +} + +static int __vc_cmd_tabsolute_check(const char *str, struct tm *td, int *exist) +{ + regmatch_t pmatch[5]; + int ret; + int len; + int idx; + int flag = -1; + int hour = -1; + int min = -1; + int sidx = -1; + int eidx = -1; + char *tempstr = NULL; + + *exist = 0; + ret = regexec(®[0], str, 5, pmatch, 0); + if (0 == ret) { + for (idx = 1; idx < 5 && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++); + + flag = idx & 1; + + if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; + if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + } + + ret = regexec(®[1], str, 2, pmatch, 0); + if (0 == ret) { + len = pmatch[1].rm_eo - pmatch[1].rm_so; + tempstr = strndup(str + pmatch[1].rm_so, len); + + if (NULL == tempstr) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed"); + return VC_ERROR_OUT_OF_MEMORY; + } + + hour = atoi(tempstr); + + if (0 <= flag) { + hour = hour + 12 * flag; + + if (12 == hour) hour = 0; + else if(24 == hour) hour = 12; + } + + if (0 > hour || 24 <= hour || (0 == flag && 12 < hour)) { + SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird"); + return VC_ERROR_NONE; + } + + free(tempstr); + tempstr = NULL; + + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[1].rm_so); + + if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; + if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + } else if (0 < flag) { + SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird"); + return VC_ERROR_NONE; + } + + ret = regexec(®[2], str, 2, pmatch, 0); + if (0 == ret) { + idx = 1; + len = pmatch[idx].rm_eo - pmatch[idx].rm_so; + if (0 < len) { + tempstr = strndup(str + pmatch[idx].rm_so, len); + + if (NULL == tempstr) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed"); + return VC_ERROR_OUT_OF_MEMORY; + } + + min = atoi(tempstr); + + if (0 > min || 60 <= min) { + SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird"); + return VC_ERROR_NONE; + } + + td->tm_sec = 0; + + free(tempstr); + tempstr = NULL; + } else { + idx = 0; + min = 30; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[idx].rm_eo - pmatch[idx].rm_so, str + pmatch[idx].rm_so); + if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; + if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + } + + if (hour < 0 && min < 0) { + SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string"); + return VC_ERROR_NONE; + } + + if (min >= 0 && hour >= 0) { + if (hour < td->tm_hour || (hour == td->tm_hour && min <= td->tm_min)) __vc_cmd_add_mday(td, 1); + + td->tm_hour = hour; + td->tm_min = min; + } else if (min >= 0) { + char *lang = NULL; + vc_config_mgr_get_default_language(&lang); + if (NULL == lang) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language"); + return VC_ERROR_OPERATION_FAILED; + } + + if (!strcmp("en_US", lang)) { + SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird"); + free(lang); + lang = NULL; + return VC_ERROR_NONE; + } + if (min <= td->tm_min) __vc_cmd_add_hour(td, 1); + + td->tm_min = min; + + free(lang); + lang = NULL; + } else { + if (hour <= td->tm_hour) __vc_cmd_add_mday(td, 1); + + td->tm_hour = hour; + td->tm_min = 0; + } + + td->tm_sec = 0; + + __update_data_sidx(sidx); + __update_data_eidx(eidx); + + *exist = 1; + return VC_ERROR_NONE; +} + +static int __vc_cmd_dphrase_check(const char *str, struct tm *td, int *exist) +{ + regmatch_t pmatch[9]; + int ret; + int len; + int idx; + + *exist = 0; + ret = regexec(®[10], str, 5, pmatch, 0); + if (0 == ret) { + for (idx = 1; idx < 5 && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++); + + len = pmatch[idx].rm_eo - pmatch[idx].rm_so; + + td->tm_year = td_now->tm_year; + td->tm_mon = td_now->tm_mon; + td->tm_mday = td_now->tm_mday; + + __vc_cmd_add_mday(td, idx - 1); + + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[idx].rm_so); + + __update_data_sidx(pmatch[0].rm_so); + __update_data_eidx(pmatch[0].rm_eo); + + *exist = 1; + return VC_ERROR_NONE; + } + + ret = regexec(®[11], str, 9, pmatch, 0); + if (0 == ret) { + for (idx = 1; idx < 9; idx++) { + len = pmatch[idx].rm_eo - pmatch[idx].rm_so; + + if (0 < len) break; + } + + td->tm_year = td_now->tm_year; + td->tm_mon = td_now->tm_mon; + td->tm_mday = td_now->tm_mday; + + __vc_cmd_add_mday(td, idx + 1); + + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[idx].rm_so); + + __update_data_sidx(pmatch[0].rm_so); + __update_data_eidx(pmatch[0].rm_eo); + + *exist = 1; + return VC_ERROR_NONE; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string"); + return VC_ERROR_NONE; +} + +static int __vc_cmd_dabsolute_check(const char *str, struct tm *td, int *exist) +{ + regmatch_t pmatch[13]; + int ret; + int len; + int idx; + int sidx = -1; + int eidx = -1; + int y_flag = 0; + int m_flag = 0; + int year = -1; + int mon = -1; + int day = -1; + char *tempstr = NULL; + + *exist = 0; + ret = regexec(®[9], str, 2, pmatch, 0); + if (0 == ret) { + len = pmatch[1].rm_eo - pmatch[1].rm_so; + tempstr = strndup(str + pmatch[1].rm_so, len); + + if (NULL == tempstr) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed"); + return VC_ERROR_OUT_OF_MEMORY; + } + + day = atoi(tempstr); + + free(tempstr); + tempstr = NULL; + + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[1].rm_so); + + if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; + if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + } else { + SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird"); + return VC_ERROR_NONE; + } + + ret = regexec(®[8], str, 13, pmatch, 0); + if (0 == ret) { + for (idx = 1; idx < 13; idx++) { + len = pmatch[idx].rm_eo - pmatch[idx].rm_so; + + if (0 < len) { + mon = idx - 1; + break; + } + } + + m_flag = 1; + + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[idx].rm_so); + + if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; + if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + } else { + char *lang = NULL; + vc_config_mgr_get_default_language(&lang); + if (NULL == lang) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Fail to get current language"); + return VC_ERROR_OPERATION_FAILED; + } + + if (!strcmp("en_US", lang)) { + SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird"); + free(lang); + lang = NULL; + return VC_ERROR_NONE; + } + + free(lang); + lang = NULL; + + mon = td->tm_mon; + } + + ret = regexec(®[7], str, 3, pmatch, 0); + if (0 == ret) { + if (!m_flag) return -1; + + len = pmatch[2].rm_eo - pmatch[2].rm_so; + tempstr = strndup(str + pmatch[2].rm_so, len); + + if (NULL == tempstr) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Memory allocation is failed"); + return VC_ERROR_OUT_OF_MEMORY; + } + + year = atoi(tempstr); + year = year > 1900 ? year - 1900 : year + 100; + + free(tempstr); + tempstr = NULL; + + y_flag = 1; + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[2].rm_so); + + if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; + if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + } else { + year = td->tm_year; + } + + if (g_time_flag < 0) { + td->tm_hour = 0; + td->tm_min = 0; + td->tm_sec = 0; + } else if (g_time_flag == 2) { + SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird"); + return VC_ERROR_NONE; + } + + int max_day[12] = {31, 28, 31, 30, 31, 30, 31, 30, 30, 31, 30, 31}; + if ((0 == (year + 1900) % 4 && 0 != (year + 1900) % 100) || 0 == (year + 1900) % 400) max_day[1] = 29; + + if (max_day[mon] < day || 1 > day) { + SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird"); + return VC_ERROR_NONE; + } + + td->tm_year = year; + td->tm_mon = mon; + td->tm_mday = day; + + if (!y_flag) { + if (!m_flag) { + if (day < td_now->tm_mday) __vc_cmd_add_mon(td, 1); + } else { + if (mon < td_now->tm_mon) __vc_cmd_add_year(td, 1); + else if (mon == td_now->tm_mon && day < td_now->tm_mday) __vc_cmd_add_year(td, 1); + } + } + + __update_data_sidx(sidx); + __update_data_eidx(eidx); + + *exist = 1; + return VC_ERROR_NONE; +} + +static int __vc_cmd_time_check(const char *str, struct tm *td) +{ + SLOG(LOG_DEBUG, TAG_VCCMD, "==== Check time value in string \"%s\"", str); + + vc_error_e ret; + int exist = 0; + + ret = __vc_cmd_tphrase_check(str, td, &exist); + if (1 == exist) { + g_time_flag = 1; + + SLOG(LOG_DEBUG, TAG_VCCMD, "==== Time value is exist"); + return ret; + } else if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret); + return ret; + } + + ret = __vc_cmd_trelative_check(str, td, &exist); + if (1 == exist) { + g_time_flag = 2; + + SLOG(LOG_DEBUG, TAG_VCCMD, "==== Time value is exist"); + return ret; + } else if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret); + return ret; + } + + ret = __vc_cmd_tabsolute_check(str, td, &exist); + if (1 == exist) { + g_time_flag = 3; + + SLOG(LOG_DEBUG, TAG_VCCMD, "==== Time value is exist"); + return ret; + } else if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret); + return ret; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "==== There is no time value"); + return VC_ERROR_NONE; +} + +static int __vc_cmd_date_check(const char *str, struct tm *td) +{ + SLOG(LOG_DEBUG, TAG_VCCMD, "==== Check date value in string \"%s\"", str); + + vc_error_e ret; + int exist = 0; + + ret = __vc_cmd_dphrase_check(str, td, &exist); + if (1 == exist) { + g_date_flag = 1; + + SLOG(LOG_DEBUG, TAG_VCCMD, "==== Date value is exist"); + return ret; + } else if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret); + return ret; + } + + ret = __vc_cmd_dabsolute_check(str, td, &exist); + if (1 == exist) { + g_date_flag = 1; + + SLOG(LOG_DEBUG, TAG_VCCMD, "==== Date value is exist"); + return ret; + } else if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured > (%d)", ret); + return ret; + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "==== There is no date value"); + return VC_ERROR_NONE; +} + +int vc_cmd_get_datetime(const char *text, time_t *result, char **remain) +{ + SLOG(LOG_DEBUG, TAG_VCCMD, "==== Get timestamp data"); + + struct tm td; + const char *day_name[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + vc_error_e ret; + + *result = -1; + if (NULL == text || NULL == result || NULL == remain) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter"); + return VC_ERROR_INVALID_PARAMETER; + } + + ret = __vc_cmd_regex_init(); + if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] initialize regex failed"); + return ret; + } + + g_data_sidx = g_data_eidx = -1; + + t_now = time(NULL); + td_now = localtime(&t_now); + SLOG(LOG_DEBUG, TAG_VCCMD, "Current timestamp = %d", (int)t_now); + + __copy_struct_tm(&td, td_now); + SLOG(LOG_DEBUG, TAG_VCCMD, "%d-%d-%d (%s), %d:%d:%d", + td.tm_year + 1900, td.tm_mon + 1, td.tm_mday, day_name[td.tm_wday], td.tm_hour, td.tm_min, td.tm_sec); + + g_time_flag = g_date_flag = -1; + + ret = __vc_cmd_time_check(text, &td); + if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured in the check > (%d)", ret); + return ret; + } + + ret = __vc_cmd_date_check(text, &td); + if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Error is occured in the check > (%d)", ret); + return ret; + } + + __vc_cmd_regex_deinit(12); + + if (g_time_flag > 0 || g_date_flag > 0) { + *result = mktime(&td); + + SLOG(LOG_DEBUG, TAG_VCCMD, "Timestamp in the text = %d", *result); + SLOG(LOG_DEBUG, TAG_VCCMD, "%d-%d-%d (%s), %d:%d:%d", + td.tm_year + 1900, td.tm_mon + 1, td.tm_mday, day_name[td.tm_wday], td.tm_hour, td.tm_min, td.tm_sec, td.tm_yday); + + *remain = (char *)calloc(sizeof(char), (strlen(text) + 1 - g_data_eidx + g_data_sidx)); + + if (NULL == *remain) { + SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Out of memory error"); + return VC_ERROR_OUT_OF_MEMORY; + } + + strncpy(*remain, text, g_data_sidx); + strncat(*remain, text + g_data_eidx, strlen(text) - g_data_eidx); + } else { + SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no data in the text"); + } + + SLOG(LOG_DEBUG, TAG_VCCMD, "===="); + SLOG(LOG_DEBUG, TAG_VCCMD, ""); + + return VC_ERROR_NONE; +} \ No newline at end of file diff --git a/common/vc_regex_rule.h b/common/vc_regex_rule.h new file mode 100755 index 0000000..973cbe4 --- /dev/null +++ b/common/vc_regex_rule.h @@ -0,0 +1,57 @@ +#ifndef __VC_REGEX_RULE_H +#define __VC_REGEX_RULE_H + +#define MAX_NUM_REGEX 12 + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +//at noon / at midnight +const char *TIME_PHR_REGEX[2] = {"(정오)|(자정)", + "( at noon)|( at midnight)"}; +//morning / afternoon +const char *TIME_ABS1_REGEX[2] = {"(오후)|(오전)|(저녁)|(아침)", + "([0-9] p.?m.?)|([0-9] a.?m.?)|( afternoon)|( morning)"}; +//hh:mm / :mm / hh o'clock / pm / am +const char *TIME_ABS2_REGEX[2] = {"([1-9]|1[0-9]|2[0-4])시", + " at ([1-9]|1[0-9]|2[0-4])( o'clock|:| pm| p.m.| am| a.m.|$)"}; +const char *TIME_ABS3_REGEX[2] = {"([1-9]|[1-5][0-9])분|반", + ":([0-5][0-9])"}; +//hh hour(s) mm minute(s) (after / later) / hh hour(s) (after / later) / mm minute(s) (after / later) +const char *TIME_REL1_REGEX[2] = {"(시간|분).*[^오](뒤|후|있다가)", + " after([^a-zA-Z]|$)| later([^a-zA-Z]|$)| in [0-9]+ (minute|hour)"}; +const char *TIME_REL2_REGEX[2] = {"([1-9][0-9]*)시간", + "([1-9][0-9]*) hours?"}; +const char *TIME_REL3_REGEX[2] = {"([1-9][0-9]*)분", + "([1-9][0-9]*) minutes?"}; + +//day month, year / day month / day +const char *DATE_ABS1_REGEX[2] = {"(([1-2][0-9]{3})년)", + "(st|nd|rd|th),? ([1-2][0-9]{3})"}; +const char *DATE_ABS2_REGEX[2] = {"(1월)|(2월)|(3월)|(4월)|(5월)|(6월)|(7월)|(8월)|(9월)|(10월)|(11월)|(12월)", + "(January)|(February)|(March)|(April)|(May)|(June)|(July)|(August)|(September)|(October)|(November)|(December)"}; +const char *DATE_ABS3_REGEX[2] = {"([1-9]|[1-2][0-9]|3[0-1])일", + "([1-9]|[1-2][0-9]|3[0-1])(st|nd|rd|th)"}; +//today / tommorow / the day after tommorow +const char *DATE_PHR1_REGEX[2] = {"(오늘)|(내일)|(모레)|(글피)", + "(today)|(tommorow)|(the day after tommorow)"}; +const char *DATE_PHR2_REGEX[2] = {"(이틀)|(사흘)|(나흘)|(닷새)|(엿새)|(이레)|(여드레)|(아흐레)|(열흘)", + "(이틀)|(사흘)|(나흘)|(닷새)|(엿새)|(이레)|(여드레)|(아흐레)|(열흘)"}; + +//Monday / Tuesday / Wednesday / Thursday / Satruday / Sunday +const char *DATE_PHR3_REGEX[2] = {"(월|화|수|목|금|토|일)(요일)?", + "(Mon|Tues|Wednes|Thurs|Fri|Satur|Sun)(day)?"}; + + +#ifdef __cplusplus +} +#endif + + +#endif \ No newline at end of file diff --git a/include/voice_control_command_expand.h b/include/voice_control_command_expand.h old mode 100644 new mode 100755 index 8bd196c..695641f --- a/include/voice_control_command_expand.h +++ b/include/voice_control_command_expand.h @@ -198,6 +198,27 @@ int vc_cmd_set_unfixed_command(vc_cmd_h vc_command, const char* command); */ int vc_cmd_get_nlu_json(vc_cmd_h vc_cmd, char** json); +/** +* @brief Gets the datetime value from the setence. +* @since_tizen 3.0 +* +* @param[in] text The sentence to analyze +* @param[out] result The datetime value in the sentence +* @param[out] remain Remained text except time +* +* @remark If the function succeeds, @a remain must be released with free() by you when you no longer need it. +* If there is no time value in @a text or the function does not work correctly, +* @a result is -1. Otherwise @a result has the time value in @a text. +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_CMD_ERROR_NONE Successful +* @retval #VC_ERROR_OPERATION_FAILED operation failure +* @retval #VC_ERROR_OUT_OF_MEMORY Not enough memory +* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter +* +* @see vc_cmd_set_datetime_lang() +*/ +int vc_cmd_get_datetime(const char *text, time_t *result, char **remain); #ifdef __cplusplus } -- 2.7.4 From f29a13694361eeedb03814ec4a6023dfb4de99a0 Mon Sep 17 00:00:00 2001 From: "stom.hwang" Date: Wed, 28 Sep 2016 10:11:25 +0900 Subject: [PATCH 11/16] Fix svace issue Change-Id: I2ffefe51b038297695eb547e4e70a9e4e1a79b7b Signed-off-by: stom.hwang --- common/vc_cmd_db.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) mode change 100644 => 100755 common/vc_cmd_db.c diff --git a/common/vc_cmd_db.c b/common/vc_cmd_db.c old mode 100644 new mode 100755 index 0168129..240928a --- a/common/vc_cmd_db.c +++ b/common/vc_cmd_db.c @@ -1249,12 +1249,13 @@ static int __vc_db_generate_command(vc_cmd_s* cmd, char** fixed_cmd, GSList** cm temp_close[0] = '\0'; // extract fixed command and remove space in front of '{' - temp = strtok(src_cmd, "{"); + char *tok_ptr = NULL; + temp = strtok_r(src_cmd, "{", &tok_ptr); __vc_db_remove_space(&temp); *fixed_cmd = strdup(temp); // merge command with fixed and vfixed - while (NULL != (temp = strtok(NULL, "|"))) { + while (NULL != (temp = strtok_r(NULL, "|", &tok_ptr))) { __vc_db_remove_space(&temp); snprintf(merge_cmd, 256, "%s %s", *fixed_cmd, temp); @@ -1277,12 +1278,14 @@ static int __vc_db_generate_command(vc_cmd_s* cmd, char** fixed_cmd, GSList** cm *fixed_cmd = strdup(temp_fixed); // remove close brace, '}' - temp = strtok(src_cmd, "}"); + char *tok_ptr = NULL; + temp = strtok_r(src_cmd, "}", &tok_ptr); // remove open brace, '{' temp = strchr(src_cmd, '{') + 1; - temp = strtok(temp, "|"); + tok_ptr = NULL; + temp = strtok_r(temp, "|", &tok_ptr); __vc_db_remove_space(&temp); // merge command with fixed and vfixed @@ -1291,7 +1294,7 @@ static int __vc_db_generate_command(vc_cmd_s* cmd, char** fixed_cmd, GSList** cm temp_list = g_slist_append(temp_list, dst_cmd); SLOG(LOG_ERROR, vc_db_tag(), "New generated cmd: %s", dst_cmd); - while (NULL != (temp = strtok(NULL, "|"))) { + while (NULL != (temp = strtok_r(NULL, "|", &tok_ptr))) { __vc_db_remove_space(&temp); // merge command with fixed and vfixed @@ -1299,7 +1302,7 @@ static int __vc_db_generate_command(vc_cmd_s* cmd, char** fixed_cmd, GSList** cm dst_cmd = strdup(merge_cmd); temp_list = g_slist_append(temp_list, dst_cmd); SLOG(LOG_ERROR, vc_db_tag(), "New generated cmd: %s", dst_cmd); - } + } } else if (VC_CMD_FORMAT_FIXED_AND_NONFIXED == cmd->format || VC_CMD_FORMAT_NONFIXED_AND_FIXED == cmd->format) { dst_cmd = strdup(src_cmd); temp_list = g_slist_append(temp_list, dst_cmd); -- 2.7.4 From 2fa3aefcbaf8bb49a433f2b8b840aed4c430b2a8 Mon Sep 17 00:00:00 2001 From: "stom.hwang" Date: Thu, 29 Sep 2016 13:30:13 +0900 Subject: [PATCH 12/16] Fix svace issue & typo Change-Id: I6627dd2bd5dbbfefba55a4eb6656097e995a5560 Signed-off-by: stom.hwang --- common/vc_command.c | 124 ++++++++++++++++++++++++------------------------ common/vc_json_parser.c | 9 ++-- 2 files changed, 67 insertions(+), 66 deletions(-) mode change 100644 => 100755 common/vc_json_parser.c diff --git a/common/vc_command.c b/common/vc_command.c index 61053a9..3252b90 100755 --- a/common/vc_command.c +++ b/common/vc_command.c @@ -41,7 +41,7 @@ static cynara *p_cynara = NULL; // For getting timestamp using regular expression static regex_t reg[MAX_NUM_REGEX]; static time_t t_now; //time_t is based on UTC -static struct tm *td_now; //if use localtime function, the value follows the local time zone, otherwise it follows the UTC. +static struct tm td_now; //if use localtime function, the value follows the local time zone, otherwise it follows the UTC. static int g_time_flag; static int g_date_flag; @@ -1381,7 +1381,7 @@ static void __vc_cmd_regex_deinit(int num_regex) SLOG(LOG_DEBUG, TAG_VCCMD, "==== Start Deinitialize regex ===="); int i; - for (i = 0; i < num_regex; i++) { + for (i = 0; num_regex > i; i++) { regfree(®[i]); } @@ -1582,7 +1582,7 @@ static void __vc_cmd_add_mday(struct tm *td, int mday) for (mon = td->tm_mon; mday >= max_day[mon % 12]; mon++) { mday -= max_day[mon % 12]; - if (mon % 12 == 11) { + if (11 == mon % 12) { year++; if ((0 == year % 4 && 0 != year % 100) || 0 == year % 400) { @@ -1650,12 +1650,12 @@ static void __copy_struct_tm(struct tm *des, struct tm *src) static void __update_data_sidx(int idx) { - if (g_data_sidx < 0 || g_data_sidx > idx) g_data_sidx = idx; + if (0 > g_data_sidx || idx < g_data_sidx) g_data_sidx = idx; } static void __update_data_eidx(int idx) { - if (g_data_eidx < 0 || g_data_eidx < idx) g_data_eidx = idx; + if (0 > g_data_eidx || idx > g_data_eidx) g_data_eidx = idx; } static int __vc_cmd_tphrase_check(const char *str, struct tm *td, int *exist) @@ -1685,7 +1685,7 @@ static int __vc_cmd_tphrase_check(const char *str, struct tm *td, int *exist) td->tm_min = 0; td->tm_sec = 0; - SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[idx].rm_so); + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so); __update_data_sidx(pmatch[0].rm_so); __update_data_eidx(pmatch[0].rm_eo); @@ -1716,8 +1716,8 @@ static int __vc_cmd_trelative_check(const char *str, struct tm *td, int *exist) SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[0].rm_eo - pmatch[0].rm_so, str+pmatch[0].rm_so); hour = min = -1; - if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; - if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + sidx = pmatch[0].rm_so; + eidx = pmatch[0].rm_eo; ret = regexec(®[4], str, 2, pmatch, 0); if (0 == ret) { @@ -1734,10 +1734,10 @@ static int __vc_cmd_trelative_check(const char *str, struct tm *td, int *exist) free(tempstr); tempstr = NULL; - SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[1].rm_so); + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so); - if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; - if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + if (pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so; + if (pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo; } ret = regexec(®[5], str, 2, pmatch, 0); @@ -1755,10 +1755,10 @@ static int __vc_cmd_trelative_check(const char *str, struct tm *td, int *exist) free(tempstr); tempstr = NULL; - SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[1].rm_so); + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so); - if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; - if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + if (pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so; + if (pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo; } if (hour < 0 && min < 0) { @@ -1766,8 +1766,8 @@ static int __vc_cmd_trelative_check(const char *str, struct tm *td, int *exist) return VC_ERROR_NONE; } - hour = hour < 0 ? 0 : hour; - min = min < 0 ? 0 : min; + hour = 0 > hour ? 0 : hour; + min = 0 > min ? 0 : min; min = min + (hour * 60); @@ -1801,12 +1801,12 @@ static int __vc_cmd_tabsolute_check(const char *str, struct tm *td, int *exist) *exist = 0; ret = regexec(®[0], str, 5, pmatch, 0); if (0 == ret) { - for (idx = 1; idx < 5 && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++); + for (idx = 1; 5 > idx && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++); flag = idx & 1; - if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; - if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + sidx = pmatch[0].rm_so; + eidx = pmatch[0].rm_eo; } ret = regexec(®[1], str, 2, pmatch, 0); @@ -1836,10 +1836,10 @@ static int __vc_cmd_tabsolute_check(const char *str, struct tm *td, int *exist) free(tempstr); tempstr = NULL; - SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[1].rm_so); + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so); - if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; - if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so; + if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo; } else if (0 < flag) { SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird"); return VC_ERROR_NONE; @@ -1873,22 +1873,22 @@ static int __vc_cmd_tabsolute_check(const char *str, struct tm *td, int *exist) min = 30; } - SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[idx].rm_eo - pmatch[idx].rm_so, str + pmatch[idx].rm_so); - if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; - if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", pmatch[0].rm_eo - pmatch[0].rm_so, str + pmatch[0].rm_so); + if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so; + if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo; } - if (hour < 0 && min < 0) { + if (0 > hour && 0 > min) { SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] There is no matched string"); return VC_ERROR_NONE; } - if (min >= 0 && hour >= 0) { + if (0 <= min && 0 <= hour) { if (hour < td->tm_hour || (hour == td->tm_hour && min <= td->tm_min)) __vc_cmd_add_mday(td, 1); td->tm_hour = hour; td->tm_min = min; - } else if (min >= 0) { + } else if (0 <= min) { char *lang = NULL; vc_config_mgr_get_default_language(&lang); if (NULL == lang) { @@ -1926,7 +1926,7 @@ static int __vc_cmd_tabsolute_check(const char *str, struct tm *td, int *exist) static int __vc_cmd_dphrase_check(const char *str, struct tm *td, int *exist) { - regmatch_t pmatch[9]; + regmatch_t pmatch[10]; int ret; int len; int idx; @@ -1934,17 +1934,17 @@ static int __vc_cmd_dphrase_check(const char *str, struct tm *td, int *exist) *exist = 0; ret = regexec(®[10], str, 5, pmatch, 0); if (0 == ret) { - for (idx = 1; idx < 5 && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++); + for (idx = 1; 5 > idx && 0 >= pmatch[idx].rm_eo - pmatch[idx].rm_so; idx++); len = pmatch[idx].rm_eo - pmatch[idx].rm_so; - td->tm_year = td_now->tm_year; - td->tm_mon = td_now->tm_mon; - td->tm_mday = td_now->tm_mday; + td->tm_year = td_now.tm_year; + td->tm_mon = td_now.tm_mon; + td->tm_mday = td_now.tm_mday; __vc_cmd_add_mday(td, idx - 1); - SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[idx].rm_so); + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so); __update_data_sidx(pmatch[0].rm_so); __update_data_eidx(pmatch[0].rm_eo); @@ -1953,21 +1953,21 @@ static int __vc_cmd_dphrase_check(const char *str, struct tm *td, int *exist) return VC_ERROR_NONE; } - ret = regexec(®[11], str, 9, pmatch, 0); + ret = regexec(®[11], str, 10, pmatch, 0); if (0 == ret) { - for (idx = 1; idx < 9; idx++) { + for (idx = 1; 10 > idx; idx++) { len = pmatch[idx].rm_eo - pmatch[idx].rm_so; if (0 < len) break; } - td->tm_year = td_now->tm_year; - td->tm_mon = td_now->tm_mon; - td->tm_mday = td_now->tm_mday; + td->tm_year = td_now.tm_year; + td->tm_mon = td_now.tm_mon; + td->tm_mday = td_now.tm_mday; __vc_cmd_add_mday(td, idx + 1); - SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[idx].rm_so); + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so); __update_data_sidx(pmatch[0].rm_so); __update_data_eidx(pmatch[0].rm_eo); @@ -1990,9 +1990,9 @@ static int __vc_cmd_dabsolute_check(const char *str, struct tm *td, int *exist) int eidx = -1; int y_flag = 0; int m_flag = 0; - int year = -1; - int mon = -1; - int day = -1; + int year = 0; + int mon = 0; + int day = 0; char *tempstr = NULL; *exist = 0; @@ -2011,10 +2011,10 @@ static int __vc_cmd_dabsolute_check(const char *str, struct tm *td, int *exist) free(tempstr); tempstr = NULL; - SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[1].rm_so); + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so); - if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; - if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + sidx = pmatch[0].rm_so; + eidx = pmatch[0].rm_eo; } else { SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird"); return VC_ERROR_NONE; @@ -2022,7 +2022,7 @@ static int __vc_cmd_dabsolute_check(const char *str, struct tm *td, int *exist) ret = regexec(®[8], str, 13, pmatch, 0); if (0 == ret) { - for (idx = 1; idx < 13; idx++) { + for (idx = 1; 13 > idx; idx++) { len = pmatch[idx].rm_eo - pmatch[idx].rm_so; if (0 < len) { @@ -2033,10 +2033,10 @@ static int __vc_cmd_dabsolute_check(const char *str, struct tm *td, int *exist) m_flag = 1; - SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[idx].rm_so); + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so); - if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; - if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so; + if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo; } else { char *lang = NULL; vc_config_mgr_get_default_language(&lang); @@ -2071,25 +2071,25 @@ static int __vc_cmd_dabsolute_check(const char *str, struct tm *td, int *exist) } year = atoi(tempstr); - year = year > 1900 ? year - 1900 : year + 100; + year = 1900 < year ? year - 1900 : year + 100; free(tempstr); tempstr = NULL; y_flag = 1; - SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[2].rm_so); + SLOG(LOG_DEBUG, TAG_VCCMD, "Matched string > %.*s", len, str + pmatch[0].rm_so); - if (sidx < 0 || sidx > pmatch[0].rm_so) sidx = pmatch[0].rm_so; - if (eidx < 0 || eidx < pmatch[0].rm_eo) eidx = pmatch[0].rm_eo; + if (0 > sidx || pmatch[0].rm_so < sidx) sidx = pmatch[0].rm_so; + if (0 > eidx || pmatch[0].rm_eo > eidx) eidx = pmatch[0].rm_eo; } else { year = td->tm_year; } - if (g_time_flag < 0) { + if (0 > g_time_flag) { td->tm_hour = 0; td->tm_min = 0; td->tm_sec = 0; - } else if (g_time_flag == 2) { + } else if (2 == g_time_flag) { SLOG(LOG_DEBUG, TAG_VCCMD, "[REGEX] Incomming sentence is weird"); return VC_ERROR_NONE; } @@ -2108,10 +2108,10 @@ static int __vc_cmd_dabsolute_check(const char *str, struct tm *td, int *exist) if (!y_flag) { if (!m_flag) { - if (day < td_now->tm_mday) __vc_cmd_add_mon(td, 1); + if (day < td_now.tm_mday) __vc_cmd_add_mon(td, 1); } else { - if (mon < td_now->tm_mon) __vc_cmd_add_year(td, 1); - else if (mon == td_now->tm_mon && day < td_now->tm_mday) __vc_cmd_add_year(td, 1); + if (mon < td_now.tm_mon) __vc_cmd_add_year(td, 1); + else if (mon == td_now.tm_mon && day < td_now.tm_mday) __vc_cmd_add_year(td, 1); } } @@ -2207,12 +2207,12 @@ int vc_cmd_get_datetime(const char *text, time_t *result, char **remain) const char *day_name[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; vc_error_e ret; - *result = -1; if (NULL == text || NULL == result || NULL == remain) { SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter"); return VC_ERROR_INVALID_PARAMETER; } + *result = -1; ret = __vc_cmd_regex_init(); if (VC_ERROR_NONE != ret) { SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] initialize regex failed"); @@ -2222,10 +2222,10 @@ int vc_cmd_get_datetime(const char *text, time_t *result, char **remain) g_data_sidx = g_data_eidx = -1; t_now = time(NULL); - td_now = localtime(&t_now); + localtime_r(&t_now, &td_now); SLOG(LOG_DEBUG, TAG_VCCMD, "Current timestamp = %d", (int)t_now); - __copy_struct_tm(&td, td_now); + __copy_struct_tm(&td, &td_now); SLOG(LOG_DEBUG, TAG_VCCMD, "%d-%d-%d (%s), %d:%d:%d", td.tm_year + 1900, td.tm_mon + 1, td.tm_mday, day_name[td.tm_wday], td.tm_hour, td.tm_min, td.tm_sec); diff --git a/common/vc_json_parser.c b/common/vc_json_parser.c old mode 100644 new mode 100755 index 6d50d51..4c99231 --- a/common/vc_json_parser.c +++ b/common/vc_json_parser.c @@ -363,16 +363,17 @@ static int __vc_json_set_commands(JsonObject *root_obj, int type, char* invocati cmd = NULL; } + free(temp_type); + free(prev_appid); + temp_type = NULL; + prev_appid = NULL; + ret = vc_db_commit_transaction(); if (0 != ret) { SLOG(LOG_ERROR, vc_json_tag(), "[ERROR] Fail to commit transaction for db"); return ret; } - free(temp_type); - free(prev_appid); - temp_type = NULL; - prev_appid = NULL; return VC_ERROR_NONE; } -- 2.7.4 From aca9db44d7920db763fe552444849cd4c8b99c8f Mon Sep 17 00:00:00 2001 From: Kwangyoun Kim Date: Wed, 5 Oct 2016 16:10:39 +0900 Subject: [PATCH 13/16] Add get error message and apply sound stream Change-Id: I0e1161c997444fe66656ed2fc4f84ecabfb5e893 --- client/vc_mgr.c | 31 ++++++++++++++++++ client/vc_mgr_client.c | 41 ++++++++++++++++++++++++ client/vc_mgr_client.h | 4 +++ include/voice_control_manager.h | 18 +++++++++++ server/vcd_recorder.c | 70 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 164 insertions(+) diff --git a/client/vc_mgr.c b/client/vc_mgr.c index 603e112..0469551 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -47,6 +47,8 @@ static int g_daemon_pid = 0; static int g_feature_enabled = -1; +static bool g_err_callback_status = false; + static Eina_Bool __vc_mgr_notify_state_changed(void *data); static Eina_Bool __vc_mgr_notify_error(void *data); static Eina_Bool __vc_mgr_notify_result(void *data); @@ -2176,6 +2178,32 @@ int vc_mgr_unset_pre_result_cb() return 0; } +int vc_mgr_get_error_message(char** err_msg) +{ + SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Get error message"); + + if (NULL == err_msg) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] invalid parameter"); + return VC_ERROR_INVALID_PARAMETER; + } + + if (false == g_err_callback_status) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Not in error callback"); + return VC_ERROR_OPERATION_FAILED; + } + + int ret; + ret = vc_mgr_client_get_error_message(g_vc_m, err_msg); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get error message"); + } + + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + + return ret; +} + static Eina_Bool __vc_mgr_notify_error(void *data) { vc_h vc_m = (vc_h)data; @@ -2189,7 +2217,9 @@ static Eina_Bool __vc_mgr_notify_error(void *data) if (NULL != callback) { vc_mgr_client_use_callback(vc_m); + g_err_callback_status = true; callback(reason, user_data); + g_err_callback_status = false; vc_mgr_client_not_use_callback(vc_m); SLOG(LOG_DEBUG, TAG_VCM, "Error callback is called"); } else { @@ -2227,6 +2257,7 @@ int __vc_mgr_cb_error(int reason, int daemon_pid, char* msg) SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Error reason(%d), msg(%s)", reason, msg); vc_mgr_client_set_error(g_vc_m, reason); + vc_mgr_client_set_error_message(g_vc_m, msg); __vc_mgr_notify_error(g_vc_m); return 0; diff --git a/client/vc_mgr_client.c b/client/vc_mgr_client.c index 90d5b9e..4f01521 100644 --- a/client/vc_mgr_client.c +++ b/client/vc_mgr_client.c @@ -77,6 +77,7 @@ typedef struct { /* error data */ int reason; + char* err_msg; /* Authorized */ GSList* authorized_client_list; @@ -184,6 +185,7 @@ int vc_mgr_client_create(vc_h* vc) client->recognition_mode = VC_RECOGNITION_MODE_STOP_BY_SILENCE; client->reason = 0; + client->err_msg = NULL; client->cb_ref_count = 0; @@ -232,6 +234,10 @@ int vc_mgr_client_destroy(vc_h vc) free(data->all_result_text); } + if (NULL != data->err_msg) { + free(data->err_msg); + } + free(data); free(vc); @@ -685,6 +691,41 @@ int vc_mgr_client_get_error(vc_h vc, int* reason) return 0; } +int vc_mgr_client_set_error_message(vc_h vc, const char* err_msg) +{ + vc_mgr_client_s* client = __mgr_client_get(vc); + + /* check handle */ + if (NULL == client) + return VC_ERROR_INVALID_PARAMETER; + + if (NULL != client->err_msg) { + free(client->err_msg); + client->err_msg = NULL; + } + + if (NULL != err_msg) { + client->err_msg = strdup(err_msg); + } + + return 0; +} + +int vc_mgr_client_get_error_message(vc_h vc, char** err_msg) +{ + vc_mgr_client_s* client = __mgr_client_get(vc); + + /* check handle */ + if (NULL == client) + return VC_ERROR_INVALID_PARAMETER; + + if (NULL != client->err_msg) { + *err_msg = strdup(client->err_msg); + } + + return 0; +} + int vc_mgr_client_set_exclusive_command(vc_h vc, bool value) { vc_mgr_client_s* client = __mgr_client_get(vc); diff --git a/client/vc_mgr_client.h b/client/vc_mgr_client.h index 15cd295..51088c5 100644 --- a/client/vc_mgr_client.h +++ b/client/vc_mgr_client.h @@ -99,6 +99,10 @@ int vc_mgr_client_set_error(vc_h vc, int reason); int vc_mgr_client_get_error(vc_h vc, int* reason); +int vc_mgr_client_set_error_message(vc_h vc, const char* err_msg); + +int vc_mgr_client_get_error_message(vc_h vc, char** err_msg); + int vc_mgr_client_set_exclusive_command(vc_h vc, bool value); bool vc_mgr_client_get_exclusive_command(vc_h vc); diff --git a/include/voice_control_manager.h b/include/voice_control_manager.h index bdef272..abcd864 100644 --- a/include/voice_control_manager.h +++ b/include/voice_control_manager.h @@ -902,6 +902,24 @@ int vc_mgr_set_current_language_changed_cb(vc_current_language_changed_cb callba int vc_mgr_unset_current_language_changed_cb(); /** +* @brief Gets the current error message. +* +* @remarks This function should be called during as stt error callback. If not, the error as operation failure will be returned. \n +* If the function succeeds, @a err_msg must be released using free() when it is no longer required. +* +* @param[out] err_msg The current error message +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_INVALID_STATE Invalid state +* @retval $VC_ERROR_OPERATION_FAILED Operation failure +* +* @see vc_error_cb() +*/ +int vc_mgr_get_error_message(char** err_msg); + +/** * @brief Registers a callback function to be called when an error occurred. * * @param[in] callback Callback function to register diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index 764a7a4..bcda93e 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -50,6 +50,8 @@ static vcd_recorder_interrupt_cb g_interrupt_cb = NULL; static audio_in_h g_audio_h; +static sound_stream_info_h g_stream_info_h; + static vcp_audio_type_e g_audio_type; static unsigned int g_audio_rate; @@ -192,6 +194,51 @@ static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void #endif +static const char* __get_focus_changed_reason_code(sound_stream_focus_change_reason_e reason) +{ + switch (reason) { + case SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA: return "SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA"; + case SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM: return "SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM"; + case SOUND_STREAM_FOCUS_CHANGED_BY_ALARM: return "SOUND_STREAM_FOCUS_CHANGED_BY_ALARM"; + case SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION: return "SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION"; + case SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY: return "SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY"; + case SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION: return "SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION"; + case SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_RECOGNITION: return "SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_RECOGNITION"; + case SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE: return "SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE"; + case SOUND_STREAM_FOCUS_CHANGED_BY_VOIP: return "SOUND_STREAM_FOCUS_CHANGED_BY_VOIP"; + case SOUND_STREAM_FOCUS_CHANGED_BY_CALL: return "SOUND_STREAM_FOCUS_CHANGED_BY_CALL"; + case SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY: return "SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY"; + default: return "Undefined reason code"; + } +} + +static void __recorder_focus_state_cb(sound_stream_info_h stream_info, sound_stream_focus_change_reason_e reason, const char *extra_info, void *user_data) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Focus state changed cb"); + + if (stream_info != g_stream_info_h) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid stream info handle"); + return; + } + + int ret; + sound_stream_focus_state_e state_for_recording; + ret = sound_manager_get_focus_state(g_stream_info_h, NULL, &state_for_recording); + if (SOUND_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to get focus state"); + return; + } + + SLOG(LOG_WARN, TAG_VCD, "[Recorder] focus state chagned to (%d) with reason (%s)", (int)state_for_recording, __get_focus_changed_reason_code(reason)); + + if (VCD_RECORDER_STATE_RECORDING == g_recorder_state && SOUND_STREAM_FOCUS_STATE_RELEASED == state_for_recording) { + SLOG(LOG_WARN, TAG_VCD, "[Recorder] Focus released as interrupt"); + if (NULL != g_interrupt_cb) { + g_interrupt_cb(); + } + } +} + int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb interrupt_cb) { if (NULL == audio_cb || NULL == interrupt_cb) { @@ -240,6 +287,10 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb g_is_valid_audio_in = false; } + if (0 != sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_RECOGNITION, __recorder_focus_state_cb, NULL, &g_stream_info_h)) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create stream info"); + } + g_audio_cb = audio_cb; g_interrupt_cb = interrupt_cb; g_recorder_state = VCD_RECORDER_STATE_READY; @@ -298,6 +349,10 @@ int vcd_recorder_destroy() g_recorder_state = VCD_RECORDER_STATE_READY; } + if (0 != sound_manager_destroy_stream_information(g_stream_info_h)) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to destroy stream info"); + } + audio_in_destroy(g_audio_h); #ifdef TV_BT_MODE @@ -568,6 +623,16 @@ int vcd_recorder_start() SLOG(LOG_ERROR, TAG_VCD, "[Recorder] started = %d", started); if (false == started) { + ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL); + if (SOUND_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to acquire focus : %d", ret); + } else { + ret = audio_in_set_stream_info(g_audio_h, g_stream_info_h); + if (AUDIO_IO_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info : %d", ret); + } + } + ret = audio_in_prepare(g_audio_h); if (AUDIO_IO_ERROR_NONE != ret) { if (AUDIO_IO_ERROR_SOUND_POLICY == ret) { @@ -654,6 +719,11 @@ int vcd_recorder_stop() SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop audio : %d", ret); return VCD_ERROR_OPERATION_FAILED; } + + ret = sound_manager_release_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL); + if (SOUND_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to release focus : %d", ret); + } } return 0; } -- 2.7.4 From 8901194db49bdedc5a5a36e94a51f4d7cd538347 Mon Sep 17 00:00:00 2001 From: Kwangyoun Kim Date: Wed, 5 Oct 2016 18:34:43 +0900 Subject: [PATCH 14/16] Fix typo and add error handling Change-Id: I6d1d39fb11ece24b6521c18cad3e18a4ea4ec27e --- client/vc_mgr_client.c | 6 ++++++ include/voice_control_manager.h | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/client/vc_mgr_client.c b/client/vc_mgr_client.c index 4f01521..328ff33 100644 --- a/client/vc_mgr_client.c +++ b/client/vc_mgr_client.c @@ -706,6 +706,9 @@ int vc_mgr_client_set_error_message(vc_h vc, const char* err_msg) if (NULL != err_msg) { client->err_msg = strdup(err_msg); + if (NULL == client->err_msg) { + return VC_ERROR_OUT_OF_MEMORY; + } } return 0; @@ -721,6 +724,9 @@ int vc_mgr_client_get_error_message(vc_h vc, char** err_msg) if (NULL != client->err_msg) { *err_msg = strdup(client->err_msg); + if (NULL == *err_msg) { + return VC_ERROR_OUT_OF_MEMORY; + } } return 0; diff --git a/include/voice_control_manager.h b/include/voice_control_manager.h index abcd864..32f4cd7 100644 --- a/include/voice_control_manager.h +++ b/include/voice_control_manager.h @@ -904,7 +904,7 @@ int vc_mgr_unset_current_language_changed_cb(); /** * @brief Gets the current error message. * -* @remarks This function should be called during as stt error callback. If not, the error as operation failure will be returned. \n +* @remarks This function should be called during as vc error callback. If not, the error as operation failure will be returned. \n * If the function succeeds, @a err_msg must be released using free() when it is no longer required. * * @param[out] err_msg The current error message @@ -914,6 +914,7 @@ int vc_mgr_unset_current_language_changed_cb(); * @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VC_ERROR_INVALID_STATE Invalid state * @retval $VC_ERROR_OPERATION_FAILED Operation failure +* @retval #VC_ERROR_OUT_OF_MEMORY Out of memory * * @see vc_error_cb() */ -- 2.7.4 From 91de4233b949bfa1120895e7175a7ce42ce01767 Mon Sep 17 00:00:00 2001 From: Kwangyoun Kim Date: Wed, 5 Oct 2016 19:53:00 +0900 Subject: [PATCH 15/16] Add internal state for prevent bug from async api call Change-Id: I8a0539cc5291f5e8860a7d6cc47950628b0ea6f7 --- client/vc_mgr.c | 51 ++++++++++++++++++++++++++++++++++ client/vc_mgr_client.c | 30 ++++++++++++++++++++ client/vc_mgr_client.h | 11 ++++++++ client/vc_widget.c | 2 +- include/voice_control_command_expand.h | 1 + include/voice_control_common.h | 5 +++- include/voice_control_widget.h | 4 +-- server/vcd_engine_agent.c | 3 ++ server/vcd_recorder.c | 10 +++++++ 9 files changed, 113 insertions(+), 4 deletions(-) mode change 100644 => 100755 client/vc_widget.c diff --git a/client/vc_mgr.c b/client/vc_mgr.c index 0469551..ab5c2f4 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -179,6 +179,8 @@ static void __vc_mgr_internal_unprepare() if (0 != ret) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request finalize : %s", __vc_mgr_get_error_code(ret)); } + + vc_mgr_client_set_internal_state(g_vc_m, VC_INTERNAL_STATE_NONE); return; } @@ -1555,6 +1557,14 @@ int vc_mgr_start(bool exclusive_command_option) return VC_ERROR_INVALID_STATE; } + /* Check internal state for async */ + vc_internal_state_e internal_state = -1; + vc_mgr_client_get_internal_state(g_vc_m, &internal_state); + if (internal_state != VC_INTERNAL_STATE_NONE) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invaid State : Internal state is NOT none : %d", internal_state); + return VC_ERROR_IN_PROGRESS_TO_RECORDING; + } + vc_mgr_client_set_exclusive_command(g_vc_m, exclusive_command_option); bool start_by_client = false; @@ -1590,6 +1600,7 @@ int vc_mgr_start(bool exclusive_command_option) } } else { SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] start recognition"); + vc_mgr_client_set_internal_state(g_vc_m, VC_INTERNAL_STATE_STARTING); } } @@ -1629,6 +1640,20 @@ int vc_mgr_stop() return VC_ERROR_INVALID_STATE; } + /* Check internal state for async */ + vc_internal_state_e internal_state = -1; + vc_mgr_client_get_internal_state(g_vc_m, &internal_state); + if (VC_INTERNAL_STATE_STARTING == internal_state) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State : Internal state is STARTING"); + return VC_ERROR_IN_PROGRESS_TO_RECORDING; + } else if (VC_INTERNAL_STATE_STOPPING == internal_state) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State : Internal state is STOPPING"); + return VC_ERROR_IN_PROGRESS_TO_PROCESSING; + } else if (VC_INTERNAL_STATE_CANCELING == internal_state) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State : Internal state is CANCELING"); + return VC_ERROR_IN_PROGRESS_TO_READY; + } + int ret = -1; int count = 0; /* do request */ @@ -1649,6 +1674,7 @@ int vc_mgr_stop() } } else { SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Stop recognition"); + vc_mgr_client_set_internal_state(g_vc_m, VC_INTERNAL_STATE_STOPPING); } } @@ -1688,6 +1714,19 @@ int vc_mgr_cancel() return VC_ERROR_INVALID_STATE; } + vc_internal_state_e internal_state = -1; + vc_mgr_client_get_internal_state(g_vc_m, &internal_state); + if (VC_INTERNAL_STATE_STARTING == internal_state) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State : Internal state is STARTING"); + return VC_ERROR_IN_PROGRESS_TO_RECORDING; + } else if (VC_INTERNAL_STATE_STOPPING == internal_state) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State : Internal state is STOPPING"); + return VC_ERROR_IN_PROGRESS_TO_PROCESSING; + } else if (VC_INTERNAL_STATE_CANCELING == internal_state) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State : Internal state is CANCELING"); + return VC_ERROR_IN_PROGRESS_TO_READY; + } + int ret = -1; int count = 0; while (0 != ret) { @@ -1707,6 +1746,7 @@ int vc_mgr_cancel() } } else { SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Cancel recognition"); + vc_mgr_client_set_internal_state(g_vc_m, VC_INTERNAL_STATE_CANCELING); } } @@ -2243,6 +2283,8 @@ int __vc_mgr_cb_error(int reason, int daemon_pid, char* msg) return -1; } + vc_mgr_client_set_internal_state(g_vc_m, VC_INTERNAL_STATE_NONE); + if (VC_ERROR_SERVICE_RESET == reason) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] VC daemon reset"); @@ -2344,6 +2386,15 @@ int __vc_mgr_cb_service_state(int state) SLOG(LOG_DEBUG, TAG_VCM, "Service State changed : Before(%d) Current(%d)", before_state, current_state); + vc_internal_state_e internal_state = -1; + vc_mgr_client_get_internal_state(g_vc_m, &internal_state); + if ((VC_INTERNAL_STATE_STARTING == internal_state && VC_SERVICE_STATE_RECORDING == current_state) || + (VC_INTERNAL_STATE_STOPPING == internal_state && VC_SERVICE_STATE_PROCESSING == current_state) || + (VC_INTERNAL_STATE_CANCELING == internal_state && VC_SERVICE_STATE_READY == current_state)) { + SLOG(LOG_DEBUG, TAG_VCM, "Internal state is changed to NONE"); + vc_mgr_client_set_internal_state(g_vc_m, VC_INTERNAL_STATE_NONE); + } + /* Save service state */ vc_mgr_client_set_service_state(g_vc_m, current_state); diff --git a/client/vc_mgr_client.c b/client/vc_mgr_client.c index 4f01521..e44644e 100644 --- a/client/vc_mgr_client.c +++ b/client/vc_mgr_client.c @@ -58,6 +58,8 @@ typedef struct { /* service state */ vc_service_state_e service_state; + vc_internal_state_e internal_state; + /* state */ vc_state_e before_state; vc_state_e current_state; @@ -175,6 +177,8 @@ int vc_mgr_client_create(vc_h* vc) client->service_state = 0; + client->internal_state = VC_INTERNAL_STATE_NONE; + client->before_state = VC_STATE_INITIALIZED; client->current_state = VC_STATE_INITIALIZED; @@ -603,6 +607,32 @@ int vc_mgr_client_get_service_state(vc_h vc, vc_service_state_e* state) return 0; } +int vc_mgr_client_set_internal_state(vc_h vc, vc_internal_state_e state) +{ + vc_mgr_client_s* client = __mgr_client_get(vc); + + /* check handle */ + if (NULL == client) + return VC_ERROR_INVALID_PARAMETER; + + client->internal_state = state; + + return 0; +} + +int vc_mgr_client_get_internal_state(vc_h vc, vc_internal_state_e* state) +{ + vc_mgr_client_s* client = __mgr_client_get(vc); + + /* check handle */ + if (NULL == client) + return VC_ERROR_INVALID_PARAMETER; + + *state = client->internal_state; + + return 0; +} + int vc_mgr_client_set_client_state(vc_h vc, vc_state_e state) { vc_mgr_client_s* client = __mgr_client_get(vc); diff --git a/client/vc_mgr_client.h b/client/vc_mgr_client.h index 51088c5..afee7a4 100644 --- a/client/vc_mgr_client.h +++ b/client/vc_mgr_client.h @@ -26,6 +26,13 @@ extern "C" { #endif +typedef enum { + VC_INTERNAL_STATE_NONE = 0, + VC_INTERNAL_STATE_STARTING = 1, + VC_INTERNAL_STATE_STOPPING = 2, + VC_INTERNAL_STATE_CANCELING = 3 +} vc_internal_state_e; + /* * Common function */ @@ -87,6 +94,10 @@ int vc_mgr_client_set_service_state(vc_h vc, vc_service_state_e state); int vc_mgr_client_get_service_state(vc_h vc, vc_service_state_e* state); +int vc_mgr_client_set_internal_state(vc_h vc, vc_internal_state_e state); + +int vc_mgr_client_get_internal_state(vc_h vc, vc_internal_state_e* state); + int vc_mgr_client_set_client_state(vc_h vc, vc_state_e state); int vc_mgr_client_get_client_state(vc_h vc, vc_state_e* state); diff --git a/client/vc_widget.c b/client/vc_widget.c old mode 100644 new mode 100755 index f05a6b6..e7a9ed1 --- a/client/vc_widget.c +++ b/client/vc_widget.c @@ -1106,7 +1106,7 @@ int vc_widget_set_send_current_command_list_cb(vc_widget_send_current_command_li return 0; } -int vc_widget_unsset_send_current_command_list_cb() +int vc_widget_unset_send_current_command_list_cb() { vc_state_e state; if (0 != vc_widget_client_get_state(g_vc_w, &state)) { diff --git a/include/voice_control_command_expand.h b/include/voice_control_command_expand.h index 695641f..fdb4101 100755 --- a/include/voice_control_command_expand.h +++ b/include/voice_control_command_expand.h @@ -18,6 +18,7 @@ #ifndef __VOICE_CONTROL_COMMAND_EXPAND_H__ #define __VOICE_CONTROL_COMMAND_EXPAND_H__ +#include #include #include diff --git a/include/voice_control_common.h b/include/voice_control_common.h index 86b07ac..b491719 100644 --- a/include/voice_control_common.h +++ b/include/voice_control_common.h @@ -50,7 +50,10 @@ typedef enum { VC_ERROR_OPERATION_REJECTED = TIZEN_ERROR_VOICE_CONTROL | 0x015, /**< Operation rejected */ VC_ERROR_ITERATION_END = TIZEN_ERROR_VOICE_CONTROL | 0x016, /**< List reached end */ VC_ERROR_EMPTY = TIZEN_ERROR_VOICE_CONTROL | 0x017, /**< List empty */ - VC_ERROR_SERVICE_RESET = TIZEN_ERROR_VOICE_CONTROL | 0x018 /**< Service Damon reset */ + VC_ERROR_SERVICE_RESET = TIZEN_ERROR_VOICE_CONTROL | 0x018, /**< Service Damon reset */ + VC_ERROR_IN_PROGRESS_TO_READY = TIZEN_ERROR_VOICE_CONTROL | 0x019, + VC_ERROR_IN_PROGRESS_TO_RECORDING = TIZEN_ERROR_VOICE_CONTROL | 0x020, + VC_ERROR_IN_PROGRESS_TO_PROCESSING = TIZEN_ERROR_VOICE_CONTROL | 0x021 } vc_error_e; /** diff --git a/include/voice_control_widget.h b/include/voice_control_widget.h index 91ddf74..2f8ca7a 100755 --- a/include/voice_control_widget.h +++ b/include/voice_control_widget.h @@ -63,7 +63,7 @@ typedef void (*vc_widget_show_tooltip_cb)(bool show, void* user_data); * @pre An application registers callback function using vc_widget_set_send_current_command_group_cb(). * * @see vc_widget_set_send_current_command_list_cb() -* @see vc_widget_unsset_send_current_command_list_cb() +* @see vc_widget_unset_send_current_command_list_cb() */ typedef void (*vc_widget_send_current_command_list_cb)(vc_cmd_list_h* vc_cmd_list, void* user_data); @@ -374,7 +374,7 @@ int vc_widget_set_send_current_command_list_cb(vc_widget_send_current_command_li * * @see vc_widget_set_send_current_command_list_cb() */ -int vc_widget_unsset_send_current_command_list_cb(); +int vc_widget_unset_send_current_command_list_cb(); /** * @brief Registers a callback function to be called when service state is changed. diff --git a/server/vcd_engine_agent.c b/server/vcd_engine_agent.c index 0863583..12f5754 100644 --- a/server/vcd_engine_agent.c +++ b/server/vcd_engine_agent.c @@ -428,6 +428,9 @@ int __internal_update_engine_list() } if (NULL != dirp) { + if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name)) + continue; + vcengine_info_s* info = NULL; char* filepath = NULL; int filesize = 0; diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index bcda93e..f7e7313 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -194,6 +194,7 @@ static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void #endif +#if 0 static const char* __get_focus_changed_reason_code(sound_stream_focus_change_reason_e reason) { switch (reason) { @@ -238,6 +239,7 @@ static void __recorder_focus_state_cb(sound_stream_info_h stream_info, sound_str } } } +#endif int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb interrupt_cb) { @@ -287,9 +289,11 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb g_is_valid_audio_in = false; } +#if 0 if (0 != sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_RECOGNITION, __recorder_focus_state_cb, NULL, &g_stream_info_h)) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create stream info"); } +#endif g_audio_cb = audio_cb; g_interrupt_cb = interrupt_cb; @@ -349,9 +353,11 @@ int vcd_recorder_destroy() g_recorder_state = VCD_RECORDER_STATE_READY; } +#if 0 if (0 != sound_manager_destroy_stream_information(g_stream_info_h)) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to destroy stream info"); } +#endif audio_in_destroy(g_audio_h); @@ -623,6 +629,7 @@ int vcd_recorder_start() SLOG(LOG_ERROR, TAG_VCD, "[Recorder] started = %d", started); if (false == started) { +#if 0 ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL); if (SOUND_MANAGER_ERROR_NONE != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to acquire focus : %d", ret); @@ -632,6 +639,7 @@ int vcd_recorder_start() SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info : %d", ret); } } +#endif ret = audio_in_prepare(g_audio_h); if (AUDIO_IO_ERROR_NONE != ret) { @@ -720,10 +728,12 @@ int vcd_recorder_stop() return VCD_ERROR_OPERATION_FAILED; } +#if 0 ret = sound_manager_release_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL); if (SOUND_MANAGER_ERROR_NONE != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to release focus : %d", ret); } +#endif } return 0; } -- 2.7.4 From 014ddb4fe6ac5ea69f2ecc5ea6cf1c2d0da2ea91 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Mon, 24 Oct 2016 16:58:24 +0900 Subject: [PATCH 16/16] Check manager client is available or not when vcd start, stop, cancel Change-Id: I1e9eb235ab56bea17fc80b856618ddf6d6b07644 Signed-off-by: Wonnam Jang --- server/vcd_server.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/server/vcd_server.c b/server/vcd_server.c index 843b587..632eb4f 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -1525,6 +1525,10 @@ int vcd_server_mgr_start(vcd_recognition_mode_e recognition_mode, bool exclusive SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready"); return VCD_ERROR_INVALID_STATE; } + if (-1 != vcd_client_manager_get_pid()) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available."); + return VCD_ERROR_OPERATION_FAILED; + } SLOG(LOG_DEBUG, TAG_VCD, "[Server] set recognition mode = %d", recognition_mode); vcd_client_set_recognition_mode(recognition_mode); @@ -1574,6 +1578,10 @@ int vcd_server_mgr_stop() SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not recording"); return VCD_ERROR_INVALID_STATE; } + if (-1 != vcd_client_manager_get_pid()) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available."); + return VCD_ERROR_OPERATION_FAILED; + } /* 2. Stop recorder */ vcd_recorder_stop(); @@ -1599,6 +1607,10 @@ int vcd_server_mgr_cancel() SLOG(LOG_WARN, TAG_VCD, "[Server ERROR] Current state is not recording or processing"); return VCD_ERROR_INVALID_STATE; } + if (-1 != vcd_client_manager_get_pid()) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available."); + return VCD_ERROR_OPERATION_FAILED; + } if (g_restart_timer != NULL) { SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Delete restart engine timer"); -- 2.7.4