From 20a15a38a598c68350f8e315dab848f5f3066bf3 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Fri, 1 Sep 2017 15:39:18 +0900 Subject: [PATCH 01/16] Add voice-control-manager APIs in public Change-Id: If1ab3468641ca2e2c92ed089120d2bea8afe9770 Signed-off-by: sooyeon.kim --- client/vc_mgr.c | 632 +++++++- common/vc_defs.h | 1 + doc/uix_vc_mgr_doc.h | 292 ++++ include/CMakeLists.txt | 1 + include/voice_control_internal.h | 4 +- include/voice_control_manager.h | 2347 +++++++++++++++++------------- include/voice_control_manager_internal.h | 92 ++ include/voice_control_widget.h | 2 +- packaging/voice-control.spec | 1 + 9 files changed, 2349 insertions(+), 1023 deletions(-) create mode 100644 doc/uix_vc_mgr_doc.h create mode 100644 include/voice_control_manager_internal.h diff --git a/client/vc_mgr.c b/client/vc_mgr.c index 9610204..e56205e 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -16,6 +16,9 @@ #include #include +#include +#include +#include #include "vc_cmd_db.h" #include "vc_config_mgr.h" @@ -30,6 +33,7 @@ #include "voice_control_command_expand.h" #include "voice_control_common.h" #include "voice_control_manager.h" +#include "voice_control_manager_internal.h" #define VC_MANAGER_CONFIG_HANDLE 100000 @@ -52,6 +56,9 @@ static int g_daemon_pid = 0; static int g_feature_enabled = -1; +static int g_privilege_allowed = -1; +static cynara *p_cynara = NULL; + static bool g_err_callback_status = false; static Eina_Bool __vc_mgr_notify_state_changed(void *data); @@ -121,7 +128,88 @@ static int __vc_mgr_get_feature_enabled() return 0; } -int vc_mgr_initialize() +static int __check_privilege_initialize() +{ + int ret = cynara_initialize(&p_cynara, NULL); + if (CYNARA_API_SUCCESS != ret) + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] fail to initialize"); + + return ret == CYNARA_API_SUCCESS; +} + +static int __check_privilege(const char* uid, const char * privilege) +{ + FILE *fp = NULL; + char label_path[1024] = "/proc/self/attr/current"; + char smack_label[1024] = {'\0',}; + + if (!p_cynara) { + return false; + } + + fp = fopen(label_path, "r"); + if (fp != NULL) { + if (fread(smack_label, 1, sizeof(smack_label), fp) <= 0) + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] fail to fread"); + + fclose(fp); + } + + pid_t pid = getpid(); + char *session = cynara_session_from_pid(pid); + int ret = cynara_check(p_cynara, smack_label, session, uid, privilege); + SLOG(LOG_DEBUG, TAG_VCM, "[Client]cynara_check returned %d(%s)", ret, (CYNARA_API_ACCESS_ALLOWED == ret) ? "Allowed" : "Denied"); + if (session) + free(session); + + if (ret != CYNARA_API_ACCESS_ALLOWED) + return false; + + return true; +} + +static void __check_privilege_deinitialize() +{ + if (p_cynara) + cynara_finish(p_cynara); + p_cynara = NULL; +} + +static int __vc_mgr_check_privilege() +{ + char uid[16]; + + if (0 == g_privilege_allowed) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Permission is denied"); + return VC_ERROR_PERMISSION_DENIED; + } else if (-1 == g_privilege_allowed) { + if (false == __check_privilege_initialize()) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] privilege initialize is failed"); + return VC_ERROR_PERMISSION_DENIED; + } + snprintf(uid, 16, "%d", getuid()); + /* check 'recorder' privilege */ + if (false == __check_privilege(uid, VC_PRIVILEGE)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Permission is denied(%s)", VC_PRIVILEGE); + g_privilege_allowed = 0; + __check_privilege_deinitialize(); + return VC_ERROR_PERMISSION_DENIED; + } + /* check 'voicecontrol.manager' privilege */ + if (false == __check_privilege(uid, VC_MGR_PRIVILEGE)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Permission is denied(%s)", VC_MGR_PRIVILEGE); + g_privilege_allowed = 0; + __check_privilege_deinitialize(); + return VC_ERROR_PERMISSION_DENIED; + } + __check_privilege_deinitialize(); + } + + g_privilege_allowed = 1; + return VC_ERROR_NONE; +} + +int vc_mgr_initialize(void) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Initialize"); @@ -131,6 +219,10 @@ int vc_mgr_initialize() return VC_ERROR_NOT_SUPPORTED; } + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + /* check handle */ if (true == vc_mgr_client_is_valid(g_vc_m)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Already initialized"); @@ -188,10 +280,19 @@ static void __vc_mgr_internal_unprepare() return; } -int vc_mgr_deinitialize() +int vc_mgr_deinitialize(void) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Deinitialize"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (false == vc_mgr_client_is_valid(g_vc_m)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] NOT initialized"); SLOG(LOG_DEBUG, TAG_VCM, "@@@"); @@ -352,10 +453,19 @@ static void __end_prepare_thread(void *data, Ecore_Thread *thread) SLOG(LOG_DEBUG, TAG_VCM, "@@@ End prepare thread"); } -int vc_mgr_prepare() +int vc_mgr_prepare(void) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Prepare"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + 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"); @@ -377,10 +487,19 @@ int vc_mgr_prepare() return VC_ERROR_NONE; } -int vc_mgr_unprepare() +int vc_mgr_unprepare(void) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Unprepare"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + 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"); @@ -409,6 +528,15 @@ int vc_mgr_foreach_supported_languages(vc_supported_language_cb callback, void* { SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Foreach Supported Language"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == callback) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL"); SLOG(LOG_DEBUG, TAG_VCM, "@@@"); @@ -436,6 +564,15 @@ int vc_mgr_foreach_supported_languages(vc_supported_language_cb callback, void* int vc_mgr_get_current_language(char** language) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == language) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL"); return VC_ERROR_INVALID_PARAMETER; @@ -463,6 +600,15 @@ int vc_mgr_get_state(vc_state_e* state) { SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Get State"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == state) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL"); return VC_ERROR_INVALID_PARAMETER; @@ -493,6 +639,15 @@ int vc_mgr_get_service_state(vc_service_state_e* state) { SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Get Service State"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == state) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL"); return VC_ERROR_INVALID_PARAMETER; @@ -536,6 +691,15 @@ int vc_mgr_set_demandable_client_rule(const char* rule) { SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Set Demandable client rule"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + 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"); @@ -568,8 +732,17 @@ int vc_mgr_set_demandable_client_rule(const char* rule) return 0; } -int vc_mgr_unset_demandable_client_rule() +int vc_mgr_unset_demandable_client_rule(void) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + vc_info_parser_set_demandable_client(NULL); int count = 0; @@ -599,6 +772,15 @@ int vc_mgr_is_command_format_supported(vc_cmd_format_e format, bool* support) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Is command type supported"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == support) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter, support is NULL ptr"); return VC_ERROR_INVALID_PARAMETER; @@ -637,8 +819,17 @@ int vc_mgr_enable_command_type(int cmd_type) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Enable Command Type, cmd_type(%d)", cmd_type); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (VC_COMMAND_TYPE_FOREGROUND > cmd_type || VC_COMMAND_TYPE_EXCLUSIVE < cmd_type) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] cmd type is not valid, (%d)", cmd_type); + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] cmd_type is not valid. (%d)", cmd_type); return VC_ERROR_INVALID_PARAMETER; } @@ -694,6 +885,15 @@ int vc_mgr_disable_command_type(int cmd_type) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Disable Command Type, cmd_type(%d)", cmd_type); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (VC_COMMAND_TYPE_FOREGROUND > cmd_type || VC_COMMAND_TYPE_EXCLUSIVE < cmd_type) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] cmd type is not valid, (%d)", cmd_type); return VC_ERROR_INVALID_PARAMETER; @@ -751,6 +951,15 @@ int vc_mgr_set_command_list(vc_cmd_list_h vc_cmd_list) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Set Command list"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + 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"); @@ -834,10 +1043,19 @@ int vc_mgr_set_command_list(vc_cmd_list_h vc_cmd_list) return ret; } -int vc_mgr_unset_command_list() +int vc_mgr_unset_command_list(void) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Unset Command list"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + 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"); @@ -886,6 +1104,15 @@ int vc_mgr_set_command_list_from_file(const char* file_path, int type) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Set Command list from file, type(%d)", type); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == file_path) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter!!"); return VC_ERROR_INVALID_PARAMETER; @@ -957,11 +1184,20 @@ int vc_mgr_set_preloaded_commands_from_file(const char* file_path) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Set preloaded command list"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == file_path) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter, file_path is NULL ptr"); + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter!! file_path is NULL ptr"); return VC_ERROR_INVALID_PARAMETER; } else { - SLOG(LOG_ERROR, TAG_VCM, "@@@ File path: %s", file_path); + SLOG(LOG_DEBUG, TAG_VCM, "@@@ File path: %s", file_path); } vc_state_e state; @@ -997,6 +1233,15 @@ int vc_mgr_set_audio_type(const char* audio_id) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Set audio type, audio_id(%s)", audio_id); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == audio_id) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL"); return VC_ERROR_INVALID_PARAMETER; @@ -1060,6 +1305,15 @@ int vc_mgr_get_audio_type(char** audio_id) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Get audio type"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == audio_id) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL"); return VC_ERROR_INVALID_PARAMETER; @@ -1132,6 +1386,15 @@ int vc_mgr_get_current_commands(vc_cmd_list_h* vc_cmd_list) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Foreach current commands"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + 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"); @@ -1325,6 +1588,21 @@ int vc_mgr_set_recognition_mode(vc_recognition_mode_e mode) { SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Set recognition mode = %d", mode); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + + /* check vc recognition mode */ + if (mode > VC_RECOGNITION_MODE_MANUAL) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] invalid parameter: 'mode' is not supported mode (%d)", mode); + 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"); @@ -1354,6 +1632,15 @@ int vc_mgr_set_recognition_mode(vc_recognition_mode_e mode) int vc_mgr_get_recognition_mode(vc_recognition_mode_e* mode) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + int ret = -1; if (NULL == mode) { @@ -1375,6 +1662,15 @@ int vc_mgr_set_private_data(const char* key, const char* data) { SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Set private data"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == key) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter"); return VC_ERROR_INVALID_PARAMETER; @@ -1433,6 +1729,15 @@ int vc_mgr_get_private_data(const char* key, char** data) { SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Get private data"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == key || NULL == data) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter"); return VC_ERROR_INVALID_PARAMETER; @@ -1500,6 +1805,15 @@ int vc_mgr_set_domain(const char* domain) { SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Set domain"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == domain) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter"); return VC_ERROR_INVALID_PARAMETER; @@ -1558,6 +1872,15 @@ int vc_mgr_do_action(vc_send_event_type_e type, char* send_event) { SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] do action"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == send_event) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter"); return VC_ERROR_INVALID_PARAMETER; @@ -1616,6 +1939,15 @@ int vc_mgr_start(bool exclusive_command_option) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Request start"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + 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"); @@ -1697,10 +2029,19 @@ int vc_mgr_start(bool exclusive_command_option) return ret; } -int vc_mgr_stop() +int vc_mgr_stop(void) { SLOG(LOG_ERROR, TAG_VCM, "@@@ [Manager] Request stop"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + 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"); @@ -1769,10 +2110,19 @@ int vc_mgr_stop() return ret; } -int vc_mgr_cancel() +int vc_mgr_cancel(void) { SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Request cancel"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + 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"); @@ -1874,6 +2224,15 @@ int __vc_mgr_cb_set_volume(float volume) int vc_mgr_get_recording_volume(float* volume) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == volume) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL"); return VC_ERROR_INVALID_PARAMETER; @@ -1935,6 +2294,15 @@ int vc_mgr_set_selected_results(vc_cmd_list_h vc_cmd_list) { SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Select result"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + /* Do not check state for 'restart continusly' mode */ vc_service_state_e service_state = -1; @@ -2056,7 +2424,14 @@ static void __vc_mgr_notify_all_result(vc_result_type_e result_type) SLOG(LOG_DEBUG, TAG_VCM, "Exclusive result callback called"); /* Release result */ - if (NULL != temp_text) free(temp_text); + if (NULL != temp_text) { + free(temp_text); + temp_text = NULL; + } + if (NULL != temp_message) { + free(temp_message); + temp_message = NULL; + } /* Release list */ vc_cmd_list_destroy(vc_cmd_list, true); @@ -2090,6 +2465,10 @@ static void __vc_mgr_notify_all_result(vc_result_type_e result_type) free(temp_text); temp_text = NULL; } + if (NULL != temp_message) { + free(temp_message); + temp_message = NULL; + } /* Release list */ vc_cmd_list_destroy(vc_cmd_list, true); @@ -2200,6 +2579,15 @@ void __vc_mgr_cb_speech_detected() int vc_mgr_set_all_result_cb(vc_mgr_all_result_cb callback, void* user_data) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == callback) return VC_ERROR_INVALID_PARAMETER; @@ -2222,8 +2610,17 @@ int vc_mgr_set_all_result_cb(vc_mgr_all_result_cb callback, void* user_data) return 0; } -int vc_mgr_unset_all_result_cb() +int vc_mgr_unset_all_result_cb(void) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset result callback : A handle is not available"); @@ -2243,6 +2640,15 @@ int vc_mgr_unset_all_result_cb() int vc_mgr_set_result_cb(vc_result_cb callback, void* user_data) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == callback) return VC_ERROR_INVALID_PARAMETER; @@ -2263,8 +2669,17 @@ int vc_mgr_set_result_cb(vc_result_cb callback, void* user_data) return 0; } -int vc_mgr_unset_result_cb() +int vc_mgr_unset_result_cb(void) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset result callback : A handle is not available"); @@ -2284,6 +2699,15 @@ int vc_mgr_unset_result_cb() int vc_mgr_set_pre_result_cb(vc_mgr_pre_result_cb callback, void* user_data) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == callback) return VC_ERROR_INVALID_PARAMETER; @@ -2304,8 +2728,17 @@ int vc_mgr_set_pre_result_cb(vc_mgr_pre_result_cb callback, void* user_data) return 0; } -int vc_mgr_unset_pre_result_cb() +int vc_mgr_unset_pre_result_cb(void) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + 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"); @@ -2327,6 +2760,15 @@ int vc_mgr_get_error_message(char** err_msg) { SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Get error message"); + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == err_msg) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] invalid parameter"); return VC_ERROR_INVALID_PARAMETER; @@ -2433,6 +2875,15 @@ static Eina_Bool __vc_mgr_notify_state_changed(void *data) int vc_mgr_set_state_changed_cb(vc_state_changed_cb callback, void* user_data) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (callback == NULL) return VC_ERROR_INVALID_PARAMETER; @@ -2454,8 +2905,17 @@ int vc_mgr_set_state_changed_cb(vc_state_changed_cb callback, void* user_data) return 0; } -int vc_mgr_unset_state_changed_cb() +int vc_mgr_unset_state_changed_cb(void) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset state changed callback : A handle is not available"); @@ -2518,6 +2978,15 @@ int __vc_mgr_cb_service_state(int state) int vc_mgr_set_service_state_changed_cb(vc_service_state_changed_cb callback, void* user_data) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (callback == NULL) return VC_ERROR_INVALID_PARAMETER; @@ -2539,8 +3008,17 @@ int vc_mgr_set_service_state_changed_cb(vc_service_state_changed_cb callback, vo return 0; } -int vc_mgr_unset_service_state_changed_cb() +int vc_mgr_unset_service_state_changed_cb(void) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset state changed callback : A handle is not available"); @@ -2559,6 +3037,15 @@ int vc_mgr_unset_service_state_changed_cb() int vc_mgr_set_speech_detected_cb(vc_mgr_begin_speech_detected_cb callback, void* user_data) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (callback == NULL) return VC_ERROR_INVALID_PARAMETER; @@ -2580,8 +3067,17 @@ int vc_mgr_set_speech_detected_cb(vc_mgr_begin_speech_detected_cb callback, void return 0; } -int vc_mgr_unset_speech_detected_cb() +int vc_mgr_unset_speech_detected_cb(void) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset state changed callback : A handle is not available"); @@ -2600,6 +3096,15 @@ int vc_mgr_unset_speech_detected_cb() int vc_mgr_set_current_language_changed_cb(vc_current_language_changed_cb callback, void* user_data) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == callback) return VC_ERROR_INVALID_PARAMETER; @@ -2621,8 +3126,17 @@ int vc_mgr_set_current_language_changed_cb(vc_current_language_changed_cb callba return 0; } -int vc_mgr_unset_current_language_changed_cb() +int vc_mgr_unset_current_language_changed_cb(void) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset current language changed : A handle is not available"); @@ -2642,6 +3156,15 @@ int vc_mgr_unset_current_language_changed_cb() int vc_mgr_set_error_cb(vc_error_cb callback, void* user_data) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == callback) return VC_ERROR_INVALID_PARAMETER; @@ -2662,8 +3185,17 @@ int vc_mgr_set_error_cb(vc_error_cb callback, void* user_data) return 0; } -int vc_mgr_unset_error_cb() +int vc_mgr_unset_error_cb(void) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + 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"); @@ -2742,6 +3274,15 @@ int __vc_mgr_cb_private_data_requested(const char* key, char** data) int vc_mgr_set_dialog_request_cb(vc_mgr_dialog_request_cb callback, void* user_data) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == callback) return VC_ERROR_INVALID_PARAMETER; @@ -2762,8 +3303,17 @@ int vc_mgr_set_dialog_request_cb(vc_mgr_dialog_request_cb callback, void* user_d return 0; } -int vc_mgr_unset_dialog_request_cb() +int vc_mgr_unset_dialog_request_cb(void) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + 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"); @@ -2783,6 +3333,15 @@ int vc_mgr_unset_dialog_request_cb() int vc_mgr_set_private_data_set_cb(vc_mgr_private_data_set_cb callback, void* user_data) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == callback) return VC_ERROR_INVALID_PARAMETER; @@ -2803,8 +3362,17 @@ int vc_mgr_set_private_data_set_cb(vc_mgr_private_data_set_cb callback, void* us return 0; } -int vc_mgr_unset_private_data_set_cb() +int vc_mgr_unset_private_data_set_cb(void) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset private data set callback : A handle is not available"); @@ -2824,6 +3392,15 @@ int vc_mgr_unset_private_data_set_cb() int vc_mgr_set_private_data_requested_cb(vc_mgr_private_data_requested_cb callback, void* user_data) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + if (NULL == callback) return VC_ERROR_INVALID_PARAMETER; @@ -2844,8 +3421,17 @@ int vc_mgr_set_private_data_requested_cb(vc_mgr_private_data_requested_cb callba return 0; } -int vc_mgr_unset_private_data_requested_cb() +int vc_mgr_unset_private_data_requested_cb(void) { + if (0 != __vc_mgr_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] not supported"); + return VC_ERROR_NOT_SUPPORTED; + } + + if (0 != __vc_mgr_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + vc_state_e state; if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset private data requested callback : A handle is not available"); diff --git a/common/vc_defs.h b/common/vc_defs.h index ed3a88a..0299485 100755 --- a/common/vc_defs.h +++ b/common/vc_defs.h @@ -208,6 +208,7 @@ extern "C" { #define VC_MIC_FEATURE_PATH "tizen.org/feature/microphone" #define VC_PRIVILEGE "http://tizen.org/privilege/recorder" +#define VC_MGR_PRIVILEGE "http://tizen.org/privilege/voicecontrol.manager" /****************************************************************************************** * Definitions for common enum diff --git a/doc/uix_vc_mgr_doc.h b/doc/uix_vc_mgr_doc.h new file mode 100644 index 0000000..0a659fd --- /dev/null +++ b/doc/uix_vc_mgr_doc.h @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2011-2018 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 __TIZEN_UIX_VOICE_CONTROL_MANAGER_DOC_H__ +#define __TIZEN_UIX_VOICE_CONTROL_MANAGER_DOC_H__ + + +/** + * @ingroup CAPI_UIX_FRAMEWORK + * @defgroup CAPI_UIX_VOICE_CONTROL_MANAGER_MODULE Voice control manager + * @brief The @ref CAPI_UIX_VOICE_CONTROL_MANAGER_MODULE API provides functions for recording voice and giving responses for recognized voice commands to users. + * @section CAPI_UIX_VOICE_CONTROLMANAGER_MODULE_HEADER Required Header + * \#include
+ * + * @section CAPI_UIX_VOICE_CONTROL_MANAGER_MODULE_OVERVIEW Overview + * A main function of Voice Control Manager API records voice and gives responses for recognized voice commands. + * A Voice Control Manager application can start recording user's utterance and get responses from Voice Control engine service. + * The responses are dependent on the Voice Control engine service. For example, the engine service may send ASR(Automatic Speech Recognition) results or NLU(Natural Language Understanding) results. + * Also, it may send plural results. Therefore, the application can get various recognition results from the engine service and handle them by showing responses to users or controling Voice Control applications. + * Like this, the Voice Control Manager application takes a role of controlling Voice Control applcations. + * For this reason, developers who have an authority granted by Tizen platform can make the Voice Control Manager application.

