From 10a8da4d9afa7b1108bf9384b4a955d4bd884fa0 Mon Sep 17 00:00:00 2001 From: Ji-hoon Lee Date: Thu, 28 Feb 2019 10:52:10 +0900 Subject: [PATCH] Add APIs for supporting advanced functionalities * Active state management for voice assistants * Recognition result notification * Previous / Follow-up speech audio streaming support * Voice feedback state notification * Assistant / Wakeup Engine specific command support Change-Id: I46d115589566e0fc3e8ee41d5d990aaa4409c959 --- client/ma.c | 364 ++++++++++++++++++++++++++++++- client/ma_client.c | 104 ++++++++- client/ma_client.h | 14 ++ client/ma_dbus.c | 364 +++++++++++++++++++++++++++---- client/ma_dbus.h | 8 + client/ma_ui.c | 87 ++++++++ client/ma_ui_client.c | 29 +++ client/ma_ui_client.h | 4 + client/ma_ui_dbus.c | 22 +- common/ma_defs.h | 52 +++-- include/multi_assistant.h | 133 +++++++++++ include/multi_assistant_common.h | 57 ++++- include/multi_assistant_ui.h | 41 ++++ server/CMakeLists.txt | 25 --- 14 files changed, 1205 insertions(+), 99 deletions(-) delete mode 100644 server/CMakeLists.txt diff --git a/client/ma.c b/client/ma.c index d3f0432..3028450 100644 --- a/client/ma.c +++ b/client/ma.c @@ -295,10 +295,21 @@ static Eina_Bool __ma_connect_daemon(void *data) SLOG(LOG_DEBUG, TAG_MAC, "[Client DEBUG] Success to connect daemon"); } + ma_state_e prev_state; + ma_active_state_e active_state; + ma_client_get_client_state(g_ma, &prev_state); + ma_client_get_client_active_state(g_ma, &active_state); ma_client_set_client_state(g_ma, MA_STATE_READY); __ma_notify_state_changed(g_ma); ma_client_set_ui_pid(g_ma, ui_pid); + + if (prev_state == MA_STATE_INITIALIZED && active_state == MA_ACTIVE_STATE_ACTIVE) { + /* This app was activated but was not in ready state, meaning we should + start receiving audio stream data */ + SLOG(LOG_DEBUG, TAG_MAC, "[Client DEBUG] Start requesting audio data"); + ma_start_receiving_audio_streaming_data(MA_AUDIO_STREAMING_DATA_TYPE_CURRENT_UTTERANCE); + } } else { SLOG(LOG_ERROR, TAG_MAC, "[Not ERROR] g_ma is not valid. It is destroyed."); //LCOV_EXCL_LINE return EINA_FALSE; @@ -396,7 +407,6 @@ int ma_unprepare(void) SLOG(LOG_DEBUG, TAG_MAC, "[Client DEBUG] Unprepare"); - ma_state_e state; if (0 != ma_client_get_client_state(g_ma, &state)) { @@ -442,6 +452,40 @@ static void __ma_notify_state_changed(void * data) } } +int __ma_cb_active_state_changed(int state) +{ + ma_active_state_changed_cb callback = NULL; + void* user_data; + + ma_client_get_active_state_changed_cb(g_ma, &callback, &user_data); + + ma_active_state_e current_state; + ma_active_state_e previous_state; + + ma_client_get_previous_active_state(g_ma, ¤t_state, &previous_state); + + current_state = (ma_active_state_e)state; + ma_client_set_client_active_state(g_ma, current_state); + + if (NULL != callback) { + ma_client_use_callback(g_ma); + callback(previous_state, current_state, user_data); + ma_client_not_use_callback(g_ma); + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] Active state changed callback is called %d", current_state); + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[WARNING] Active state changed callback is NULL"); + } + + ma_client_get_previous_active_state(g_ma, ¤t_state, &previous_state); + SLOG(LOG_DEBUG, TAG_MAC, + "[DEBUG] previous : %d , current : %d Sending audio streaming request", + previous_state, current_state + ); + ma_start_receiving_audio_streaming_data(MA_AUDIO_STREAMING_DATA_TYPE_CURRENT_UTTERANCE); + + return 0; +} + int __ma_cb_audio_streaming(int event, char* buffer, int len) { ma_audio_streaming_cb callback = NULL; @@ -453,7 +497,7 @@ int __ma_cb_audio_streaming(int event, char* buffer, int len) ma_client_use_callback(g_ma); callback((ma_audio_streaming_event_e)event, buffer, len, user_data); ma_client_not_use_callback(g_ma); - SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] Audio streaming callback is called"); + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] Audio streaming callback is called, event(%d)", event); } else { SLOG(LOG_DEBUG, TAG_MAC, "[WARNING] Audio streaming callback is NULL"); } @@ -537,6 +581,24 @@ static void __ma_lang_changed_cb(const char* previous_lang, const char* current_ } } */ +int __ma_cb_wakeup_engine_command(const char* command) +{ + ma_wakeup_engine_command_cb callback = NULL; + void* user_data; + + ma_client_get_wakeup_engine_command_cb(g_ma, &callback, &user_data); + + if (NULL != callback) { + ma_client_use_callback(g_ma); + callback(command, user_data); + ma_client_not_use_callback(g_ma); + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] Wakeup engine command callback is called, (%s)", (command ? command : "NULL")); + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[WARNING] Wakeup engine command callback is NULL"); + } + + return 0; +} int ma_get_state(ma_state_e* state) { @@ -923,7 +985,7 @@ int ma_send_asr_result(ma_asr_result_event_e event, const char* asr_result) if (0 != ret) { SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Fail to send ASR result"); } else { - SLOG(LOG_DEBUG, TAG_MAC, "[ERROR] Success to send ASR result"); + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] Success to send ASR result"); } return ret; @@ -963,8 +1025,302 @@ int ma_send_result(const char* display_text, const char* utterance_text, const c if (0 != ret) { SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Fail to send result"); } else { - SLOG(LOG_DEBUG, TAG_MAC, "[ERROR] Success to send result"); + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] Success to send result"); + } + + return ret; +} + +int ma_send_recognition_result(ma_recognition_result_event_e result) +{ + if (0 != __ma_get_feature_enabled()) { + return MA_ERROR_NOT_SUPPORTED; + } + + if (0 != __ma_check_privilege()) { + return MA_ERROR_PERMISSION_DENIED; + } + + ma_state_e state; + if (0 != ma_client_get_client_state(g_ma, &state)) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] A handle is not available"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != MA_STATE_READY) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Invalid State: Current state is not 'READY'"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + SLOG(LOG_DEBUG, TAG_MAC, "[Client DEBUG] Send result to the Multi-assistant"); + + int ret = -1; + int pid = getpid(); + ret = ma_dbus_send_recognition_result(pid, result); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Fail to send result"); + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] Success to send result"); } return ret; } + +int ma_set_active_state_changed_cb(ma_active_state_changed_cb callback, void* user_data) +{ + if (0 != __ma_get_feature_enabled()) { + return MA_ERROR_NOT_SUPPORTED; + } + + SLOG(LOG_DEBUG, TAG_MAC, "[Client DEBUG] Set Multi-assistant active state changed cb"); + + if (NULL == callback) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Invalid parameter"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_PARAMETER; + } + + ma_state_e state; + + if (0 != ma_client_get_client_state(g_ma, &state)) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] A handle is not available"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != MA_STATE_INITIALIZED) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Invalid State: Current state is not 'Initialized' (%d)", state); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + ma_client_set_active_state_changed_cb(g_ma, callback, user_data); + + return MA_ERROR_NONE; +} + +int ma_unset_active_state_changed_cb(void) +{ + if (0 != __ma_get_feature_enabled()) { + return MA_ERROR_NOT_SUPPORTED; + } + + SLOG(LOG_DEBUG, TAG_MAC, "[Client DEBUG] Unset Multi-assistant active state changed cb"); + + ma_state_e state; + + if (0 != ma_client_get_client_state(g_ma, &state)) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] A handle is not available"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != MA_STATE_INITIALIZED) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Invalid State: Current state is not 'Initialized'"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + ma_client_set_active_state_changed_cb(g_ma, NULL, NULL); + + return MA_ERROR_NONE; +} + +int ma_start_receiving_audio_streaming_data(ma_audio_streaming_data_type_e type) +{ + if (0 != __ma_get_feature_enabled()) { + return MA_ERROR_NOT_SUPPORTED; + } + + if (0 != __ma_check_privilege()) { + return MA_ERROR_PERMISSION_DENIED; + } + + ma_state_e state; + if (0 != ma_client_get_client_state(g_ma, &state)) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] A handle is not available"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != MA_STATE_READY) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Invalid State: Current state is not 'READY'"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + SLOG(LOG_DEBUG, TAG_MAC, "[Client DEBUG] Send streaming request to the Multi-assistant"); + + int ret = -1; + int pid = getpid(); + ret = ma_dbus_start_streaming_audio_data(pid, type); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Fail to send request"); + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] Success to send request"); + } + + return ret; +} + +int ma_stop_receiving_audio_streaming_data(ma_audio_streaming_data_type_e type) +{ + if (0 != __ma_get_feature_enabled()) { + return MA_ERROR_NOT_SUPPORTED; + } + + if (0 != __ma_check_privilege()) { + return MA_ERROR_PERMISSION_DENIED; + } + + ma_state_e state; + if (0 != ma_client_get_client_state(g_ma, &state)) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] A handle is not available"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != MA_STATE_READY) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Invalid State: Current state is not 'READY'"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + SLOG(LOG_DEBUG, TAG_MAC, "[Client DEBUG] Send error to the Multi-assistant"); + + int ret = -1; + int pid = getpid(); + ret = ma_dbus_stop_streaming_audio_data(pid, type); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Fail to send request"); + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] Success to send request"); + } + + return ret; +} + +int ma_update_voice_feedback_state(ma_voice_feedback_state_e feedback_state) +{ + if (0 != __ma_get_feature_enabled()) { + return MA_ERROR_NOT_SUPPORTED; + } + + if (0 != __ma_check_privilege()) { + return MA_ERROR_PERMISSION_DENIED; + } + + ma_state_e state; + if (0 != ma_client_get_client_state(g_ma, &state)) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] A handle is not available"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != MA_STATE_READY) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Invalid State: Current state is not 'READY'"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + SLOG(LOG_DEBUG, TAG_MAC, "[Client DEBUG] Send error to the Multi-assistant"); + + int ret = -1; + int pid = getpid(); + ret = ma_dbus_update_voice_feedback_state(pid, feedback_state); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Fail to send result"); + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] Success to send result"); + } + + return ret; +} + +int ma_send_assistant_specific_command(const char* command) +{ + if (0 != __ma_get_feature_enabled()) { + return MA_ERROR_NOT_SUPPORTED; + } + + if (0 != __ma_check_privilege()) { + return MA_ERROR_PERMISSION_DENIED; + } + + ma_state_e state; + if (0 != ma_client_get_client_state(g_ma, &state)) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] A handle is not available"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != MA_STATE_READY) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Invalid State: Current state is not 'READY'"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + SLOG(LOG_DEBUG, TAG_MAC, "[Client DEBUG] Send error to the Multi-assistant"); + + int ret = -1; + int pid = getpid(); + ret = ma_dbus_send_assistant_specific_command(pid, command); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Fail to send result"); + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] Success to send result"); + } + + return ret; +} + +int ma_set_wakeup_engine_command_cb(ma_wakeup_engine_command_cb callback, void* user_data) +{ + if (0 != __ma_get_feature_enabled()) { + return MA_ERROR_NOT_SUPPORTED; + } + + SLOG(LOG_DEBUG, TAG_MAC, "[Client DEBUG] Set Multi-assistant wakeup engine command cb"); + + if (NULL == callback) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Invalid parameter"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_PARAMETER; + } + + ma_state_e state; + + if (0 != ma_client_get_client_state(g_ma, &state)) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] A handle is not available"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != MA_STATE_INITIALIZED) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Invalid State: Current state is not 'Initialized' (%d)", state); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + ma_client_set_wakeup_engine_command_cb(g_ma, callback, user_data); + + return MA_ERROR_NONE; +} + +int ma_unset_wakeup_engine_command_cb(void) +{ + if (0 != __ma_get_feature_enabled()) { + return MA_ERROR_NOT_SUPPORTED; + } + + SLOG(LOG_DEBUG, TAG_MAC, "[Client DEBUG] Unset Multi-assistant wakeup engine command cb"); + + ma_state_e state; + + if (0 != ma_client_get_client_state(g_ma, &state)) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] A handle is not available"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + /* check state */ + if (state != MA_STATE_INITIALIZED) { + SLOG(LOG_ERROR, TAG_MAC, "[ERROR] Invalid State: Current state is not 'Initialized'"); //LCOV_EXCL_LINE + return MA_ERROR_INVALID_STATE; + } + + ma_client_set_wakeup_engine_command_cb(g_ma, NULL, NULL); + + return MA_ERROR_NONE; +} \ No newline at end of file diff --git a/client/ma_client.c b/client/ma_client.c index 3bb416f..167889b 100644 --- a/client/ma_client.c +++ b/client/ma_client.c @@ -32,11 +32,19 @@ typedef struct { void* lang_changed_user_data; ma_audio_streaming_cb audio_streaming_cb; void* audio_streaming_user_data; + ma_active_state_changed_cb active_state_changed_cb; + void* active_state_changed_user_data; + ma_wakeup_engine_command_cb wakeup_engine_command_cb; + void* wakeup_engine_command_user_data; /* state */ ma_state_e previous_state; ma_state_e current_state; + /* state */ + ma_active_state_e previous_active_state; + ma_active_state_e current_active_state; + /* mutex */ int cb_ref_count; @@ -107,12 +115,18 @@ int ma_client_create(ma_h* ma) client->lang_changed_user_data = NULL; client->audio_streaming_cb = NULL; client->audio_streaming_user_data = NULL; + client->active_state_changed_cb = NULL; + client->active_state_changed_user_data = NULL; + client->wakeup_engine_command_cb = NULL; + client->wakeup_engine_command_user_data = NULL; client->previous_state = MA_STATE_INITIALIZED; client->current_state = MA_STATE_INITIALIZED; - client->cb_ref_count = 0; + client->previous_active_state = MA_ACTIVE_STATE_INACTIVE; + client->current_active_state = MA_ACTIVE_STATE_INACTIVE; + client->cb_ref_count = 0; g_client_list = g_slist_append(g_client_list, client); @@ -379,4 +393,92 @@ int ma_client_get_error_cb(ma_h ma, ma_error_cb* callback, void** user_data) return MA_ERROR_NONE; } +int ma_client_set_client_active_state(ma_h ma, ma_active_state_e state) +{ + ma_client_s* client = __client_get(ma); + + if (NULL == client) + return MA_ERROR_INVALID_PARAMETER; + + client->previous_active_state = client->current_active_state; + client->current_active_state = state; + + return MA_ERROR_NONE; +} + +int ma_client_get_client_active_state(ma_h ma, ma_active_state_e* state) +{ + ma_client_s* client = __client_get(ma); + + if (NULL == client) + return MA_ERROR_INVALID_PARAMETER; + + *state = client->current_active_state; + + return MA_ERROR_NONE; +} + +int ma_client_get_previous_active_state(ma_h ma, ma_active_state_e* current_state, ma_active_state_e* previous_state) +{ + ma_client_s* client = __client_get(ma); + + if (NULL == client) + return MA_ERROR_INVALID_PARAMETER; + + *current_state = client->current_active_state; + *previous_state = client->previous_active_state; + + return MA_ERROR_NONE; +} + +int ma_client_set_active_state_changed_cb(ma_h ma, ma_active_state_changed_cb callback, void* user_data) +{ + ma_client_s* client = __client_get(ma); + if (NULL == client) + return MA_ERROR_INVALID_PARAMETER; + + client->active_state_changed_cb = callback; + client->active_state_changed_user_data = user_data; + + return MA_ERROR_NONE; +} + +int ma_client_get_active_state_changed_cb(ma_h ma, ma_active_state_changed_cb* callback, void** user_data) +{ + ma_client_s* client = __client_get(ma); + + if (NULL == client) + return MA_ERROR_INVALID_PARAMETER; + + *callback = client->active_state_changed_cb; + *user_data = client->active_state_changed_user_data; + + return MA_ERROR_NONE; +} + +int ma_client_set_wakeup_engine_command_cb(ma_h ma, ma_wakeup_engine_command_cb callback, void* user_data) +{ + ma_client_s* client = __client_get(ma); + + if (NULL == client) + return MA_ERROR_INVALID_PARAMETER; + + client->wakeup_engine_command_cb = callback; + client->wakeup_engine_command_user_data = user_data; + + return MA_ERROR_NONE; +} + +int ma_client_get_wakeup_engine_command_cb(ma_h ma, ma_wakeup_engine_command_cb* callback, void** user_data) +{ + ma_client_s* client = __client_get(ma); + + if (NULL == client) + return MA_ERROR_INVALID_PARAMETER; + + *callback = client->wakeup_engine_command_cb; + *user_data = client->wakeup_engine_command_user_data; + + return MA_ERROR_NONE; +} \ No newline at end of file diff --git a/client/ma_client.h b/client/ma_client.h index 9174443..4cfa1fb 100644 --- a/client/ma_client.h +++ b/client/ma_client.h @@ -70,6 +70,20 @@ int ma_client_set_error_cb(ma_h ma, ma_error_cb callback, void* user_data); int ma_client_get_error_cb(ma_h ma, ma_error_cb* callback, void** user_data); +int ma_client_set_client_active_state(ma_h ma, ma_active_state_e state); + +int ma_client_get_client_active_state(ma_h ma, ma_active_state_e* state); + +int ma_client_get_previous_active_state(ma_h ma, ma_active_state_e* current_state, ma_active_state_e* previous_state); + +int ma_client_set_active_state_changed_cb(ma_h ma, ma_active_state_changed_cb callback, void* user_data); + +int ma_client_get_active_state_changed_cb(ma_h ma, ma_active_state_changed_cb* callback, void** user_data); + +int ma_client_set_wakeup_engine_command_cb(ma_h ma, ma_wakeup_engine_command_cb callback, void* user_data); + +int ma_client_get_wakeup_engine_command_cb(ma_h ma, ma_wakeup_engine_command_cb* callback, void** user_data); + #ifdef __cplusplus } #endif diff --git a/client/ma_dbus.c b/client/ma_dbus.c index 54a2128..f3b46e2 100644 --- a/client/ma_dbus.c +++ b/client/ma_dbus.c @@ -30,6 +30,8 @@ static DBusConnection* g_conn_listener = NULL; extern int __ma_cb_error(int reason, char* msg); extern int __ma_cb_audio_streaming(int event, char* buffer, int len); +extern int __ma_cb_active_state_changed(int state); +extern int __ma_cb_wakeup_engine_command(const char *command); static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler* fd_handler) { @@ -91,11 +93,13 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler* fd_handle } /* MAS_METHOD_HELLO */ - else if (dbus_message_is_method_call(msg, if_name, MAS_METHOD_SEND_SPEECH_DATA)) { + else if (dbus_message_is_method_call(msg, if_name, MAS_METHOD_STREAMING_AUDIO_DATA)) { SLOG(LOG_INFO, TAG_MAC, "@@@ Send speech data"); int event; char* buffer = NULL; int len; + static int count = 0; + static bool start_received = false; dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &event, @@ -103,12 +107,59 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler* fd_handle &buffer, &len, DBUS_TYPE_INVALID); + /* Just in case CONTINUE is received without START */ + SLOG(LOG_INFO, TAG_MAC, "@@@ Send streaming data org event(%d)", event); + if (event == MA_AUDIO_STREAMING_EVENT_CONTINUE && !start_received) + event = MA_AUDIO_STREAMING_EVENT_START; + + if (event == MA_AUDIO_STREAMING_EVENT_START) start_received = true; + /* Reset if FINISHED received */ + if (event == MA_AUDIO_STREAMING_EVENT_FINISH) start_received = false; + + SLOG(LOG_INFO, TAG_MAC, "@@@ Send streaming data event(%d) %d", event, count++); __ma_cb_audio_streaming(event, buffer, len); SLOG(LOG_INFO, TAG_MAC, "@@@"); } /* MAS_METHOD_SEND_SPEECH_DATA */ + else if (dbus_message_is_method_call(msg, if_name, MAS_METHOD_ACTIVE_STATE_CHANGE)) { + SLOG(LOG_INFO, TAG_MAC, "@@@ Activate"); + int state; + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &state, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_MAC, "@@ Get arguments error (%s)", err.message); + dbus_error_free(&err); + } else { + SLOG(LOG_DEBUG, TAG_MAC, "@@ state(%d)", state); + __ma_cb_active_state_changed(state); + } + + SLOG(LOG_INFO, TAG_MAC, "@@@"); + } /* MAS_METHOD_ACTIVE_STATE_CHANGE */ + + else if (dbus_message_is_method_call(msg, if_name, MAS_METHOD_WAKEUP_ENGINE_COMMAND)) { + SLOG(LOG_INFO, TAG_MAC, "@@@ Activate"); + char* command = NULL; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_STRING, &command, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_MAC, "@@ Get arguments error (%s)", err.message); + dbus_error_free(&err); + } else { + SLOG(LOG_DEBUG, TAG_MAC, "@@ command(%s)", (command ? command : "NULL")); + __ma_cb_wakeup_engine_command(command); + } + + SLOG(LOG_INFO, TAG_MAC, "@@@"); + } /* MAS_METHOD_WAKEUP_ENGINE_COMMAND */ + else if (dbus_message_is_signal(msg, if_name, MAS_METHOD_ERROR)) { SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] Get Error"); int reason; @@ -394,7 +445,8 @@ int ma_dbus_request_hello() result = MA_ERROR_TIMED_OUT; } - return result;} + return result; +} int ma_dbus_request_initialize(int pid) { @@ -421,56 +473,21 @@ int ma_dbus_request_initialize(int pid) DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID); - DBusError err; dbus_error_init(&err); - DBusMessage* result_msg = NULL; - int result = MA_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_DEBUG, TAG_MAC, "[ERROR] Dbus Error (%s)", err.message); //LCOV_EXCL_LINE - 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_MAC, "@@ Get arguments error (%s)", err.message); //LCOV_EXCL_LINE - dbus_error_free(&err); - result = MA_ERROR_OPERATION_FAILED; - } - - dbus_message_unref(result_msg); - - if (0 == result) { - /* 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'", MA_SERVER_SERVICE_INTERFACE); - dbus_bus_add_match(g_conn_listener, rule, &err); - - if (dbus_error_is_set(&err)) { - SLOG(LOG_ERROR, TAG_MAC, "Match Error (%s)", err.message); //LCOV_EXCL_LINE - dbus_error_free(&err); - } + dbus_message_set_no_reply(msg, TRUE); - SLOG(LOG_DEBUG, TAG_MAC, "@@ multi-assistant initialize : result = %d", result); //LCOV_EXCL_LINE - } else { - SLOG(LOG_ERROR, TAG_MAC, "@@ multi-assistant initialize : result = %d", result); //LCOV_EXCL_LINE - } + if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) { + SLOG(LOG_ERROR, TAG_MAC, "[Dbus ERROR] Fail to Send"); //LCOV_EXCL_LINE + return MA_ERROR_OPERATION_FAILED; } else { - SLOG(LOG_ERROR, TAG_MAC, "@@ Result message is NULL "); //LCOV_EXCL_LINE - ma_dbus_reconnect(); - result = MA_ERROR_TIMED_OUT; + SLOG(LOG_DEBUG, TAG_MAC, "[Dbus DEBUG] Success to Send"); + dbus_connection_flush(g_conn_sender); } - return result; + dbus_message_unref(msg); + return 0; } int ma_dbus_request_deinitialize(int pid) @@ -759,3 +776,260 @@ int ma_dbus_send_result(int pid, const char* display_text, const char* utterance return 0; } +int ma_dbus_send_recognition_result(int pid, ma_recognition_result_event_e result) +{ + if (0 != __dbus_check()) { + return MA_ERROR_OPERATION_FAILED; + } + + DBusMessage* msg; + + msg = dbus_message_new_method_call( + MA_SERVER_SERVICE_NAME, + MA_SERVER_SERVICE_OBJECT_PATH, + MA_SERVER_SERVICE_INTERFACE, + MA_METHOD_SEND_RECOGNITION_RESULT); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_MAC, "@@ Request multi-assistant send recognition result : Fail to make message"); //LCOV_EXCL_LINE + return MA_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] multi-assistant send recognition result"); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_INVALID); + + dbus_message_set_no_reply(msg, TRUE); + + DBusError error; + dbus_error_init (&error); + if (!dbus_connection_send(g_conn_sender, msg, NULL)) { + if (dbus_error_is_set (&error)) { + SLOG(LOG_ERROR, TAG_MAC, "[Dbus ERROR] Fail to Send : %s", error.message); //LCOV_EXCL_LINE + dbus_error_free (&error); + } else { + SLOG(LOG_ERROR, TAG_MAC, "[Dbus ERROR] Fail to Send"); //LCOV_EXCL_LINE + } + return MA_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[Dbus DEBUG] Success to Send"); + dbus_connection_flush(g_conn_sender); + } + + dbus_message_unref(msg); + + return 0; +} + +int ma_dbus_start_streaming_audio_data(int pid, ma_audio_streaming_data_type_e type) +{ + if (0 != __dbus_check()) { + return MA_ERROR_OPERATION_FAILED; + } + + DBusMessage* msg; + + msg = dbus_message_new_method_call( + MA_SERVER_SERVICE_NAME, + MA_SERVER_SERVICE_OBJECT_PATH, + MA_SERVER_SERVICE_INTERFACE, + MA_METHOD_START_STREAMING_AUDIO_DATA); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_MAC, "@@ multi-assistant send streaming request : Fail to make message"); //LCOV_EXCL_LINE + return MA_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] multi-assistant send streaming request"); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &type, + DBUS_TYPE_INVALID); + + dbus_message_set_no_reply(msg, TRUE); + + DBusError error; + dbus_error_init (&error); + if (!dbus_connection_send(g_conn_sender, msg, NULL)) { + if (dbus_error_is_set (&error)) { + SLOG(LOG_ERROR, TAG_MAC, "[Dbus ERROR] Fail to Send : %s", error.message); //LCOV_EXCL_LINE + dbus_error_free (&error); + } else { + SLOG(LOG_ERROR, TAG_MAC, "[Dbus ERROR] Fail to Send"); //LCOV_EXCL_LINE + } + return MA_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[Dbus DEBUG] Success to Send"); + dbus_connection_flush(g_conn_sender); + } + + dbus_message_unref(msg); + + return 0; +} + +int ma_dbus_stop_streaming_audio_data(int pid, ma_audio_streaming_data_type_e type) +{ + if (0 != __dbus_check()) { + return MA_ERROR_OPERATION_FAILED; + } + + DBusMessage* msg; + + msg = dbus_message_new_method_call( + MA_SERVER_SERVICE_NAME, + MA_SERVER_SERVICE_OBJECT_PATH, + MA_SERVER_SERVICE_INTERFACE, + MA_METHOD_STOP_STREAMING_AUDIO_DATA); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_MAC, "@@ Request multi-assistant send recognition result : Fail to make message"); //LCOV_EXCL_LINE + return MA_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] multi-assistant send recognition result"); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &type, + DBUS_TYPE_INVALID); + + dbus_message_set_no_reply(msg, TRUE); + + DBusError error; + dbus_error_init (&error); + if (!dbus_connection_send(g_conn_sender, msg, NULL)) { + if (dbus_error_is_set (&error)) { + SLOG(LOG_ERROR, TAG_MAC, "[Dbus ERROR] Fail to Send : %s", error.message); //LCOV_EXCL_LINE + dbus_error_free (&error); + } else { + SLOG(LOG_ERROR, TAG_MAC, "[Dbus ERROR] Fail to Send"); //LCOV_EXCL_LINE + } + return MA_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[Dbus DEBUG] Success to Send"); + dbus_connection_flush(g_conn_sender); + } + + dbus_message_unref(msg); + + return 0; +} + +int ma_dbus_update_voice_feedback_state(int pid, ma_voice_feedback_state_e state) +{ + if (0 != __dbus_check()) { + return MA_ERROR_OPERATION_FAILED; + } + + DBusMessage* msg; + + msg = dbus_message_new_method_call( + MA_SERVER_SERVICE_NAME, + MA_SERVER_SERVICE_OBJECT_PATH, + MA_SERVER_SERVICE_INTERFACE, + MA_METHOD_UPDATE_VOICE_FEEDBACK_STATE); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_MAC, "@@ Request multi-assistant send recognition result : Fail to make message"); //LCOV_EXCL_LINE + return MA_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] multi-assistant send recognition result"); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &state, + DBUS_TYPE_INVALID); + + dbus_message_set_no_reply(msg, TRUE); + + DBusError error; + dbus_error_init (&error); + if (!dbus_connection_send(g_conn_sender, msg, NULL)) { + if (dbus_error_is_set (&error)) { + SLOG(LOG_ERROR, TAG_MAC, "[Dbus ERROR] Fail to Send : %s", error.message); //LCOV_EXCL_LINE + dbus_error_free (&error); + } else { + SLOG(LOG_ERROR, TAG_MAC, "[Dbus ERROR] Fail to Send"); //LCOV_EXCL_LINE + } + return MA_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[Dbus DEBUG] Success to Send"); + dbus_connection_flush(g_conn_sender); + } + + dbus_message_unref(msg); + + return 0; +} + +int ma_dbus_send_assistant_specific_command(int pid, const char* command) +{ + if (0 != __dbus_check()) { + return MA_ERROR_OPERATION_FAILED; + } + + DBusMessage* msg; + + msg = dbus_message_new_method_call( + MA_SERVER_SERVICE_NAME, + MA_SERVER_SERVICE_OBJECT_PATH, + MA_SERVER_SERVICE_INTERFACE, + MA_METHOD_SEND_ASSISTANT_SPECIFIC_COMMAND); + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_MAC, "@@ Request multi-assistant send recognition result : Fail to make message"); //LCOV_EXCL_LINE + return MA_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[DEBUG] multi-assistant send recognition result"); + } + + char* tmp_command = NULL; + if (NULL != command) { + tmp_command = strdup(command); + } else { + tmp_command = strdup("#NULL"); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_STRING, &tmp_command, + DBUS_TYPE_INVALID); + + dbus_message_set_no_reply(msg, TRUE); + + DBusError error; + dbus_error_init (&error); + if (!dbus_connection_send(g_conn_sender, msg, NULL)) { + + if (NULL != tmp_command) { + free(tmp_command); + tmp_command = NULL; + } + + if (dbus_error_is_set (&error)) { + SLOG(LOG_ERROR, TAG_MAC, "[Dbus ERROR] Fail to Send : %s", error.message); //LCOV_EXCL_LINE + dbus_error_free (&error); + } else { + SLOG(LOG_ERROR, TAG_MAC, "[Dbus ERROR] Fail to Send"); //LCOV_EXCL_LINE + } + return MA_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_MAC, "[Dbus DEBUG] Success to Send"); + dbus_connection_flush(g_conn_sender); + } + + if (NULL != tmp_command) { + free(tmp_command); + tmp_command = NULL; + } + + dbus_message_unref(msg); + + return 0; +} diff --git a/client/ma_dbus.h b/client/ma_dbus.h index eb6ea04..a9ec690 100644 --- a/client/ma_dbus.h +++ b/client/ma_dbus.h @@ -44,7 +44,15 @@ int ma_dbus_send_asr_result(int pid, ma_asr_result_event_e event, const char* as int ma_dbus_send_result(int pid, const char* display_text, const char* utterance_text, const char* result_json); +int ma_dbus_send_recognition_result(int pid, ma_recognition_result_event_e result); +int ma_dbus_start_streaming_audio_data(int pid, ma_audio_streaming_data_type_e type); + +int ma_dbus_stop_streaming_audio_data(int pid, ma_audio_streaming_data_type_e type); + +int ma_dbus_update_voice_feedback_state(int pid, ma_voice_feedback_state_e state); + +int ma_dbus_send_assistant_specific_command(int pid, const char* command); #ifdef __cplusplus } diff --git a/client/ma_ui.c b/client/ma_ui.c index a3b9806..ff563a4 100644 --- a/client/ma_ui.c +++ b/client/ma_ui.c @@ -624,6 +624,38 @@ static void __ma_ui_notify_error(void* data) } } +static void __ma_ui_notify_send_recognition_result(ma_recognition_result_event_e result) +{ + ma_ui_recognition_result_cb callback = NULL; + void* user_data; + + ma_ui_client_get_recognition_result_cb(g_ma_ui, &callback, &user_data); + + if (NULL != callback) { + ma_ui_client_use_callback(g_ma_ui); + callback(result, user_data); + ma_ui_client_not_use_callback(g_ma_ui); + SLOG(LOG_DEBUG, TAG_MAUI, "[DEBUG] recognition result callback is called"); + } else { + SLOG(LOG_DEBUG, TAG_MAUI, "[WARNING] recognition result callback is NULL"); + } +} + +int __ma_ui_cb_send_recognition_result(ma_recognition_result_event_e result) +{ + ma_state_e state; + if (0 != ma_ui_client_get_client_state(g_ma_ui, &state)) { + SLOG(LOG_ERROR, TAG_MAUI, "[ERROR] Invalid client"); + return MA_ERROR_INVALID_PARAMETER; + } + + SLOG(LOG_DEBUG, TAG_MAUI, "[DEBUG] send recognition result, result(%d)", result); + + __ma_ui_notify_send_recognition_result(result); + + return MA_ERROR_NONE; +} + int ma_ui_get_state(ma_state_e* state) { if (0 != __ma_ui_get_feature_enabled()) { @@ -1055,3 +1087,58 @@ int ma_ui_unset_change_assistant_cb(void) return MA_ERROR_NONE; } +int ma_ui_set_recognition_result_cb(ma_ui_recognition_result_cb callback, void* user_data) +{ + if (0 != __ma_ui_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_MAUI, "@@@ [UI] not supported"); + return MA_ERROR_NOT_SUPPORTED; + } + + if (NULL == callback) { + SLOG(LOG_ERROR, TAG_MAUI, "[UI ERROR] Invalid parameter"); + return MA_ERROR_INVALID_PARAMETER; + } + + ma_state_e state; + if (0 != ma_ui_client_get_client_state(g_ma_ui, &state)) { + SLOG(LOG_ERROR, TAG_MAUI, "[UI ERROR] A handle is not available"); + return MA_ERROR_INVALID_STATE; + } + + /* check state */ + if (MA_STATE_INITIALIZED!= state) { + SLOG(LOG_ERROR, TAG_MAUI, "[UI ERROR] Invalid state: Current state is not 'Initialized' (%d)", state); + return MA_ERROR_INVALID_STATE; + } + + ma_ui_client_set_recognition_result_cb(g_ma_ui, callback, user_data); + + return MA_ERROR_NONE; +} + +int ma_ui_unset_recognition_result_cb(void) +{ + if (0 != __ma_ui_get_feature_enabled()) { + SLOG(LOG_DEBUG, TAG_MAUI, "@@@ [UI] not supported"); + return MA_ERROR_NOT_SUPPORTED; + } + + SLOG(LOG_DEBUG, TAG_MAUI, "[UI] Set a default assistant"); + + ma_state_e state; + if (0 != ma_ui_client_get_client_state(g_ma_ui, &state)) { + SLOG(LOG_ERROR, TAG_MAUI, "[UI ERROR] A handle is not available"); + return MA_ERROR_INVALID_STATE; + } + + /* check state */ + if (MA_STATE_INITIALIZED!= state) { + SLOG(LOG_ERROR, TAG_MAUI, "[UI ERROR] Invalid state: Current state is not 'Initialized' (%d)", state); + return MA_ERROR_INVALID_STATE; + } + + ma_ui_client_set_recognition_result_cb(g_ma_ui, NULL, NULL); + + return MA_ERROR_NONE; +} + diff --git a/client/ma_ui_client.c b/client/ma_ui_client.c index 06839b0..34e9809 100644 --- a/client/ma_ui_client.c +++ b/client/ma_ui_client.c @@ -41,6 +41,9 @@ typedef struct { ma_asr_result_event_e asr_result_event; char* asr_result_text; + ma_ui_recognition_result_cb recognition_result_cb; + void* recognition_result_user_data; + /* state */ ma_state_e previous_state; ma_state_e current_state; @@ -454,3 +457,29 @@ int ma_ui_client_get_lang_changed_cb(ma_h ma, ma_language_changed_cb* callback, return MA_ERROR_NONE; } +int ma_ui_client_set_recognition_result_cb(ma_h ma, ma_ui_recognition_result_cb callback, void* user_data) +{ + ma_ui_client_s* client = __ui_client_get(ma); + + if (NULL == client) + return MA_ERROR_INVALID_PARAMETER; + + client->recognition_result_cb = callback; + client->recognition_result_user_data = user_data; + + return MA_ERROR_NONE; +} + +int ma_ui_client_get_recognition_result_cb(ma_h ma, ma_ui_recognition_result_cb* callback, void** user_data) +{ + ma_ui_client_s* client = __ui_client_get(ma); + + if (NULL == client) + return MA_ERROR_INVALID_PARAMETER; + + *callback = client->recognition_result_cb; + *user_data = client->recognition_result_user_data; + + return MA_ERROR_NONE; +} + diff --git a/client/ma_ui_client.h b/client/ma_ui_client.h index 358b6e5..66a9345 100644 --- a/client/ma_ui_client.h +++ b/client/ma_ui_client.h @@ -75,6 +75,10 @@ int ma_ui_client_set_lang_changed_cb(ma_h ma, ma_language_changed_cb callback, v int ma_ui_client_get_lang_changed_cb(ma_h ma, ma_language_changed_cb* callback, void** user_data); +int ma_ui_client_set_recognition_result_cb(ma_h ma, ma_ui_recognition_result_cb callback, void* user_data); + +int ma_ui_client_get_recognition_result_cb(ma_h ma, ma_ui_recognition_result_cb* callback, void** user_data); + #ifdef __cplusplus } diff --git a/client/ma_ui_dbus.c b/client/ma_ui_dbus.c index ab9967c..a418a69 100644 --- a/client/ma_ui_dbus.c +++ b/client/ma_ui_dbus.c @@ -32,7 +32,7 @@ extern int __ma_ui_cb_error(int reason, char* msg); extern int __ma_ui_cb_send_asr_result(int event, char* asr_result); extern int __ma_ui_cb_send_result(const char* display_text, const char* utterance_text, const char* result_json); extern int __ma_ui_cb_change_assistant(const char* app_id); - +extern int __ma_ui_cb_send_recognition_result(int result); static Eina_Bool ma_ui_listener_event_callback(void* data, Ecore_Fd_Handler* fd_handler) { @@ -200,6 +200,26 @@ static Eina_Bool ma_ui_listener_event_callback(void* data, Ecore_Fd_Handler* fd_ } } /* MAD_MANAGER_METHOD_ERROR */ + if (dbus_message_is_method_call(msg, if_name, MAS_UI_METHOD_SEND_RECOGNITION_RESULT)) { + SLOG(LOG_DEBUG, TAG_MAUI, "[DEBUG] Send recognition result"); + int pid = 0; + int result = 0; + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_MAUI, "[ERROR] Dbus Error (%s)", err.message); + dbus_error_free(&err); + } else { + SLOG(LOG_DEBUG, TAG_MAUI, "[DEBUG] multi-assistant ui Send recognition result : pid(%d), result(%d)", pid, result); + + __ma_ui_cb_send_recognition_result(result); + } + + } /* MAS_UI_METHOD_SEND_RESULT */ else if (dbus_message_is_signal(msg, "org.freedesktop.DBus", "NameOwnerChanged")) { SLOG(LOG_DEBUG, TAG_MAUI, "[DEBUG] Owner Changed"); /* remove a rule for daemon error */ diff --git a/common/ma_defs.h b/common/ma_defs.h index 86ba562..0eadd5b 100644 --- a/common/ma_defs.h +++ b/common/ma_defs.h @@ -63,28 +63,36 @@ extern "C" /************************************************************************************** *** Definitions for DBus methods *************************************************************************************/ -#define MA_METHOD_HELLO "ma_method_hello" - -#define MA_METHOD_INITIALIZE "ma_method_initialize" -#define MA_METHOD_DEINITIALIZE "ma_method_deinitialize" -#define MA_METHOD_REQUEST_SPEECH_DATA "ma_method_request_speech_data" -#define MA_METHOD_GET_RECORDING_AUDIO_FORMAT "ma_method_get_recording_audio_format" -#define MA_METHOD_SEND_ASR_RESULT "ma_method_send_asr_result" -#define MA_METHOD_SEND_RESULT "ma_method_send_result" - -#define MA_UI_METHOD_INITIALIZE "ma_ui_method_initialize" -#define MA_UI_METHOD_DEINITIALIZE "ma_ui_method_deinitialize" -#define MA_UI_METHOD_CHANGE_ASSISTANT "ma_ui_method_change_assistant" - -#define MAS_METHOD_HELLO "mas_method_hello" -#define MAS_METHOD_SEND_SPEECH_DATA "mas_method_send_speech_data" -#define MAS_METHOD_ERROR "mas_method_error" - -#define MAS_UI_METHOD_HELLO "mas_ui_method_hello" -#define MAS_UI_METHOD_SEND_ASR_RESULT "mas_ui_method_send_asr_result" -#define MAS_UI_METHOD_SEND_RESULT "mas_ui_method_send_result" -#define MAS_UI_METHOD_CHANGE_ASSISTANT "mas_ui_method_change_assistant" -#define MAS_UI_METHOD_ERROR "mas_ui_method_error" +#define MA_METHOD_HELLO "ma_method_hello" + +#define MA_METHOD_INITIALIZE "ma_method_initialize" +#define MA_METHOD_DEINITIALIZE "ma_method_deinitialize" +#define MA_METHOD_GET_RECORDING_AUDIO_FORMAT "ma_method_get_recording_audio_format" +#define MA_METHOD_SEND_ASR_RESULT "ma_method_send_asr_result" +#define MA_METHOD_SEND_RESULT "ma_method_send_result" +#define MA_METHOD_SEND_RECOGNITION_RESULT "ma_method_send_recognition_result" +#define MA_METHOD_START_STREAMING_AUDIO_DATA "ma_method_start_streaming_audio_data" +#define MA_METHOD_STOP_STREAMING_AUDIO_DATA "ma_method_stop_streaming_audio_data" +#define MA_METHOD_UPDATE_VOICE_FEEDBACK_STATE "ma_method_update_voice_feedback_state" +#define MA_METHOD_SEND_ASSISTANT_SPECIFIC_COMMAND "ma_method_send_assistant_specific_command" +#define MA_METHOD_ERROR "ma_method_error" + +#define MA_UI_METHOD_INITIALIZE "ma_ui_method_initialize" +#define MA_UI_METHOD_DEINITIALIZE "ma_ui_method_deinitialize" +#define MA_UI_METHOD_CHANGE_ASSISTANT "ma_ui_method_change_assistant" + +#define MAS_METHOD_HELLO "mas_method_hello" +#define MAS_METHOD_ACTIVE_STATE_CHANGE "mas_method_active_state_change" +#define MAS_METHOD_STREAMING_AUDIO_DATA "mas_method_streaming_audio_data" +#define MAS_METHOD_WAKEUP_ENGINE_COMMAND "mas_method_wakeup_engine_command" +#define MAS_METHOD_ERROR "mas_method_error" + +#define MAS_UI_METHOD_HELLO "mas_ui_method_hello" +#define MAS_UI_METHOD_SEND_ASR_RESULT "mas_ui_method_send_asr_result" +#define MAS_UI_METHOD_SEND_RESULT "mas_ui_method_send_result" +#define MAS_UI_METHOD_CHANGE_ASSISTANT "mas_ui_method_change_assistant" +#define MAS_UI_METHOD_SEND_RECOGNITION_RESULT "mas_ui_method_send_recognition_result" +#define MAS_UI_METHOD_ERROR "mas_ui_method_error" /************************************************************************************** *** Definitions for xml file diff --git a/include/multi_assistant.h b/include/multi_assistant.h index 357d4f8..5d8d75b 100644 --- a/include/multi_assistant.h +++ b/include/multi_assistant.h @@ -334,6 +334,139 @@ int ma_send_asr_result(ma_asr_result_event_e event, const char* asr_result); */ int ma_send_result(const char* display_text, const char* utterance_text, const char* result_json); +/** + * @brief Sends recognition result to the multi-assistant service. + * @since_tizen 5.5 + * @privlevel public + * + * @param[in] result The recognition result + * + * @return @c 0 on success, otherwise a negative error value + * @retval #MA_ERROR_NONE Successful + * @retval #MA_ERROR_NOT_SUPPORTED Not supported + * @retval #MA_ERROR_PERMISSION_DENIED Permission denied + * @retval #MA_ERROR_INVALID_PARAMETER Invalid parameter + */ +int ma_send_recognition_result(ma_recognition_result_event_e result); + +/** + * @brief Sets a active state changed callback. + * @since_tizen 5.5 + * + * @param[in] callback The callback + * @param[in] user_data The user data passed to the callback function + * + * @return @c 0 on success, otherwise a negative error value + * @retval #MA_ERROR_NONE Successful + * @retval #MA_ERROR_NOT_SUPPORTED Not supported + * @retval #MA_ERROR_INVALID_STATE Invalid state + * @retval #MA_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The state should be #MA_STATE_INITIALIZED. + * @see ma_active_state_changed_cb() + * @see ma_unset_active_state_changed_cb() + */ +int ma_set_active_state_changed_cb(ma_active_state_changed_cb callback, void* user_data); + +/** + * @brief Unsets a active state changed callback. + * @since_tizen 5.5 + * + * @return @c 0 on success, otherwise a negative error value + * @retval #MA_ERROR_NONE Successful + * @retval #MA_ERROR_NOT_SUPPORTED Not supported + * @retval #MA_ERROR_INVALID_STATE Invalid state + * + * @pre The state should be #MA_STATE_INITIALIZED. + * @see ma_active_state_changed_cb() + * @see ma_set_active_state_changed_cb() + */ +int ma_unset_active_state_changed_cb(void); + +/** + * @brief Start receiving audio streaming data. + * @since_tizen 5.5 + * @privlevel public + * + * @return @c 0 on success, otherwise a negative error value + * @retval #MA_ERROR_NONE Successful + * @retval #MA_ERROR_NOT_SUPPORTED Not supported + * @retval #MA_ERROR_PERMISSION_DENIED Permission denied + */ +int ma_start_receiving_audio_streaming_data(ma_audio_streaming_data_type_e type); + +/** + * @brief Stop receiving audio streaming data. + * @since_tizen 5.5 + * @privlevel public + * + * @return @c 0 on success, otherwise a negative error value + * @retval #MA_ERROR_NONE Successful + * @retval #MA_ERROR_NOT_SUPPORTED Not supported + * @retval #MA_ERROR_PERMISSION_DENIED Permission denied + */ +int ma_stop_receiving_audio_streaming_data(ma_audio_streaming_data_type_e type); + +/** + * @brief Update the client's voice feedback state to the server. + * @since_tizen 5.5 + * @privlevel public + * + * @return @c 0 on success, otherwise a negative error value + * @retval #MA_ERROR_NONE Successful + * @retval #MA_ERROR_NOT_SUPPORTED Not supported + * @retval #MA_ERROR_PERMISSION_DENIED Permission denied + */ +int ma_update_voice_feedback_state(ma_voice_feedback_state_e state); + +/** + * @brief Send assistant-specific command to the server. + * @since_tizen 5.5 + * @privlevel public + * + * @param[in] command The command to be sent to the server + * + * @return @c 0 on success, otherwise a negative error value + * @retval #MA_ERROR_NONE Successful + * @retval #MA_ERROR_NOT_SUPPORTED Not supported + * @retval #MA_ERROR_PERMISSION_DENIED Permission denied + */ +int ma_send_assistant_specific_command(const char* command); + +/** + * @brief Sets a wakeup engine command callback. + * @since_tizen 5.5 + * + * @param[in] callback The callback + * @param[in] user_data The user data passed to the callback function + * + * @return @c 0 on success, otherwise a negative error value + * @retval #MA_ERROR_NONE Successful + * @retval #MA_ERROR_NOT_SUPPORTED Not supported + * @retval #MA_ERROR_INVALID_STATE Invalid state + * @retval #MA_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The state should be #MA_STATE_INITIALIZED. + * @see ma_wakeup_engine_command_cb() + * @see ma_unset_wakeup_engine_command_cb() + */ +int ma_set_wakeup_engine_command_cb(ma_wakeup_engine_command_cb callback, void* user_data); + +/** + * @brief Unsets a active state changed callback. + * @since_tizen 5.5 + * + * @return @c 0 on success, otherwise a negative error value + * @retval #MA_ERROR_NONE Successful + * @retval #MA_ERROR_NOT_SUPPORTED Not supported + * @retval #MA_ERROR_INVALID_STATE Invalid state + * + * @pre The state should be #MA_STATE_INITIALIZED. + * @see ma_wakeup_engine_command_cb() + * @see ma_set_wakeup_engine_command_cb() + */ +int ma_unset_wakeup_engine_command_cb(void); + #ifdef __cplusplus } #endif diff --git a/include/multi_assistant_common.h b/include/multi_assistant_common.h index 13115cc..72db430 100644 --- a/include/multi_assistant_common.h +++ b/include/multi_assistant_common.h @@ -61,7 +61,7 @@ typedef enum { typedef enum { MA_STATE_NONE = 0, /**< 'None' state */ MA_STATE_INITIALIZED = 1, /**< 'Initialized' state */ - MA_STATE_READY = 2 /**< 'Ready' state */ + MA_STATE_READY = 2, /**< 'Ready' state */ } ma_state_e; /** @@ -103,6 +103,43 @@ typedef enum { MA_ASR_RESULT_EVENT_ERROR /**< ASR result event for error */ } ma_asr_result_event_e; +/** + * @brief Enumerations for recognition result events. + * @since_tizen 5.5 + */ +typedef enum { + MA_RECOGNITION_RESULT_EVENT_SUCCESS = 0, /**< Recognition succeeded */ + MA_RECOGNITION_RESULT_EVENT_EMPTY_TEXT, /**< No text result recognized */ + MA_RECOGNITION_RESULT_EVENT_ERROR /**< Unknown error occurred */ +} ma_recognition_result_event_e; + +/** + * @brief Enumerations for speech data types. + * @since_tizen 5.5 + */ +typedef enum { + MA_AUDIO_STREAMING_DATA_TYPE_CURRENT_UTTERANCE = 0, /**< Current utterance */ + MA_AUDIO_STREAMING_DATA_TYPE_PREVIOUS_UTTERANCE, /**< Previous utterance */ + MA_AUDIO_STREAMING_DATA_TYPE_FOLLOW_UP_SPEECH /**< Follow-up speech */ +} ma_audio_streaming_data_type_e; + +/** + * @brief Enumerations for individual assistant's voice feedback state. + * @since_tizen 5.5 + */ +typedef enum { + MA_VOICE_FEEDBACK_STATE_NONE = 0, /**< No voice feedback being provided */ + MA_VOICE_FEEDBACK_STATE_STARTED, /**< Voice feedback being provided */ +} ma_voice_feedback_state_e; + +/** + * @brief Enumerations for multi-assistant active state. + * @since_tizen 5.5 + */ +typedef enum { + MA_ACTIVE_STATE_INACTIVE = 0, /**< 'Inactive' state */ + MA_ACTIVE_STATE_ACTIVE = 1, /**< 'Active' state */ +} ma_active_state_e; /** * @brief Called when the client state is changed. @@ -168,6 +205,24 @@ typedef void (*ma_language_changed_cb)(const char* previous, const char* current */ typedef void (*ma_audio_streaming_cb)(ma_audio_streaming_event_e event, char* buffer, int len, void* user_data); +/** + * @brief Called when the active state is changed. + * @since_tizen 5.5 + * + * @param[in] previous The previous active state + * @param[in] current The current active state + * @param[in] user_data The user data passed from the callback registration function + */ +typedef void (*ma_active_state_changed_cb)(ma_active_state_e previous, ma_active_state_e current, void* user_data); + +/** + * @brief Called when a wakeup engine specific command is retrieved. + * @since_tizen 5.5 + * + * @param[in] command The wakeup engine specific command + * @param[in] user_data The user data passed from the callback registration function + */ +typedef void (*ma_wakeup_engine_command_cb)(const char *command, void* user_data); #ifdef __cplusplus } diff --git a/include/multi_assistant_ui.h b/include/multi_assistant_ui.h index 377739a..a5f31e3 100644 --- a/include/multi_assistant_ui.h +++ b/include/multi_assistant_ui.h @@ -103,6 +103,18 @@ typedef void (*ma_ui_result_cb)(const char* display_text, const char* utterance_ */ typedef void (*ma_ui_change_assistant_cb)(const char* app_id, void* user_data); +/** + * @brief Called when the multi-assistant service sends the recognition results for showing at UI. + * @since_tizen 5.5 + * + * @param[in] result The recognition result + * @param[in] user_data The user data passed from the callback registration function + * + * @see ma_ui_set_recognition_result_cb() + * @see ma_ui_unset_recognition_result_cb() + */ +typedef void (*ma_ui_recognition_result_cb)(ma_recognition_result_event_e result, void* user_data); + /** * @brief Initializes multi-assistant UI. * @since_tizen 5.0 @@ -404,6 +416,35 @@ int ma_ui_set_change_assistant_cb(ma_ui_change_assistant_cb callback, void* user */ int ma_ui_unset_change_assistant_cb(void); +/** + * @brief Sets a callback for getting recognition results. + * @since_tizen 5.5 + * + * @param[in] callback The callback function + * @param[in] user_data The user data passed to the callback function + * + * @return @c 0 on success, otherwise a negative error value + * @retval #MA_ERROR_NONE Successful + * @retval #MA_ERROR_NOT_SUPPORTED Not supported + * @retval #MA_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MA_ERROR_INVALID_STATE Invalid state + * + * @pre The state should be #MA_STATE_INITIALIZED. + */ +int ma_ui_set_recognition_result_cb(ma_ui_recognition_result_cb callback, void* user_data); + +/** + * @brief Unsets a callback for getting recognition results. + * @since_tizen 5.5 + * + * @return @c 0 on success, otherwise a negative error value + * @retval #MA_ERROR_NONE Successful + * @retval #MA_ERROR_NOT_SUPPORTED Not supported + * @retval #MA_ERROR_INVALID_STATE Invalid state + * + * @pre The state should be #MA_STATE_INITIALIZED. + */ +int ma_ui_unset_recognition_result_cb(void); #ifdef __cplusplus } #endif diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt deleted file mode 100644 index 9b7e362..0000000 --- a/server/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -SET(SRCS -# mad_server.c -# mae.c -) - -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) -INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/common) -INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/include) - -FOREACH(flag ${pkgs_CFLAGS}) - SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") -ENDFOREACH(flag) - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE") -SET(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE") -SET(CMAKE_C_FLAGS_DEBUG "-O0 -g -fPIE") -SET(CMAKE_C_FLAGS_RELEASE "-O2 -fPIE") -SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie") - -## Executable ## -ADD_LIBRARY("${PROJECT_NAME}_engine" SHARED ${SRCS}) -TARGET_LINK_LIBRARIES("${PROJECT_NAME}_engine" -ldl ${pkgs_LDFLAGS}) - -## Install -INSTALL(TARGETS "${PROJECT_NAME}_engine" DESTINATION ${LIBDIR} COMPONENT RuntimeLibraries) -- 2.34.1