+ * To use of Voice Control Manager, use the following steps:
+ * 1. Initialize
+ * 2. Register callback functions for notifications
+ * 3. Connect to voice control service asynchronously. The state should be changed to Ready
+ * 4. Make command list as the following step and Step 4 is called repeatedly for each command which an application wants
+ * 4-1. Create command list handle
+ * 4-2. Create command handle
+ * 4-3. Set command and type for command handle
+ * 4-4. Add command handle to command list
+ * 5. Set command list for recognition
+ * 6. Get recognition results
+ * 7. Request the dialogue
+ * 8. If an application wants to finish voice control,
+ * 8-1. Destroy command and command list handle
+ * 8-2. Deinitialize
+ * An application can obtain command handle from command list, and also get information from handle. + * The Voice Control API also notifies you (by callback mechanism) when the states of client and service are changed, + * command is recognized, current language is changed or error occurred. + * An application should register callback functions: vc_state_changed_cb(), vc_service_state_changed_cb(), vc_mgr_all_result_cb(), vc_mgr_pre_result_cb(), vc_result_cb(), + * vc_mgr_begin_speech_detected_cb(), vc_current_language_changed_cb(), vc_error_cb(), vc_mgr_dialog_request_cb(), vc_mgr_private_data_set_cb(), vc_mgr_private_data_requested_cb(). + * + * + * @section CAPI_UIX_VOICE_CONTROL_MANAGER_MODULE_STATE_TRANSITIONS State Transitions + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
FUNCTIONPRE-STATEPOST-STATESYNC TYPE
vc_mgr_initialize()NoneInitializedSYNC
vc_mgr_deinitialize()None, Initialized, ReadyNoneSYNC
vc_mgr_prepare()InitializedReadyASYNC
vc_mgr_unprepare()ReadyInitializedSYNC
+ * + * @section CAPI_UIX_VOICE_CONTROL_MANAGER_MODULE_STATE_DEPENDENT_FUNCTION_CALLS State Dependent Function Calls + * The following table shows state-dependent function calls. + * It is forbidden to call functions listed below in wrong states. + * Violation of this rule may result in an unpredictable behavior. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * vc_mgr_set_dialog_request_cb()
+ * vc_mgr_unset_dialog_request_cb() + * vc_mgr_set_private_data_set_cb()
+ * vc_mgr_unset_private_data_set_cb() + * vc_mgr_set_private_data_requested_cb()
+ * vc_mgr_unset_private_data_requested_cb() + * + * + * + *
FUNCTIONVALID STATESDESCRIPTION
vc_mgr_initialize()NoneAll functions must be called after vc_mgr_initialize()
vc_mgr_deinitialize()None, Initialized, ReadyThis function should be called when an application want to finalize voice control manager using
vc_mgr_prepare()InitializedThis function works asynchronously. If service start is failed, application gets the error callback.
vc_mgr_unprepare()Ready
vc_mgr_foreach_supported_languages()Initialized, Ready
vc_mgr_get_current_language()Initialized, Ready
vc_mgr_get_state()Initialized, Ready
vc_mgr_get_service_state()Ready
vc_mgr_is_command_format_supported()Ready
vc_mgr_set_command_list()Ready
vc_mgr_unset_command_list()Ready
vc_mgr_set_command_list_from_file()Ready
vc_mgr_set_preloaded_commands_from_file()Ready
vc_mgr_get_current_commands()ReadyThe service state should be #VC_SERVICE_STATE_READY.
vc_mgr_set_audio_type()ReadyThe service state should be #VC_SERVICE_STATE_READY.
vc_mgr_get_audio_type()ReadyThe service state should be #VC_SERVICE_STATE_READY.
vc_mgr_set_recognition_mode()ReadyThe service state should be #VC_SERVICE_STATE_READY.
vc_mgr_get_recognition_mode()Ready
vc_mgr_set_private_data()Ready
vc_mgr_get_private_data()Ready
vc_mgr_do_action()Ready
vc_mgr_start()ReadyThe service state should be #VC_SERVICE_STATE_READY. If this function succeeds, the service state will be changed to #VC_SERVICE_STATE_RECORDING.
vc_mgr_stop()ReadyThe service state should be #VC_SERVICE_STATE_RECORDING. If this function succeeds, the service state will be changed to #VC_SERVICE_STATE_PROCESSING.
vc_mgr_cancel()ReadyThe service state should be #VC_SERVICE_STATE_RECORDING or #VC_SERVICE_STATE_PROCESSING. If this function succeeds, the service state will be changed to #VC_SERVICE_STATE_READY.
vc_mgr_get_recording_volume()None, Initialized, ReadyThe service state should be #VC_SERVICE_STATE_RECORDING.
vc_mgr_set_selected_results()None, Initialized, Ready
vc_mgr_get_error_message()None, Initialized, Ready
vc_mgr_enable_command_type()Ready
vc_mgr_disable_command_type()Ready
+ * vc_mgr_set_all_result_cb()
+ * vc_mgr_unset_all_result_cb()
+ * vc_mgr_set_pre_result_cb()
+ * vc_mgr_unset_pre_result_cb()
+ * vc_mgr_set_result_cb()
+ * vc_mgr_unset_result_cb()
+ * vc_mgr_set_state_changed_cb()
+ * vc_mgr_unset_state_changed_cb()
+ * vc_mgr_set_service_state_changed_cb()
+ * vc_mgr_unset_service_state_changed_cb()
+ * vc_mgr_set_speech_detected_cb()
+ * vc_mgr_unset_speech_detected_cb()
+ * vc_mgr_set_current_language_changed_cb()
+ * vc_mgr_unset_current_language_changed_cb()
+ * vc_mgr_set_error_cb()
+ * vc_mgr_unset_error_cb()
Initialized All callback function should be registered in Initialized state
+ * + * @section CAPI_UIX_VOICE_CONTROL_MANAGER_MODULE_FEATURES Related Features + * This API is related with the following features:
+ * - http://tizen.org/feature/microphone
+ * - http://tizen.org/feature/speech.control
+ * It is recommended to design feature related codes in your application for reliability.
+ * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.
+ * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.
+ * More details on featuring your application can be found from Feature Element. + */ + + +#endif /* __TIZEN_UIX_VOICE_CONTROL_MANAGER_DOC_H__ */ + + + + diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 84fd0df..eeacc29 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -21,6 +21,7 @@ INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_command_expand.h DESTINA INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_common.h DESTINATION ${INCLUDEDIR}) INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_key_defines.h DESTINATION ${INCLUDEDIR}) INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_manager.h DESTINATION ${INCLUDEDIR}) +INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_manager_internal.h DESTINATION ${INCLUDEDIR}) INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_setting.h DESTINATION ${INCLUDEDIR}) INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_widget.h DESTINATION ${INCLUDEDIR}) INSTALL(FILES ${CMAKE_BINARY_DIR}/include/vce.h DESTINATION ${INCLUDEDIR}) diff --git a/include/voice_control_internal.h b/include/voice_control_internal.h index b653ca9..0f62a23 100644 --- a/include/voice_control_internal.h +++ b/include/voice_control_internal.h @@ -92,7 +92,7 @@ int vc_prepare_sync(void); #endif /** - * @} - */ + * @} + */ #endif /* __VOICE_CONTROL_INTERNAL_H__ */ diff --git a/include/voice_control_manager.h b/include/voice_control_manager.h index 3d6d294..cdd8af3 100644 --- a/include/voice_control_manager.h +++ b/include/voice_control_manager.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved +* Copyright (c) 2011-2018 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. @@ -23,9 +23,9 @@ #include /** -* @addtogroup VOICE_CONTROL_MANAGER -* @{ -*/ + * @addtogroup CAPI_UIX_VOICE_CONTROL_MANAGER_MODULE + * @{ + */ #ifdef __cplusplus extern "C" @@ -34,1069 +34,1422 @@ extern "C" /** - * @brief Definition of bluetooth audio-in type. -*/ + * @brief Definition of Bluetooth audio-in type. + * @since_tizen 5.0 + */ #define VC_AUDIO_TYPE_BLUETOOTH "VC_AUDIO_ID_BLUETOOTH" /**< Bluetooth audio type */ /** * @brief Definition of Wi-Fi audio-in type. -*/ + * @since_tizen 5.0 + */ #define VC_AUDIO_TYPE_WIFI "VC_AUDIO_ID_WIFI" /**< Wi-Fi audio type */ /** -* @brief Definition for foreground command type. -* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif -*/ + * @brief Definition for foreground command type. + * @since_tizen 5.0 + */ #define VC_COMMAND_TYPE_FOREGROUND 1 /** -* @brief Definition for background command type. -* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif -*/ + * @brief Definition for background command type. + * @since_tizen 5.0 + */ #define VC_COMMAND_TYPE_BACKGROUND 2 /** -* @brief Definition for widget command type. -* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif -*/ + * @brief Definition for widget command type. + * @since_tizen 5.0 + */ #define VC_COMMAND_TYPE_WIDGET 3 /** -* @brief Definition for system command type. -* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif -*/ + * @brief Definition for system command type. + * @since_tizen 5.0 + */ #define VC_COMMAND_TYPE_SYSTEM 4 /** -* @brief Definition for exclusive command type. -* @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif -*/ + * @brief Definition for system background command type. + * @since_tizen 5.0 + */ #define VC_COMMAND_TYPE_SYSTEM_BACKGROUND 5 /** -* @brief Definitions for exclusive command type. -* @since_tizen 2.4 -*/ + * @brief Definition for exclusive command type. + * @since_tizen 5.0 + */ #define VC_COMMAND_TYPE_EXCLUSIVE 6 /** -* @brief Definition for none message. -*/ + * @brief Definition for none message. + * @since_tizen 5.0 + */ #define VC_RESULT_MESSAGE_NONE "vc.result.message.none" /** -* @brief Definition for failed recognition because the speech is too loud to listen. -*/ + * @brief Definition for failed recognition because the speech is too loud to listen. + * @since_tizen 5.0 + */ #define VC_RESULT_MESSAGE_ERROR_TOO_LOUD "vc.result.message.error.too.loud" /** -* @brief Enumerations of recognition mode. -*/ + * @brief Enumeration of recognition mode. + * @since_tizen 5.0 + */ typedef enum { VC_RECOGNITION_MODE_STOP_BY_SILENCE, /**< Default mode */ VC_RECOGNITION_MODE_RESTART_AFTER_REJECT, /**< Restart recognition after rejected result */ VC_RECOGNITION_MODE_RESTART_CONTINUOUSLY, /**< Continuously restart recognition - not support yet*/ - VC_RECOGNITION_MODE_MANUAL /**< Start and stop manually without silence */ + VC_RECOGNITION_MODE_MANUAL /**< Start and stop manually without silence */ } vc_recognition_mode_e; /** -* @brief Enumerations of send event type. -*/ + * @brief Enumeration of send event type. + * @since_tizen 5.0 + */ 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_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. -*/ + * @brief Enumeration of pre result event. + * @since_tizen 5.0 + */ typedef enum { - VC_PRE_RESULT_EVENT_FINAL_RESULT = 0, - VC_PRE_RESULT_EVENT_PARTIAL_RESULT, - VC_PRE_RESULT_EVENT_ERROR + VC_PRE_RESULT_EVENT_FINAL_RESULT = 0, /**< Pre-result event for final result */ + VC_PRE_RESULT_EVENT_PARTIAL_RESULT, /**< Pre-result event for partial result */ + VC_PRE_RESULT_EVENT_ERROR /**< Pre-result event for 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. -* -* @param[in] event The result event -* @param[in] vc_cmd_list_h Command list handle -* @param[in] result Command 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 callback registration function -* -* @return @c true to release command to client, \n @c false to wait for selecting command. -* @pre An application registers callback function using vc_mgr_set_all_result_cb(). -* -* @see vc_mgr_set_all_result_cb() -* @see vc_mgr_unset_all_result_cb() -*/ + * @brief Called when client gets the all recognition results from voice control service. + * @since_tizen 5.0 + * + * @remarks The @a vc_cmd_list should not be released. It is managed by the platform and will be released when invoking this callback is finished. \n + * The @a result and @a msg are also managed by the platform and will be released when invoking this callback is finished. + * + * @param[in] event The result event + * @param[in] vc_cmd_list Command list handle + * @param[in] result Command 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 callback registration function + * + * @return @c true to release command to client, \n @c false to wait for selecting command. + * @pre An application registers callback function using vc_mgr_set_all_result_cb(). + * + * @see vc_mgr_set_all_result_cb() + * @see vc_mgr_unset_all_result_cb() + */ 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); - -/** -* @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. -* -* @param[in] user_data The user data passed from the callback registration function -* -* @pre An application registers callback function using vc_mgr_set_speech_detected_cb(). -* -* @see vc_mgr_set_speech_detected_cb() -* @see vc_mgr_unset_speech_detected_cb() -*/ + const char *result, const char *msg, void *user_data); + +/** + * @brief Called when client gets the pre recognition results (partial ASR) from voice control service. + * @since_tizen 5.0 + * + * @remarks The @a result is managed by the platform and will be released when invoking this callback is finished. + * + * @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. + * @since_tizen 5.0 + * + * @param[in] user_data The user data passed from the callback registration function + * + * @pre An application registers callback function using vc_mgr_set_speech_detected_cb(). + * + * @see vc_mgr_set_speech_detected_cb() + * @see vc_mgr_unset_speech_detected_cb() + */ 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 Called when engine set private data to manager client -* -* @param[in] key Private key -* @param[in] data Private data -* @param[in] user_data The user data passed from the callback registration function -* -* @pre An application registers callback function using vc_mgr_set_private_data_set_cb(). -* -* @see vc_mgr_set_private_data_set_cb() -* @see vc_mgr_unset_private_data_set_cb() -*/ -typedef int (*vc_mgr_private_data_set_cb)(const char* key, const char* data, void *user_data); - -/** -* @brief Called when engine request private data from manager client -* -* @param[in] key Private key -* @param[out] data Private data -* @param[in] user_data The user data passed from the callback registration function -* -* @pre An application registers callback function using vc_mgr_set_private_data_requested_cb(). -* -* @see vc_mgr_set_private_data_requested_cb() -* @see vc_mgr_unset_private_data_requested_cb() -*/ -typedef int (*vc_mgr_private_data_requested_cb)(const char* key, char** data, void *user_data); - - -/** -* @brief Initialize voice control manager. -* -* @remarks If the function succeeds, @a vc mgr must be released with vc_mgr_deinitialize(). -* -* @return 0 on success, otherwise a negative error value -* @retval #VC_ERROR_NONE Successful -* @retval #VC_ERROR_OUT_OF_MEMORY Out of memory -* @retval #VC_ERROR_OPERATION_FAILED Operation fail -* -* @pre The state should be #VC_STATE_NONE. -* @post If this function is called, the state will be #VC_STATE_INITIALIZED. -* -* @see vc_mgr_deinitialize() -*/ -int vc_mgr_initialize(); - -/** -* @brief Deinitialize voice control manager. -* -* @return 0 on success, otherwise a negative error value -* @retval #VC_ERROR_NONE Successful -* @retval #VC_ERROR_INVALID_STATE Invalid state -* -* @post If this function is called, the state will be #VC_STATE_NONE. -* -* @see vc_mgr_deinitialize() -*/ -int vc_mgr_deinitialize(); - -/** -* @brief Connects the voice control service. -* -* @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. -* @post If this function is called, the state will be #VC_STATE_READY. -* -* @see vc_mgr_unprepare() -*/ -int vc_mgr_prepare(); - -/** -* @brief Disconnects the vc-daemon. -* -* @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_READY. -* @post If this function is called, the state will be #VC_STATE_INITIALIZED. -* -* @see vc_mgr_prepare() -*/ -int vc_mgr_unprepare(); - -/** -* @brief Retrieves all supported languages using callback function. -* -* @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_OPERATION_FAILED Operation failure -* @retval #VC_ERROR_INVALID_STATE Invalid state -* -* @pre The state should NOT be #VC_SERVICE_STATE_NONE. -* @post This function invokes vc_supported_language_cb() repeatedly for getting languages. -* -* @see vc_supported_language_cb() -* @see vc_mgr_get_current_language() -*/ -int vc_mgr_foreach_supported_languages(vc_supported_language_cb callback, void* user_data); - -/** -* @brief Gets current language set by user. -* -* @remark If the function succeeds, @a language must be released with free() by you when you no longer need it. -* -* @param[out] language A language is specified as an ISO 3166 alpha-2 two letter country-code \n -* followed by ISO 639-1 for the two-letter language code. \n -* For example, "ko_KR" for Korean, "en_US" for American English. -* -* @return 0 on success, otherwise a negative error value -* @retval #VC_ERROR_NONE Successful -* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VC_ERROR_OUT_OF_MEMORY Out of memory -* @retval #VC_ERROR_OPERATION_FAILED Operation failure -* @retval #VC_ERROR_INVALID_STATE Invalid state -* -* @pre The state should NOT be #VC_SERVICE_STATE_NONE. -* -* @see vc_mgr_foreach_supported_languages() -*/ -int vc_mgr_get_current_language(char** language); - -/** -* @brief Gets current state of voice control manager. -* -* @param[out] state The current state -* -* @return 0 on success, otherwise a negative error value -* @retval #VC_ERROR_NONE Successful -* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter -* -* @pre The state should NOT be #VC_SERVICE_STATE_NONE. -* -* @see vc_state_changed_cb() -* @see vc_set_state_changed_cb() -*/ -int vc_mgr_get_state(vc_state_e* state); - -/** -* @brief Gets current state of voice control service. -* -* @param[out] state The current state -* -* @return 0 on success, otherwise a negative error value -* @retval #VC_ERROR_NONE Successful -* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter -* -* @pre The state should be #VC_STATE_READY. -* -* @see vc_mgr_start() -* @see vc_mgr_stop() -* @see vc_mgr_cancel() -* @see vc_set_service_state_changed_cb() -* @see vc_unset_service_state_changed_cb() -*/ -int vc_mgr_get_service_state(vc_service_state_e* state); - -/** -* @brief Sets demandable client list. -* -* @param[in] rule demandable client list rule path -* -* @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_READY. -* -* @see vc_mgr_get_demandable_client_rule() -*/ -int vc_mgr_set_demandable_client_rule(const char* rule); - -/** -* @brief Gets demandable client list. -* -* @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_READY. -* -* @see vc_mgr_set_demandable_client_rule() -*/ -int vc_mgr_unset_demandable_client_rule(); - -/** -* @brief Checks whether the command format is supported. -* -* @param[in] format The command format -* @param[out] support The result status @c true = supported, @c false = not supported -* -* @return 0 on success, otherwise a negative error value -* @retval #VC_ERROR_NONE Successful -* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter -* @retval #VC_ERROR_OPERATION_FAILED Operation failure -* @retval #VC_ERROR_INVALID_STATE Invalid state -* -* @pre The state should be #VC_STATE_READY. -*/ -int vc_mgr_is_command_format_supported(vc_cmd_format_e format, bool* support); - -/** -* @brief Sets system or exclusive commands. -* -* @remarks The command type is valid for VC_COMMAND_TYPE_SYSTEM or VC_COMMAND_TYPE_EXCLUSIVE. -* 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 -* -* @pre The state should be #VC_STATE_READY. -* -* @see vc_mgr_unset_command_list() -*/ + * @brief Called when an application (VC client) requests dialog. + * @since_tizen 5.0 + * + * @remarks The @a disp_text and @a utt_text are managed by the platform and will be released when invoking this callback is finished. + * + * @param[in] pid Pid of VC client to request dialog + * @param[in] disp_text Text requested to be displayed + * @param[in] utt_text Text requested 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 Called when engine sets private data to manager client. + * @since_tizen 5.0 + * + * @remarks The @a key and @a data are managed by the platform and will be released when invoking this callback is finished. + * + * @param[in] key Private key + * @param[in] data Private data + * @param[in] user_data The user data passed from the callback registration function + * + * @pre An application registers callback function using vc_mgr_set_private_data_set_cb(). + * + * @see vc_mgr_set_private_data_set_cb() + * @see vc_mgr_unset_private_data_set_cb() + */ +typedef int (*vc_mgr_private_data_set_cb)(const char *key, const char *data, void *user_data); + +/** + * @brief Called when engine requests private data from manager client. + * @since_tizen 5.0 + * + * @remarks The @a data should not be released. The @a data and @a key are managed by the platform and will be released when invoking this callback is finished. + * + * @param[in] key Private key + * @param[out] data Private data + * @param[in] user_data The user data passed from the callback registration function + * + * @pre An application registers callback function using vc_mgr_set_private_data_requested_cb(). + * + * @see vc_mgr_set_private_data_requested_cb() + * @see vc_mgr_unset_private_data_requested_cb() + */ +typedef int (*vc_mgr_private_data_requested_cb)(const char *key, char **data, void *user_data); + +/** + * @platform + * @brief Initializes the voice control manager. + * @since_tizen 5.0 + * + * @privlevel public + * @privilege %http://tizen.org/privilege/recorder + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @remarks If the function succeeds, VC manager must be released with vc_mgr_deinitialize(). + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_OUT_OF_MEMORY Out of memory + * @retval #VC_ERROR_OPERATION_FAILED Operation fail + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_NONE. + * @post If this function is called, the state will be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_deinitialize() + */ +int vc_mgr_initialize(void); + +/** + * @platform + * @brief Deinitializes the voice control manager. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @post If this function is called, the state will be #VC_STATE_NONE. + * + * @see vc_mgr_initialize() + */ +int vc_mgr_deinitialize(void); + +/** + * @platform + * @brief Connects the voice control service. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * @post If this function is called, the state will be #VC_STATE_READY. + * + * @see vc_mgr_unprepare() + */ +int vc_mgr_prepare(void); + +/** + * @platform + * @brief Disconnects the voice control service. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_READY. + * @post If this function is called, the state will be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_prepare() + */ +int vc_mgr_unprepare(void); + +/** + * @platform + * @brief Retrieves all supported languages using callback function. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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_OPERATION_FAILED Operation failure + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should NOT be #VC_SERVICE_STATE_NONE. + * @post This function invokes vc_supported_language_cb() for each supported language. + * + * @see vc_supported_language_cb() + * @see vc_mgr_get_current_language() + */ +int vc_mgr_foreach_supported_languages(vc_supported_language_cb callback, void *user_data); + +/** + * @platform + * @brief Gets the current language set by user. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @remarks If the function succeeds, @a language must be released with free() by you when you no longer need it. + * + * @param[out] language A language is specified as an ISO 3166 alpha-2 two letter country-code \n + * followed by ISO 639-1 for the two-letter language code. \n + * For example, "ko_KR" for Korean, "en_US" for American English. + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VC_ERROR_OUT_OF_MEMORY Out of memory + * @retval #VC_ERROR_OPERATION_FAILED Operation failure + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should NOT be #VC_SERVICE_STATE_NONE. + * + * @see vc_mgr_foreach_supported_languages() + */ +int vc_mgr_get_current_language(char **language); + +/** + * @platform + * @brief Gets the current state of voice control manager. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @param[out] state The current state + * + * @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 VC not supported + * + * @pre The state should NOT be #VC_SERVICE_STATE_NONE. + * + * @see vc_state_changed_cb() + * @see vc_set_state_changed_cb() + */ +int vc_mgr_get_state(vc_state_e *state); + +/** + * @platform + * @brief Gets the current state of voice control service. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @param[out] state The current state + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_READY. + * + * @see vc_mgr_start() + * @see vc_mgr_stop() + * @see vc_mgr_cancel() + * @see vc_set_service_state_changed_cb() + * @see vc_unset_service_state_changed_cb() + */ +int vc_mgr_get_service_state(vc_service_state_e *state); + +/** + * @platform + * @brief Checks whether the command format is supported. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @param[in] format The command format + * @param[out] support The result status @c true = supported, @c false = not supported + * + * @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 VC not supported + * + * @pre The state should be #VC_STATE_READY. + */ +int vc_mgr_is_command_format_supported(vc_cmd_format_e format, bool *support); + +/** + * @platform + * @brief Sets all types of commands. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @remarks VC manager client can register all types of commands. + * 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_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_READY. + * + * @see vc_mgr_unset_command_list() + */ int vc_mgr_set_command_list(vc_cmd_list_h vc_cmd_list); /** -* @brief Unsets system or exclusive commands. -* -* @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_READY. -* -* @see vc_mgr_set_command_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). -* -* @param[in] vc_cmd_list The command list -* -* @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 and the service state should be #VC_SERVICE_STATE_READY. -*/ -int vc_mgr_get_current_commands(vc_cmd_list_h* vc_cmd_list); - -/** -* @brief Sets audio in type. -* -* @param[in] audio_id audio type (e.g. #VC_AUDIO_TYPE_BLUETOOTH or usb device id) -* -* @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 and the service state should be #VC_SERVICE_STATE_READY. -* -* @see vc_mgr_get_audio_type() -*/ -int vc_mgr_set_audio_type(const char* audio_id); - -/** -* @brief Gets audio-in type. -* -* @remarks audio_id must be released using free() when it is no longer required. -* -* @param[out] audio_id audio id (e.g. #VC_AUDIO_TYPE_BLUETOOTH or usb device id) -* -* @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 and the service state should be #VC_SERVICE_STATE_READY. -* -* @see vc_mgr_set_audio_type() -*/ -int vc_mgr_get_audio_type(char** audio_id); - -/** -* @brief Sets recognition mode. -* -* @param[in] mode recognition mode (e.g. #VC_RECOGNITION_MODE_STOP_BY_SILENCE is default value) -* -* @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_READY and the service state should be #VC_SERVICE_STATE_READY. -* -* @see vc_mgr_set_recognition_mode() -*/ + * @platform + * @brief Unsets all types of commands. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @remarks All previously registered commands will be unset. + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_READY. + * + * @see vc_mgr_set_command_list() + */ +int vc_mgr_unset_command_list(void); + +/** + * @platform + * @brief Sets commands from file. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @remarks The commands should include type, command text, format. + * + * @param[in] file_path The directory of a file which has command list + * @param[in] type The command type (e.g. #VC_COMMAND_TYPE_FOREGROUND, #VC_COMMAND_TYPE_BACKGROUND, #VC_COMMAND_TYPE_WIDGET, #VC_COMMAND_TYPE_SYSTEM, #VC_COMMAND_TYPE_SYSTEM_BACKGROUND, #VC_COMMAND_TYPE_EXCLUSIVE) + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @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); + +/** + * @platform + * @brief Sets background commands of preloaded app from file. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @remarks The command type is valid for #VC_COMMAND_TYPE_BACKGROUND. + * The commands should include type, command text, format. + * + * @param[in] file_path The directory of a file which has command list + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @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); + +/** + * @platform + * @brief Retrieves all available commands. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @remarks If the function succeeds, @a vc_cmd_list must be released with vc_cmd_list_destroy(vc_cmd_list, true). + * + * @param[in] vc_cmd_list The command list + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_READY and the service state should be #VC_SERVICE_STATE_READY. + */ +int vc_mgr_get_current_commands(vc_cmd_list_h *vc_cmd_list); + +/** + * @platform + * @brief Sets a type of audio-in. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @param[in] audio_id The audio type (e.g. #VC_AUDIO_TYPE_BLUETOOTH or USB device ID) + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_READY and the service state should be #VC_SERVICE_STATE_READY. + * + * @see vc_mgr_get_audio_type() + */ +int vc_mgr_set_audio_type(const char *audio_id); + +/** + * @platform + * @brief Gets a type of audio-in. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @remarks audio_id must be released using free() when it is no longer required. + * + * @param[out] audio_id The audio id (e.g. #VC_AUDIO_TYPE_BLUETOOTH or USB device ID) + * + * @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 VC not supported + * + * @pre The state should be #VC_STATE_READY and the service state should be #VC_SERVICE_STATE_READY. + * + * @see vc_mgr_set_audio_type() + */ +int vc_mgr_get_audio_type(char **audio_id); + +/** + * @platform + * @brief Sets recognition mode. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @param[in] mode Recognition mode (e.g. #VC_RECOGNITION_MODE_STOP_BY_SILENCE is default value) + * + * @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 VC not supported + * + * @pre The state should be #VC_STATE_READY and the service state should be #VC_SERVICE_STATE_READY. + * + * @see vc_mgr_set_recognition_mode() + */ int vc_mgr_set_recognition_mode(vc_recognition_mode_e mode); /** -* @brief Gets recognition mode. -* -* @param[out] mode recognition mode -* -* @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_READY. -* -* @see vc_mgr_get_recognition_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 -* If you want to use other mode, you can set mode with vc_mgr_set_recognition_mode(). -* -* @param[in] exclusive_command_option Exclusive command option -* -* @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 and the service state should be #VC_SERVICE_STATE_READY. -* @post It will invoke vc_service_state_changed_cb(), if you register a callback with vc_service_state_changed_cb(). \n -* If this function succeeds, the service state will be #VC_SERVICE_STATE_RECORDING. -* -* @see vc_mgr_stop() -* @see vc_mgr_cancel() -* @see vc_service_state_changed_cb() -* @see vc_mgr_set_recognition_mode() -* @see vc_mgr_get_recognition_mode() -*/ + * @platform + * @brief Gets recognition mode. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @param[out] mode Recognition mode + * + * @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 VC not supported + * + * @pre The state should be #VC_STATE_READY. + * + * @see vc_mgr_get_recognition_mode() + */ +int vc_mgr_get_recognition_mode(vc_recognition_mode_e *mode); + +/** + * @platform + * @brief Sets private data to VC engine. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @remarks VC manager client can set private data to VC engine using this function. + * + * @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_PARAMETER Invalid parameter + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The service state should be #VC_SERVICE_STATE_READY. + */ +int vc_mgr_set_private_data(const char *key, const char *data); + +/** + * @platform + * @brief Gets private data from VC engine. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @remarks VC manager client can get private data from VC engine using this function. + * @a 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_PARAMETER Invalid parameter + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The service state should be #VC_SERVICE_STATE_READY. + */ +int vc_mgr_get_private_data(const char *key, char **data); + +/** + * @platform + * @brief Requests to do action as if utterence is spoken. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The service state should be #VC_SERVICE_STATE_READY. + */ +int vc_mgr_do_action(vc_send_event_type_e type, char *send_event); + +/** + * @platform + * @brief Starts recognition. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @remarks The default recognition mode is #VC_RECOGNITION_MODE_STOP_BY_SILENCE. \n + * If you want to use other mode, you can set mode with vc_mgr_set_recognition_mode(). + * + * @param[in] exclusive_command_option Exclusive command option + * + * @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 + * @retval #VC_ERROR_IN_PROGRESS_TO_RECORDING In progress to recording + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_READY and the service state should be #VC_SERVICE_STATE_READY. + * @post It will invoke vc_service_state_changed_cb(), if you register a callback with vc_service_state_changed_cb(). \n + * If this function succeeds, the service state will be #VC_SERVICE_STATE_RECORDING. + * + * @see vc_mgr_stop() + * @see vc_mgr_cancel() + * @see vc_service_state_changed_cb() + * @see vc_mgr_set_recognition_mode() + * @see vc_mgr_get_recognition_mode() + */ int vc_mgr_start(bool exclusive_command_option); /** -* @brief Stop recognition. -* -* @return 0 on success, otherwise a negative error value -* @retval #VC_ERROR_NONE Successful -* @retval #VC_ERROR_INVALID_STATE Invalid state -* @retval #VC_ERROR_OPERATION_FAILED Operation failure -* -* @pre The service state should be #VC_SERVICE_STATE_RECORDING. -* @post It will invoke vc_service_state_changed_cb(), if you register a callback with vc_service_state_changed_cb(). \n -* If this function succeeds, the service state will be #VC_SERVICE_STATE_PROCESSING. -* -* @see vc_mgr_start() -* @see vc_mgr_cancel() -* @see vc_service_state_changed_cb() -* @see vc_mgr_result_cb() -*/ -int vc_mgr_stop(); - -/** -* @brief Cancels recognition. -* -* @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_RECORDING or #VC_SERVICE_STATE_PROCESSING. -* @post It will invoke vc_service_state_changed_cb(), if you register a callback with vc_service_state_changed_cb(). \n -* If this function succeeds, the service state will be #VC_SERVICE_STATE_READY. -* -* @see vc_mgr_start() -* @see vc_mgr_stop() -* @see vc_service_state_changed_cb() -*/ -int vc_mgr_cancel(); - -/** -* @brief Gets the microphone volume during recording. -* -* @param[out] volume Recording volume -* -* @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_RECORDING. -* -* @see vc_mgr_start() -*/ -int vc_mgr_get_recording_volume(float* volume); - -/** -* @brief Select valid result from all results. -* -* @param[in] vc_cmd_list The valid result list -* -* @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 vc_mgr_all_result_cb() should be called -* -* @see vc_mgr_all_result_cb() -*/ + * @platform + * @brief Stops recognition. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_OPERATION_FAILED Operation failure + * @retval #VC_ERROR_IN_PROGRESS_TO_READY In progress to ready + * @retval #VC_ERROR_IN_PROGRESS_TO_RECORDING In progress to recording + * @retval #VC_ERROR_IN_PROGRESS_TO_PROCESSING In progress to processing + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The service state should be #VC_SERVICE_STATE_RECORDING. + * @post It will invoke vc_service_state_changed_cb(), if you register a callback with vc_service_state_changed_cb(). \n + * If this function succeeds, the service state will be #VC_SERVICE_STATE_PROCESSING. + * + * @see vc_mgr_start() + * @see vc_mgr_cancel() + * @see vc_service_state_changed_cb() + * @see vc_mgr_result_cb() + */ +int vc_mgr_stop(void); + +/** + * @platform + * @brief Cancels recognition. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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 + * @retval #VC_ERROR_IN_PROGRESS_TO_READY In progress to ready + * @retval #VC_ERROR_IN_PROGRESS_TO_RECORDING In progress to recording + * @retval #VC_ERROR_IN_PROGRESS_TO_PROCESSING In progress to processing + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The service state should be #VC_SERVICE_STATE_RECORDING or #VC_SERVICE_STATE_PROCESSING. + * @post It will invoke vc_service_state_changed_cb(), if you register a callback with vc_service_state_changed_cb(). \n + * If this function succeeds, the service state will be #VC_SERVICE_STATE_READY. + * + * @see vc_mgr_start() + * @see vc_mgr_stop() + * @see vc_service_state_changed_cb() + */ +int vc_mgr_cancel(void); + +/** + * @platform + * @brief Gets the microphone volume during recording. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @param[out] volume Recording volume + * + * @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 VC not supported + * + * @pre The service state should be #VC_SERVICE_STATE_RECORDING. + * + * @see vc_mgr_start() + */ +int vc_mgr_get_recording_volume(float *volume); + +/** + * @platform + * @brief Selects valid results from all results. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @remarks This function should be called in vc_mgr_all_result_cb(). + * The @a vc_cmd_list can be NULL, in that case the function does nothing. + * @param[in] vc_cmd_list The valid result list + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre vc_mgr_all_result_cb() should be called + * + * @see vc_mgr_all_result_cb() + */ int vc_mgr_set_selected_results(vc_cmd_list_h vc_cmd_list); /** -* @brief Registers a callback function for getting 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_all_result_cb() -* @see vc_mgr_unset_all_result_cb() -*/ -int vc_mgr_set_all_result_cb(vc_mgr_all_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_all_result_cb() -*/ -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 -* @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_result_cb() -* @see vc_mgr_unset_result_cb() -*/ -int vc_mgr_set_result_cb(vc_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_result_cb() -*/ -int vc_mgr_unset_result_cb(); - -/** -* @brief Registers a callback function to be called when state is changed. -* -* @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_state_changed_cb() -* @see vc_mgr_unset_state_changed_cb() -*/ -int vc_mgr_set_state_changed_cb(vc_state_changed_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_state_changed_cb() -*/ -int vc_mgr_unset_state_changed_cb(); - -/** -* @brief Registers a callback function to be called when state is changed. -* -* @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_service_state_changed_cb() -* @see vc_mgr_unset_service_state_changed_cb() -*/ -int vc_mgr_set_service_state_changed_cb(vc_service_state_changed_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_service_state_changed_cb() -*/ -int vc_mgr_unset_service_state_changed_cb(); - -/** -* @brief Registers a callback function to be called when begin of speech is detected. -* -* @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_begin_speech_detected_cb() -* @see vc_mgr_unset_speech_detected_cb() -*/ -int vc_mgr_set_speech_detected_cb(vc_mgr_begin_speech_detected_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_speech_detected_cb() -*/ -int vc_mgr_unset_speech_detected_cb(); - -/** -* @brief Registers a callback function to be called when current language is changed. -* -* @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_current_language_changed_cb() -* @see vc_mgr_unset_current_language_changed_cb() -*/ -int vc_mgr_set_current_language_changed_cb(vc_current_language_changed_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_current_language_changed_cb() -*/ -int vc_mgr_unset_current_language_changed_cb(); - -/** -* @brief Gets the current error message. -* -* @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 -* -* @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 -* @retval #VC_ERROR_OUT_OF_MEMORY Out of memory -* -* @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 -* @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_error_cb() -* @see vc_mgr_unset_error_cb() -*/ -int vc_mgr_set_error_cb(vc_error_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_error_cb() -*/ -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(); - -/** -* @brief Enable command type as candidate command. -* -* @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_READY. -* -* @see vc_mgr_disable_command_type() -*/ + * @platform + * @brief Sets a callback function for getting recognition result. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_all_result_cb() + * @see vc_mgr_unset_all_result_cb() + */ +int vc_mgr_set_all_result_cb(vc_mgr_all_result_cb callback, void *user_data); + +/** + * @platform + * @brief Unsets the recognition result callback function. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_set_all_result_cb() + */ +int vc_mgr_unset_all_result_cb(void); + +/** + * @platform + * @brief Sets a callback function for getting pre recognition result. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @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); + +/** + * @platform + * @brief Unsets the pre recognition result callback function. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_set_pre_result_cb() + */ +int vc_mgr_unset_pre_result_cb(void); + +/** + * @platform + * @brief Sets a callback function for getting all types of recognition results. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_result_cb() + * @see vc_mgr_unset_result_cb() + */ +int vc_mgr_set_result_cb(vc_result_cb callback, void *user_data); + +/** + * @platform + * @brief Unsets the callback function for getting all types of recognition results. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_set_result_cb() + */ +int vc_mgr_unset_result_cb(void); + +/** + * @platform + * @brief Sets a callback function to be called when state is changed. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_state_changed_cb() + * @see vc_mgr_unset_state_changed_cb() + */ +int vc_mgr_set_state_changed_cb(vc_state_changed_cb callback, void *user_data); + +/** + * @platform + * @brief Unsets the state changed callback function. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_set_state_changed_cb() + */ +int vc_mgr_unset_state_changed_cb(void); + +/** + * @platform + * @brief Sets a callback function to be called when service state is changed. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_service_state_changed_cb() + * @see vc_mgr_unset_service_state_changed_cb() + */ +int vc_mgr_set_service_state_changed_cb(vc_service_state_changed_cb callback, void *user_data); + +/** + * @platform + * @brief Unsets the service state changed callback function. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_set_service_state_changed_cb() + */ +int vc_mgr_unset_service_state_changed_cb(void); + +/** + * @platform + * @brief Sets a callback function to be called when begin of speech is detected. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_begin_speech_detected_cb() + * @see vc_mgr_unset_speech_detected_cb() + */ +int vc_mgr_set_speech_detected_cb(vc_mgr_begin_speech_detected_cb callback, void *user_data); + +/** + * @platform + * @brief Unsets the speech detected callback function. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_set_speech_detected_cb() + */ +int vc_mgr_unset_speech_detected_cb(void); + +/** + * @platform + * @brief Sets a callback function to be called when current language is changed. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_current_language_changed_cb() + * @see vc_mgr_unset_current_language_changed_cb() + */ +int vc_mgr_set_current_language_changed_cb(vc_current_language_changed_cb callback, void *user_data); + +/** + * @platform + * @brief Unsets the current language changed callback function. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_set_current_language_changed_cb() + */ +int vc_mgr_unset_current_language_changed_cb(void); + +/** + * @platform + * @brief Gets the current error message. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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 + * + * @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 + * @retval #VC_ERROR_OUT_OF_MEMORY Out of memory + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @see vc_error_cb() + */ +int vc_mgr_get_error_message(char **err_msg); + +/** + * @platform + * @brief Sets a callback function to be called when an error occurred. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_error_cb() + * @see vc_mgr_unset_error_cb() + */ +int vc_mgr_set_error_cb(vc_error_cb callback, void *user_data); + +/** + * @platform + * @brief Unsets the callback function to be called when an error occurred. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_set_error_cb() + */ +int vc_mgr_unset_error_cb(void); + + +/** + * @platform + * @brief Sets a callback function to be called when dialog requests. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @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); + +/** + * @platform + * @brief Unsets the callback function to be called when dialog requests. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_set_dialog_request_cb() + */ +int vc_mgr_unset_dialog_request_cb(void); + +/** + * @platform + * @brief Enables command type as candidate command. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @param[in] cmd_type The command type (e.g. #VC_COMMAND_TYPE_FOREGROUND, #VC_COMMAND_TYPE_BACKGROUND, #VC_COMMAND_TYPE_WIDGET, #VC_COMMAND_TYPE_SYSTEM, #VC_COMMAND_TYPE_SYSTEM_BACKGROUND, #VC_COMMAND_TYPE_EXCLUSIVE) + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_READY. + * + * @see vc_mgr_disable_command_type() + */ int vc_mgr_enable_command_type(int cmd_type); /** -* @brief Disable command type as candidate command. -* -* @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_READY. -* -* @see vc_mgr_enable_command_type() -*/ + * @platform + * @brief Disables command type as candidate command. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @param[in] cmd_type The command type (e.g. #VC_COMMAND_TYPE_FOREGROUND, #VC_COMMAND_TYPE_BACKGROUND, #VC_COMMAND_TYPE_WIDGET, #VC_COMMAND_TYPE_SYSTEM, #VC_COMMAND_TYPE_SYSTEM_BACKGROUND, #VC_COMMAND_TYPE_EXCLUSIVE) + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_READY. + * + * @see vc_mgr_enable_command_type() + */ int vc_mgr_disable_command_type(int cmd_type); /** -* @brief Registers a callback function to be called when engine set private data. -* -* @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_private_data_set_cb() -* @see vc_mgr_unset_private_data_set_cb() -*/ -int vc_mgr_set_private_data_set_cb(vc_mgr_private_data_set_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_private_data_set_cb() -*/ -int vc_mgr_unset_private_data_set_cb(); - -/** -* @brief Registers a callback function to be called when engine request private data. -* -* @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_private_data_requested_cb() -* @see vc_mgr_unset_private_data_requested_cb() -*/ -int vc_mgr_set_private_data_requested_cb(vc_mgr_private_data_requested_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_private_data_requested_cb() -*/ -int vc_mgr_unset_private_data_requested_cb(); + * @platform + * @brief Sets a callback function to be called when engine set private data. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_private_data_set_cb() + * @see vc_mgr_unset_private_data_set_cb() + */ +int vc_mgr_set_private_data_set_cb(vc_mgr_private_data_set_cb callback, void *user_data); + +/** + * @platform + * @brief Unsets the callback function to be called when engine set private data. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_set_private_data_set_cb() + */ +int vc_mgr_unset_private_data_set_cb(void); + +/** + * @platform + * @brief Sets a callback function to be called when engine request private data. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_private_data_requested_cb() + * @see vc_mgr_unset_private_data_requested_cb() + */ +int vc_mgr_set_private_data_requested_cb(vc_mgr_private_data_requested_cb callback, void *user_data); + +/** + * @platform + * @brief Unsets the callback function to be called when engine request private data. + * @since_tizen 5.0 + * + * @privlevel platform + * @privilege %http://tizen.org/privilege/voicecontrol.manager + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_INITIALIZED. + * + * @see vc_mgr_set_private_data_requested_cb() + */ +int vc_mgr_unset_private_data_requested_cb(void); #ifdef __cplusplus } diff --git a/include/voice_control_manager_internal.h b/include/voice_control_manager_internal.h new file mode 100644 index 0000000..c06d38b --- /dev/null +++ b/include/voice_control_manager_internal.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2011-2018 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 __VOICE_CONTROL_MANAGER_INTERNAL_H__ +#define __VOICE_CONTROL_MANAGER_INTERNAL_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** + * @brief Sets demandable client list. + * + * @param[in] rule demandable client list rule path + * + * @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 + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_READY. + * + * @see vc_mgr_get_demandable_client_rule() + */ +int vc_mgr_set_demandable_client_rule(const char* rule); + +/** + * @brief Gets demandable client list. + * + * @return 0 on success, otherwise a negative error value + * @retval #VC_ERROR_NONE Successful + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The state should be #VC_STATE_READY. + * + * @see vc_mgr_set_demandable_client_rule() + */ +int vc_mgr_unset_demandable_client_rule(void); + +/** + * @brief Sets domain such as agent or device type. + * @since_tizen 5.0 + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #VC_ERROR_INVALID_STATE Invalid state + * @retval #VC_ERROR_PERMISSION_DENIED Permission denied + * @retval #VC_ERROR_NOT_SUPPORTED VC not supported + * + * @pre The service state should be #VC_SERVICE_STATE_READY. + */ +int vc_mgr_set_domain(const char* domain); + + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __VOICE_CONTROL_MANAGER_INTERNAL_H__ */ + diff --git a/include/voice_control_widget.h b/include/voice_control_widget.h index 510eb20..93c3e4c 100644 --- a/include/voice_control_widget.h +++ b/include/voice_control_widget.h @@ -574,7 +574,7 @@ int vc_widget_unset_asr_result_cb(vc_h vc); #endif /** - * @}@} + * @} */ #endif /* __VOICE_CONTROL_WIDGET_H__ */ diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index 9bc04cd..9483add 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -152,6 +152,7 @@ mkdir -p %{_libdir}/voice/vc %defattr(-,root,root,-) %{_libdir}/pkgconfig/voice-control-manager.pc %{_includedir}/voice_control_manager.h +%{_includedir}/voice_control_manager_internal.h %{_includedir}/voice_control_command.h %{_includedir}/voice_control_common.h %{_includedir}/voice_control_key_defines.h -- 2.7.4 From 0337478daef1b5b5f501e954363d199e49b384bf Mon Sep 17 00:00:00 2001 From: sungrae jo Date: Mon, 30 Apr 2018 13:31:41 +0900 Subject: [PATCH 02/16] Add client cleanup code Change-Id: Ia645bb071a54092ac9ddefe8099a834a8c2b273d Signed-off-by: sungrae jo --- server/vcd_server.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/server/vcd_server.c b/server/vcd_server.c index 872e95b..5ac1869 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -33,6 +33,7 @@ #include "voice_control_command_expand.h" #include "voice_control_common.h" +#define CLIENT_CLEAN_UP_TIME 500 /* * VC Server static variable */ @@ -40,6 +41,7 @@ static GList *g_proc_list = NULL; static Ecore_Timer *g_restart_timer = NULL; static Ecore_Timer *g_check_widget_client_timer = NULL; +static Ecore_Timer *g_check_client_timer = NULL; /** * @brief Enumerations of send event type. @@ -1172,6 +1174,12 @@ int vcd_initialize(vce_request_callback_s *callback) vcd_config_set_service_state(VCD_STATE_READY); vcdc_send_service_state(VCD_STATE_READY); + /* Set timer cleanup client all */ + g_check_client_timer = ecore_timer_add(CLIENT_CLEAN_UP_TIME, vcd_cleanup_client_all, NULL); + if (NULL == g_check_client_timer) { + SLOG(LOG_WARN, TAG_VCD, "[Server Warning] Fail to create timer of client check"); + } + SLOG(LOG_ERROR, TAG_VCD, "[Server SUCCESS] initialize"); return 0; @@ -1188,11 +1196,16 @@ bool vcd_finalize() } } - if (g_restart_timer != NULL) { + if (NULL != g_restart_timer) { ecore_timer_del(g_restart_timer); g_restart_timer = NULL; } + if (NULL != g_check_client_timer) { + ecore_timer_del(g_check_client_timer); + g_check_client_timer = NULL; + } + vcd_state_e state = vcd_config_get_service_state(); if (VCD_STATE_READY != state) { if (VCD_STATE_RECORDING == state) { -- 2.7.4 From 145153364e60d829877ed8a5297679cee0d7d4fd Mon Sep 17 00:00:00 2001 From: sungrae jo Date: Mon, 30 Apr 2018 13:47:03 +0900 Subject: [PATCH 03/16] Fixed vce command header Change-Id: Icd9d26f65494cfbb5791e18c28f9e603a0294e0a Signed-off-by: sungrae jo --- include/vce.h | 3 +-- server/vcd_main.h | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/vce.h b/include/vce.h index 2712547..d37ffbe 100644 --- a/include/vce.h +++ b/include/vce.h @@ -18,7 +18,6 @@ #ifndef __VCE_H__ #define __VCE_H__ -#include /** * @addtogroup CAPI_UIX_VOICE_CONTROL_ENGINE_MODULE @@ -105,7 +104,7 @@ typedef enum { * @brief A structure of handle for VC command. * @since_tizen 5.0 */ -typedef int vce_cmd_h; +typedef struct vce_cmd_s* vce_cmd_h; /** * @brief Definition for foreground command type. diff --git a/server/vcd_main.h b/server/vcd_main.h index 9393804..72e105c 100644 --- a/server/vcd_main.h +++ b/server/vcd_main.h @@ -73,6 +73,10 @@ typedef enum { } vcd_state_e; typedef struct { + int index; +} vce_cmd_s; + +typedef struct { int version; /**< Version */ /* Mandatory callbacks */ -- 2.7.4 From f7f39ca366f18efb12c859d455368845387bc52d Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Mon, 30 Apr 2018 18:00:06 +0900 Subject: [PATCH 04/16] Fix dbus policy Change-Id: If87853f48be5f391698fe0749b62cd4c1453738e Signed-off-by: sooyeon.kim --- vc-server.conf | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/vc-server.conf b/vc-server.conf index 58c306e..60a1d1b 100644 --- a/vc-server.conf +++ b/vc-server.conf @@ -3,46 +3,17 @@ - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - -- 2.7.4 From fb68ea33b35910bf42c1eab4889e1ba4e56ace35 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Wed, 2 May 2018 14:08:23 +0900 Subject: [PATCH 05/16] Add a service file for TV profile Change-Id: I1b13c7cdbd6a346a7d87915018d7425501284013 Signed-off-by: sooyeon.kim --- org.tizen.voice.vcserver.tv.service | 4 ++++ packaging/voice-control.spec | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 org.tizen.voice.vcserver.tv.service diff --git a/org.tizen.voice.vcserver.tv.service b/org.tizen.voice.vcserver.tv.service new file mode 100644 index 0000000..22b0781 --- /dev/null +++ b/org.tizen.voice.vcserver.tv.service @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=org.tizen.voice.vcserver +#Exec=/usr/bin/vc-daemon +Exec=/bin/sh -c "launch_app org.tizen.voice-client" diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index 9483add..278936c 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -104,6 +104,10 @@ make %{?jobs:-j%jobs} %install rm -rf %{buildroot} +%if "%{tizen_profile_name}" == "tv" +mv -f org.tizen.voice.vcserver.tv.service org.tizen.voice.vcserver.service +%endif + %make_install %post -- 2.7.4 From ffbede3137d3d2dda97293dff1d0b17b8c4de8f1 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Tue, 8 May 2018 18:54:55 +0900 Subject: [PATCH 06/16] Destroy cmd list after use Change-Id: I3c2473cde20de094eafff87b4406ccaae015714d Signed-off-by: Wonnam Jang --- server/vcd_server.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/vcd_server.c b/server/vcd_server.c index 5ac1869..baee35e 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -751,11 +751,12 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c // There are more than one result. if (false == vcd_client_manager_get_exclusive()) { + vc_cmd_list_h temp_list = NULL; + /* Foreground, Widget, Background, System, System-Background */ if (top_priority >= VC_COMMAND_PRIORITY_BACKGROUND) { vc_cmd_list_h widget_cmd_list = NULL; vc_cmd_list_h foreground_cmd_list = NULL; - vc_cmd_list_h temp_list = NULL; int cnt = 0; if (0 != vc_cmd_list_create(&temp_list)) { @@ -815,7 +816,6 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c vc_cmd_list_destroy(foreground_cmd_list, true); } vc_cmd_list_destroy(widget_cmd_list, true); - vc_cmd_list_destroy(temp_list, true); } int pid = vcd_client_widget_get_foreground_pid(); @@ -825,6 +825,7 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c } vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, false); + vc_cmd_list_destroy(vc_cmd_list, true); if (-1 != vcd_client_manager_get_pid()) { /* Manager client is available */ @@ -838,6 +839,7 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c } else { /* exclusive command */ vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, true); + vc_cmd_list_destroy(vc_cmd_list, true); if (-1 != vcd_client_manager_get_pid()) { /* Manager client is available */ @@ -851,8 +853,6 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c vcd_client_manager_set_exclusive(false); } - vc_cmd_list_destroy(vc_cmd_list, true); - if (VCD_RECOGNITION_MODE_RESTART_AFTER_REJECT == recognition_mode) { if (VCE_RESULT_EVENT_REJECTED == event) { SLOG(LOG_DEBUG, TAG_VCD, "[Server] Restart by no or rejected result"); -- 2.7.4 From 7f3e13f65ad8eae50d0c7fde8c4470e210ac913f Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Fri, 18 May 2018 14:18:45 +0900 Subject: [PATCH 07/16] Do not return error when vc feature is disabled Change-Id: I42123b6108212320497f7e2d4a048091fe2f88e6 Signed-off-by: Wonnam Jang --- client/vc_widget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/vc_widget.c b/client/vc_widget.c index 46d68ac..6e5ea93 100644 --- a/client/vc_widget.c +++ b/client/vc_widget.c @@ -152,7 +152,7 @@ int vc_widget_initialize(vc_h* vc_w) if (0 != __vc_widget_get_feature_enabled()) { SLOG(LOG_ERROR, TAG_VCW, "@@@ [Widget] not supported"); - return VC_ERROR_NOT_SUPPORTED; + return VC_ERROR_NONE; } if (NULL == vc_w) { @@ -370,7 +370,7 @@ static Eina_Bool __vc_widget_connect_daemon(void *data) ecore_main_loop_thread_safe_call_async(__vc_widget_notify_error, vc_w); SLOG(LOG_DEBUG, TAG_VCW, "@@@"); - return EINA_FALSE; + return EINA_TRUE; } vc_widget_client_set_service_state(vc_w, (vc_service_state_e)service_state); -- 2.7.4 From 60e86d06347726c1516f2d16281ac9e152236b6c Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Mon, 21 May 2018 11:02:31 +0900 Subject: [PATCH 08/16] No error when pid is already added on vc server Change-Id: I5ec883ede970b65d77555ebb40070cf269bc6bbb Signed-off-by: Wonnam Jang --- server/vcd_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/vcd_server.c b/server/vcd_server.c index baee35e..0a9b9e9 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -2090,8 +2090,8 @@ int vcd_server_initialize(int pid) /* check if pid is valid */ if (true == vcd_client_is_available(pid)) { - SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The pid is already exist"); - return VCD_ERROR_INVALID_PARAMETER; + SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] The pid is already exist"); + return VCD_ERROR_NONE; } /* Add client information to client manager */ -- 2.7.4 From f1b1491ea447fa6e881dd80c98a1eec0f220ba61 Mon Sep 17 00:00:00 2001 From: sungrae jo Date: Mon, 21 May 2018 18:59:29 +0900 Subject: [PATCH 09/16] Remove daemon reset for web TC Change-Id: I9b815897b8c98101c27daf2cddd0addbab54e01b Signed-off-by: sungrae jo --- client/vc_dbus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/vc_dbus.c b/client/vc_dbus.c index cab1bcb..51714b3 100644 --- a/client/vc_dbus.c +++ b/client/vc_dbus.c @@ -170,7 +170,8 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle SLOG(LOG_ERROR, TAG_VCC, "Match Error (%s)", err.message); dbus_error_free(&err); } - __vc_cb_error(VC_ERROR_SERVICE_RESET, -1, "Daemon Reset"); + //FIXME + //__vc_cb_error(VC_ERROR_SERVICE_RESET, -1, "Daemon Reset"); SLOG(LOG_DEBUG, TAG_VCC, "@@@"); } /* NameOwnerChanged */ -- 2.7.4 From 01776134e70dac60ab9c2b20d8c52ccadb49b9c9 Mon Sep 17 00:00:00 2001 From: sungrae jo Date: Mon, 21 May 2018 21:48:18 +0900 Subject: [PATCH 10/16] Fixed thread unsafe bug when deinitialize as soon as initialize Change-Id: Ia8a615696212f69472e915c4489dd8a86331db70 Signed-off-by: sungrae jo --- client/vc_widget.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/client/vc_widget.c b/client/vc_widget.c index 6e5ea93..ea0d2cf 100644 --- a/client/vc_widget.c +++ b/client/vc_widget.c @@ -262,6 +262,21 @@ int vc_widget_deinitialize(vc_h vc_w) return VC_ERROR_INVALID_STATE; } + + int thread_count = ecore_thread_active_get(); + int count = 0; + while (0 < thread_count) { + usleep(50000); + count++; + if (100 == count) { + SLOG(LOG_WARN, TAG_VCW, "[WARNING!!] Thread is blocked, cnt(%d), thread count(%d)", count, thread_count); + break; + } else if (0 == count % 5) { + SLOG(LOG_WARN, TAG_VCW, "[WARNING!!] Thread is alive, cnt(%d), thread count(%d)", count, thread_count); + } + thread_count = ecore_thread_active_get(); + } + vc_state_e state; vc_widget_client_get_state(vc_w, &state); vc_widget_s* widget = widget_get(vc_w); @@ -338,7 +353,7 @@ static Eina_Bool __focus_changed_cb(void *data, int type, void *event) return ECORE_CALLBACK_RENEW; } -static Eina_Bool __vc_widget_connect_daemon(void *data) +static void __vc_widget_connect_daemon(void *data) { vc_h vc_w = (vc_h)data; @@ -359,7 +374,7 @@ static Eina_Bool __vc_widget_connect_daemon(void *data) ecore_main_loop_thread_safe_call_async(__vc_widget_notify_error, vc_w); SLOG(LOG_DEBUG, TAG_VCW, "@@@"); - return EINA_FALSE; + return; } else if (VC_ERROR_INVALID_PARAMETER == ret) { SLOG(LOG_WARN, TAG_VCW, "[WARNING] Invalid Parameter"); @@ -370,19 +385,17 @@ static Eina_Bool __vc_widget_connect_daemon(void *data) ecore_main_loop_thread_safe_call_async(__vc_widget_notify_error, vc_w); SLOG(LOG_DEBUG, TAG_VCW, "@@@"); - return EINA_TRUE; + return; } vc_widget_client_set_service_state(vc_w, (vc_service_state_e)service_state); SLOG(LOG_INFO, TAG_VCW, "@@@ [Widget] Connect daemon"); - ecore_thread_main_loop_begin(); if (NULL == g_focus_in_handler) g_focus_in_handler = ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN, __focus_changed_cb, NULL); if (NULL == g_focus_out_handler) g_focus_out_handler = ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT, __focus_changed_cb, NULL); - ecore_thread_main_loop_end(); char appid[1024] = {'\0',}; aul_app_get_appid_bypid(getpid(), appid, sizeof(appid) - 1); @@ -419,7 +432,7 @@ static Eina_Bool __vc_widget_connect_daemon(void *data) SLOG(LOG_DEBUG, TAG_VCW, "@@@"); - return EINA_FALSE; + return; } static void __start_prepare_thread(void *data, Ecore_Thread *thread) @@ -444,6 +457,7 @@ static void __start_prepare_thread(void *data, Ecore_Thread *thread) } } +#if 0 ret = -1; retry_count = 0; while (0 != ret) { @@ -457,6 +471,9 @@ static void __start_prepare_thread(void *data, Ecore_Thread *thread) else retry_count++; } +#endif + + ecore_main_loop_thread_safe_call_async(__vc_widget_connect_daemon, vc_w); return; } -- 2.7.4 From b1521796d5d40d5270ea973cff9e7b2d2feaefef Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Wed, 23 May 2018 16:10:03 +0900 Subject: [PATCH 11/16] Move 'dbus_bus_add_match' to vc_dbus_request_initialize Change-Id: I8e446a807b7919f37878e70154661a35e961e23a Signed-off-by: sooyeon.kim --- client/vc.c | 1 + client/vc_dbus.c | 25 ++++++++++++------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/client/vc.c b/client/vc.c index b3c9b24..9a893f3 100644 --- a/client/vc.c +++ b/client/vc.c @@ -1631,6 +1631,7 @@ int __vc_cb_error(int reason, int daemon_pid, char* msg) /* check state */ if (state != VC_STATE_READY) { + SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] State is not READY"); if (VC_ERROR_SERVICE_RESET != reason) { SLOG(LOG_ERROR, TAG_VCC, "[ERROR] not connected client yet"); return -1; diff --git a/client/vc_dbus.c b/client/vc_dbus.c index 51714b3..186d259 100644 --- a/client/vc_dbus.c +++ b/client/vc_dbus.c @@ -170,8 +170,8 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle SLOG(LOG_ERROR, TAG_VCC, "Match Error (%s)", err.message); dbus_error_free(&err); } - //FIXME - //__vc_cb_error(VC_ERROR_SERVICE_RESET, -1, "Daemon Reset"); + + __vc_cb_error(VC_ERROR_SERVICE_RESET, -1, "Daemon Reset"); SLOG(LOG_DEBUG, TAG_VCC, "@@@"); } /* NameOwnerChanged */ @@ -286,17 +286,6 @@ int vc_dbus_open_connection() return VC_ERROR_OPERATION_FAILED; } - /* add a rule for daemon error */ - snprintf(rule, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", VC_SERVER_SERVICE_INTERFACE); - dbus_bus_add_match(g_conn_listener, rule, &err); - - if (dbus_error_is_set(&err)) { - SLOG(LOG_ERROR, TAG_VCC, "Match Error (%s)", err.message); - dbus_error_free(&err); - __vc_dbus_connection_free(); - return VC_ERROR_OPERATION_FAILED; - } - int fd = 0; if (1 != dbus_connection_get_unix_fd(g_conn_listener, &fd)) { SLOG(LOG_ERROR, TAG_VCC, "fail to get fd from dbus "); @@ -496,6 +485,16 @@ int vc_dbus_request_initialize(int pid, int* mgr_pid, int* service_state, int* d *service_state = tmp_service_state; *daemon_pid = tmp_daemon_pid; + /* add a rule for daemon error */ + char rule[256] = {0, }; + snprintf(rule, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", VC_SERVER_SERVICE_INTERFACE); + dbus_bus_add_match(g_conn_listener, rule, &err); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCC, "Match Error (%s)", err.message); + dbus_error_free(&err); + } + 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); -- 2.7.4 From 6a3d144029eb9b73afaeca49f1fdea6ffb4ec16f Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Thu, 24 May 2018 08:40:00 +0900 Subject: [PATCH 12/16] Fix coverity issues Change-Id: I46e33c4e2d2425055c5a0540575f56e828654ce4 Signed-off-by: Wonnam Jang --- client/vc_mgr_dbus.c | 6 +++--- common/vc_cmd_db.c | 26 +++++++++++++++++--------- server/vcd_dbus.c | 36 ++++++++++++++++++++++++++++-------- server/vcd_recorder.c | 8 ++++---- 4 files changed, 52 insertions(+), 24 deletions(-) diff --git a/client/vc_mgr_dbus.c b/client/vc_mgr_dbus.c index 2277fa9..0935452 100644 --- a/client/vc_mgr_dbus.c +++ b/client/vc_mgr_dbus.c @@ -286,12 +286,12 @@ static Eina_Bool vc_mgr_listener_event_callback(void* data, Ecore_Fd_Handler *fd int pid = 0; int ret = -1; char* key = NULL; - char* data = NULL; + char* private_data = NULL; dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_STRING, &key, - DBUS_TYPE_STRING, &data, + DBUS_TYPE_STRING, &private_data, DBUS_TYPE_INVALID); if (dbus_error_is_set(&err)) { @@ -301,7 +301,7 @@ static Eina_Bool vc_mgr_listener_event_callback(void* data, Ecore_Fd_Handler *fd if (pid > 0) { SLOG(LOG_DEBUG, TAG_VCM, "@@ vc mgr get request set private data : pid(%d) ", pid); - ret = __vc_mgr_cb_private_data_set(key, data); + ret = __vc_mgr_cb_private_data_set(key, private_data); } else { SLOG(LOG_ERROR, TAG_VCM, "@@ vc mgr get requset set private data : invalid pid "); } diff --git a/common/vc_cmd_db.c b/common/vc_cmd_db.c index 7c74a97..928dfac 100644 --- a/common/vc_cmd_db.c +++ b/common/vc_cmd_db.c @@ -692,6 +692,10 @@ static int __vc_db_extract_unfixed_command(char* command, char* fixed, char** te } char* temp = (char*)calloc(256, sizeof(char)); + if (NULL == temp) { + SLOG(LOG_ERROR, vc_db_tag(), "[ERROR] Fail to allocate memory"); + return VC_DB_ERROR_OUT_OF_MEMORY; + } if (0 == strncasecmp(command, fixed, strlen(fixed))) { strncpy(temp, command + strlen(fixed) + 1, strlen(command) - strlen(fixed) - 1); SLOG(LOG_WARN, vc_db_tag(), "@@@"); @@ -1610,17 +1614,21 @@ static int __vc_db_generate_command(vc_cmd_s* cmd, char** fixed_cmd, GSList** cm // extract fixed command and remove space in front of '{' 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_r(NULL, "|", &tok_ptr))) { + if (NULL != temp) { __vc_db_remove_space(&temp); + *fixed_cmd = strdup(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); + // merge command with fixed and vfixed + while (NULL != (temp = strtok_r(NULL, "|", &tok_ptr))) { + __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 { + *fixed_cmd = strdup(cmd->command); } } else if (VC_CMD_FORMAT_VFIXED_AND_FIXED == cmd->format) { // check string validation diff --git a/server/vcd_dbus.c b/server/vcd_dbus.c index 5d37055..250e5a0 100755 --- a/server/vcd_dbus.c +++ b/server/vcd_dbus.c @@ -1049,6 +1049,20 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handle return ECORE_CALLBACK_RENEW; } +static void __vcd_dbus_connection_free() +{ + if (NULL != g_conn_listener) { + dbus_connection_close(g_conn_listener); + dbus_connection_unref(g_conn_listener); + g_conn_listener = NULL; + } + if (NULL != g_conn_sender) { + dbus_connection_close(g_conn_sender); + dbus_connection_unref(g_conn_sender); + g_conn_sender = NULL; + } +} + int vcd_dbus_open_connection() { DBusError err; @@ -1081,6 +1095,7 @@ int vcd_dbus_open_connection() if (NULL == g_conn_listener) { SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to get dbus connection"); + __vcd_dbus_connection_free(); return VCD_ERROR_OPERATION_FAILED; } @@ -1092,12 +1107,14 @@ int vcd_dbus_open_connection() if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { printf("Fail to be primary owner in dbus request."); SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to be primary owner"); + __vcd_dbus_connection_free(); return VCD_ERROR_OPERATION_FAILED; } if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] dbus_bus_request_name() : %s", err.message); dbus_error_free(&err); + __vcd_dbus_connection_free(); return VCD_ERROR_OPERATION_FAILED; } @@ -1111,16 +1128,25 @@ int vcd_dbus_open_connection() if (dbus_error_is_set(&err)) { SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] dbus_bus_add_match() : %s", err.message); dbus_error_free(&err); + __vcd_dbus_connection_free(); return VCD_ERROR_OPERATION_FAILED; } int fd = 0; - dbus_connection_get_unix_fd(g_conn_listener, &fd); + if (1 != dbus_connection_get_unix_fd(g_conn_listener, &fd)) { + SLOG(LOG_ERROR, TAG_VCD, "fail to get fd from dbus "); + __vcd_dbus_connection_free(); + return VCD_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCD, "Get fd from dbus : %d", fd); + } + g_dbus_fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)listener_event_callback, g_conn_listener, NULL, NULL); if (NULL == g_dbus_fd_handler) { SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to get fd handler"); + __vcd_dbus_connection_free(); return VCD_ERROR_OPERATION_FAILED; } @@ -1144,13 +1170,7 @@ int vcd_dbus_close_connection() dbus_error_free(&err); } - dbus_connection_close(g_conn_listener); - dbus_connection_unref(g_conn_listener); - dbus_connection_close(g_conn_sender); - dbus_connection_unref(g_conn_sender); - - g_conn_listener = NULL; - g_conn_sender = NULL; + __vcd_dbus_connection_free(); return 0; } diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index eea8f50..5d1f689 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -574,7 +574,7 @@ int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, in audio_in_destroy(g_audio_h); audio_channel_e audio_ch; - audio_sample_type_e audio_type; + audio_sample_type_e audio_sample_type; switch (channel) { case 1: audio_ch = AUDIO_CHANNEL_MONO; break; @@ -586,15 +586,15 @@ int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, in } switch (type) { - case VCE_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break; - case VCE_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break; + case VCE_AUDIO_TYPE_PCM_S16_LE: audio_sample_type = AUDIO_SAMPLE_TYPE_S16_LE; break; + case VCE_AUDIO_TYPE_PCM_U8: audio_sample_type = AUDIO_SAMPLE_TYPE_U8; break; default: SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type"); return VCD_ERROR_OPERATION_FAILED; break; } - ret = audio_in_create(rate, audio_ch, audio_type, &g_audio_h); + ret = audio_in_create(rate, audio_ch, audio_sample_type, &g_audio_h); if (AUDIO_IO_ERROR_NONE != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret); g_is_valid_audio_in = false; -- 2.7.4 From c92dccc4912de8666b6c73dd6129c6cceb516585 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Wed, 23 May 2018 22:36:46 +0900 Subject: [PATCH 13/16] Fix vc_widget_unprepare Change-Id: Ica2f4dde4da7a3e9d17ce8d24d8826913f3f7cf8 Signed-off-by: sooyeon.kim --- client/vc_widget.c | 92 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/client/vc_widget.c b/client/vc_widget.c index ea0d2cf..0dcca65 100644 --- a/client/vc_widget.c +++ b/client/vc_widget.c @@ -45,6 +45,7 @@ static int g_feature_enabled = -1; static Eina_Bool __vc_widget_notify_state_changed(void *data); static void __vc_widget_notify_error(void *data); +static void __vc_widget_delete_focus_event_handler(void *data); static int __vc_widget_get_feature_enabled() { @@ -213,14 +214,7 @@ static void __vc_widget_internal_unprepare(vc_h vc_w) SLOG(LOG_WARN, TAG_VCW, "[ERROR] Fail to request finalize : %s", __vc_widget_get_error_code(ret)); } - if (NULL != g_focus_in_handler) { - ecore_event_handler_del(g_focus_in_handler); - g_focus_in_handler = NULL; - } - if (NULL != g_focus_out_handler) { - ecore_event_handler_del(g_focus_out_handler); - g_focus_out_handler = NULL; - } + __vc_widget_delete_focus_event_handler(NULL); ret = vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_WIDGET); if (0 != ret) @@ -262,21 +256,6 @@ int vc_widget_deinitialize(vc_h vc_w) return VC_ERROR_INVALID_STATE; } - - int thread_count = ecore_thread_active_get(); - int count = 0; - while (0 < thread_count) { - usleep(50000); - count++; - if (100 == count) { - SLOG(LOG_WARN, TAG_VCW, "[WARNING!!] Thread is blocked, cnt(%d), thread count(%d)", count, thread_count); - break; - } else if (0 == count % 5) { - SLOG(LOG_WARN, TAG_VCW, "[WARNING!!] Thread is alive, cnt(%d), thread count(%d)", count, thread_count); - } - thread_count = ecore_thread_active_get(); - } - vc_state_e state; vc_widget_client_get_state(vc_w, &state); vc_widget_s* widget = widget_get(vc_w); @@ -353,7 +332,35 @@ static Eina_Bool __focus_changed_cb(void *data, int type, void *event) return ECORE_CALLBACK_RENEW; } -static void __vc_widget_connect_daemon(void *data) +static void __vc_widget_add_focus_event_handler(void *data) +{ + SLOG(LOG_INFO, TAG_VCW, "@@@ [Widget] add focus event handler"); + + if (NULL == g_focus_in_handler) + g_focus_in_handler = ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN, __focus_changed_cb, NULL); + if (NULL == g_focus_out_handler) + g_focus_out_handler = ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT, __focus_changed_cb, NULL); + + return; +} + +static void __vc_widget_delete_focus_event_handler(void *data) +{ + SLOG(LOG_INFO, TAG_VCW, "@@@ [Widget] delete focus event handler"); + + if (NULL != g_focus_in_handler) { + ecore_event_handler_del(g_focus_in_handler); + g_focus_in_handler = NULL; + } + if (NULL != g_focus_out_handler) { + ecore_event_handler_del(g_focus_out_handler); + g_focus_out_handler = NULL; + } + + return; +} + +static Eina_Bool __vc_widget_connect_daemon(void *data) { vc_h vc_w = (vc_h)data; @@ -374,7 +381,7 @@ static void __vc_widget_connect_daemon(void *data) ecore_main_loop_thread_safe_call_async(__vc_widget_notify_error, vc_w); SLOG(LOG_DEBUG, TAG_VCW, "@@@"); - return; + return EINA_FALSE; } else if (VC_ERROR_INVALID_PARAMETER == ret) { SLOG(LOG_WARN, TAG_VCW, "[WARNING] Invalid Parameter"); @@ -385,18 +392,13 @@ static void __vc_widget_connect_daemon(void *data) ecore_main_loop_thread_safe_call_async(__vc_widget_notify_error, vc_w); SLOG(LOG_DEBUG, TAG_VCW, "@@@"); - return; + return EINA_TRUE; } vc_widget_client_set_service_state(vc_w, (vc_service_state_e)service_state); SLOG(LOG_INFO, TAG_VCW, "@@@ [Widget] Connect daemon"); - if (NULL == g_focus_in_handler) - g_focus_in_handler = ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN, __focus_changed_cb, NULL); - if (NULL == g_focus_out_handler) - g_focus_out_handler = ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT, __focus_changed_cb, NULL); - char appid[1024] = {'\0',}; aul_app_get_appid_bypid(getpid(), appid, sizeof(appid) - 1); @@ -432,7 +434,7 @@ static void __vc_widget_connect_daemon(void *data) SLOG(LOG_DEBUG, TAG_VCW, "@@@"); - return; + return EINA_FALSE; } static void __start_prepare_thread(void *data, Ecore_Thread *thread) @@ -445,6 +447,7 @@ static void __start_prepare_thread(void *data, Ecore_Thread *thread) while (0 != ret) { if (retry_count == 30) { SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to request hello !!"); + ecore_main_loop_thread_safe_call_async(__vc_widget_delete_focus_event_handler, NULL); return; } @@ -457,12 +460,12 @@ static void __start_prepare_thread(void *data, Ecore_Thread *thread) } } -#if 0 ret = -1; retry_count = 0; while (0 != ret) { if (retry_count == 10) { SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to connect daemon !!"); + ecore_main_loop_thread_safe_call_async(__vc_widget_delete_focus_event_handler, NULL); return; } ret = __vc_widget_connect_daemon((void*)vc_w); @@ -471,9 +474,8 @@ static void __start_prepare_thread(void *data, Ecore_Thread *thread) else retry_count++; } -#endif - ecore_main_loop_thread_safe_call_async(__vc_widget_connect_daemon, vc_w); + SLOG(LOG_DEBUG, TAG_VCW, "@@@"); return; } @@ -513,6 +515,9 @@ int vc_widget_prepare(vc_h vc_w) return VC_ERROR_INVALID_STATE; } + // Add focus event handler before start sub thread. If connection fails, event handler will be deleted. + __vc_widget_add_focus_event_handler(NULL); + ecore_thread_run(__start_prepare_thread, __end_prepare_thread, NULL, (void*)vc_w); SLOG(LOG_DEBUG, TAG_VCW, "@@@"); @@ -529,6 +534,21 @@ int vc_widget_unprepare(vc_h vc_w) return VC_ERROR_NONE; } + int thread_count = ecore_thread_active_get(); + int count = 0; + SLOG(LOG_INFO, TAG_VCW, "[Widget] Thread count(%d)", thread_count); + while (0 < thread_count) { + usleep(50000); + if (100 == count) { + SLOG(LOG_WARN, TAG_VCW, "[WARNING!!] Thread is blocked, cnt(%d), thread count(%d)", count, thread_count); + break; + } else if (0 == count % 5) { + SLOG(LOG_WARN, TAG_VCW, "[WARNING!!] Thread is alive, cnt(%d), thread count(%d)", count, thread_count); + } + count++; + thread_count = ecore_thread_active_get(); + } + vc_state_e state; if (0 != vc_widget_client_get_state(vc_w, &state)) { SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available"); @@ -538,7 +558,7 @@ int vc_widget_unprepare(vc_h vc_w) /* check state */ if (state != VC_STATE_READY) { - SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'READY'"); + SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'READY', state(%d)", state); SLOG(LOG_DEBUG, TAG_VCW, "@@@"); return VC_ERROR_INVALID_STATE; } -- 2.7.4 From 5d84fa5d582936a2938f3357e6b23879ef4c4cec Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Tue, 29 May 2018 21:17:06 +0900 Subject: [PATCH 14/16] Change partial match level to word Change-Id: Ia3110f87da01bac30720c91f7ef4ada86ae98972 Signed-off-by: Wonnam Jang --- server/vcd_server.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/vcd_server.c b/server/vcd_server.c index 0a9b9e9..89a58d1 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -683,7 +683,7 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c vc_cmd_list_get_count(widget_cmd_list, &cnt); if (0 < cnt) { /* Matched with widget command partially */ - vc_cmd_get_partially_matched_cmd_list(all_result, widget_cmd_list, vc_cmd_list, VC_SEARCH_CHAR_LEVEL); + vc_cmd_get_partially_matched_cmd_list(all_result, widget_cmd_list, vc_cmd_list, VC_SEARCH_WORD_LEVEL); vc_cmd_list_get_count(vc_cmd_list, &cnt); if (0 < cnt) { top_priority = VC_COMMAND_PRIORITY_WIDGET; @@ -702,7 +702,7 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c vc_cmd_list_get_count(foreground_cmd_list, &cnt); if (0 < cnt) { /* Matched with foreground command partially */ - vc_cmd_get_partially_matched_cmd_list(all_result, foreground_cmd_list, vc_cmd_list, VC_SEARCH_CHAR_LEVEL); + vc_cmd_get_partially_matched_cmd_list(all_result, foreground_cmd_list, vc_cmd_list, VC_SEARCH_WORD_LEVEL); vc_cmd_list_get_count(vc_cmd_list, &cnt); if (0 < cnt) { top_priority = VC_COMMAND_PRIORITY_FOREGROUND; @@ -777,7 +777,7 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c vc_cmd_list_get_count(widget_cmd_list, &cnt); if (0 < cnt) { /* Matched with widget command partially */ - vc_cmd_get_partially_matched_cmd_list(all_result, widget_cmd_list, temp_list, VC_SEARCH_CHAR_LEVEL); + vc_cmd_get_partially_matched_cmd_list(all_result, widget_cmd_list, temp_list, VC_SEARCH_WORD_LEVEL); vc_cmd_list_get_count(temp_list, &cnt); if (0 < cnt) { if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) { @@ -801,7 +801,7 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c vc_cmd_list_get_count(foreground_cmd_list, &cnt); if (0 < cnt) { /* Matched with foreground command partially */ - vc_cmd_get_partially_matched_cmd_list(all_result, foreground_cmd_list, temp_list, VC_SEARCH_CHAR_LEVEL); + vc_cmd_get_partially_matched_cmd_list(all_result, foreground_cmd_list, temp_list, VC_SEARCH_WORD_LEVEL); vc_cmd_list_get_count(temp_list, &cnt); if (0 < cnt) { if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) { -- 2.7.4 From 96889b116efb6c717376ee51c451ff530dfcaad3 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Thu, 31 May 2018 16:22:47 +0900 Subject: [PATCH 15/16] Not use partial match Change-Id: Ica25f29ae0be807863d4b4831e0a9c2523be1dcd Signed-off-by: Wonnam Jang --- include/voice_control_command_expand.h | 1 + server/vcd_server.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/voice_control_command_expand.h b/include/voice_control_command_expand.h index 7947fa5..c188e77 100755 --- a/include/voice_control_command_expand.h +++ b/include/voice_control_command_expand.h @@ -42,6 +42,7 @@ typedef enum { VC_CMD_FORMAT_PARTIAL /**< Partial matched command */ } vc_cmd_format_e; +#define VC_SEARCH_NONE_LEVEL 0 #define VC_SEARCH_TEXT_LEVEL 1 #define VC_SEARCH_WORD_LEVEL 2 #define VC_SEARCH_CHAR_LEVEL 3 diff --git a/server/vcd_server.c b/server/vcd_server.c index 89a58d1..ef9dc76 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -683,7 +683,7 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c vc_cmd_list_get_count(widget_cmd_list, &cnt); if (0 < cnt) { /* Matched with widget command partially */ - vc_cmd_get_partially_matched_cmd_list(all_result, widget_cmd_list, vc_cmd_list, VC_SEARCH_WORD_LEVEL); + vc_cmd_get_partially_matched_cmd_list(all_result, widget_cmd_list, vc_cmd_list, VC_SEARCH_NONE_LEVEL); vc_cmd_list_get_count(vc_cmd_list, &cnt); if (0 < cnt) { top_priority = VC_COMMAND_PRIORITY_WIDGET; @@ -702,7 +702,7 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c vc_cmd_list_get_count(foreground_cmd_list, &cnt); if (0 < cnt) { /* Matched with foreground command partially */ - vc_cmd_get_partially_matched_cmd_list(all_result, foreground_cmd_list, vc_cmd_list, VC_SEARCH_WORD_LEVEL); + vc_cmd_get_partially_matched_cmd_list(all_result, foreground_cmd_list, vc_cmd_list, VC_SEARCH_NONE_LEVEL); vc_cmd_list_get_count(vc_cmd_list, &cnt); if (0 < cnt) { top_priority = VC_COMMAND_PRIORITY_FOREGROUND; @@ -777,7 +777,7 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c vc_cmd_list_get_count(widget_cmd_list, &cnt); if (0 < cnt) { /* Matched with widget command partially */ - vc_cmd_get_partially_matched_cmd_list(all_result, widget_cmd_list, temp_list, VC_SEARCH_WORD_LEVEL); + vc_cmd_get_partially_matched_cmd_list(all_result, widget_cmd_list, temp_list, VC_SEARCH_NONE_LEVEL); vc_cmd_list_get_count(temp_list, &cnt); if (0 < cnt) { if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) { @@ -801,7 +801,7 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c vc_cmd_list_get_count(foreground_cmd_list, &cnt); if (0 < cnt) { /* Matched with foreground command partially */ - vc_cmd_get_partially_matched_cmd_list(all_result, foreground_cmd_list, temp_list, VC_SEARCH_WORD_LEVEL); + vc_cmd_get_partially_matched_cmd_list(all_result, foreground_cmd_list, temp_list, VC_SEARCH_NONE_LEVEL); vc_cmd_list_get_count(temp_list, &cnt); if (0 < cnt) { if (0 != vc_cmd_list_destroy(vc_cmd_list, true)) { -- 2.7.4 From 3c6c8fcee27573f0e2f0e2e495e4b8a7543329a7 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Mon, 4 Jun 2018 23:21:49 +0900 Subject: [PATCH 16/16] Add feedback and server dialog APIs Change-Id: I7a4bfe718206b21f723fe693940185a5e18916c2 Signed-off-by: sooyeon.kim --- client/CMakeLists.txt | 3 + client/vc.c | 183 +++++++++++++- client/vc_dbus.c | 69 ++++++ client/vc_dbus.h | 2 + client/vc_mgr.c | 519 +++++++++++++++++++++++++++++++++++----- client/vc_mgr_client.c | 101 +++++++- client/vc_mgr_client.h | 13 + client/vc_mgr_data.cpp | 126 ++++++++++ client/vc_mgr_data.h | 63 +++++ client/vc_mgr_dbus.c | 92 +++++++ client/vc_mgr_dbus.h | 6 + client/vc_mgr_player.c | 413 ++++++++++++++++++++++++++++++++ client/vc_mgr_player.h | 25 ++ common/vc_defs.h | 9 + common/vc_info_parser.h | 1 + doc/uix_vc_doc.h | 5 + doc/uix_vc_engine_main_doc.h | 4 + include/vce.h | 136 +++++++++++ include/voice_control.h | 43 ++++ include/voice_control_common.h | 29 +++ include/voice_control_manager.h | 202 ++++++++++++++++ server/vcd_client_data.c | 33 +++ server/vcd_client_data.h | 5 + server/vcd_dbus.c | 132 ++++++++++ server/vcd_dbus.h | 8 + server/vcd_dbus_server.c | 201 +++++++++++++++- server/vcd_dbus_server.h | 10 + server/vcd_engine_agent.c | 66 ++++- server/vcd_engine_agent.h | 5 + server/vcd_main.h | 39 +-- server/vcd_server.c | 169 ++++++++++++- server/vcd_server.h | 18 ++ server/vce.c | 73 ++++++ 33 files changed, 2692 insertions(+), 111 deletions(-) create mode 100644 client/vc_mgr_data.cpp create mode 100644 client/vc_mgr_data.h create mode 100644 client/vc_mgr_player.c create mode 100644 client/vc_mgr_player.h mode change 100755 => 100644 common/vc_defs.h mode change 100755 => 100644 server/vcd_dbus.c mode change 100755 => 100644 server/vcd_dbus_server.c diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index fcc4c43..0380cc0 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -34,6 +34,8 @@ SET(WIDGET_SRCS SET(MANAGER_SRCS vc_mgr.c vc_mgr_client.c + vc_mgr_data.cpp + vc_mgr_player.c vc_mgr_dbus.c ../common/vc_cmd_db.c ../common/vc_command.c @@ -52,6 +54,7 @@ FOREACH(flag ${pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") ## voice control library ## ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) diff --git a/client/vc.c b/client/vc.c index 9a893f3..14bdf8b 100644 --- a/client/vc.c +++ b/client/vc.c @@ -2146,6 +2146,187 @@ int vc_set_invocation_name(const char* name) return ret; } +int vc_set_server_dialog(const char* app_id, const char* credential) +{ + vc_state_e state; + int ret = -1; + + SLOG(LOG_DEBUG, TAG_VCC, "@@@ Set server dialog, pid(%d), app_id(%s)", getpid(), app_id); + if (0 != __vc_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + if (0 != __vc_check_privilege()) { + return VC_ERROR_PERMISSION_DENIED; + } + + if (NULL == credential) { + SLOG(LOG_DEBUG, TAG_VCC, "[ERROR] Credential is NULL"); + return VC_ERROR_INVALID_PARAMETER; + } + + 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, "@@@"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state(%d) is not 'READY'", state); + 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(%d) is not 'READY'", service_state); + SLOG(LOG_DEBUG, TAG_VCC, "@@@"); + return VC_ERROR_INVALID_STATE; + } + + char* tmp_appid = NULL; + if (NULL == app_id) { + ret = app_manager_get_app_id(getpid(), &tmp_appid); + if (0 != ret || NULL == tmp_appid) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] app_id is NULL"); + if (NULL != tmp_appid) + free(tmp_appid); + return VC_ERROR_INVALID_PARAMETER; + } + } else { + tmp_appid = strdup(app_id); + } + int pid = getpid(); + + SLOG(LOG_DEBUG, TAG_VCC, "Set server dialog : pid(%d), app_id(%s)", pid, tmp_appid); + + int count = 0; + bool is_prepared = false; + do { + ret = vc_dbus_set_server_dialog(pid, tmp_appid, credential); + if (0 != ret) { + if (VC_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { + vc_client_set_client_state(g_vc, VC_STATE_INITIALIZED); + if (0 == vc_prepare_sync()) { + is_prepared = true; + SLOG(LOG_INFO, TAG_VCC, "[INFO] Success vc_prepare_sync"); + } + } else if (VC_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request set server dialog to vc service : %s", __vc_get_error_code(ret)); + break; + } else { + SLOG(LOG_WARN, TAG_VCC, "[WARNING] retry request set server dialog : %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 != tmp_appid) + free(tmp_appid); + + SLOG(LOG_DEBUG, TAG_VCC, "@@@"); + + return ret; +} + +int vc_unset_server_dialog(const char* app_id) +{ + vc_state_e state; + int ret = -1; + + SLOG(LOG_DEBUG, TAG_VCC, "@@@ Unset server dialog, pid(%d), app_id(%s)", getpid(), app_id); + 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, "@@@"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state(%d) is not 'READY'", state); + 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(%d) is not 'READY'", service_state); + SLOG(LOG_DEBUG, TAG_VCC, "@@@"); + return VC_ERROR_INVALID_STATE; + } + + char* tmp_appid = NULL; + if (NULL == app_id) { + ret = app_manager_get_app_id(getpid(), &tmp_appid); + if (0 != ret || NULL == tmp_appid) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] app_id is NULL"); + if (NULL != tmp_appid) + free(tmp_appid); + return VC_ERROR_INVALID_PARAMETER; + } + } else { + tmp_appid = strdup(app_id); + } + int pid = getpid(); + + SLOG(LOG_DEBUG, TAG_VCC, "Unset server dialog : pid(%d), app_id(%s)", pid, tmp_appid); + + int count = 0; + bool is_prepared = false; + char* credential = strdup("#NULL"); + do { + ret = vc_dbus_set_server_dialog(pid, tmp_appid, credential); + if (0 != ret) { + if (VC_ERROR_INVALID_PARAMETER == ret && false == is_prepared) { + vc_client_set_client_state(g_vc, VC_STATE_INITIALIZED); + if (0 == vc_prepare_sync()) { + is_prepared = true; + SLOG(LOG_INFO, TAG_VCC, "[INFO] Success vc_prepare_sync"); + } + } else if (VC_ERROR_TIMED_OUT != ret) { + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request unset server dialog to vc service : %s", __vc_get_error_code(ret)); + break; + } else { + SLOG(LOG_WARN, TAG_VCC, "[WARNING] retry request unset server dialog : %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 != tmp_appid) + free(tmp_appid); + if (NULL != credential) + free(credential); + + SLOG(LOG_DEBUG, TAG_VCC, "@@@"); + + return ret; +} + + int vc_request_dialog(const char* disp_text, const char* utt_text, bool auto_start) { vc_state_e state; @@ -2183,7 +2364,7 @@ int vc_request_dialog(const char* disp_text, const char* utt_text, bool auto_sta 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); + SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request dialog, ret(%d)", ret); return VC_ERROR_OPERATION_FAILED; } diff --git a/client/vc_dbus.c b/client/vc_dbus.c index 186d259..dfe0228 100644 --- a/client/vc_dbus.c +++ b/client/vc_dbus.c @@ -851,6 +851,75 @@ int vc_dbus_set_foreground(int pid, bool value) return 0; } +int vc_dbus_set_server_dialog(int pid, const char* app_id, const char* credential) +{ + 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_SET_SERVER_DIALOG); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCC, "@@ vc set server dialog : Fail to make message"); + return VC_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCC, "@@ vc set server dialog : pid(%d), app_id(%s)", pid, app_id); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &app_id, + DBUS_TYPE_STRING, &credential, + 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 server dialog : result = %d", result); + } else { + SLOG(LOG_ERROR, TAG_VCC, "@@ vc set server dialog : 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_dialog(int pid, const char* disp_text, const char* utt_text, bool continuous) { if (NULL == g_conn_sender) { diff --git a/client/vc_dbus.h b/client/vc_dbus.h index b5db90b..e7f7512 100644 --- a/client/vc_dbus.h +++ b/client/vc_dbus.h @@ -42,6 +42,8 @@ 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_set_server_dialog(int pid, const char* app_id, const char* credential); + 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); diff --git a/client/vc_mgr.c b/client/vc_mgr.c index e56205e..ab8d584 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -28,6 +28,8 @@ #include "vc_main.h" #include "vc_mgr_client.h" #include "vc_mgr_dbus.h" +#include "vc_mgr_data.h" +#include "vc_mgr_player.h" #include "voice_control.h" #include "voice_control_command.h" #include "voice_control_command_expand.h" @@ -61,6 +63,12 @@ static cynara *p_cynara = NULL; static bool g_err_callback_status = false; +/* for TTS feedback */ +static int g_feedback_rate = 16000; +static vc_audio_channel_e g_feedback_audio_channel = 0; +static vc_audio_type_e g_feedback_audio_type = 0; + + static Eina_Bool __vc_mgr_notify_state_changed(void *data); static void __vc_mgr_notify_error(void *data); static Eina_Bool __vc_mgr_notify_result(void *data); @@ -262,6 +270,12 @@ int vc_mgr_initialize(void) return ret; } + /* for TTS feedback */ +/* ret = vc_mgr_player_init(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to initialize VC mgr player : %d", ret); + } +*/ SLOG(LOG_ERROR, TAG_VCM, "[Success] pid(%d)", g_vc_m->handle); SLOG(LOG_DEBUG, TAG_VCM, "@@@"); @@ -339,6 +353,12 @@ int vc_mgr_deinitialize(void) SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to finalize DB, ret(%d)", ret); } + /* for TTS feedback */ +/* ret = vc_mgr_player_release(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to release VC mgr player(%d)", ret); + } +*/ if (0 != vc_mgr_dbus_close_connection()) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to close connection"); } @@ -1700,26 +1720,14 @@ int vc_mgr_set_private_data(const char* key, const char* data) } int ret = -1; - int count = 0; - while (0 != ret) { - 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_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 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"); - break; - } - } - } else { - SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Set domain"); - } + ret = vc_mgr_dbus_request_set_private_data(g_vc_m->handle, key, data); + if (0 != ret) { + SLOG(LOG_DEBUG, TAG_VCM, "[ERROR] Fail to set private data : %s", __vc_mgr_get_error_code(ret)); + return ret; + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Set private data"); } + SLOG(LOG_DEBUG, TAG_VCM, "@@@"); return 0; @@ -1910,25 +1918,61 @@ int vc_mgr_do_action(vc_send_event_type_e type, char* send_event) } 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"); - } + ret = vc_mgr_dbus_request_do_action(g_vc_m->handle, type, send_event); + if (0 != ret) { + SLOG(LOG_DEBUG, TAG_VCM, "[ERROR] Fail to do action request : %s", __vc_mgr_get_error_code(ret)); + return ret; + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] do action"); + } + SLOG(LOG_DEBUG, TAG_VCM, "@@@"); + + return 0; +} + +int vc_mgr_send_specific_engine_request(const char* engine_app_id, const char* event, const char* request) +{ + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] specific engine request. engine app id(%s), event(%s), request(%s)", engine_app_id, event, request); + + if (NULL == engine_app_id || NULL == event) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid parameter"); + return VC_ERROR_INVALID_PARAMETER; + } + + if (NULL == request) { + SLOG(LOG_ERROR, TAG_VCM, "[INFO] Input parameter is NULL. (no request)"); + } + + 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, "@@@"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != VC_STATE_READY) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state(%d) is not 'READY'", state); + 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(%d) is not 'READY'", service_state); + SLOG(LOG_DEBUG, TAG_VCM, "@@@"); + return VC_ERROR_INVALID_STATE; + } + + int ret = -1; + ret = vc_mgr_dbus_send_specific_engine_request(g_vc_m->handle, engine_app_id, event, request); + if (0 != ret) { + SLOG(LOG_DEBUG, TAG_VCM, "[ERROR] Fail to specific engine request : %s", __vc_mgr_get_error_code(ret)); + return ret; + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] specific engine request"); } SLOG(LOG_DEBUG, TAG_VCM, "@@@"); @@ -2332,30 +2376,14 @@ int vc_mgr_set_selected_results(vc_cmd_list_h vc_cmd_list) } } - int ret; - int count = 0; - /* Request */ - ret = -1; - count = 0; - while (0 != ret) { - ret = vc_mgr_dbus_send_result_selection(g_vc_m->handle); - if (0 != ret) { - if (VC_ERROR_TIMED_OUT != ret) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to send result selection : %s", __vc_mgr_get_error_code(ret)); - break; - } else { - SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry send result selection : %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] result selection"); - } + int ret = -1; + ret = vc_mgr_dbus_send_result_selection(g_vc_m->handle); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to send result selection : %s", __vc_mgr_get_error_code(ret)); + return ret; + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] result selection"); } vc_mgr_client_unset_all_result(g_vc_m); @@ -3272,6 +3300,81 @@ int __vc_mgr_cb_private_data_requested(const char* key, char** data) return ret; } +/* for TTS feedback */ +int __vc_mgr_cb_feedback_audio_format(int rate, vc_audio_channel_e channel, vc_audio_type_e audio_type) +{ + vc_mgr_feedback_audio_format_cb callback = NULL; + void* user_data = NULL; + + /* set global audio formats */ + g_feedback_rate = rate; + g_feedback_audio_channel = channel; + g_feedback_audio_type = audio_type; + + vc_mgr_client_get_feedback_audio_format_cb(g_vc_m, &callback, &user_data); + + if (NULL != callback) { + vc_mgr_client_use_callback(g_vc_m); + callback(rate, channel, audio_type, user_data); + vc_mgr_client_not_use_callback(g_vc_m); + SLOG(LOG_DEBUG, TAG_VCM, "TTS feedback audio format callback is called"); + } else { + SLOG(LOG_WARN, TAG_VCM, "[WARNING] TTS feedback audio format callback is null"); + } + + return VC_ERROR_NONE; +} + +int __vc_mgr_cb_feedback_streaming(vc_feedback_event_e event, char* buffer, int len) +{ + /* add feedback data */ + vc_feedback_data_s* temp_feedback_data = NULL; + temp_feedback_data = (vc_feedback_data_s*)calloc(1, sizeof(vc_feedback_data_s)); + if (NULL == temp_feedback_data) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Out of memory"); + return VC_ERROR_OUT_OF_MEMORY; + } + + temp_feedback_data->data = NULL; + temp_feedback_data->rate = g_feedback_rate; + temp_feedback_data->data_size = 0; + + if (0 < len) { + temp_feedback_data->data = (char*)calloc(len + 5, sizeof(char)); + if (NULL != temp_feedback_data->data) { + memcpy(temp_feedback_data->data, buffer, len); + temp_feedback_data->data_size = len; + SLOG(LOG_DEBUG, TAG_VCM, "[DEBUG][memcpy] data(%p) size(%d)", + temp_feedback_data->data, temp_feedback_data->data_size); + } else { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] fail to allocate memory"); + } + } else { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] feedback data is NULL"); + } + + temp_feedback_data->event = event; + temp_feedback_data->audio_type = g_feedback_audio_type; + temp_feedback_data->channel = g_feedback_audio_channel; + + int ret = vc_mgr_data_add_feedback_data(temp_feedback_data); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to add feedback data"); + if (NULL != temp_feedback_data->data) { + free(temp_feedback_data->data); + temp_feedback_data->data = NULL; + } + if (NULL != temp_feedback_data) { + free(temp_feedback_data); + temp_feedback_data = NULL; + } + + return ret; + } + + return VC_ERROR_NONE; +} + int vc_mgr_set_dialog_request_cb(vc_mgr_dialog_request_cb callback, void* user_data) { if (0 != __vc_mgr_get_feature_enabled()) { @@ -3631,3 +3734,297 @@ int __vc_mgr_request_auth_cancel(int pid) return 0; } + +int vc_mgr_set_specific_engine_result_cb(vc_mgr_specific_engine_result_cb callback, void* user_data) +{ + if (0 != __vc_mgr_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + + 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 specific engine 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 specific engine result callback : Current state(%d) is not 'Initialized'", state); + return VC_ERROR_INVALID_STATE; + } + + vc_mgr_client_set_specific_engine_result_cb(g_vc_m, callback, user_data); + + return 0; +} +int vc_mgr_unset_specific_engine_result_cb(void) +{ + if (0 != __vc_mgr_get_feature_enabled()) { + return VC_ERROR_NOT_SUPPORTED; + } + + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset specific engine 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 specific engine result callback : Current state(%d) is not 'Initialize'", state); + return VC_ERROR_INVALID_STATE; + } + + vc_mgr_client_set_specific_engine_result_cb(g_vc_m, NULL, NULL); + + return 0; +} + +void __vc_mgr_cb_specific_engine_result(const char* engine_app_id, const char* event, const char* result) +{ + vc_mgr_specific_engine_result_cb callback = NULL; + void* user_data = NULL; + + vc_mgr_client_get_specific_engine_result_cb(g_vc_m, &callback, &user_data); + if (NULL == callback) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Client specific engine result callback is NULL"); + return; + } + + vc_mgr_client_use_callback(g_vc_m); + callback(engine_app_id, event, result, user_data); + vc_mgr_client_not_use_callback(g_vc_m); + SLOG(LOG_DEBUG, TAG_VCM, "Specific engine result callback is called, engine app id(%s), event(%s), result(%s)", engine_app_id, event, result); + + return; +} + +/* for TTS feedback */ +int vc_mgr_set_feedback_audio_format_cb(vc_mgr_feedback_audio_format_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 feedback audio format callback : A handle is not available"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (VC_STATE_INITIALIZED != state) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set feedback audio format callback : Current state is not 'Initialized' (%d)", state); + return VC_ERROR_INVALID_STATE; + } + + vc_mgr_client_set_feedback_audio_format_cb(g_vc_m, callback, user_data); + + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Set feedback audio format callback"); + + return 0; +} + +int vc_mgr_unset_feedback_audio_format_cb() +{ + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset feedback audio format callback : A handle is not available"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (VC_STATE_INITIALIZED != state) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset feedback audio format callback : Current state is not 'Initialized' (%d)", state); + return VC_ERROR_INVALID_STATE; + } + + vc_mgr_client_set_feedback_audio_format_cb(g_vc_m, NULL, NULL); + + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Unset feedback audio format callback"); + + return 0; +} + +int vc_mgr_set_feedback_streaming_cb(vc_mgr_feedback_streaming_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 feedback streaming callback : A handle is not available"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (VC_STATE_INITIALIZED != state) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set feedback streaming callback : Current state is not 'Initialized' (%d)", state); + return VC_ERROR_INVALID_STATE; + } + + vc_mgr_client_set_feedback_streaming_cb(g_vc_m, callback, user_data); + + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Set feedback streaming callback"); + + return 0; +} + +int vc_mgr_unset_feedback_streaming_cb() +{ + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset feedback streaming callback : A handle is not available"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (VC_STATE_INITIALIZED != state) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset feedback streaming callback : Current state is not 'Initialized' (%d)", state); + return VC_ERROR_INVALID_STATE; + } + + vc_mgr_client_set_feedback_streaming_cb(g_vc_m, NULL, NULL); + + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Unset feedback streaming callback"); + + return 0; +} + +static void __tts_feedback_thread(void* data, Ecore_Thread* thread) +{ + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Start thread"); + + vc_feedback_data_s* feedback_data = NULL; + vc_mgr_feedback_streaming_cb callback = NULL; + void* user_data = NULL; + + vc_mgr_client_get_feedback_streaming_cb(g_vc_m, &callback, &user_data); + if (NULL == callback) { + SLOG(LOG_WARN, TAG_VCM, "[WARNING] TTS feedback streaming callback is null"); + return; + } + + while (1) { + int ret = -1; + int cnt = 0; + + /* get feedback data */ + ret = vc_mgr_data_get_feedback_data(&feedback_data); + if (0 != ret || NULL == feedback_data) { + /* empty queue */ + SLOG(LOG_DEBUG, TAG_VCM, "[DEBUG] No feedback data. Waiting mode"); + + /* waiting */ + while (1) { + usleep(10000); + if (0 < vc_mgr_data_get_feedback_data_size()) { + SLOG(LOG_INFO, TAG_VCM, "[INFO] Resume thread"); + break; + } + if (200 < cnt) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Wrong request, there's no pcm data"); + return; + } + cnt++; + } + SLOG(LOG_INFO, TAG_VCM, "[INFO] Finish to wait for new feedback data come"); + + /* resume feedback thread */ + continue; + } + + SLOG(LOG_DEBUG, TAG_VCM, "TTS feedback streaming callback is called"); + vc_mgr_client_use_callback(g_vc_m); + callback(feedback_data->event, feedback_data->data, feedback_data->data_size, user_data); + vc_mgr_client_not_use_callback(g_vc_m); + + /* If no feedback data and EVENT_FINISH */ + if (0 >= vc_mgr_data_get_feedback_data_size() && VC_FEEDBACK_EVENT_FINISH == feedback_data->event) { + SLOG(LOG_INFO, TAG_VCM, "[INFO] Finish feedback"); + break; + } + } +} + +static void __end_tts_feedback_thread(void* data, Ecore_Thread* thread) +{ + SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] End thread"); +} + +int vc_mgr_start_feedback(void) +{ + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Request start TTS feedback"); + + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Start feedback : A handle is not available"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (VC_STATE_READY != state) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Start feedback : Current state is not 'Ready' (%d)", state); + return VC_ERROR_INVALID_STATE; + } + +#if 1 + ecore_thread_run(__tts_feedback_thread, __end_tts_feedback_thread, NULL, NULL); +#else + /* start playing TTS feedback */ + int ret = -1; + ret = vc_mgr_player_play(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to player play, ret(%d)", ret); + } +#endif + return 0; +} + +int vc_mgr_stop_feedback(void) +{ + SLOG(LOG_DEBUG, TAG_VCM, "@@@ [Manager] Request stop TTS feedback"); + + vc_state_e state; + if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Stop feedback : A handle is not available"); + return VC_ERROR_INVALID_STATE; + } + + /* check state */ + if (VC_STATE_READY != state) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Stop feedback : Current state is not 'Ready' (%d)", state); + return VC_ERROR_INVALID_STATE; + } + +#if 1 + int ret = -1; + + while (1) { + vc_feedback_data_s* feedback_data = NULL; + + /* get feedback data */ + ret = vc_mgr_data_get_feedback_data(&feedback_data); + if (0 != ret || NULL == feedback_data) { + /* empty queue */ + SLOG(LOG_INFO, TAG_VCM, "[INFO] No feedback data to stop any more"); + return 0; + } + ret = vc_mgr_data_clear_feedback_data(&feedback_data); + if (0 != ret) { + SLOG(LOG_INFO, TAG_VCM, "[ERROR] Fail to clear data, ret(%d)", ret); + break; + } + } +#else + /* request to stop playing TTS feedback */ + int ret = -1; + ret = vc_mgr_player_stop(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to player stop, ret(%d)", ret); + } +#endif + return ret; +} diff --git a/client/vc_mgr_client.c b/client/vc_mgr_client.c index 985f460..18120ed 100644 --- a/client/vc_mgr_client.c +++ b/client/vc_mgr_client.c @@ -46,7 +46,15 @@ typedef struct { vc_mgr_private_data_set_cb private_data_set_cb; void* private_data_set_user_data; vc_mgr_private_data_requested_cb private_data_requested_cb; - void* private_data_requested_user_data; + void* private_data_requested_user_data; + vc_mgr_specific_engine_result_cb specific_engine_result_cb; + void* specific_engine_result_user_data; + + /* for TTS feedback */ + vc_mgr_feedback_audio_format_cb feedback_audio_format_cb; + void* feedback_audio_format_user_data; + vc_mgr_feedback_streaming_cb feedback_streaming_cb; + void* feedback_streaming_user_data; /* All result */ vc_result_event_e all_result_event; @@ -174,6 +182,13 @@ int vc_mgr_client_create(vc_h* vc) client->private_data_set_user_data = NULL; client->private_data_requested_cb = NULL; client->private_data_requested_user_data = NULL; + client->specific_engine_result_cb = NULL; + client->specific_engine_result_user_data = NULL; + + client->feedback_audio_format_cb = NULL; + client->feedback_audio_format_user_data = NULL; + client->feedback_streaming_cb = NULL; + client->feedback_streaming_user_data = NULL; client->exclusive_cmd_option = false; @@ -645,6 +660,62 @@ int vc_mgr_client_get_private_data_requested_cb(vc_h vc, vc_mgr_private_data_req return 0; } +int vc_mgr_client_set_feedback_audio_format_cb(vc_h vc, vc_mgr_feedback_audio_format_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->feedback_audio_format_cb = callback; + client->feedback_audio_format_user_data = user_data; + + return 0; +} + +int vc_mgr_client_get_feedback_audio_format_cb(vc_h vc, vc_mgr_feedback_audio_format_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->feedback_audio_format_cb; + *user_data = client->feedback_audio_format_user_data; + + return 0; +} + +int vc_mgr_client_set_feedback_streaming_cb(vc_h vc, vc_mgr_feedback_streaming_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->feedback_streaming_cb = callback; + client->feedback_streaming_user_data = user_data; + + return 0; +} + +int vc_mgr_client_get_feedback_streaming_cb(vc_h vc, vc_mgr_feedback_streaming_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->feedback_streaming_cb; + *user_data = client->feedback_streaming_user_data; + + return 0; +} + /* set/get option */ int vc_mgr_client_set_service_state(vc_h vc, vc_service_state_e state) { @@ -1191,3 +1262,31 @@ int vc_mgr_client_get_start_by_client(vc_h vc, bool* option) return 0; } + +int vc_mgr_client_set_specific_engine_result_cb(vc_h vc, vc_mgr_specific_engine_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->specific_engine_result_cb = callback; + client->specific_engine_result_user_data = user_data; + + return 0; +} + +int vc_mgr_client_get_specific_engine_result_cb(vc_h vc, vc_mgr_specific_engine_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->specific_engine_result_cb; + *user_data = client->specific_engine_result_user_data; + + return 0; +} diff --git a/client/vc_mgr_client.h b/client/vc_mgr_client.h index 4c91392..e8104c0 100644 --- a/client/vc_mgr_client.h +++ b/client/vc_mgr_client.h @@ -95,6 +95,19 @@ int vc_mgr_client_set_private_data_requested_cb(vc_h vc, vc_mgr_private_data_req int vc_mgr_client_get_private_data_requested_cb(vc_h vc, vc_mgr_private_data_requested_cb* callback, void** user_data); +int vc_mgr_client_set_specific_engine_result_cb(vc_h vc, vc_mgr_specific_engine_result_cb callback, void* user_data); + +int vc_mgr_client_get_specific_engine_result_cb(vc_h vc, vc_mgr_specific_engine_result_cb* callback, void** user_data); + +int vc_mgr_client_set_feedback_audio_format_cb(vc_h vc, vc_mgr_feedback_audio_format_cb callback, void* user_data); + +int vc_mgr_client_get_feedback_audio_format_cb(vc_h vc, vc_mgr_feedback_audio_format_cb* callback, void** user_data); + +int vc_mgr_client_set_feedback_streaming_cb(vc_h vc, vc_mgr_feedback_streaming_cb callback, void* user_data); + +int vc_mgr_client_get_feedback_streaming_cb(vc_h vc, vc_mgr_feedback_streaming_cb* callback, void** user_data); + + /* * set/get option */ diff --git a/client/vc_mgr_data.cpp b/client/vc_mgr_data.cpp new file mode 100644 index 0000000..fa455cd --- /dev/null +++ b/client/vc_mgr_data.cpp @@ -0,0 +1,126 @@ +/* +* Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the License); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include + +#include "vc_mgr_data.h" + +using namespace std; + +std::list g_feedback_data; + +static pthread_mutex_t g_feedback_data_mutex = PTHREAD_MUTEX_INITIALIZER; + +int vc_mgr_data_add_feedback_data(vc_feedback_data_s* data) +{ + if (NULL == data) { + SLOG(LOG_ERROR, TAG_VCM, "[DATA ERROR] feedback data is NULL"); + return VC_ERROR_INVALID_PARAMETER; + } + + pthread_mutex_lock(&g_feedback_data_mutex); + + std::list::iterator iter; + + try { + iter = g_feedback_data.insert(g_feedback_data.end(), data); + } catch (const std::bad_alloc&) { + SLOG(LOG_ERROR, TAG_VCM, "[DATA ERROR] Fail to insert feedback data (bad alloc)"); + pthread_mutex_unlock(&g_feedback_data_mutex); + + return VC_ERROR_OUT_OF_MEMORY; + } + + pthread_mutex_unlock(&g_feedback_data_mutex); + + return VC_ERROR_NONE; +} + +int vc_mgr_data_get_feedback_data(vc_feedback_data_s** data) +{ + SLOG(LOG_DEBUG, TAG_VCM, "[DATA] feedback_data : %p", *data); + + pthread_mutex_lock(&g_feedback_data_mutex); + + if (0 == g_feedback_data.size()) { + SLOG(LOG_DEBUG, TAG_VCM, "[DATA] There is no feedback data"); + *data = NULL; + pthread_mutex_unlock(&g_feedback_data_mutex); + + return -1; + } + + std::list::iterator iter; + + if (!g_feedback_data.empty()) { + iter = g_feedback_data.begin(); + *data = *iter; + g_feedback_data.pop_front(); + } + + pthread_mutex_unlock(&g_feedback_data_mutex); + + return VC_ERROR_NONE; +} + +int vc_mgr_data_get_feedback_data_size() +{ + SLOG(LOG_DEBUG, TAG_VCM, "[DATA] get feedback data size"); + + int data_size = 0; + + pthread_mutex_lock(&g_feedback_data_mutex); + data_size = g_feedback_data.size(); + + pthread_mutex_unlock(&g_feedback_data_mutex); + + return data_size; +} + +int vc_mgr_data_clear_feedback_data(vc_feedback_data_s** data) +{ + SLOG(LOG_DEBUG, TAG_VCM, "[DATA] clear feedback data"); + + pthread_mutex_lock(&g_feedback_data_mutex); + + if (!g_feedback_data.empty()) { + SLOG(LOG_DEBUG, TAG_VCM, "[DEBUG] data(%p) size(%d) rate(%d)", (*data)->data, (*data)->data_size, (*data)->rate); + + if (NULL != (*data)->data) { + free((*data)->data); + (*data)->data = NULL; + } + + free(*data); + *data = NULL; + } + + pthread_mutex_unlock(&g_feedback_data_mutex); + + return VC_ERROR_NONE; +} + +int vc_mgr_data_get_pid() +{ +// SLOG(LOG_DEBUG, TAG_VCM, "[DATA] get VC mgr pid"); + + return getpid(); +} diff --git a/client/vc_mgr_data.h b/client/vc_mgr_data.h new file mode 100644 index 0000000..3e2960f --- /dev/null +++ b/client/vc_mgr_data.h @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2018 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_MGR_DATA_H__ +#define __VC_MGR_DATA_H__ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define TAG_VCM "vcm" /* Manager client log tag */ + +typedef enum { + VC_FEEDBACK_STATE_CREATED = 0, + VC_FEEDBACK_STATE_READY, + VC_FEEDBACK_STATE_PLAYING +} vc_feedback_state_e; + +typedef struct { + int utt_id; + void* data; + unsigned int data_size; + + vc_feedback_event_e event; + vc_audio_type_e audio_type; + vc_audio_channel_e channel; + int rate; +} vc_feedback_data_s; + + +int vc_mgr_data_add_feedback_data(vc_feedback_data_s* data); + +int vc_mgr_data_get_feedback_data(vc_feedback_data_s** data); + +int vc_mgr_data_get_feedback_data_size(); + +int vc_mgr_data_clear_feedback_data(vc_feedback_data_s** data); + +int vc_mgr_data_get_pid(); + +#ifdef __cplusplus +} +#endif + +#endif /* __VC_MGR_DATA_H__ */ diff --git a/client/vc_mgr_dbus.c b/client/vc_mgr_dbus.c index 0935452..040ebcb 100644 --- a/client/vc_mgr_dbus.c +++ b/client/vc_mgr_dbus.c @@ -51,6 +51,11 @@ extern int __vc_mgr_cb_private_data_set(const char* key, const char* data); extern int __vc_mgr_cb_private_data_requested(const char* key, char** data); +/* for TTS feedback */ +extern int __vc_mgr_cb_feedback_audio_format(int rate, vc_audio_channel_e channel, vc_audio_type_e audio_type); + +extern int __vc_mgr_cb_feedback_streaming(vc_feedback_event_e event, char* buffer, int len); + /* Authority */ extern int __vc_mgr_request_auth_enable(int pid); @@ -64,6 +69,8 @@ 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); +extern void __vc_mgr_cb_specific_engine_result(const char* engine_app_id, const char* event, const char* result); + 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; @@ -195,7 +202,20 @@ static Eina_Bool vc_mgr_listener_event_callback(void* data, Ecore_Fd_Handler *fd SLOG(LOG_DEBUG, TAG_VCM, "@@@"); } /* VCD_MANAGER_METHOD_PRE_RESULT */ + else if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_SPECIFIC_ENGINE_RESULT)) { + SLOG(LOG_DEBUG, TAG_VCM, "@@@ Get specific engine result"); + char* engine_app_id = NULL; + char* event = NULL; + char* result = NULL; + + dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &engine_app_id, DBUS_TYPE_STRING, &event, DBUS_TYPE_STRING, &result, DBUS_TYPE_INVALID); + if (NULL != result) { + __vc_mgr_cb_specific_engine_result(engine_app_id, event, result); + } + + SLOG(LOG_DEBUG, TAG_VCM, "@@@"); + } /* VCD_MANAGER_METHOD_SPECIFIC_ENGINE_RESULT */ else if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_RESULT)) { SLOG(LOG_DEBUG, TAG_VCM, "@@@ Get System Result"); @@ -372,6 +392,40 @@ static Eina_Bool vc_mgr_listener_event_callback(void* data, Ecore_Fd_Handler *fd SLOG(LOG_DEBUG, TAG_VCM, "@@@"); } /* VCD_MANAGER_METHOD_GET_PRIVATE_DATA */ + else if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_FEEDBACK_AUDIO_FORMAT)) { + SLOG(LOG_INFO, TAG_VCM, "@@@ Get TTS feedback audio format"); + int rate; + vc_audio_channel_e channel; + vc_audio_type_e audio_type; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &rate, + DBUS_TYPE_INT32, &channel, + DBUS_TYPE_INT32, &audio_type, + DBUS_TYPE_INVALID); + + __vc_mgr_cb_feedback_audio_format(rate, channel, audio_type); + + SLOG(LOG_INFO, TAG_VCM, "@@@"); + } /* VCD_MANAGER_METHOD_FEEDBACK_AUDIO_FORMAT */ + + else if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_FEEDBACK_STREAMING)) { + SLOG(LOG_INFO, TAG_VCM, "@@@ Get TTS feedback streaming"); + vc_feedback_event_e event; + char* buffer = NULL; + int len; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &event, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, + &buffer, &len, + DBUS_TYPE_INVALID); + + __vc_mgr_cb_feedback_streaming(event, buffer, len); + + SLOG(LOG_INFO, TAG_VCM, "@@@"); + } /* VCD_MANAGER_METHOD_FEEDBACK_STREAMING */ + /* Authority */ else if (dbus_message_is_method_call(msg, if_name, VC_METHOD_AUTH_ENABLE)) { SLOG(LOG_DEBUG, TAG_VCM, "@@@ Get request auth enable"); @@ -2200,3 +2254,41 @@ int vc_mgr_dbus_send_result_selection(int pid) return 0; } + +int vc_mgr_dbus_send_specific_engine_request(int pid, const char* engine_app_id, const char* event, const char* request) +{ + 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_SPECIFIC_ENGINE_REQUEST); /* name of the signal */ + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCM, "@@ vc send specific engine : Fail to make message"); + return VC_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCM, "@@ vc send specific engine : pid(%d), engine_app_id(%s), event(%s), request(%s)", pid, engine_app_id, event, request); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &engine_app_id, + DBUS_TYPE_STRING, &event, + DBUS_TYPE_STRING, &request, + 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; +} diff --git a/client/vc_mgr_dbus.h b/client/vc_mgr_dbus.h index 267aa05..26789e8 100644 --- a/client/vc_mgr_dbus.h +++ b/client/vc_mgr_dbus.h @@ -64,10 +64,16 @@ int vc_mgr_dbus_send_result(int pid, int cmd_type, int result_id); int vc_mgr_dbus_send_result_selection(int pid); +int vc_mgr_dbus_send_specific_engine_request(int pid, const char* engine_app_id, const char* event, const char* request); + int vc_mgr_dbus_request_enable_command_type(int pid, int cmd_type); int vc_mgr_dbus_request_disable_command_type(int pid, int cmd_type); +int vc_mgr_dbus_request_start_feedback(int pid); + +int vc_mgr_dbus_request_stop_feedback(int pid); + #ifdef __cplusplus } #endif diff --git a/client/vc_mgr_player.c b/client/vc_mgr_player.c new file mode 100644 index 0000000..06915f9 --- /dev/null +++ b/client/vc_mgr_player.c @@ -0,0 +1,413 @@ +/* +* Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the License); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an AS IS BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include + +#include "vc_main.h" +#include "vc_mgr_player.h" +#include "vc_mgr_data.h" + +typedef enum { + AUDIO_STATE_NONE = 0, + AUDIO_STATE_READY, + AUDIO_STATE_PLAY +} audio_state_e; + +typedef struct { + vc_feedback_state_e state; + + vc_feedback_event_e event; + int idx; +} player_s; + +#define SOUND_BUFFER_LENGTH 2048 + +static bool g_player_init = false; + +static player_s* g_playing_info; + +static audio_state_e g_audio_state; + +static vc_audio_type_e g_audio_type; + +static vc_audio_channel_e g_audio_channel; + +static int g_sampling_rate; + +static audio_out_h g_audio_h; + + +static int __create_audio_out(int rate, vc_audio_channel_e channel, vc_audio_type_e audio_type) +{ + int ret = -1; + audio_channel_e sample_channel = 0; + audio_sample_type_e sample_type = 0; + + if (VC_AUDIO_CHANNEL_MONO == channel) { + sample_channel = AUDIO_CHANNEL_MONO; + } else if (VC_AUDIO_CHANNEL_STEREO == channel) { + sample_channel = AUDIO_CHANNEL_STEREO; + } + + if (VC_AUDIO_TYPE_PCM_S16_LE == audio_type) { + sample_type = AUDIO_SAMPLE_TYPE_S16_LE; + } else { + sample_type = AUDIO_SAMPLE_TYPE_U8; + } + + /* create audio_out new */ + ret = audio_out_create_new(rate, sample_channel, sample_type, &g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + g_audio_state = AUDIO_STATE_NONE; + g_audio_h = NULL; + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] Fail to create audio"); + return -1; + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] Create audio"); + } + + g_audio_channel = channel; + g_audio_type = audio_type; + g_sampling_rate = rate; + + g_audio_state = AUDIO_STATE_READY; + + return 0; +} + +static int __destroy_audio_out() +{ + if (NULL == g_audio_h) { + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] Current handle is not valid"); + return -1; + } + + int ret = -1; + ret = audio_out_destroy(g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] Fail to destroy audio"); + return -1; + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] Destroy audio"); + } + + g_audio_channel = 0; + g_audio_type = 0; + g_sampling_rate = 0; + + g_audio_state = AUDIO_STATE_NONE; + g_audio_h = NULL; + + return 0; +} + +int vc_mgr_player_init(int rate, vc_audio_channel_e channel, vc_audio_type_e audio_type) +{ + g_audio_state = AUDIO_STATE_NONE; + g_audio_h = NULL; + + ecore_thread_max_set(1); + + int ret = -1; + + + ret = __create_audio_out(rate, channel, audio_type); + if (0 != ret) { + return -1; + } + + g_player_init = true; + + return 0; +} + +int vc_mgr_player_release() +{ + if (false == g_player_init) { + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] Not initialized"); + return VC_ERROR_OPERATION_FAILED; + } + + int ret = -1; + + int thread_count = ecore_thread_active_get(); + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] Active thread count : %d", thread_count); + int count = 0; + while (0 < thread_count) { + usleep(10000); + + count++; + if (20 == count) { + SLOG(LOG_WARN, TAG_VCM, "[Player WARN] Thread is blocked. Player release continue"); + break; + } + + thread_count = ecore_thread_active_get(); + } + + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] Thread is release"); + + ret = __destroy_audio_out(); + if (0 != ret) { + return -1; + } + + g_player_init = false; + + return 0; +} + +static void __play_feedback_thread(void* data, Ecore_Thread* thread) +{ + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] Start thread"); + + if (NULL == g_playing_info) { + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] No current player"); + return; + } + + player_s* player = g_playing_info; + vc_feedback_data_s* feedback_data = NULL; + + int ret = -1; + int len = SOUND_BUFFER_LENGTH; + int idx = 0; + + while (1) { + /* get feedback data */ + ret = vc_mgr_data_get_feedback_data(&feedback_data); + if (0 != ret || NULL == feedback_data) { + /* empty queue */ + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] No feedback data. Waiting mode"); + + /* waiting */ + while (1) { + usleep(10000); + if (0 < vc_mgr_data_get_feedback_data_size()) { + SLOG(LOG_INFO, TAG_VCM, "[Player INFO] Resume thread"); + break; + } + + if (AUDIO_STATE_PLAY == g_audio_state) { + /* release audio & recover session */ + ret = audio_out_unprepare(g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] Fail to unprepare audio"); + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] Unprepare audio"); + } + g_audio_state = AUDIO_STATE_READY; + } + } + + SLOG(LOG_INFO, TAG_VCM, "[Player INFO] Finish to wait for new feedback data come"); + + /* resume play thread */ + player->state = VC_FEEDBACK_STATE_PLAYING; + continue; + } + + if (VC_FEEDBACK_EVENT_START == feedback_data->event || + (VC_FEEDBACK_EVENT_FINISH == player->event && VC_FEEDBACK_EVENT_FINISH == feedback_data->event)) { + int pid = vc_mgr_data_get_pid(); + SLOG(LOG_INFO, TAG_VCM, "[Player DEBUG] Start utterance (%d)", pid); + } + + player->event = feedback_data->event; + idx = 0; + /* If no feedback data and EVENT_FINISH */ + if (NULL == feedback_data->data || 0 >= feedback_data->data_size) { + if (VC_FEEDBACK_EVENT_FINISH == feedback_data->event) { + int pid = vc_mgr_data_get_pid(); + if (pid <= 0) { + return; + } + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] No sound data"); + } + SLOG(LOG_INFO, TAG_VCM, "[Player INFO] Finish utterance"); + vc_mgr_data_clear_feedback_data(&feedback_data); + continue; + } + + if (g_sampling_rate != feedback_data->rate || g_audio_type != feedback_data->audio_type || g_audio_channel != feedback_data->channel) { + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] change audio handle"); + if (NULL != g_audio_h) { + __destroy_audio_out(); + } + + if (0 > __create_audio_out(feedback_data->rate, feedback_data->channel, feedback_data->audio_type)) { + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] Fail to create audio out"); + vc_mgr_data_clear_feedback_data(&feedback_data); + + return; + } + } + + while (VC_FEEDBACK_STATE_PLAYING == player->state) { + if ((unsigned int)idx >= feedback_data->data_size) + break; + + if ((unsigned int)idx + SOUND_BUFFER_LENGTH > feedback_data->data_size) { + len = feedback_data->data_size - idx; + } else { + len = SOUND_BUFFER_LENGTH; + } + + if (AUDIO_STATE_READY == g_audio_state) { + /* request prepare */ + ret = audio_out_prepare(g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] Fail to prepare audio"); + vc_mgr_data_clear_feedback_data(&feedback_data); + return; + } + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] Prepare audio"); + g_audio_state = AUDIO_STATE_PLAY; + } + + char* temp_data = feedback_data->data; + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] data(%p), idx(%d), len(%d)", temp_data, idx, len); + + ret = audio_out_write(g_audio_h, &temp_data[idx], len); + if (0 > ret) { + SLOG(LOG_WARN, TAG_VCM, "[Player WARN] Fail to audio write - %d", ret); + } else { + idx += len; + } + + if (NULL == g_playing_info) { + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] Current player is NULL"); + g_audio_state = AUDIO_STATE_READY; + ret = audio_out_unprepare(g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] Fail to unprepare audio"); + } + + vc_mgr_data_clear_feedback_data(&feedback_data); + + return; + } + } + + if (NULL == g_playing_info && VC_FEEDBACK_STATE_READY == player->state) { + /* player stop */ + g_audio_state = AUDIO_STATE_READY; + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] Stop play thread"); + + /* request to unprepare audio */ + ret = audio_out_unprepare(g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] Fail to unprepare audio"); + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] Unprepare audio"); + } + + vc_mgr_data_clear_feedback_data(&feedback_data); + return; + } + + if ((VC_FEEDBACK_STATE_PLAYING == player->state) && (VC_FEEDBACK_EVENT_FINISH == feedback_data->event)) { + int pid = vc_mgr_data_get_pid(); + if (pid <= 0) { + return; + } + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] Finish utterance"); + } + + vc_mgr_data_clear_feedback_data(&feedback_data); + + if (NULL == g_playing_info) { + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] Current player is NULL"); + g_audio_state = AUDIO_STATE_READY; + ret = audio_out_unprepare(g_audio_h); + if (AUDIO_IO_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] Fail to unprepare audio"); + } + + return; + } + + } + +} + +static void __end_play_feedback_thread(void* data, Ecore_Thread* thread) +{ + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] End thread"); +} + +int vc_mgr_player_play() +{ + if (false == g_player_init) { + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] Not initialized"); + return VC_ERROR_OPERATION_FAILED; + } + + if (NULL != g_playing_info) { + SLOG(LOG_WARN, TAG_VCM, "[Player WARN] Stop old player"); + vc_mgr_player_stop(); + } + + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] start play"); + + /* check sound queue size */ + int data_size = vc_mgr_data_get_feedback_data_size(); + if (0 == data_size) { + SLOG(LOG_WARN, TAG_VCM, "[Player WARN] A sound queue of current player is empty"); + } else if (0 < data_size) { + SLOG(LOG_INFO, TAG_VCM, "[Player INFO] Run thread"); + ecore_thread_run(__play_feedback_thread, __end_play_feedback_thread, NULL, NULL); + } + + return 0; +} + +int vc_mgr_player_stop() +{ + if (false == g_player_init) { + SLOG(LOG_ERROR, TAG_VCM, "[Player ERROR] Not initialized"); + return VC_ERROR_OPERATION_FAILED; + } + + if (NULL != g_playing_info) { + g_playing_info = NULL; + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] No more current playing"); + } + + SLOG(LOG_DEBUG, TAG_VCM, "[Player DEBUG] stop play"); + + int thread_count = ecore_thread_active_get(); + int count = 0; + + while (0 < thread_count) { + usleep(10000); + + count++; + if (30 == count) { + SLOG(LOG_WARN, TAG_VCM, "[Player WARN] Thread is blocked. Player release continue"); + break; + } + + thread_count = ecore_thread_active_get(); + } + + return 0; +} diff --git a/client/vc_mgr_player.h b/client/vc_mgr_player.h new file mode 100644 index 0000000..6cf550c --- /dev/null +++ b/client/vc_mgr_player.h @@ -0,0 +1,25 @@ + +#ifndef __VC_MGR_PLAYER_H__ +#define __VC_MGR_PLAYER_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int vc_mgr_player_init(int rate, vc_audio_channel_e channel, vc_audio_type_e audio_type); + +int vc_mgr_player_release(); + +int vc_mgr_player_play(); + +int vc_mgr_player_stop(); + + +#ifdef __cplusplus +} +#endif + +#endif /* __VC_MGR_PLAYER_H__ */ diff --git a/common/vc_defs.h b/common/vc_defs.h old mode 100755 new mode 100644 index 0299485..096aa4f --- a/common/vc_defs.h +++ b/common/vc_defs.h @@ -66,6 +66,7 @@ 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_SET_SERVER_DIALOG "vc_method_set_server_dialog" #define VC_METHOD_DIALOG "vc_method_dialog" #define VC_METHOD_IS_SYS_COMMAND_VALID "vc_method_is_system_command_valid" @@ -139,6 +140,10 @@ extern "C" { #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 VC_MANAGER_METHOD_SPECIFIC_ENGINE_REQUEST "vcd_manager_method_specific_engine_request" + +#define VC_MANAGER_METHOD_START_FEEDBACK "vc_manager_method_request_start_feedback" +#define VC_MANAGER_METHOD_STOP_FEEDBACK "vc_manager_method_request_stop_feedback" #define VCD_MANAGER_METHOD_HELLO "vcd_manager_method_hello" #define VCD_MANAGER_METHOD_SPEECH_DETECTED "vcd_manager_method_speech_detected" @@ -150,9 +155,13 @@ extern "C" { #define VCD_MANAGER_METHOD_DIALOG "vcd_manager_method_dialog" #define VCD_MANAGER_METHOD_SET_PRIVATE_DATA "vcd_manager_set_private_data" #define VCD_MANAGER_METHOD_GET_PRIVATE_DATA "vcd_manager_get_private_data" +#define VCD_MANAGER_METHOD_SPECIFIC_ENGINE_RESULT "vcd_manager_method_specific_engine_result" #define VCD_MANAGER_METHOD_ERROR "vcd_manager_method_error" +#define VCD_MANAGER_METHOD_FEEDBACK_AUDIO_FORMAT "vcd_manager_method_feedback_audio_format" +#define VCD_MANAGER_METHOD_FEEDBACK_STREAMING "vcd_manager_method_feedback_streaming" + #define VCC_MANAGER_METHOD_SET_FOREGROUND "vcd_manager_method_set_foreground" diff --git a/common/vc_info_parser.h b/common/vc_info_parser.h index d1532a6..45b7a1e 100644 --- a/common/vc_info_parser.h +++ b/common/vc_info_parser.h @@ -37,6 +37,7 @@ typedef struct _client_s { bool fg_cmd; bool bg_cmd; bool exclusive_cmd; + bool server_dialog; } vc_client_info_s; diff --git a/doc/uix_vc_doc.h b/doc/uix_vc_doc.h index 771f326..d9c6fc9 100644 --- a/doc/uix_vc_doc.h +++ b/doc/uix_vc_doc.h @@ -169,6 +169,11 @@ * * * + * vc_set_server_dialog() + * Ready + * + * + * * vc_request_dialog() * Ready * diff --git a/doc/uix_vc_engine_main_doc.h b/doc/uix_vc_engine_main_doc.h index 6c01165..e81a1fd 100644 --- a/doc/uix_vc_engine_main_doc.h +++ b/doc/uix_vc_engine_main_doc.h @@ -93,6 +93,10 @@ * Called when the engine service user sets audio recording type. * * + * vce_set_server_dialog_cb() + * Called when the engine service user sets app id which is want to ask server dialog. + * + * * vce_set_domain_cb() * Called when the engine service user sets domain (agent or device type). * diff --git a/include/vce.h b/include/vce.h index d37ffbe..c735acd 100644 --- a/include/vce.h +++ b/include/vce.h @@ -18,6 +18,7 @@ #ifndef __VCE_H__ #define __VCE_H__ +#include /** * @addtogroup CAPI_UIX_VOICE_CONTROL_ENGINE_MODULE @@ -101,6 +102,27 @@ typedef enum { } vce_asr_result_event_e; /** + * @brief Enumerations of audio channels + * @since_tizen 5.0 + */ +typedef enum { + VCE_AUDIO_CHANNEL_MONO = 0, /**< 1 channel, mono */ + VCE_AUDIO_CHANNEL_STEREO = 1 /**< 2 channels, stereo */ +} vce_audio_channel_e; + +/** + * @brief Enumeration for TTS feedback events + * @since_tizen 5.0 + */ +typedef enum { + VCE_FEEDBACK_EVENT_FAIL = -1, /**< Failed */ + VCE_FEEDBACK_EVENT_START = 1, /**< Start event */ + VCE_FEEDBACK_EVENT_CONTINUE = 2, /**< Continue event */ + VCE_FEEDBACK_EVENT_FINISH = 3 /**< Finish event */ +} vce_feedback_event_e; + + +/** * @brief A structure of handle for VC command. * @since_tizen 5.0 */ @@ -373,6 +395,19 @@ typedef int (*vce_cancel_cb)(void); typedef int (*vce_set_audio_type_cb)(const char* audio_type); /** +* @brief Called when the engine service user sets app id which is want to ask server dialog. +* @since_tizen 5.0 +* @remarks The @a app_id and @a credential can be used only in the callback. To use outside, make a copy. +* @param[in] app_id App id which is to want to ask server dialog. +* @param[in] credential Credential key. +* @return 0 on success, otherwise a negative error value. +* @retval #VCE_ERROR_NONE Successful. +* @retval #VCE_ERROR_NOT_SUPPORTED_FEATURE Not supported feature. +* @retval #VCE_ERROR_PERMISSION_DENIED Permission denied. +*/ +typedef int (*vce_set_server_dialog_cb)(const char* app_id, const char* credential); + +/** * @brief Called when the engine service user sets domain (agent or device type). * @since_tizen 5.0 * @remarks The @a domain can be used only in the callback. To use outside, make a copy. @@ -396,6 +431,26 @@ typedef int (*vce_set_domain_cb)(const char* domain); typedef int (*vce_nlu_base_info_requested_cb)(const char* key, char** value); /** +* @brief Called when client gets the specific engine's request from the engine service user. +* @since_tizen 5.0 +* +* @param[in] engine_app_id The specific engine's app id +* @param[in] event The specific engine event type +* @param[in] request The specific engine request +* +* @return 0 on success, otherwise a negative error value. +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VCE_ERROR_OPERATION_FAILED Operation failure +* +* @pre An application registers callback function using vce_set_specific_engine_request_cb(). +* +* @see vce_set_specific_engine_request_cb() +* @see vce_unset_specific_engine_request_cb() +*/ +typedef int (*vce_specific_engine_request_cb)(const char* engine_app_id, const char* event, const char* request); + +/** * @brief Called when the engine service user sets private data between app and engine. * @since_tizen 5.0 * @remarks The @a key, @a data can be used only in the callback. To use outside, make a copy. @@ -519,11 +574,18 @@ typedef struct { vce_cancel_cb cancel; /**< Cancel recording and processing */ vce_set_audio_type_cb set_audio_type; /**< Set audio type */ + vce_set_server_dialog_cb set_server_dialog; /**< Set server dialog */ vce_set_domain_cb set_domain; /**< Set domain */ vce_process_text_cb process_text; /**< Request to process text */ vce_process_list_event_cb process_list_event; /**< Request to process list event */ vce_process_haptic_event_cb process_haptic_event; /**< Request to process haptic event */ + + /* Optional callbacks */ + vce_private_data_set_cb private_data_set; + vce_private_data_requested_cb private_data_request; + vce_nlu_base_info_requested_cb nlu_base_info_request; + vce_specific_engine_request_cb specific_engine_request; } vce_request_callback_s; /** @@ -693,6 +755,24 @@ int vce_send_asr_result(vce_asr_result_event_e event, const char* asr_result, vo int vce_send_nlg_result(const char* nlg_result, void* user_data); /** +* @brief Sends the specific engine result to the engine service user. +* @since_tizen 5.0 +* +* @param[in] engine_app_id A specific engine's app id +* @param[in] event A specific engine result event +* @param[in] result A specific engine result text +* @param[in] user_data The user data passed from the start +* +* @return 0 on success, otherwise a negative error value +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VCE_ERROR_OUT_OF_MEMORY Out of Memory +* @retval #VCE_ERROR_OPERATION_FAILED Operation failure +* @pre The vce_main() function should be invoked before this function is called. +*/ +int vce_send_specific_engine_result(const char* engine_app_id, const char* event, const char* result, void *user_info); + +/** * @brief Sends the error to the engine service user. * @details The following error codes can be delivered. \n * #VCE_ERROR_NONE, \n @@ -771,6 +851,36 @@ int vce_set_private_data_requested_cb(vce_private_data_requested_cb callback_fun int vce_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func); /** +* @brief Registers a callback function for getting the engine service request. +* @since_tizen 5.0 +* +* @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 #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VCE_ERROR_PERMISSION_DENIED Permission denied +* @retval #VCE_ERROR_NOT_SUPPORTED Not supported +* +* @see vce_unset_specific_engine_request_cb() +*/ +int vce_set_specific_engine_request_cb(vce_specific_engine_request_cb callback_func); + +/** +* @brief Unregisters the engine service request callback function. +* @since_tizen 5.0 +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ERROR_NOT_SUPPORTED Not supported +* +* @see vce_set_specific_engine_request_cb() +*/ +int vce_unset_specific_engine_request_cb(void); + +/** * @brief Retrieves all commands using callback function. * @since_tizen 5.0 * @param[in] vce_command The handle to be passed to the vce_set_commands() function @@ -879,6 +989,32 @@ int vce_start_recording(void); */ int vce_stop_recording(void); +/* for TTS feeadback */ +/** +* @brief Sends audio formats necessary for playing TTS feedback. +* @since_tizen 5.0 +* @return 0 on success, otherwise a negative error value. +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_PERMISSION_DENIED Permission denied +* @retval #VCE_ERROR_NOT_SUPPORTED Not supported +* @retval #VCE_ERROR_OPERATION_FAILED Operation failure +* @retval #VCE_ERROR_OUT_OF_MEMORY Out of Memory +*/ +int vce_send_feedback_audio_format(int rate, vce_audio_channel_e channel, vce_audio_type_e audio_type); + +/** +* @brief Sends audio streaming necessary for playing TTS feedback. +* @since_tizen 5.0 +* @return 0 on success, otherwise a negative error value. +* @retval #VCE_ERROR_NONE Successful +* @retval #VCE_ERROR_PERMISSION_DENIED Permission denied +* @retval #VCE_ERROR_NOT_SUPPORTED Not supported +* @retval #VCE_ERROR_OPERATION_FAILED Operation failure +* @retval #VCE_ERROR_OUT_OF_MEMORY Out of Memory +*/ +int vce_send_feedback_streaming(vce_feedback_event_e event, char* buffer, int len); + + #ifdef __cplusplus } #endif diff --git a/include/voice_control.h b/include/voice_control.h index 9dfe6e0..f46b5c0 100644 --- a/include/voice_control.h +++ b/include/voice_control.h @@ -289,6 +289,49 @@ int vc_set_invocation_name(const char* name); /** + * @brief Requests to set app id which is to want to ask the server dialogue. + * @details Using this function, the developer can request registering the application on vc framework. + * If developer requests to register @a app_id with @a credential which is valid, the application will be set on vc framework. + * and then, when the developer requests the dialogue using vc_request_dialog(), dialog from specific engine server will be played by vc framework. + * @since_tizen 5.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/recorder + * @param[in] app_id App id which is to want to ask server dialog. + * @param[in] credential Credential key. + * @return @c 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_server_dialog() + */ +int vc_set_server_dialog(const char* app_id, const char* credential); + + +/** + * @brief Requests to unset app id which is to not want to ask the server dialogue. + * @details Using this function, the developer can disable function to ask dialog based on server. + * @since_tizen 5.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/recorder + * @param[in] app_id App id which is to not want to ask server dialog. + * @return @c 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_set_server_dialog() + */ +int vc_unset_server_dialog(const char* app_id); + + +/** * @brief Requests to start the dialogue. * @details Using this function, the developer can request starting the dialogue to the framework. * When the developer requests the dialogue, two types of texts, @a disp_text and @a utt_text, can be sent by this function. diff --git a/include/voice_control_common.h b/include/voice_control_common.h index b979562..5ae1ffa 100644 --- a/include/voice_control_common.h +++ b/include/voice_control_common.h @@ -93,6 +93,35 @@ typedef enum { VC_STATE_READY = 2 /**< 'Ready' state */ } vc_state_e; +/** +* @brief Enumerations of audio types. +* @since_tizen 5.0 +*/ +typedef enum { + VC_AUDIO_TYPE_PCM_S16_LE = 0, /**< Signed 16bit audio type, Little endian */ + VC_AUDIO_TYPE_PCM_U8 /**< Unsigned 8bit audio type */ +} vc_audio_type_e; + +/** + * @brief Enumerations for audio channels + * @since_tizen 5.0 + */ +typedef enum { + VC_AUDIO_CHANNEL_MONO = 0, /**< 1 channel, mono */ + VC_AUDIO_CHANNEL_STEREO = 1 /**< 2 channels, stereo */ +} vc_audio_channel_e; + +/** + * @brief Enumeration for TTS feedback events + * @since_tizen 5.0 + */ +typedef enum { + VC_FEEDBACK_EVENT_FAIL = -1, /**< Failed */ + VC_FEEDBACK_EVENT_START = 1, /**< Start event */ + VC_FEEDBACK_EVENT_CONTINUE = 2, /**< Continue event */ + VC_FEEDBACK_EVENT_FINISH = 3 /**< Finish event */ +} vc_feedback_event_e; + /** * @brief Called when client gets the recognition result. diff --git a/include/voice_control_manager.h b/include/voice_control_manager.h index cdd8af3..a1aab2b 100644 --- a/include/voice_control_manager.h +++ b/include/voice_control_manager.h @@ -164,6 +164,22 @@ typedef bool (*vc_mgr_all_result_cb)(vc_result_event_e event, vc_cmd_list_h vc_c typedef void (*vc_mgr_pre_result_cb)(vc_pre_result_event_e event, const char *result, void *user_data); /** +* @brief Called when client gets the specific engine's result from vc-service. +* @since_tizen 5.0 +* +* @param[in] engine_app_id The specific engine's app id +* @param[in] event The specific engine event type +* @param[in] result The specific engine result +* @param[in] user_data The user data passed from the callback registration function +* +* @pre An application registers callback function using vc_mgr_set_specific_engine_result_cb(). +* +* @see vc_mgr_set_specific_engine_result_cb() +* @see vc_mgr_unset_specific_engine_result_cb() +*/ +typedef void (*vc_mgr_specific_engine_result_cb)(const char* engine_app_id, const char* event, const char* result, void *user_data); + +/** * @brief Called when user speaking is detected. * @since_tizen 5.0 * @@ -230,6 +246,38 @@ typedef int (*vc_mgr_private_data_set_cb)(const char *key, const char *data, voi */ typedef int (*vc_mgr_private_data_requested_cb)(const char *key, char **data, void *user_data); +/* for TTS feedback */ +/** +* @brief Called when engine sends audio formats necessary for playing TTS feedback +* +* @param[in] rate Audio sampling rate +* @param[in] channel Audio channel (e.g. #VC_AUDIO_CHANNEL_MONO, #VC_AUDIO_CHANNEL_STEREO) +* @param[in] audio_type Audio type (e.g. #VC_AUDIO_TYPE_PCM_S16_LE, #VC_AUDIO_TYPE_PCM_U8) +* @param[in] user_data The user data passed from the callback registration function +* +* @pre An application registers callback function using vc_mgr_set_feedback_audio_format_cb(). +* +* @see vc_mgr_set_feedback_audio_format_cb() +* @see vc_mgr_unset_feedback_audio_format_cb() +*/ +typedef void (*vc_mgr_feedback_audio_format_cb)(int rate, vc_audio_channel_e channel, vc_audio_type_e audio_type, void *user_data); + +/** +* @brief Called when engine sends audio streaming for TTS feedback +* +* @param[in] event TTS feedback event (e.g. #VC_FEEDBACK_EVENT_START, #VC_FEEDBACK_EVENT_CONTINUE) +* @param[in] buffer Audio streaming data +* @param[in] len Length of the audio streaming data +* @param[in] user_data The user data passed from the callback registration function +* +* @pre An application registers callback function using vc_mgr_set_feedback_streaming_cb(). +* +* @see vc_mgr_set_feedback_streaming_cb() +* @see vc_mgr_unset_feedback_streaming_cb() +*/ +typedef void (*vc_mgr_feedback_streaming_cb)(vc_feedback_event_e event, char* buffer, int len, void *user_data); + + /** * @platform * @brief Initializes the voice control manager. @@ -745,6 +793,23 @@ int vc_mgr_get_private_data(const char *key, char **data); int vc_mgr_do_action(vc_send_event_type_e type, char *send_event); /** +* @brief Sends the specific engine request to the vc-service. +* @since_tizen 5.0 +* +* @param[in] engine_app_id A specific engine's app id +* @param[in] event A engine service user request event +* @param[in] request A engine service user request text +* +* @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_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_OPERATION_FAILED Operation failure +*/ +int vc_mgr_send_specific_engine_request(const char* engine_app_id, const char* event, const char* request); + +/** * @platform * @brief Starts recognition. * @since_tizen 5.0 @@ -975,6 +1040,42 @@ int vc_mgr_set_pre_result_cb(vc_mgr_pre_result_cb callback, void *user_data); int vc_mgr_unset_pre_result_cb(void); /** +* @brief Registers a callback function for getting specific engine result. +* @since_tizen 5.0 +* +* @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 +* @retval #VC_ERROR_PERMISSION_DENIED Permission denied +* @retval #VC_ERROR_NOT_SUPPORTED Not supported +* +* @pre The state should be #VC_STATE_INITIALIZED. +* +* @see vc_mgr_unset_specific_engine_result_cb() +*/ +int vc_mgr_set_specific_engine_result_cb(vc_mgr_specific_engine_result_cb callback, void* user_data); + +/** +* @brief Unregisters the specific engine result callback function. +* @since_tizen 5.0 +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @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_INITIALIZED. +* +* @see vc_mgr_set_specific_engine_result_cb() +*/ +int vc_mgr_unset_specific_engine_result_cb(void); + +/** * @platform * @brief Sets a callback function for getting all types of recognition results. * @since_tizen 5.0 @@ -1451,6 +1552,107 @@ int vc_mgr_set_private_data_requested_cb(vc_mgr_private_data_requested_cb callba */ int vc_mgr_unset_private_data_requested_cb(void); +/* for TTS feedback */ +/** +* @brief Sets a callback function to be called when engine sends audio formats necessary for playing TTS feedback. +* +* @param[in] callback Callback function to set +* @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_feedback_audio_format_cb() +* @see vc_mgr_unset_feedback_audio_format_cb() +*/ +int vc_mgr_set_feedback_audio_format_cb(vc_mgr_feedback_audio_format_cb callback, void* user_data); + +/** +* @brief Unsets a callback function to be called when engine sends audio formats necessary for playing TTS feedback. +* +* @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_feedback_audio_format_cb() +* @see vc_mgr_set_feedback_audio_format_cb() +*/ +int vc_mgr_unset_feedback_audio_format_cb(void); + +/** +* @brief Sets a callback function to be called when engine sends audio streaming for TTS feedback. +* +* @param[in] callback Callback function to set +* @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_feedback_streaming_cb() +* @see vc_mgr_unset_feedback_streaming_cb() +*/ +int vc_mgr_set_feedback_streaming_cb(vc_mgr_feedback_streaming_cb callback, void* user_data); + +/** +* @brief Unsets a callback function to be called when engine sends audio streaming for TTS feedback. +* +* @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_feedback_streaming_cb() +* @see vc_mgr_set_feedback_streaming_cb() +*/ +int vc_mgr_unset_feedback_streaming_cb(void); + +/** +* @brief Starts getting TTS feedback streaming data from the buffer. +* +* @remarks In order to get TTS feedback streaming data, the application should set 'vc_mgr_feedback_streaming_cb()' using vc_mgr_set_feedback_streaming_cb(). +* +* @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_READY. \n +* 'vc_mgr_feedback_streaming_cb()' should be registered. +* +* @see vc_mgr_feedback_streaming_cb() +* @see vc_mgr_set_feedback_streaming_cb() +* @see vc_mgr_unset_feedback_streaming_cb() +* @see vc_mgr_stop_feedback() +*/ +int vc_mgr_start_feedback(void); + +/** +* @brief Stops getting and removes TTS feedback streaming data from the buffer. +* +* @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_READY. +* +* @see vc_mgr_feedback_streaming_cb() +* @see vc_mgr_set_feedback_streaming_cb() +* @see vc_mgr_unset_feedback_streaming_cb() +* @see vc_mgr_start_feedback() +*/ +int vc_mgr_stop_feedback(void); + + #ifdef __cplusplus } #endif diff --git a/server/vcd_client_data.c b/server/vcd_client_data.c index 4ae7bb3..6953e17 100644 --- a/server/vcd_client_data.c +++ b/server/vcd_client_data.c @@ -769,6 +769,38 @@ vcd_recognition_mode_e vcd_client_get_recognition_mode() return g_recognition_mode; } +int vcd_client_set_server_dialog(int pid, bool is_server_dialog) +{ + vc_client_info_s* client_info = NULL; + + client_info = __client_get_element(pid); + if (NULL == client_info) { + SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] vcd_client_get_pid : pid(%d) is not found", pid); + return VCD_ERROR_INVALID_PARAMETER; + } + + client_info->server_dialog = is_server_dialog; + + SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Set server dialog, client pid(%d), server_dialog(%d)", pid, client_info->server_dialog); + return 0; +} + +int vcd_client_get_server_dialog(int pid, bool* is_server_dialog) +{ + vc_client_info_s* client_info = NULL; + + client_info = __client_get_element(pid); + if (NULL == client_info) { + SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] vcd_client_get_pid : pid(%d) is not found", pid); + return VCD_ERROR_INVALID_PARAMETER; + } + + *is_server_dialog = client_info->server_dialog; + + SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Get server dialog, client pid(%d), server_dialog(%d)", pid, *is_server_dialog); + return 0; +} + int vcd_client_append_cmd_from_type(int type, vc_cmd_list_h list) { GSList *item = NULL; @@ -998,6 +1030,7 @@ int vcd_client_add(int pid) info->fg_cmd = false; info->bg_cmd = false; info->exclusive_cmd = false; + info->server_dialog = false; /* Add item to global list */ g_client_list = g_slist_append(g_client_list, info); diff --git a/server/vcd_client_data.h b/server/vcd_client_data.h index 3ee5f0d..6060c81 100644 --- a/server/vcd_client_data.h +++ b/server/vcd_client_data.h @@ -155,6 +155,11 @@ int vcd_client_unset_exclusive_command(int pid); int vcd_client_save_client_info(); void vcd_client_update_foreground_pid(); + +int vcd_client_set_server_dialog(int pid, bool is_server_dialog); + +int vcd_client_get_server_dialog(int pid, bool* is_server_dialog); + /* * widget API */ diff --git a/server/vcd_dbus.c b/server/vcd_dbus.c old mode 100755 new mode 100644 index 250e5a0..5b3d4ee --- a/server/vcd_dbus.c +++ b/server/vcd_dbus.c @@ -405,6 +405,42 @@ int vcdc_send_pre_result_to_manager(int manager_pid, int event, const char* pre_ return 0; } +int vcdc_send_specific_engine_result_to_manager(int manager_pid, const char* engine_app_id, const char* event, const char* result) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[VCDC] send specific engine result to manager, mgr pid(%d), engine app id(%s), event(%s), result(%s),", + manager_pid, engine_app_id, event, result); + + if (0 != __dbus_check()) { + return VCD_ERROR_OPERATION_FAILED; + } + + DBusError err; + dbus_error_init(&err); + + DBusMessage* msg = NULL; + + msg = __get_message(manager_pid, VCD_MANAGER_METHOD_SPECIFIC_ENGINE_RESULT, VCD_CLIENT_TYPE_MANAGER); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Message is NULL"); + return VCD_ERROR_OUT_OF_MEMORY; + } + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &engine_app_id, DBUS_TYPE_STRING, &event, DBUS_TYPE_STRING, &result, 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); + } + + return 0; +} + int vcdc_send_result_to_manager(int manger_pid, int result_type) { if (0 != __dbus_check()) { @@ -902,6 +938,90 @@ int vcdc_send_request_get_private_data(int pid, const char* key, char** data) return result; } +int vcdc_send_feedback_audio_format_to_manager(int manager_pid, int rate, vc_audio_channel_e channel, vce_audio_type_e audio_type) +{ + SLOG(LOG_INFO, TAG_VCD, "[Dbus] Send TTS feedback audio format : manager_pid(%d), rate(%d), audio channel(%d), audio type(%d)", manager_pid, rate, channel, audio_type); + + if (0 != __dbus_check()) { + return VCD_ERROR_OPERATION_FAILED; + } + + DBusError err; + dbus_error_init(&err); + + /* make dbus message */ + DBusMessage* msg = NULL; + msg = __get_message(manager_pid, VCD_MANAGER_METHOD_FEEDBACK_AUDIO_FORMAT, VCD_CLIENT_TYPE_MANAGER); + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Message is NULL"); + return VCD_ERROR_OUT_OF_MEMORY; + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &rate, + DBUS_TYPE_INT32, &channel, + DBUS_TYPE_INT32, &audio_type, + DBUS_TYPE_INVALID); + + dbus_message_set_no_reply(msg, TRUE); + + int ret = VCD_ERROR_NONE; + + if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to Send"); + ret = VCD_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_INFO, TAG_VCD, "[Dbus] SUCCESS Send"); + dbus_connection_flush(g_conn_sender); + } + + dbus_message_unref(msg); + + return ret; +} + +int vcdc_send_feedback_streaming_to_manager(int manager_pid, vc_feedback_event_e event, char* buffer, int len) +{ + SLOG(LOG_INFO, TAG_VCD, "[Dbus] Send TTS feedback streaming : manager_pid(%d), feedback event(%d), buffer(%p), length(%d)", manager_pid, event, buffer, len); + + if (0 != __dbus_check()) { + return VCD_ERROR_OPERATION_FAILED; + } + + DBusError err; + dbus_error_init(&err); + + /* make dbus message */ + DBusMessage* msg = NULL; + msg = __get_message(manager_pid, VCD_MANAGER_METHOD_FEEDBACK_STREAMING, VCD_CLIENT_TYPE_MANAGER); + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Message is NULL"); + return VCD_ERROR_OUT_OF_MEMORY; + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &event, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, + &buffer, len, + DBUS_TYPE_INVALID); + + dbus_message_set_no_reply(msg, TRUE); + + int ret = VCD_ERROR_NONE; + + if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to Send"); + ret = VCD_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_INFO, TAG_VCD, "[Dbus] SUCCESS Send"); + dbus_connection_flush(g_conn_sender); + } + + dbus_message_unref(msg); + + return ret; +} + static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler) { if (NULL == g_conn_listener) return ECORE_CALLBACK_RENEW; @@ -970,12 +1090,21 @@ 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_DO_ACTION)) vcd_dbus_server_mgr_do_action(g_conn_listener, msg); + else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_SPECIFIC_ENGINE_REQUEST)) + vcd_dbus_server_mgr_send_specific_engine_request(g_conn_listener, msg); + else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_ENABLE_COMMAND_TYPE)) vcd_dbus_server_mgr_enable_command_type(g_conn_listener, msg); else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_DISABLE_COMMAND_TYPE)) vcd_dbus_server_mgr_disable_command_type(g_conn_listener, msg); + else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_START_FEEDBACK)) + vcd_dbus_server_mgr_start_feedback(g_conn_listener, msg); + + else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_STOP_FEEDBACK)) + vcd_dbus_server_mgr_stop_feedback(g_conn_listener, msg); + /* client event */ else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_INITIALIZE)) vcd_dbus_server_initialize(g_conn_listener, msg); @@ -995,6 +1124,9 @@ 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_SET_SERVER_DIALOG)) + vcd_dbus_server_set_server_dialog(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); diff --git a/server/vcd_dbus.h b/server/vcd_dbus.h index d4674ec..0dbe188 100644 --- a/server/vcd_dbus.h +++ b/server/vcd_dbus.h @@ -48,6 +48,8 @@ int vcdc_send_asr_result(int pid, int event, const char* asr_result, int cmd_typ int vcdc_send_pre_result_to_manager(int manager_pid, int event, const char* pre_result); +int vcdc_send_specific_engine_result_to_manager(int manager_pid, const char* engine_app_id, const char* event, const char* result); + int vcdc_send_result_to_manager(int manger_pid, int result_type); int vcdc_send_speech_detected(int manger_pid); @@ -66,6 +68,12 @@ int vcdc_send_request_set_private_data(int pid, const char* key, const char* dat int vcdc_send_request_get_private_data(int pid, const char* key, char** data); +/* for TTS feedback */ +int vcdc_send_feedback_audio_format_to_manager(int manager_pid, int rate, vc_audio_channel_e channel, vce_audio_type_e audio_type); + +int vcdc_send_feedback_streaming_to_manager(int manager_pid, vc_feedback_event_e event, char* buffer, int len); + + #ifdef __cplusplus } #endif diff --git a/server/vcd_dbus_server.c b/server/vcd_dbus_server.c old mode 100755 new mode 100644 index 6a6a15d..297ef13 --- a/server/vcd_dbus_server.c +++ b/server/vcd_dbus_server.c @@ -620,6 +620,39 @@ int vcd_dbus_server_mgr_get_private_data(DBusConnection* conn, DBusMessage* msg) return 0; } +int vcd_dbus_server_mgr_send_specific_engine_request(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid = 0; + char* engine_app_id = NULL; + char* event = NULL; + char* request = NULL; + + int ret = VCD_ERROR_OPERATION_FAILED; + + SLOG(LOG_DEBUG, TAG_VCD, "@@@ VCD Manager specific engine request"); + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &engine_app_id, + DBUS_TYPE_STRING, &event, + DBUS_TYPE_STRING, &request, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr specific engine request : get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = VCD_ERROR_OPERATION_FAILED; + } else { + ret = vcd_server_mgr_send_specific_engine_request(pid, engine_app_id, event, request); + SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr specific engine request : pid(%d), engine_app_id(%s), event(%s), request(%s), ret(%d)", pid, engine_app_id, event, request, ret); + } + + return 0; +} + int vcd_dbus_server_mgr_set_domain(DBusConnection* conn, DBusMessage* msg) { DBusError err; @@ -630,7 +663,7 @@ int vcd_dbus_server_mgr_set_domain(DBusConnection* conn, DBusMessage* msg) int ret = VCD_ERROR_OPERATION_FAILED; - SLOG(LOG_DEBUG, TAG_VCD, "@@@ VCD Manager set audio type"); + SLOG(LOG_DEBUG, TAG_VCD, "@@@ VCD Manager set domain type"); dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, @@ -1033,6 +1066,114 @@ int vcd_dbus_server_mgr_result_selection(DBusConnection* conn, DBusMessage* msg) */ } +/* for TTS feedback */ +int vcd_dbus_server_mgr_start_feedback(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid = 0; + + int ret = VCD_ERROR_OPERATION_FAILED; + + SLOG(LOG_DEBUG, TAG_VCD, "@@@ VCD Manager start TTS feedback"); + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] vcd mgr start TTS feedback : get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = VCD_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] vcd mgr start TTS feedback : pid(%d)", pid); + ret = vcd_server_mgr_start_feedback(); + } + + 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, "[SUCCESS] Result(%d)", ret); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Result(%d)", ret); + } + + if (!dbus_connection_send(conn, reply, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Out of Memory"); + } + + dbus_connection_flush(conn); + dbus_message_unref(reply); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create reply message"); + } + + SLOG(LOG_DEBUG, TAG_VCD, "@@@"); + + return 0; +} + +int vcd_dbus_server_mgr_stop_feedback(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid = 0; + + int ret = VCD_ERROR_OPERATION_FAILED; + + SLOG(LOG_DEBUG, TAG_VCD, "@@@ VCD Manager stop TTS feedback"); + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] vcd mgr stop TTS feedback : get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = VCD_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] vcd mgr stop TTS feedback : pid(%d)", pid); + ret = vcd_server_mgr_stop_feedback(); + } + + 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, "[SUCCESS] Result(%d)", ret); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Result(%d)", ret); + } + + if (!dbus_connection_send(conn, reply, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Out of Memory"); + } + + dbus_connection_flush(conn); + dbus_message_unref(reply); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to create reply message"); + } + + SLOG(LOG_DEBUG, TAG_VCD, "@@@"); + + return 0; +} + + /* * Dbus Server functions for client */ @@ -1330,6 +1471,64 @@ int vcd_dbus_server_set_foreground(DBusConnection* conn, DBusMessage* msg) return 0; } +int vcd_dbus_server_set_server_dialog(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid = -1; + char* app_id = NULL; + char* credential = NULL; + int ret = VCD_ERROR_OPERATION_FAILED; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &app_id, + DBUS_TYPE_STRING, &credential, + DBUS_TYPE_INVALID); + + SLOG(LOG_DEBUG, TAG_VCD, "@@@ VCD set server dialog"); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd set server dialog : get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = VCD_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd set server dialog : pid(%d), app_id(%s)", pid, app_id); + ret = vcd_server_set_server_dialog(pid, app_id, credential); + } + + 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, "@@@"); + + return 0; + +} + int vcd_dbus_server_dialog(DBusConnection* conn, DBusMessage* msg) { DBusError err; diff --git a/server/vcd_dbus_server.h b/server/vcd_dbus_server.h index caa87df..1456536 100644 --- a/server/vcd_dbus_server.h +++ b/server/vcd_dbus_server.h @@ -67,6 +67,14 @@ int vcd_dbus_server_mgr_enable_command_type(DBusConnection* conn, DBusMessage* m int vcd_dbus_server_mgr_disable_command_type(DBusConnection* conn, DBusMessage* msg); +int vcd_dbus_server_mgr_send_specific_engine_request(DBusConnection* conn, DBusMessage* msg); + +/* for TTS feedback */ +int vcd_dbus_server_mgr_start_feedback(DBusConnection* conn, DBusMessage* msg); + +int vcd_dbus_server_mgr_stop_feedback(DBusConnection* conn, DBusMessage* msg); + + /* * Dbus Server functions for client */ @@ -85,6 +93,8 @@ int vcd_dbus_server_unset_command(DBusConnection* conn, DBusMessage* msg); int vcd_dbus_server_set_foreground(DBusConnection* conn, DBusMessage* msg); +int vcd_dbus_server_set_server_dialog(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); diff --git a/server/vcd_engine_agent.c b/server/vcd_engine_agent.c index bd3ecea..da79346 100644 --- a/server/vcd_engine_agent.c +++ b/server/vcd_engine_agent.c @@ -42,7 +42,7 @@ typedef struct { bool use_network; void *handle; - vc_engine_callback_s* callbacks; + vce_request_callback_s* callbacks; } vcengine_s; typedef struct _vcengine_info { @@ -94,7 +94,7 @@ int vcd_engine_agent_init() g_dynamic_engine.handle = NULL; g_dynamic_engine.is_command_ready = false; - g_dynamic_engine.callbacks = (vc_engine_callback_s*)calloc(1, sizeof(vc_engine_callback_s)); + g_dynamic_engine.callbacks = (vce_request_callback_s*)calloc(1, sizeof(vce_request_callback_s)); if (NULL == g_dynamic_engine.callbacks) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Fail to allocate memory"); return VCD_ERROR_OUT_OF_MEMORY; @@ -186,7 +186,7 @@ int __internal_get_engine_info(vce_request_callback_s* callback) free(g_dynamic_engine.callbacks); g_dynamic_engine.callbacks = NULL; } - g_dynamic_engine.callbacks = (vc_engine_callback_s*)calloc(1, sizeof(vc_engine_callback_s)); + g_dynamic_engine.callbacks = (vce_request_callback_s*)calloc(1, sizeof(vce_request_callback_s)); if (NULL == g_dynamic_engine.callbacks) { SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to allocate memory"); return VCD_ERROR_OUT_OF_MEMORY; @@ -208,6 +208,7 @@ int __internal_get_engine_info(vce_request_callback_s* callback) g_dynamic_engine.callbacks->cancel = callback->cancel; g_dynamic_engine.callbacks->set_domain = callback->set_domain; g_dynamic_engine.callbacks->set_audio_type = callback->set_audio_type; + g_dynamic_engine.callbacks->set_server_dialog = callback->set_server_dialog; g_dynamic_engine.callbacks->process_text = callback->process_text; g_dynamic_engine.callbacks->process_list_event = callback->process_list_event; g_dynamic_engine.callbacks->process_haptic_event = callback->process_haptic_event; @@ -215,6 +216,7 @@ int __internal_get_engine_info(vce_request_callback_s* callback) g_dynamic_engine.callbacks->private_data_set = NULL; g_dynamic_engine.callbacks->private_data_request = NULL; g_dynamic_engine.callbacks->nlu_base_info_request = NULL; + g_dynamic_engine.callbacks->specific_engine_request = NULL; SLOG(LOG_DEBUG, TAG_VCD, "@@@ Valid Engine"); SLOG(LOG_DEBUG, TAG_VCD, "Engine uuid : %s", g_dynamic_engine.engine_uuid); @@ -266,6 +268,7 @@ int vcd_engine_agent_load_current_engine(vce_request_callback_s* callback) NULL == g_dynamic_engine.callbacks->stop || NULL == g_dynamic_engine.callbacks->cancel || NULL == g_dynamic_engine.callbacks->set_audio_type || + NULL == g_dynamic_engine.callbacks->set_server_dialog || NULL == g_dynamic_engine.callbacks->set_domain || NULL == g_dynamic_engine.callbacks->process_text || NULL == g_dynamic_engine.callbacks->process_list_event || @@ -472,6 +475,25 @@ int vcd_engine_set_audio_type(const char* audio) return 0; } +int vcd_engine_set_server_dialog(const char* app_id, const char* credential) +{ + 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.callbacks->set_server_dialog(app_id, credential); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set server dialog (%d)", ret); + return ret; + } + } + + return 0; +} + int vcd_engine_set_domain(int pid, const char* domain) { if (false == g_agent_init) { @@ -567,6 +589,28 @@ int vcd_engine_get_private_data(int pid, const char* key, char** data) return 0; } +int vcd_engine_send_specific_engine_request(const char* engine_app_id, const char* event, const char* request) +{ + 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 && NULL != g_dynamic_engine.callbacks->specific_engine_request) { + ret = g_dynamic_engine.callbacks->specific_engine_request(engine_app_id, event, request); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set specific engine request (%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + } else { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded or There is no specific_engine_request callback"); + return VCD_ERROR_OPERATION_FAILED; + } + + return 0; +} + int vcd_engine_process_text(int pid, const char* text) { if (false == g_agent_init) { @@ -844,3 +888,19 @@ int vcd_engine_agent_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_ return VCD_ERROR_NONE; } +int vcd_engine_agent_set_specific_engine_request_cb(vce_specific_engine_request_cb callback_func) +{ + if (false == g_agent_init) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized"); + return VCD_ERROR_OPERATION_FAILED; + } + + if (false == g_dynamic_engine.is_loaded) { + SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not loaded engine"); + return VCD_ERROR_OPERATION_FAILED; + } + + g_dynamic_engine.callbacks->specific_engine_request = callback_func; + + return VCD_ERROR_NONE; +} diff --git a/server/vcd_engine_agent.h b/server/vcd_engine_agent.h index a327584..4dc5e25 100644 --- a/server/vcd_engine_agent.h +++ b/server/vcd_engine_agent.h @@ -66,6 +66,8 @@ int vcd_engine_recognize_cancel(); int vcd_engine_set_audio_type(const char* audio); +int vcd_engine_set_server_dialog(const char* app_id, const char* credential); + int vcd_engine_set_domain(int pid, const char* domain); int vcd_engine_get_nlu_base_info(int pid, const char* key, char** value); @@ -74,6 +76,8 @@ int vcd_engine_set_private_data(int pid, const char* key, const char* data); int vcd_engine_get_private_data(int pid, const char* key, char** data); +int vcd_engine_send_specific_engine_request(const char* engine_app_id, const char* event, const char* request); + int vcd_engine_process_text(int pid, const char* text); int vcd_engine_process_list_event(int pid, const char* event); @@ -101,6 +105,7 @@ int vcd_engine_agent_set_private_data_requested_cb(vce_private_data_requested_cb int vcd_engine_agent_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func); +int vcd_engine_agent_set_specific_engine_request_cb(vce_specific_engine_request_cb callback_func); #ifdef __cplusplus } diff --git a/server/vcd_main.h b/server/vcd_main.h index 72e105c..a9f7943 100644 --- a/server/vcd_main.h +++ b/server/vcd_main.h @@ -32,6 +32,8 @@ #include "vc_defs.h" #include "vce.h" +#include "voice_control_common.h" + #ifdef __cplusplus extern "C" { @@ -76,43 +78,6 @@ typedef struct { int index; } vce_cmd_s; -typedef struct { - int version; /**< Version */ - - /* Mandatory callbacks */ - /* Get engine information */ - vce_get_info_cb get_info; /**< Called when the engine service user requests the basic information of VC engine */ - vce_get_recording_format_cb get_recording_format; /**< Get recording format */ - vce_foreach_supported_languages_cb foreach_langs; /**< Foreach language list */ - vce_is_language_supported_cb is_lang_supported; /**< Check language */ - - vce_initialize_cb initialize; /**< Initialize engine */ - vce_deinitialize_cb deinitialize; /**< Shutdown engine */ - - /* Set info */ - vce_set_language_cb set_language; /**< Set language */ - vce_set_commands_cb set_commands; /**< Request to set current commands */ - vce_unset_commands_cb unset_commands; /**< Request to unset current commands */ - - /* Control recognition */ - vce_start_cb start; /**< Start recognition */ - vce_set_recording_data_cb set_recording; /**< Set recording data */ - vce_stop_cb stop; /**< Stop recording for getting result */ - vce_cancel_cb cancel; /**< Cancel recording and processing */ - - vce_set_audio_type_cb set_audio_type; /**< Set audio type */ - - vce_set_domain_cb set_domain; /**< Set domain */ - vce_process_text_cb process_text; /**< Request to process text */ - vce_process_list_event_cb process_list_event; /**< Request to process list event */ - vce_process_haptic_event_cb process_haptic_event; /**< Request to process haptic event */ - - /* Optional callbacks */ - vce_private_data_set_cb private_data_set; - vce_private_data_requested_cb private_data_request; - vce_nlu_base_info_requested_cb nlu_base_info_request; -} vc_engine_callback_s; - #ifdef __cplusplus } diff --git a/server/vcd_server.c b/server/vcd_server.c index ef9dc76..d5bf69b 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -445,6 +445,21 @@ int vcd_send_asr_result(vce_asr_result_event_e event, const char* asr_result, vo return ret; } +int vcd_send_specific_engine_result(const char* engine_app_id, const char* event, const char* result, void *user_info) +{ + if (NULL != result) { + SLOG(LOG_DEBUG, TAG_VCD, "[Server] specific engine result - Event(%s), Text(%s)", event, result); + vcdc_send_specific_engine_result_to_manager(vcd_client_manager_get_pid(), engine_app_id, event, result); + } + + if (VCD_RECOGNITION_MODE_RESTART_CONTINUOUSLY != vcd_client_get_recognition_mode()) { + vcd_config_set_service_state(VCD_STATE_READY); + vcdc_send_service_state(VCD_STATE_READY); + } + + return VCD_ERROR_NONE; +} + int vcd_send_nlg_result(const char* nlg_result, void *user_data) { int ret = __vcd_server_launch_manager_app(); @@ -1078,6 +1093,36 @@ int vcd_send_error(vce_error_e error, const char* msg, void *user_data) return ret; } +/* for TTS feedback */ +int vcd_send_feedback_audio_format(int rate, vce_audio_channel_e channel, vce_audio_type_e audio_type) +{ + SLOG(LOG_INFO, TAG_VCD, "[Server DEBUG] Engine - Send TTS feedback audio format"); + + /* send TTS feedback audio format to VC manager */ + int ret = VCD_ERROR_NONE; + ret = vcdc_send_feedback_audio_format_to_manager(vcd_client_manager_get_pid(), rate, channel, audio_type); + if (VCD_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send TTS feedback audio format to VC manager"); + } + + return ret; +} + +int vcd_send_feedback_streaming(vce_feedback_event_e event, char* buffer, int len) +{ + SLOG(LOG_INFO, TAG_VCD, "[Server DEBUG] Engine - Send TTS feedback streaming"); + + /* send TTS feedback streaming to VC manager */ + int ret = VCD_ERROR_NONE; + ret = vcdc_send_feedback_streaming_to_manager(vcd_client_manager_get_pid(), event, buffer, len); + if (VCD_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send TTS feedback streaming to VC manager"); + } + + return ret; +} + + /* * vcd server Interfaces */ @@ -1991,6 +2036,30 @@ int vcd_server_mgr_get_private_data(int pid, const char* key, char** data) return ret; } +int vcd_server_mgr_send_specific_engine_request(int pid, const char* engine_app_id, const char* event, const char* request) +{ + /* 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_send_specific_engine_request(engine_app_id, event, request); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set specific engine request : %d", ret); + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] Set specific engine request "); + } + + return ret; +} + int vcd_server_mgr_do_action(int pid, int type, const char* action) { int ret = -1; @@ -2078,6 +2147,40 @@ int vcd_server_mgr_disable_command_type(int pid, int cmd_type) return ret; } +/* for TTS feedback */ +int vcd_server_mgr_start_feedback(void) +{ + /* check current state */ + /* not Recording??? */ + + if (-1 == vcd_client_manager_get_pid()) { + SLOG(LOG_ERROR, TAG_VCD, "[Server] Manager is NOT available"); + return VCD_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCD, "[Server] start TTS feedback"); + + /* check there is TTS buffer to be spoken */ + + return VCD_ERROR_NONE; +} + +int vcd_server_mgr_stop_feedback(void) +{ + /* check current state */ + /* not Recording??? */ + + if (-1 == vcd_client_manager_get_pid()) { + SLOG(LOG_ERROR, TAG_VCD, "[Server] Manager is NOT available"); + return VCD_ERROR_OPERATION_FAILED; + } + + SLOG(LOG_DEBUG, TAG_VCD, "[Server] stop TTS feedback"); + + return VCD_ERROR_NONE; +} + + /* * VC Server Functions for Client */ @@ -2225,26 +2328,66 @@ static int __vcd_server_launch_manager_app() return VCD_ERROR_NONE; } -int vcd_server_dialog(int pid, const char* disp_text, const char* utt_text, int continuous) +int vcd_server_set_server_dialog(int pid, const char* app_id, const char* credential) { /* check if pid is valid */ - if (false == vcd_client_is_available(pid) && false == vcd_client_widget_is_available(pid)) { + if (false == vcd_client_is_available(pid)) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid "); return VCD_ERROR_INVALID_PARAMETER; } - int ret = __vcd_server_launch_manager_app(); + int ret = vcd_engine_set_server_dialog(app_id, credential); 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); + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set server dialog, pid(%d), app_id(%s), ret(%d)", pid, app_id, ret); + vcd_client_set_server_dialog(pid, false); return ret; } + SLOG(LOG_ERROR, TAG_VCD, "[Success] Set server dialog, pid(%d), app_id(%s)", pid, app_id); + + if (0 != strncmp(credential, "#NULL", strlen(credential))) { + ret = vcd_client_set_server_dialog(pid, true); + if (0 != ret) + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set to true for server dialog, app_id(%s)", app_id); + } else { + ret = vcd_client_set_server_dialog(pid, false); + if (0 != ret) + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set to false for server dialog, app_id(%s)", app_id); + } + + 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; + } - ret = vcdc_send_dialog(vcd_client_manager_get_pid(), pid, disp_text, utt_text, continuous); + bool is_server_dialog = false; + int ret = vcd_client_get_server_dialog(pid, &is_server_dialog); 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; + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get server dialog, pid(%d), ret(%d)", pid, ret); } + if (true == is_server_dialog) { + /* ++ Request tts event to engine */ + + /* -- Request tts event to engine */ + } else { + 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 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; } @@ -2742,3 +2885,15 @@ int vcd_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_f return ret; } + +int vcd_set_specific_engine_request_cb(vce_specific_engine_request_cb callback_func) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Server] Set specific engine request cb"); + int ret = 0; + ret = vcd_engine_agent_set_specific_engine_request_cb(callback_func); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set specific engine request cb : ret(%d)", ret); + } + + return ret; +} diff --git a/server/vcd_server.h b/server/vcd_server.h index 70bc3d9..e11108f 100644 --- a/server/vcd_server.h +++ b/server/vcd_server.h @@ -80,6 +80,12 @@ int vcd_server_mgr_enable_command_type(int pid, int cmd_type); int vcd_server_mgr_disable_command_type(int pid, int cmd_type); +/* for TTS feedback */ +int vcd_server_mgr_start_feedback(void); + +int vcd_server_mgr_stop_feedback(void); + + /* * For client */ @@ -93,6 +99,8 @@ 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_set_server_dialog(int pid, const char* app_id, const char* credential); + 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); @@ -126,6 +134,8 @@ int vcd_server_widget_enable_asr_result(int pid, bool enable); int vcd_server_set_language(const char* language); +int vcd_server_mgr_send_specific_engine_request(int pid, const char* engine_app_id, const char* event, const char* request); + /* * For engine service */ @@ -133,6 +143,8 @@ int vcd_send_result(vce_result_event_e event, int* result_id, int count, const c int vcd_send_asr_result(vce_asr_result_event_e event, const char* asr_result, void *user_data); +int vcd_send_specific_engine_result(const char* engine_app_id, const char* event, const char* result, void *user_info); + int vcd_send_nlg_result(const char* nlg_result, void *user_data); int vcd_send_error(vce_error_e error, const char* msg, void *user_data); @@ -157,6 +169,12 @@ int vcd_set_private_data_requested_cb(vce_private_data_requested_cb callback_fun int vcd_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_func); +int vcd_set_specific_engine_request_cb(vce_specific_engine_request_cb callback_func); + +int vcd_send_feedback_audio_format(int rate, vce_audio_channel_e channel, vce_audio_type_e audio_type); + +int vcd_send_feedback_streaming(vce_feedback_event_e event, char* buffer, int len); + #ifdef __cplusplus } diff --git a/server/vce.c b/server/vce.c index cbb21fa..087cee8 100644 --- a/server/vce.c +++ b/server/vce.c @@ -221,6 +221,29 @@ int vce_send_asr_result(vce_asr_result_event_e event, const char* asr_result, vo return ret; } +int vce_send_specific_engine_result(const char* engine_app_id, const char* event, const char* result, void *user_info) +{ + int ret = VCE_ERROR_NONE; + + if (NULL == engine_app_id || NULL == event) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter"); + return VCE_ERROR_INVALID_PARAMETER; + } + + if (NULL == result) { + SLOG(LOG_ERROR, TAG_VCD, "[INFO] Input parameter is NULL. (no result)"); + } + + ret = vcd_send_specific_engine_result(engine_app_id, event, result, user_info); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send specific engine result, ret(%d)", ret); + } else { + SLOG(LOG_INFO, TAG_VCD, "[INFO] Success to send specific engine result, event(%s), result(%s)", event, result); + } + + return ret; +} + int vce_send_nlg_result(const char* nlg_result, void *user_data) { int ret = VCE_ERROR_NONE; @@ -449,3 +472,53 @@ int vce_set_nlu_base_info_requested_cb(vce_nlu_base_info_requested_cb callback_f return ret; } + +int vce_set_specific_engine_request_cb(vce_specific_engine_request_cb callback_func) +{ + if (NULL == callback_func) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Invalid parameter"); + return VCE_ERROR_INVALID_PARAMETER; + } + + int ret = vcd_set_specific_engine_request_cb(callback_func); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set specific engine request cb"); + } + + return ret; +} + +int vce_unset_specific_engine_request_cb(void) +{ + int ret = vcd_set_specific_engine_request_cb(NULL); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set specific engine request cb"); + } + + return ret; +} + +/* for TTS feedback */ +int vce_send_feedback_audio_format(int rate, vce_audio_channel_e channel, vce_audio_type_e audio_type) +{ + int ret = VCE_ERROR_NONE; + + ret = vcd_send_feedback_audio_format(rate, channel, audio_type); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send feedback audio format"); + } + + return ret; +} + +int vce_send_feedback_streaming(vce_feedback_event_e event, char* buffer, int len) +{ + int ret = VCE_ERROR_NONE; + + ret = vcd_send_feedback_streaming(event, buffer, len); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to send feedback streaming"); + } + + return ret; +} -- 2.7.4