From 14eb3b4d4d85cb8d9b7502eeddd38ff9323fcdb5 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Mon, 1 Oct 2018 19:23:52 +0900 Subject: [PATCH 01/16] Add apis to change system volume Change-Id: Ic04618b85abd6e5c3a162bd3d204dd91bc4aeac9 Signed-off-by: Wonnam Jang --- client/vc_mgr.c | 75 ++++++++++++++++++++++++++++ client/vc_mgr_dbus.c | 84 ++++++++++++++++++++++++++++++++ client/vc_mgr_dbus.h | 2 + common/vc_defs.h | 1 + include/voice_control_manager_internal.h | 5 ++ server/vcd_dbus.c | 3 ++ server/vcd_dbus_server.c | 53 ++++++++++++++++++++ server/vcd_dbus_server.h | 2 + server/vcd_main.h | 5 ++ server/vcd_recorder.c | 56 +++++++++++++++++++++ server/vcd_recorder.h | 4 ++ server/vcd_server.c | 22 +++++++++ server/vcd_server.h | 2 + 13 files changed, 314 insertions(+) diff --git a/client/vc_mgr.c b/client/vc_mgr.c index d97a038..553ef4c 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -4369,3 +4369,78 @@ int vc_mgr_set_audio_streaming_mode(vc_audio_streaming_mode_e streaming_mode) return ret; } + +int vc_mgr_change_system_volume() +{ + SLOG(LOG_DEBUG, TAG_VCM, "[Manager] Change system 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; + } + + 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 is not 'READY', state(%d)", state); + SLOG(LOG_DEBUG, TAG_VCM, "@@@"); + return VC_ERROR_INVALID_STATE; + } + + /* send audio streaming */ + int ret = vc_mgr_dbus_change_system_volume(g_vc_m->handle, VC_SYSTEM_VOLUME_EVENT_CHANGE); + if (0 != ret) { + SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry to change volume"); + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[DEBUG] Success to send"); + } + return ret; +} + +int vc_mgr_recover_system_volume() +{ + SLOG(LOG_DEBUG, TAG_VCM, "[Manager] recover system 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; + } + + 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 is not 'READY', state(%d)", state); + SLOG(LOG_DEBUG, TAG_VCM, "@@@"); + return VC_ERROR_INVALID_STATE; + } + + /* send audio streaming */ + int ret = vc_mgr_dbus_change_system_volume(g_vc_m->handle, VC_SYSTEM_VOLUME_EVENT_RECOVER); + if (0 != ret) { + SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry to recover volume"); + } else { + SLOG(LOG_DEBUG, TAG_VCM, "[DEBUG] Success to send"); + } + return ret; + +} diff --git a/client/vc_mgr_dbus.c b/client/vc_mgr_dbus.c index 7545a7f..7b7c432 100644 --- a/client/vc_mgr_dbus.c +++ b/client/vc_mgr_dbus.c @@ -2468,3 +2468,87 @@ int vc_mgr_dbus_send_audio_streaming(int pid, vc_audio_streaming_event_e event, return 0; } +int vc_mgr_dbus_change_system_volume(int pid, vc_system_volume_event_e volume_event) +{ + if (0 != __dbus_check()) { + return VC_ERROR_OPERATION_FAILED; + } + + DBusError err; + dbus_error_init(&err); + + bool exist = dbus_bus_name_has_owner(g_m_conn_sender, VC_SERVER_SERVICE_NAME, &err); + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message); + dbus_error_free(&err); + } + + int ret; + int temp_event = (int)volume_event; + if (false == exist) { + ret = __dbus_restore_daemon(); + if (VC_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to restore daemon"); + return VC_ERROR_TIMED_OUT; + } + return VC_ERROR_OPERATION_FAILED; + } + + 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_CHANGE_SYSTEM_VOLUME); /* name of the signal */ + + if (NULL == msg) { + SLOG(LOG_ERROR, TAG_VCM, "@@ vc change system volume : Fail to make message "); + return VC_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCM, "@@ vc change system volume : pid(%d) volume_event(%d)", pid, temp_event); + } + + dbus_message_append_args(msg, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &temp_event, + DBUS_TYPE_INVALID); + + DBusMessage* result_msg; + int result = VC_ERROR_OPERATION_FAILED; + + result_msg = dbus_connection_send_with_reply_and_block(g_m_conn_sender, msg, g_m_waiting_time, &err); + dbus_message_unref(msg); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message); + dbus_error_free(&err); + } + + if (NULL != result_msg) { + dbus_message_get_args(result_msg, &err, + DBUS_TYPE_INT32, &result, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCM, "@@ Get arguments error (%s)", err.message); + dbus_error_free(&err); + result = VC_ERROR_OPERATION_FAILED; + } + dbus_message_unref(result_msg); + + if (0 == result) { + SLOG(LOG_DEBUG, TAG_VCM, "@@ vc change system volume : result = %d", result); + } else { + SLOG(LOG_ERROR, TAG_VCM, "@@ vc change system volume : result = %d", result); + } + } else { + SLOG(LOG_DEBUG, TAG_VCM, "@@ Result Message is NULL"); + vc_mgr_dbus_reconnect(); + result = VC_ERROR_TIMED_OUT; + } + + return result; +} + diff --git a/client/vc_mgr_dbus.h b/client/vc_mgr_dbus.h index 9ce1239..a6202ea 100644 --- a/client/vc_mgr_dbus.h +++ b/client/vc_mgr_dbus.h @@ -80,6 +80,8 @@ int vc_mgr_dbus_send_utterance_status(int pid, int utt_id, int utt_status); int vc_mgr_dbus_send_audio_streaming(int pid, vc_audio_streaming_event_e event, unsigned char* buffer, unsigned int len); +int vc_mgr_dbus_change_system_volume(int pid, vc_system_volume_event_e volume_event); + #ifdef __cplusplus } #endif diff --git a/common/vc_defs.h b/common/vc_defs.h index 55fc210..79b6d7a 100644 --- a/common/vc_defs.h +++ b/common/vc_defs.h @@ -152,6 +152,7 @@ extern "C" { #define VC_MANAGER_METHOD_UTTERANCE_STATUS "vc_manager_method_utterance_status" #define VC_MANAGER_METHOD_SEND_AUDIO_STREAMING "vc_manager_method_send_audio_streaming" +#define VC_MANAGER_METHOD_CHANGE_SYSTEM_VOLUME "vc_manager_method_change_system_volume" #define VCD_MANAGER_METHOD_HELLO "vcd_manager_method_hello" #define VCD_MANAGER_METHOD_SPEECH_DETECTED "vcd_manager_method_speech_detected" diff --git a/include/voice_control_manager_internal.h b/include/voice_control_manager_internal.h index 91778b2..4e3953c 100644 --- a/include/voice_control_manager_internal.h +++ b/include/voice_control_manager_internal.h @@ -40,6 +40,11 @@ typedef enum { VC_AUDIO_STREAMING_MODE_OUTSIDE = 2, /**< Use audio streaming from outside */ } vc_audio_streaming_mode_e; +typedef enum { + VC_SYSTEM_VOLUME_EVENT_CHANGE, + VC_SYSTEM_VOLUME_EVENT_RECOVER +} vc_system_volume_event_e; + #define VC_SERVICE_STATE_UPDATING 4 /**< 'Updating' state */ /** diff --git a/server/vcd_dbus.c b/server/vcd_dbus.c index 1718191..4c9fde0 100644 --- a/server/vcd_dbus.c +++ b/server/vcd_dbus.c @@ -1153,6 +1153,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_MANAGER_METHOD_SEND_AUDIO_STREAMING)) vcd_dbus_server_mgr_send_audio_streaming(g_conn_listener, msg); + else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_CHANGE_SYSTEM_VOLUME)) + vcd_dbus_server_mgr_change_system_volume(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); diff --git a/server/vcd_dbus_server.c b/server/vcd_dbus_server.c index 9740609..2739c5b 100644 --- a/server/vcd_dbus_server.c +++ b/server/vcd_dbus_server.c @@ -1224,6 +1224,59 @@ int vcd_dbus_server_mgr_send_audio_streaming(DBusConnection* conn, DBusMessage* return ret; } +int vcd_dbus_server_mgr_change_system_volume(DBusConnection* conn, DBusMessage* msg) +{ + DBusError err; + dbus_error_init(&err); + + int pid = 0; + int volume_event = 0; + + int ret = VCD_ERROR_OPERATION_FAILED; + + SLOG(LOG_DEBUG, TAG_VCD, "@@@ VCD Manager change system volume"); + + dbus_message_get_args(msg, &err, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INT32, &volume_event, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&err)) { + SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr disable command type : get arguments error (%s)", err.message); + dbus_error_free(&err); + ret = VCD_ERROR_OPERATION_FAILED; + } else { + SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr change system volume: pid(%d), volume_event(%d)", pid, volume_event); + ret = vcd_server_mgr_change_system_volume(pid, volume_event); + } + + DBusMessage* reply; + reply = dbus_message_new_method_return(msg); + + if (NULL != reply) { + dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID); + + if (0 == ret) { + SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret); + } + + if (!dbus_connection_send(conn, reply, NULL)) { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!"); + } + + dbus_connection_flush(conn); + dbus_message_unref(reply); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!"); + } + + SLOG(LOG_DEBUG, TAG_VCD, "@@@"); + + return 0; + +} /* * Dbus Server functions for client diff --git a/server/vcd_dbus_server.h b/server/vcd_dbus_server.h index ac02296..6182697 100644 --- a/server/vcd_dbus_server.h +++ b/server/vcd_dbus_server.h @@ -69,6 +69,8 @@ int vcd_dbus_server_mgr_disable_command_type(DBusConnection* conn, DBusMessage* int vcd_dbus_server_mgr_send_specific_engine_request(DBusConnection* conn, DBusMessage* msg); +int vcd_dbus_server_mgr_change_system_volume(DBusConnection* conn, DBusMessage* msg); + /* for TTS feedback */ int vcd_dbus_server_mgr_start_feedback(DBusConnection* conn, DBusMessage* msg); diff --git a/server/vcd_main.h b/server/vcd_main.h index 782f501..04ecdbf 100644 --- a/server/vcd_main.h +++ b/server/vcd_main.h @@ -88,6 +88,11 @@ typedef enum { VCD_AUDIO_STREAMING_MODE_OUTSIDE = 2, /**< Use audio streaming from outside */ } vcd_audio_streaming_mode_e; +typedef enum { + VCD_SYSTEM_VOLUME_EVENT_CHANGE, + VCD_SYSTEM_VOLUME_EVENT_RECOVER +} vcd_system_volume_event_e; + struct vce_cmd_s { int index; }; diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index 6ffb708..a024942 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -74,6 +74,9 @@ static int g_buffer_count; static int g_device_id = -1; +static sound_stream_info_h g_stream_for_volume_h = NULL; +static virtual_sound_stream_h g_virtual_sound_stream_h = NULL; + /* Sound buf save */ #if 0 #define BUF_SAVE_MODE @@ -897,6 +900,59 @@ int vcd_recorder_stop_streaming() return 0; } +int vcd_recorder_change_system_volume() +{ + if (!g_stream_for_volume_h) { + int ret = sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE, NULL, NULL, &g_stream_for_volume_h); + if (0 != ret) { + SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Fail to create stream information, ret(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + if (!g_virtual_sound_stream_h) { + ret = sound_manager_create_virtual_stream(g_stream_for_volume_h, &g_virtual_sound_stream_h); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create virtual stream, ret(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + ret = sound_manager_start_virtual_stream(g_virtual_sound_stream_h); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start virtual stream, ret(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + } + } + + return 0; +} + +int vcd_recorder_recover_system_volume() +{ + if (g_virtual_sound_stream_h) { + int ret = sound_manager_stop_virtual_stream(g_virtual_sound_stream_h); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop virtual stream, ret(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + ret = sound_manager_destroy_virtual_stream(g_virtual_sound_stream_h); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to destroy virtual stream, ret(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + g_virtual_sound_stream_h = NULL; + + if (g_stream_for_volume_h) { + ret = sound_manager_destroy_stream_information(g_stream_for_volume_h); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to destroy stream information, ret(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + g_stream_for_volume_h = NULL; + } + } + + return 0; +} + int vcd_recorder_start() { int ret = -1; diff --git a/server/vcd_recorder.h b/server/vcd_recorder.h index 7a612b8..9ac8b1e 100644 --- a/server/vcd_recorder.h +++ b/server/vcd_recorder.h @@ -49,6 +49,10 @@ int vcd_recorder_send_streaming(const void* buffer, const unsigned int length); int vcd_recorder_stop_streaming(); +int vcd_recorder_change_system_volume(); + +int vcd_recorder_recover_system_volume(); + int vcd_recorder_start(); int vcd_recorder_read(); diff --git a/server/vcd_server.c b/server/vcd_server.c index 3839763..4f369e0 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -2257,6 +2257,28 @@ int vcd_server_mgr_send_audio_streaming(int pid, int event, unsigned char* buffe return VCD_ERROR_NONE; } +int vcd_server_mgr_change_system_volume(int pid, vcd_system_volume_event_e system_volume_event) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] change system volume, system volume event(%d)", system_volume_event); + + int ret = 0; + if (VCD_SYSTEM_VOLUME_EVENT_CHANGE == system_volume_event) { + ret = vcd_recorder_change_system_volume(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to change system volume, ret(%d)", ret); + return ret; + } + } else if (VCD_SYSTEM_VOLUME_EVENT_RECOVER == system_volume_event) { + ret = vcd_recorder_recover_system_volume(); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to recover system volume, ret(%d)", ret); + return ret; + } + } + + return ret; +} + /* * VC Server Functions for Client diff --git a/server/vcd_server.h b/server/vcd_server.h index 739e6ec..7979e4a 100644 --- a/server/vcd_server.h +++ b/server/vcd_server.h @@ -81,6 +81,8 @@ int vcd_server_mgr_enable_command_type(int pid, int cmd_type); int vcd_server_mgr_disable_command_type(int pid, int cmd_type); +int vcd_server_mgr_change_system_volume(int pid, vcd_system_volume_event_e system_volume_event); + /* for TTS feedback */ int vcd_server_mgr_start_feedback(void); -- 2.7.4 From ce46d2756a744b8b2320d84c0d6764651f84b1dc Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Mon, 1 Oct 2018 20:55:45 +0900 Subject: [PATCH 02/16] Add system volume api on internal header Change-Id: I5ade6a51bf9c30ebc75d06ccdb9c3ed528df5087 Signed-off-by: Wonnam Jang --- include/voice_control_manager_internal.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/voice_control_manager_internal.h b/include/voice_control_manager_internal.h index 4e3953c..9d22ede 100644 --- a/include/voice_control_manager_internal.h +++ b/include/voice_control_manager_internal.h @@ -108,6 +108,20 @@ int vc_mgr_send_audio_streaming(vc_audio_streaming_event_e event, unsigned char* int vc_mgr_set_audio_streaming_mode(vc_audio_streaming_mode_e streaming_mode); +/** + * @brief Changes system volume. + * @since_tizen 5.0 + * + */ +int vc_mgr_change_system_volume(); + +/** + * @brief Recover system volume. + * @since_tizen 5.0 + * + */ +int vc_mgr_recover_system_volume(); + #ifdef __cplusplus } #endif -- 2.7.4 From b6e06afc544143e6b05f3fb0cc59a9386784a430 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Mon, 8 Oct 2018 17:51:01 +0900 Subject: [PATCH 03/16] Sync with tizen 4.0 branch Change-Id: I22ddb9911deeafa4b12dc3d89fea3b0059fec383 Signed-off-by: Wonnam Jang --- client/vc_mgr.c | 4 +- client/vc_mgr_data.cpp | 18 +++--- include/voice_control_internal.h | 56 +++++++++---------- include/voice_control_manager.h | 118 ++++++++++++++++++++------------------- server/vcd_main.h | 3 +- server/vcd_server.c | 72 ++++++++++++++++-------- 6 files changed, 152 insertions(+), 119 deletions(-) diff --git a/client/vc_mgr.c b/client/vc_mgr.c index 553ef4c..39e46e9 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -3443,7 +3443,7 @@ int __vc_mgr_cb_feedback_streaming(int pid, int utt_id, vc_feedback_event_e even } } - return ret; + return ret; } @@ -4079,6 +4079,7 @@ static void __tts_feedback_thread(void* data, Ecore_Thread* thread) } if (200 < cnt) { SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Wrong request, there's no pcm data"); + vc_mgr_data_clear_feedback_data(&feedback_data); return; } cnt++; @@ -4086,6 +4087,7 @@ static void __tts_feedback_thread(void* data, Ecore_Thread* thread) SLOG(LOG_INFO, TAG_VCM, "[INFO] Finish to wait for new feedback data come"); /* resume feedback thread */ + vc_mgr_data_clear_feedback_data(&feedback_data); continue; } diff --git a/client/vc_mgr_data.cpp b/client/vc_mgr_data.cpp index 866d3da..26482c1 100644 --- a/client/vc_mgr_data.cpp +++ b/client/vc_mgr_data.cpp @@ -96,20 +96,22 @@ int vc_mgr_data_get_feedback_data_size() int vc_mgr_data_clear_feedback_data(vc_feedback_data_s** data) { - SLOG(LOG_DEBUG, TAG_VCM, "[DATA] clear feedback data"); + SLOG(LOG_DEBUG, TAG_VCM, "[DATA] clear feedback data, empty(%d)", g_feedback_data.empty()); pthread_mutex_lock(&g_feedback_data_mutex); if (!g_feedback_data.empty()) { - SLOG(LOG_DEBUG, TAG_VCM, "[DEBUG] pid(%d), utt_id(%d), data(%p) size(%d) rate(%d)", (*data)->pid, (*data)->utt_id, (*data)->data, (*data)->data_size, (*data)->rate); + if (NULL != *data) { + SLOG(LOG_DEBUG, TAG_VCM, "[DEBUG] pid(%d), utt_id(%d), data(%p) size(%d) rate(%d)", (*data)->pid, (*data)->utt_id, (*data)->data, (*data)->data_size, (*data)->rate); - if (NULL != (*data)->data) { - free((*data)->data); - (*data)->data = NULL; - } + if (NULL != (*data)->data) { + free((*data)->data); + (*data)->data = NULL; + } - free(*data); - *data = NULL; + free(*data); + *data = NULL; + } } pthread_mutex_unlock(&g_feedback_data_mutex); diff --git a/include/voice_control_internal.h b/include/voice_control_internal.h index 8bc1961..cfbb9ea 100644 --- a/include/voice_control_internal.h +++ b/include/voice_control_internal.h @@ -1,18 +1,18 @@ -/* - * Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +/** + * 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_INTERNAL_H__ @@ -42,19 +42,19 @@ typedef enum { /** -* @brief Called when client gets the asr recognition result from vc-daemon. -* -* @param[in] event The result event -* @param[in] result ASR text -* @param[in] user_data The user data passed from the callback registration function -* -* @return @c true when asr result is consumed \n @c false to propagate. -* -* @pre An application registers callback function using vc_mgr_set_pre_result_cb(). -* -* @see vc_widget_set_asr_result_cb() -* @see vc_widget_unset_asr_result_cb() -*/ + * @brief Called when client gets the asr recognition result from vc-daemon. + * + * @param[in] event The result event + * @param[in] result ASR text + * @param[in] user_data The user data passed from the callback registration function + * + * @return @c true when asr result is consumed \n @c false to propagate. + * + * @pre An application registers callback function using vc_mgr_set_pre_result_cb(). + * + * @see vc_widget_set_asr_result_cb() + * @see vc_widget_unset_asr_result_cb() + */ typedef bool (*vc_asr_result_cb)(vc_result_event_e event, const char* result, void *user_data); /** diff --git a/include/voice_control_manager.h b/include/voice_control_manager.h index 430daa5..3d4ece3 100644 --- a/include/voice_control_manager.h +++ b/include/voice_control_manager.h @@ -1,18 +1,18 @@ -/* -* 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. -*/ +/** + * 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_H__ @@ -247,55 +247,57 @@ typedef int (*vc_mgr_private_data_requested_cb)(const char *key, char **data, vo /* for TTS feedback */ /** -* @brief Called when engine sends audio formats necessary for playing TTS feedback -* @since_tizen 5.0 -* -* @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() -*/ + * @brief Called when engine sends audio formats necessary for playing TTS feedback + * @since_tizen 5.0 + * + * @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 -* @since_tizen 5.0 -* -* @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() -*/ + * @brief Called when engine sends audio streaming for TTS feedback + * @since_tizen 5.0 + * + * @remarks The @a buffer must be released with free() by you when you no longer need it. + * + * @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); /** -* @brief Called when the vc client sends audio streaming for TTS feedback -* @since_tizen 5.0 -* -* @remarks The @a buffer must be released with free() by you when you no longer need it. -* -* @param[in] pid The process id of the vc client -* @param[in] utt_id The utterance id -* @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_vc_tts_streaming_cb(). -* -* @see vc_mgr_set_vc_tts_streaming_cb() -* @see vc_mgr_unset_vc_tts_streaming_cb() -*/ + * @brief Called when the vc client sends audio streaming for TTS feedback + * @since_tizen 5.0 + * + * @remarks The @a buffer must be released with free() by you when you no longer need it. + * + * @param[in] pid The process id of the vc client + * @param[in] utt_id The utterance id + * @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_vc_tts_streaming_cb(). + * + * @see vc_mgr_set_vc_tts_streaming_cb() + * @see vc_mgr_unset_vc_tts_streaming_cb() + */ typedef void (*vc_mgr_vc_tts_streaming_cb)(int pid, int utt_id, vc_feedback_event_e event, char* buffer, int len, void *user_data); /** diff --git a/server/vcd_main.h b/server/vcd_main.h index 04ecdbf..70bcd18 100644 --- a/server/vcd_main.h +++ b/server/vcd_main.h @@ -72,7 +72,8 @@ typedef enum { VCD_STATE_READY = 1, VCD_STATE_RECORDING = 2, VCD_STATE_PROCESSING = 3, - VCD_STATE_UPDATING = 4 + VCD_STATE_SYNTHESIZING = 4, + VCD_STATE_UPDATING = 5 } vcd_state_e; typedef enum { diff --git a/server/vcd_server.c b/server/vcd_server.c index 4f369e0..f2e34f1 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -1098,16 +1098,16 @@ int vcd_send_error(vce_error_e error, const char* msg, void *user_data) /* 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"); + SLOG(LOG_INFO, TAG_VCD, "[Server DEBUG] Engine - Send TTS feedback audio format, g_current_uid(%d)", g_current_uid); /* send TTS feedback audio format to VC manager */ int ret = VCD_ERROR_NONE; int pid = g_current_uid / 1000; if (-1 == g_current_uid || vcd_client_manager_get_pid() == pid) { - 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"); - } + 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"); + } } else { SLOG(LOG_INFO, TAG_VCD, "[Server INFO] Do not send TTS feedback audio format to VC manager"); } @@ -1120,14 +1120,14 @@ int vcd_send_feedback_streaming(vce_feedback_event_e event, char* buffer, int le if (-1 == g_current_uid && VCE_FEEDBACK_EVENT_START == event) { g_current_utt_id = (g_current_utt_id + 1) % 1000; g_current_uid = vcd_client_manager_get_pid() * 1000 + g_current_utt_id; - SLOG(LOG_INFO, TAG_VCD, "[Server info] set current uid and utt_id as manager pid"); + SLOG(LOG_INFO, TAG_VCD, "[Server info] set current uid and utt_id as manager pid(%d)", vcd_client_manager_get_pid()); } int ret = VCD_ERROR_NONE; int pid = g_current_uid / 1000; int utt_id = g_current_uid % 1000; - SLOG(LOG_INFO, TAG_VCD, "[Server DEBUG] Engine - Send TTS feedback streaming to pid(%d), is_mgr_client(%d)", pid, (pid == vcd_client_manager_get_pid() ? true : false)); + SLOG(LOG_INFO, TAG_VCD, "[Server DEBUG] Engine - Send TTS feedback streaming event(%d), uid(%d), is_mgr_client(%d)", event, g_current_uid, (pid == vcd_client_manager_get_pid() ? true : false)); if (pid == vcd_client_manager_get_pid()) { /* send TTS feedback streaming to manager client */ @@ -1138,14 +1138,21 @@ int vcd_send_feedback_streaming(vce_feedback_event_e event, char* buffer, int le } else { /* send TTS feedback streaming to client */ ret = vcdc_send_feedback_streaming(pid, utt_id, event, buffer, len); - if (VCD_ERROR_NONE != ret) { + if (VCD_ERROR_NONE != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to send TTS feedback streaming to client"); - } + } } if (VCE_FEEDBACK_EVENT_FINISH == event) { /* reset current uid */ g_current_uid = -1; + + /* Set service state to ready if state is synthesizing */ + vcd_state_e state = vcd_config_get_service_state(); + if (VCD_STATE_SYNTHESIZING == state) { + vcd_config_set_service_state(VCD_STATE_READY); + } + SLOG(LOG_INFO, TAG_VCD, "[Server info] feedback streaming finish event, reset current uid & service state(%d)", vcd_config_get_service_state()); } return ret; } @@ -1845,8 +1852,8 @@ int vcd_server_mgr_start(vcd_recognition_mode_e recognition_mode, bool exclusive /* 1. check current state */ 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"); + if (VCD_STATE_READY != state && VCD_STATE_SYNTHESIZING != state) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready and not synthesizine, state(%d)", state); return VCD_ERROR_INVALID_STATE; } if (-1 == vcd_client_manager_get_pid()) { @@ -2091,8 +2098,8 @@ int vcd_server_mgr_send_specific_engine_request(int pid, const char* engine_app_ 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"); + if (VCD_STATE_READY != state && VCD_STATE_SYNTHESIZING != state) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready and not synthesizing, state(%d)", state); return VCD_ERROR_INVALID_STATE; } @@ -2118,8 +2125,8 @@ int vcd_server_mgr_do_action(int pid, int type, const char* action) } 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"); + if (VCD_STATE_READY != state && VCD_STATE_SYNTHESIZING != state) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready and not synthesizing, state(%d)", state); return VCD_ERROR_INVALID_STATE; } @@ -2514,6 +2521,7 @@ static void __start_tts_request_thread(void* data, Ecore_Thread* thread) while (1) { int ret = -1; + int cnt = 0; /* Get tts text data */ ret = vcd_data_get_first_tts_text_data(&tts_text_data); @@ -2527,6 +2535,23 @@ static void __start_tts_request_thread(void* data, Ecore_Thread* thread) continue; } + while (1) { + vcd_state_e state = vcd_config_get_service_state(); + if (VCD_STATE_READY != state) { + if (0 == cnt++ % 10) + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Waiting to request TTS, state(%d)", state); + usleep(100000); + continue; + } + break; + } + + /* Set service state to synthesizing */ + vcd_config_set_service_state(VCD_STATE_SYNTHESIZING); + + /* Set current uid */ + g_current_uid = tts_text_data->uid; + /* Request tts to engine */ ret = vcd_engine_request_tts(tts_text_data->pid, tts_text_data->utt_id, tts_text_data->text, tts_text_data->language); if (0 != ret) { @@ -2556,20 +2581,21 @@ int vcd_server_request_tts(int pid, const char* text, const char* language, int } vcd_state_e state = vcd_config_get_service_state(); - if (VCD_STATE_READY != state) { + if (VCD_STATE_READY != state && VCD_STATE_SYNTHESIZING != state) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready, state(%d)", state); return VCD_ERROR_INVALID_STATE; } + int uid = -1; g_current_utt_id = (g_current_utt_id + 1) % 1000; *utt_id = g_current_utt_id; if (0 == to_vcm) { - g_current_uid = pid * 1000 + g_current_utt_id; + uid = pid * 1000 + g_current_utt_id; } else { - g_current_uid = vcd_client_manager_get_pid() * 1000 + g_current_utt_id; + uid = vcd_client_manager_get_pid() * 1000 + g_current_utt_id; } SLOG(LOG_INFO, TAG_VCD, "[Server INFO] pid(%d), text(%s), language(%s), to_vcm(%d), ", pid, text, language, to_vcm); - SLOG(LOG_INFO, TAG_VCD, "[Server INFO] current_uid(%d), current_utt_id(%d)", g_current_uid, g_current_utt_id); + SLOG(LOG_INFO, TAG_VCD, "[Server INFO] current_uid(%d), current_utt_id(%d)", uid, g_current_utt_id); vc_tts_text_data_s* tts_text_data; tts_text_data = (vc_tts_text_data_s*)calloc(1, sizeof(vc_tts_text_data_s)); @@ -2577,7 +2603,7 @@ int vcd_server_request_tts(int pid, const char* text, const char* language, int SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to callocate memory "); return VCD_ERROR_OUT_OF_MEMORY; } - tts_text_data->uid = g_current_uid; + tts_text_data->uid = uid; tts_text_data->pid = pid; tts_text_data->utt_id = g_current_utt_id; tts_text_data->text = strdup(text); @@ -2606,7 +2632,7 @@ int vcd_server_cancel_tts(int pid, int utt_id) } vcd_state_e state = vcd_config_get_service_state(); - if (VCD_STATE_READY != state) { + if (VCD_STATE_READY != state && VCD_STATE_SYNTHESIZING != state) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready, state(%d)", state); return VCD_ERROR_INVALID_STATE; } @@ -2642,8 +2668,8 @@ int vcd_server_get_tts_audio_format(int pid, int* rate, int* channel, int* audio } 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"); + if (VCD_STATE_READY != state && VCD_STATE_SYNTHESIZING != state) { + SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready and not synthesizing, state(%d)", state); return VCD_ERROR_INVALID_STATE; } -- 2.7.4 From ea44357fdcbd58eb9ebc7aacaed248c8f9b0fad0 Mon Sep 17 00:00:00 2001 From: sungrae jo Date: Mon, 8 Oct 2018 20:48:50 +0900 Subject: [PATCH 04/16] Fixed update service code Change-Id: I3b1809b0bdd16c6607af4567f2a4530125d7eecd Signed-off-by: sungrae jo --- include/voice_control_manager_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/voice_control_manager_internal.h b/include/voice_control_manager_internal.h index 9d22ede..e50011f 100644 --- a/include/voice_control_manager_internal.h +++ b/include/voice_control_manager_internal.h @@ -45,7 +45,7 @@ typedef enum { VC_SYSTEM_VOLUME_EVENT_RECOVER } vc_system_volume_event_e; -#define VC_SERVICE_STATE_UPDATING 4 /**< 'Updating' state */ +#define VC_SERVICE_STATE_UPDATING 5 /**< 'Updating' state */ /** * @brief Sets demandable client list. -- 2.7.4 From 07eb236de91fa87bd005eb9fd5332a5be4bcae2c Mon Sep 17 00:00:00 2001 From: sungrae jo Date: Mon, 8 Oct 2018 21:02:41 +0900 Subject: [PATCH 05/16] Fixed service state compare code. Change-Id: Ibf2650c502b121a7dd2d581dbf823d4a3a405c50 Signed-off-by: sungrae jo --- client/vc_mgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/vc_mgr.c b/client/vc_mgr.c index 39e46e9..516db90 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -2919,7 +2919,7 @@ int __vc_mgr_cb_error(int reason, int daemon_pid, char* msg) vc_service_state_e service_state = -1; vc_mgr_client_get_service_state(g_vc_m, &service_state); - if (service_state != VC_SERVICE_STATE_UPDATING) { + if (VC_SERVICE_STATE_UPDATING == service_state) { SLOG(LOG_INFO, TAG_VCM, "[INFO] VC daemon is terminated by update manager"); return 0; } -- 2.7.4 From 075cc94926c53a9f9c3db378cb38a3c3b8c589ab Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Thu, 11 Oct 2018 10:37:12 +0900 Subject: [PATCH 06/16] Fix dbus crash issue in vc widget Change-Id: I15087eaa8dfc7e042f7c6fbb385b78f478087503 Signed-off-by: sooyeon.kim --- client/vc_widget_dbus.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/client/vc_widget_dbus.c b/client/vc_widget_dbus.c index d71d479..4cd4b9d 100644 --- a/client/vc_widget_dbus.c +++ b/client/vc_widget_dbus.c @@ -15,11 +15,15 @@ */ +#include + #include "vc_main.h" #include "vc_widget_client.h" #include "vc_widget_dbus.h" +static pthread_mutex_t g_w_dbus_mutex = PTHREAD_MUTEX_INITIALIZER; + static int g_w_waiting_time = 3000; static Ecore_Fd_Handler* g_w_fd_handler = NULL; @@ -286,8 +290,11 @@ static void __vc_widget_dbus_connection_free() int vc_widget_dbus_open_connection() { + pthread_mutex_lock(&g_w_dbus_mutex); + if (NULL != g_w_conn_sender && NULL != g_w_conn_listener) { SLOG(LOG_WARN, TAG_VCW, "Already existed connection "); + pthread_mutex_unlock(&g_w_dbus_mutex); return 0; } @@ -307,6 +314,7 @@ int vc_widget_dbus_open_connection() if (NULL == g_w_conn_sender) { SLOG(LOG_ERROR, TAG_VCW, "Fail to get dbus connection "); + pthread_mutex_unlock(&g_w_dbus_mutex); return VC_ERROR_OPERATION_FAILED; } @@ -322,6 +330,7 @@ int vc_widget_dbus_open_connection() if (NULL == g_w_conn_listener) { SLOG(LOG_ERROR, TAG_VCW, "Fail to get dbus connection "); __vc_widget_dbus_connection_free(); + pthread_mutex_unlock(&g_w_dbus_mutex); return VC_ERROR_OPERATION_FAILED; } @@ -346,12 +355,14 @@ int vc_widget_dbus_open_connection() if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { SLOG(LOG_ERROR, TAG_VCW, "fail dbus_bus_request_name()"); __vc_widget_dbus_connection_free(); + pthread_mutex_unlock(&g_w_dbus_mutex); return -2; } if (NULL != g_w_fd_handler) { SLOG(LOG_WARN, TAG_VCW, "The handler already exists."); __vc_widget_dbus_connection_free(); + pthread_mutex_unlock(&g_w_dbus_mutex); return 0; } @@ -365,6 +376,7 @@ int vc_widget_dbus_open_connection() SLOG(LOG_ERROR, TAG_VCW, "Match Error (%s)", err.message); dbus_error_free(&err); __vc_widget_dbus_connection_free(); + pthread_mutex_unlock(&g_w_dbus_mutex); return VC_ERROR_OPERATION_FAILED; } @@ -372,6 +384,7 @@ int vc_widget_dbus_open_connection() if (1 != dbus_connection_get_unix_fd(g_w_conn_listener, &fd)) { SLOG(LOG_ERROR, TAG_VCW, "fail to get fd from dbus "); __vc_widget_dbus_connection_free(); + pthread_mutex_unlock(&g_w_dbus_mutex); return VC_ERROR_OPERATION_FAILED; } else { SLOG(LOG_DEBUG, TAG_VCW, "Get fd from dbus : %d", fd); @@ -382,14 +395,18 @@ int vc_widget_dbus_open_connection() if (NULL == g_w_fd_handler) { SLOG(LOG_ERROR, TAG_VCW, "fail to get fd handler from ecore "); __vc_widget_dbus_connection_free(); + pthread_mutex_unlock(&g_w_dbus_mutex); return VC_ERROR_OPERATION_FAILED; } + pthread_mutex_unlock(&g_w_dbus_mutex); return 0; } int vc_widget_dbus_close_connection() { + pthread_mutex_lock(&g_w_dbus_mutex); + DBusError err; dbus_error_init(&err); @@ -415,6 +432,8 @@ int vc_widget_dbus_close_connection() __vc_widget_dbus_connection_free(); + pthread_mutex_unlock(&g_w_dbus_mutex); + return 0; } -- 2.7.4 From 74a2b9c52036bb66d43233c13b058fc09890d7f9 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Thu, 11 Oct 2018 19:46:06 +0900 Subject: [PATCH 07/16] check vc_m handle before use Change-Id: I49c9f14e30c30208597fb8f41470e55d65cd9e20 Signed-off-by: Wonnam Jang --- client/vc_mgr.c | 101 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 46 deletions(-) diff --git a/client/vc_mgr.c b/client/vc_mgr.c index 516db90..70c7190 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -384,69 +384,77 @@ static Eina_Bool __vc_mgr_connect_daemon(void *data) g_m_connect_timer = NULL; - vc_audio_streaming_mode_e streaming_mode; - vc_mgr_client_get_audio_streaming_mode(g_vc_m, &streaming_mode); + /* check handle */ + if (true == vc_mgr_client_is_valid(g_vc_m)) { + SLOG(LOG_DEBUG, TAG_VCM, "[DEBUG] g_vc_m is valid"); - ret = vc_mgr_dbus_request_initialize(g_vc_m->handle, (int)streaming_mode, &service_state, &foreground, &g_daemon_pid); + vc_audio_streaming_mode_e streaming_mode; + vc_mgr_client_get_audio_streaming_mode(g_vc_m, &streaming_mode); - if (VC_ERROR_ENGINE_NOT_FOUND == ret) { - SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to initialize : %s", __vc_mgr_get_error_code(ret)); + ret = vc_mgr_dbus_request_initialize(g_vc_m->handle, (int)streaming_mode, &service_state, &foreground, &g_daemon_pid); - vc_mgr_client_set_error(g_vc_m, VC_ERROR_ENGINE_NOT_FOUND); - ecore_main_loop_thread_safe_call_async(__vc_mgr_notify_error, (void*)g_vc_m); + if (VC_ERROR_ENGINE_NOT_FOUND == ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to initialize : %s", __vc_mgr_get_error_code(ret)); - SLOG(LOG_DEBUG, TAG_VCM, "@@@"); - return EINA_FALSE; + vc_mgr_client_set_error(g_vc_m, VC_ERROR_ENGINE_NOT_FOUND); + ecore_main_loop_thread_safe_call_async(__vc_mgr_notify_error, (void*)g_vc_m); - } else if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCM, "[WARNING] Fail to connection. Retry to connect : %s", __vc_mgr_get_error_code(ret)); - return EINA_TRUE; - } else { - /* Success to connect */ - } + SLOG(LOG_DEBUG, TAG_VCM, "@@@"); + return EINA_FALSE; - /* Set service state */ - vc_service_state_e previous_service_state; - vc_mgr_client_get_service_state(g_vc_m, &previous_service_state); + } else if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[WARNING] Fail to connection. Retry to connect : %s", __vc_mgr_get_error_code(ret)); + return EINA_TRUE; + } else { + /* Success to connect */ + } - vc_mgr_client_set_service_state(g_vc_m, (vc_service_state_e)service_state); + /* Set service state */ + vc_service_state_e previous_service_state; + vc_mgr_client_get_service_state(g_vc_m, &previous_service_state); - vc_service_state_changed_cb service_changed_callback = NULL; - void* user_data = NULL; - vc_mgr_client_get_service_state_changed_cb(g_vc_m, &service_changed_callback, &user_data); + vc_mgr_client_set_service_state(g_vc_m, (vc_service_state_e)service_state); - if (NULL != service_changed_callback) { - vc_mgr_client_use_callback(g_vc_m); - service_changed_callback(previous_service_state, service_state, user_data); - vc_mgr_client_not_use_callback(g_vc_m); - SLOG(LOG_DEBUG, TAG_VCM, "Service state changed callback is called"); - } else { - SLOG(LOG_WARN, TAG_VCM, "[WARNING] Service state changed callback is null"); - } + vc_service_state_changed_cb service_changed_callback = NULL; + void* user_data = NULL; + vc_mgr_client_get_service_state_changed_cb(g_vc_m, &service_changed_callback, &user_data); - /* Set foreground */ - vc_mgr_client_set_foreground(g_vc_m, foreground, true); + if (NULL != service_changed_callback) { + vc_mgr_client_use_callback(g_vc_m); + service_changed_callback(previous_service_state, service_state, user_data); + vc_mgr_client_not_use_callback(g_vc_m); + SLOG(LOG_DEBUG, TAG_VCM, "Service state changed callback is called"); + } else { + SLOG(LOG_WARN, TAG_VCM, "[WARNING] Service state changed callback is null"); + } - SLOG(LOG_ERROR, TAG_VCM, "[SUCCESS] Connected daemon"); + /* Set foreground */ + vc_mgr_client_set_foreground(g_vc_m, foreground, true); - /* Set client state */ - vc_mgr_client_set_client_state(g_vc_m, VC_STATE_READY); + SLOG(LOG_ERROR, TAG_VCM, "[SUCCESS] Connected daemon"); - vc_state_changed_cb changed_callback = NULL; - vc_mgr_client_get_state_changed_cb(g_vc_m, &changed_callback, &user_data); + /* Set client state */ + vc_mgr_client_set_client_state(g_vc_m, VC_STATE_READY); - vc_state_e current_state; - vc_state_e before_state; + vc_state_changed_cb changed_callback = NULL; + vc_mgr_client_get_state_changed_cb(g_vc_m, &changed_callback, &user_data); - vc_mgr_client_get_before_state(g_vc_m, ¤t_state, &before_state); + vc_state_e current_state; + vc_state_e before_state; - if (NULL != changed_callback) { - vc_mgr_client_use_callback(g_vc_m); - changed_callback(before_state, current_state, user_data); - vc_mgr_client_not_use_callback(g_vc_m); - SLOG(LOG_DEBUG, TAG_VCM, "State changed callback is called"); + vc_mgr_client_get_before_state(g_vc_m, ¤t_state, &before_state); + + if (NULL != changed_callback) { + vc_mgr_client_use_callback(g_vc_m); + changed_callback(before_state, current_state, user_data); + vc_mgr_client_not_use_callback(g_vc_m); + SLOG(LOG_DEBUG, TAG_VCM, "State changed callback is called"); + } else { + SLOG(LOG_WARN, TAG_VCM, "[WARNING] State changed callback is null"); + } } else { - SLOG(LOG_WARN, TAG_VCM, "[WARNING] State changed callback is null"); + SLOG(LOG_ERROR, TAG_VCM, "[Not ERROR] g_vc_m is not valid. It is destroyed."); //LCOV_EXCL_LINE + return EINA_FALSE; } SLOG(LOG_DEBUG, TAG_VCM, "@@@"); @@ -454,6 +462,7 @@ static Eina_Bool __vc_mgr_connect_daemon(void *data) return EINA_FALSE; } + static void __start_prepare_thread(void *data, Ecore_Thread *thread) { SLOG(LOG_ERROR, TAG_VCM, "@@@ Start prepare thread"); -- 2.7.4 From 33e3ca166a54031f2081eb1b75ff87c856a22b33 Mon Sep 17 00:00:00 2001 From: sungrae jo Date: Wed, 24 Oct 2018 18:56:44 +0900 Subject: [PATCH 08/16] Add init code for STT user_data Change-Id: I7d9285046c6b46cd7443cc420112c59fa4e7e466 Signed-off-by: sungrae jo --- server/vcd_engine_agent.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/vcd_engine_agent.c b/server/vcd_engine_agent.c index 68b8f83..7b1dde8 100644 --- a/server/vcd_engine_agent.c +++ b/server/vcd_engine_agent.c @@ -236,8 +236,11 @@ int __internal_get_engine_info(vce_request_callback_s* callback) g_dynamic_engine.callbacks->nlu_base_info_request = NULL; g_dynamic_engine.callbacks->specific_engine_request = NULL; g_dynamic_engine.internal_callbacks->request_tts = NULL; + g_dynamic_engine.internal_callbacks->request_tts_user_data = NULL; g_dynamic_engine.internal_callbacks->cancel_tts = NULL; + g_dynamic_engine.internal_callbacks->cancel_tts_user_data = NULL; g_dynamic_engine.internal_callbacks->get_tts_audio_format = NULL; + g_dynamic_engine.internal_callbacks->get_tts_audio_format_user_data = NULL; SLOG(LOG_DEBUG, TAG_VCD, "@@@ Valid Engine"); SLOG(LOG_DEBUG, TAG_VCD, "Engine uuid : %s", g_dynamic_engine.engine_uuid); -- 2.7.4 From 743e25a7735d0bc67aae2dc66dcae86c944b4c3a Mon Sep 17 00:00:00 2001 From: sungrae jo Date: Mon, 5 Nov 2018 19:31:59 +0900 Subject: [PATCH 09/16] Fixed system volume code Change-Id: I45f881d10ae13fd6c0e19a6772d66f5376c7a1fb Signed-off-by: sungrae jo --- server/vcd_recorder.c | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index a024942..8151e00 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -902,33 +902,39 @@ int vcd_recorder_stop_streaming() int vcd_recorder_change_system_volume() { + int ret = VCD_ERROR_NONE; + if (!g_stream_for_volume_h) { - int ret = sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE, NULL, NULL, &g_stream_for_volume_h); + ret = sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE, NULL, NULL, &g_stream_for_volume_h); if (0 != ret) { SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Fail to create stream information, ret(%d)", ret); return VCD_ERROR_OPERATION_FAILED; } - if (!g_virtual_sound_stream_h) { - ret = sound_manager_create_virtual_stream(g_stream_for_volume_h, &g_virtual_sound_stream_h); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create virtual stream, ret(%d)", ret); - return VCD_ERROR_OPERATION_FAILED; - } - ret = sound_manager_start_virtual_stream(g_virtual_sound_stream_h); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start virtual stream, ret(%d)", ret); - return VCD_ERROR_OPERATION_FAILED; - } + } + + if (!g_virtual_sound_stream_h) { + ret = sound_manager_create_virtual_stream(g_stream_for_volume_h, &g_virtual_sound_stream_h); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create virtual stream, ret(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; } } + ret = sound_manager_start_virtual_stream(g_virtual_sound_stream_h); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start virtual stream, ret(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; + } + return 0; } int vcd_recorder_recover_system_volume() { + int ret = VCD_ERROR_NONE; + if (g_virtual_sound_stream_h) { - int ret = sound_manager_stop_virtual_stream(g_virtual_sound_stream_h); + ret = sound_manager_stop_virtual_stream(g_virtual_sound_stream_h); if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop virtual stream, ret(%d)", ret); return VCD_ERROR_OPERATION_FAILED; @@ -939,15 +945,15 @@ int vcd_recorder_recover_system_volume() return VCD_ERROR_OPERATION_FAILED; } g_virtual_sound_stream_h = NULL; + } - if (g_stream_for_volume_h) { - ret = sound_manager_destroy_stream_information(g_stream_for_volume_h); - if (0 != ret) { - SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to destroy stream information, ret(%d)", ret); - return VCD_ERROR_OPERATION_FAILED; - } - g_stream_for_volume_h = NULL; + if (g_stream_for_volume_h) { + ret = sound_manager_destroy_stream_information(g_stream_for_volume_h); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to destroy stream information, ret(%d)", ret); + return VCD_ERROR_OPERATION_FAILED; } + g_stream_for_volume_h = NULL; } return 0; -- 2.7.4 From 21dbcba34abd3e5c96a59ee5dfbf818a2950a315 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Wed, 7 Nov 2018 14:52:28 +0900 Subject: [PATCH 10/16] Fix setting vc mgr pid Change-Id: I520abf1debc3d20c66752b8ce94251c3705cfbb1 Signed-off-by: sooyeon.kim --- server/vcd_client_data.c | 20 +++++++++++--------- server/vcd_server.c | 3 ++- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/server/vcd_client_data.c b/server/vcd_client_data.c index 8639155..2944216 100644 --- a/server/vcd_client_data.c +++ b/server/vcd_client_data.c @@ -52,15 +52,6 @@ vc_client_info_s* __client_get_element(int pid); int vcd_client_manager_set(int pid) { - if (-1 != g_manager.pid && NULL != g_manager.appid) { - SLOG(LOG_DEBUG, TAG_VCD, "Manager has already registered"); - return -1; - } - g_manager.pid = pid; - g_manager.manager_cmd = false; - g_manager.exclusive_cmd_option = false; - g_manager.appid = NULL; - // Get appid by pid using app control char* appid = NULL; int ret = app_manager_get_app_id(pid, &appid); @@ -68,6 +59,17 @@ int vcd_client_manager_set(int pid) SLOG(LOG_ERROR, TAG_VCD, "[ERROR] fail to get app id, ret(%d), pid(%d)", ret, pid); return -1; } + + if (-1 != g_manager.pid && NULL != g_manager.appid && 0 == strncmp(g_manager.appid, appid, strlen(g_manager.appid))) { + SLOG(LOG_WARN, TAG_VCD, "Same manager has already registered. It doesn't need to set manager again."); + return 0; + } + + g_manager.pid = pid; + g_manager.manager_cmd = false; + g_manager.exclusive_cmd_option = false; + g_manager.appid = NULL; + g_manager.appid = strdup(appid); free(appid); diff --git a/server/vcd_server.c b/server/vcd_server.c index f2e34f1..0a109ca 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -1568,7 +1568,8 @@ int vcd_server_mgr_initialize(int pid) } /* Add client information to client manager */ - if (0 != vcd_client_manager_set(pid)) { + int ret = vcd_client_manager_set(pid); + if (0 != ret) { SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add manager"); return VCD_ERROR_OPERATION_FAILED; } -- 2.7.4 From 68e7335ae5aced5b0622f2cc7a5f756cef6941bb Mon Sep 17 00:00:00 2001 From: Jihoon Kim Date: Fri, 7 Dec 2018 17:01:57 +0900 Subject: [PATCH 11/16] Fix mismatch between log format and actual parameter Change-Id: I7df022dc33db89c28acc3d5b97b8074b07cfa7ca Signed-off-by: Jihoon Kim --- common/vc_info_parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/vc_info_parser.c b/common/vc_info_parser.c index 864f470..d4b48ac 100644 --- a/common/vc_info_parser.c +++ b/common/vc_info_parser.c @@ -401,7 +401,7 @@ int vc_info_parser_set_nlu_result(const char* nlu_result) SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to set file mode - %s", VC_RUNTIME_INFO_NLU_RESULT); } - SLOG(LOG_DEBUG, vc_info_tag(), "[SUCCESS] Write file (%s) size (%d)", VC_RUNTIME_INFO_NLU_RESULT, strlen(nlu_result)); + SLOG(LOG_DEBUG, vc_info_tag(), "[SUCCESS] Write file (%s) size (%zu)", VC_RUNTIME_INFO_NLU_RESULT, strlen(nlu_result)); return 0; } -- 2.7.4 From 5286cbd4525ab72f93db9ede18890341c475c726 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Fri, 14 Dec 2018 16:07:45 +0900 Subject: [PATCH 12/16] Update error msg Change-Id: I79ae3bbb21ed954334277a88df1daa770bc0dc27 Signed-off-by: Wonnam Jang --- server/vcd_engine_agent.c | 2 +- server/vcd_server.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/server/vcd_engine_agent.c b/server/vcd_engine_agent.c index 7b1dde8..c1c7c77 100644 --- a/server/vcd_engine_agent.c +++ b/server/vcd_engine_agent.c @@ -916,7 +916,7 @@ int vcd_engine_agent_start_recording() SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recorder : result(%d)", ret); vcd_engine_recognize_cancel(); /* Send error cb to manager */ - vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail"); + vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_framework.error.vcfw.send_rc_fail"); return ret; } diff --git a/server/vcd_server.c b/server/vcd_server.c index 0a109ca..fe5f960 100644 --- a/server/vcd_server.c +++ b/server/vcd_server.c @@ -141,9 +141,9 @@ static int __server_recorder_callback(const void* data, const unsigned int lengt ecore_timer_add(0, __cancel_by_interrupt, NULL); /* Send error cb to manager */ if (VCE_ERROR_OUT_OF_NETWORK == ret) { - vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_TIMED_OUT, "Engine connection failed"); + vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_TIMED_OUT, "voice_framework.error.engine.set_recording_fail"); } else { - vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "Engine recognition failed"); + vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_framework.error.engine.set_recording_fail"); } return 0; } @@ -1778,7 +1778,7 @@ static int __start_internal_recognition() /* Send error cb to manager */ int pid = vcd_client_widget_get_foreground_pid(); if (-1 != pid) - vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail"); + vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_framework.error.vcfw.collect_command_fail"); return VCD_ERROR_OPERATION_FAILED; } @@ -1789,7 +1789,7 @@ static int __start_internal_recognition() /* Send error cb to manager */ int pid = vcd_client_widget_get_foreground_pid(); if (-1 != pid) - vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail"); + vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_framework.error.engine.set_commands_fail"); return VCD_ERROR_OPERATION_FAILED; } @@ -1809,7 +1809,7 @@ static int __start_internal_recognition() /* Send error cb to manager */ int pid = vcd_client_widget_get_foreground_pid(); if (-1 != pid) - vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail"); + vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_framework.error.engine.start_fail"); return VCD_ERROR_OPERATION_FAILED; } @@ -1824,7 +1824,7 @@ static int __start_internal_recognition() /* Send error cb to manager */ int pid = vcd_client_widget_get_foreground_pid(); if (-1 != pid) - vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_engine.error.proc_fail"); + vcdc_send_error_signal_to_manager(vcd_client_manager_get_pid(), VCD_ERROR_OPERATION_FAILED, "voice_framework.error.vcfw.send_rc_fail"); return ret; } #endif -- 2.7.4 From e760840b9673e63b763adee87f61cf84a2cdaa88 Mon Sep 17 00:00:00 2001 From: sungrae jo Date: Wed, 9 Jan 2019 20:08:21 +0900 Subject: [PATCH 13/16] Dbus usage Memory Leak fix Change-Id: I811c33c2a2dff8545a1e42169c82e770c9ae50d5 Signed-off-by: sungrae jo --- client/vc_setting_dbus.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/vc_setting_dbus.c b/client/vc_setting_dbus.c index d82c436..c249d40 100755 --- a/client/vc_setting_dbus.c +++ b/client/vc_setting_dbus.c @@ -103,10 +103,12 @@ static void __vc_setting_dbus_connection_free() { if (NULL != g_s_conn_listener) { dbus_connection_close(g_s_conn_listener); + dbus_connection_unref(g_s_conn_listener); g_s_conn_listener = NULL; } if (NULL != g_s_conn_sender) { dbus_connection_close(g_s_conn_sender); + dbus_connection_unref(g_s_conn_sender); g_s_conn_sender = NULL; } } @@ -226,6 +228,10 @@ int vc_setting_dbus_close_connection() memset(service_name, '\0', 64); snprintf(service_name, 64, "%s%d", VC_SETTING_SERVICE_NAME, pid); + char rule[128] = {0, }; + snprintf(rule, 128, "type='signal',interface='%s'", VC_SETTING_SERVICE_INTERFACE); + dbus_bus_remove_match(g_s_conn_listener, rule, NULL); + dbus_bus_release_name(g_s_conn_listener, service_name, &err); if (dbus_error_is_set(&err)) { -- 2.7.4 From c4c7d83bfdc1bde6fe13b67b83f8f3dfbdccde97 Mon Sep 17 00:00:00 2001 From: "sooyeon.kim" Date: Fri, 7 Dec 2018 10:54:54 +0900 Subject: [PATCH 14/16] Fix to check widget prepare thread Change-Id: Ia45698e372651bddf592c0e76e5c6172e90fc387 Signed-off-by: sooyeon.kim (cherry picked from commit 8b665df6bc3f11a889593006b2c8687eb16d8ccb) --- client/vc_widget.c | 49 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/client/vc_widget.c b/client/vc_widget.c index eb54aa7..efb64b6 100644 --- a/client/vc_widget.c +++ b/client/vc_widget.c @@ -39,6 +39,9 @@ static Ecore_Timer* g_w_start_timer = NULL; static Ecore_Timer* g_w_notify_state_timer = NULL; static Ecore_Timer* g_w_notify_result_timer = NULL; +static Ecore_Thread* g_w_prepare_thread = NULL; +static int g_w_prepare_canceled = 0; + static int g_daemon_pid = 0; static int g_feature_enabled = -1; @@ -463,6 +466,11 @@ static void __start_prepare_thread(void *data, Ecore_Thread *thread) /* Send hello */ while (0 != ret) { + if (g_w_prepare_canceled) { + SLOG(LOG_WARN, TAG_VCW, "[WARNING] Thread is canceled."); + return; + } + 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); @@ -481,6 +489,11 @@ static void __start_prepare_thread(void *data, Ecore_Thread *thread) ret = -1; retry_count = 0; while (0 != ret) { + if (g_w_prepare_canceled) { + SLOG(LOG_WARN, TAG_VCW, "[WARNING] Thread is canceled."); + return; + } + 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); @@ -503,6 +516,13 @@ static void __end_prepare_thread(void *data, Ecore_Thread *thread) SLOG(LOG_DEBUG, TAG_VCW, "@@@ End prepare thread"); } +static void __cancel_prepare_thread(void *data, Ecore_Thread *thread) +{ + SLOG(LOG_DEBUG, TAG_VCW, "@@@ Cancel prepare thread"); + + g_w_prepare_canceled = 1; +} + int vc_widget_prepare(vc_h vc_w) { SLOG(LOG_DEBUG, TAG_VCW, "@@@ [Widget] Prepare"); @@ -536,7 +556,13 @@ int vc_widget_prepare(vc_h vc_w) // 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); + // Check ecore thread + if (g_w_prepare_thread && !ecore_thread_check(g_w_prepare_thread)) { + ecore_thread_cancel(g_w_prepare_thread); + g_w_prepare_thread = NULL; + } + g_w_prepare_canceled = 0; + g_w_prepare_thread = ecore_thread_run(__start_prepare_thread, __end_prepare_thread, __cancel_prepare_thread, (void*)vc_w); SLOG(LOG_DEBUG, TAG_VCW, "@@@"); @@ -552,20 +578,29 @@ int vc_widget_unprepare(vc_h vc_w) return VC_ERROR_NONE; } - int thread_count = ecore_thread_active_get(); + int prev_thread_count = ecore_thread_active_get(); + int curr_thread_count = prev_thread_count; int count = 0; - SLOG(LOG_INFO, TAG_VCW, "[Widget] Thread count(%d)", thread_count); - while (0 < thread_count) { + SLOG(LOG_INFO, TAG_VCW, "[Widget] Current thread count(%d)", curr_thread_count); + + if (g_w_prepare_thread && !ecore_thread_check(g_w_prepare_thread)) { + SLOG(LOG_WARN, TAG_VCW, "[WARNING] Thread is alive. Call cancel thread."); + ecore_thread_cancel(g_w_prepare_thread); + } + + while (0 < curr_thread_count && 1 != prev_thread_count - curr_thread_count && !ecore_thread_check(g_w_prepare_thread)) { usleep(50000); + if (100 == count) { - SLOG(LOG_WARN, TAG_VCW, "[WARNING!!] Thread is blocked, cnt(%d), thread count(%d)", count, thread_count); + SLOG(LOG_WARN, TAG_VCW, "[WARNING!!] Thread is blocked, cnt(%d), thread count(%d)", count, curr_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); + SLOG(LOG_WARN, TAG_VCW, "[WARNING!!] Thread is alive, cnt(%d), thread count(%d)", count, curr_thread_count); } count++; - thread_count = ecore_thread_active_get(); + curr_thread_count = ecore_thread_active_get(); } + g_w_prepare_thread = NULL; vc_state_e state; if (0 != vc_widget_client_get_state(vc_w, &state)) { -- 2.7.4 From 2a7ae05810bbdb27f337f708a2d7e23d5938fac4 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Tue, 11 Dec 2018 12:02:22 +0900 Subject: [PATCH 15/16] Add to set prepare thread as NULL Change-Id: I70ddc61cfacf1bc45f2466a2176b3b89c3021336 Signed-off-by: Wonnam Jang (cherry picked from commit fcca8ce240486c446838eff01e6104884d43e190) --- client/vc_widget.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/vc_widget.c b/client/vc_widget.c index efb64b6..c3e634c 100644 --- a/client/vc_widget.c +++ b/client/vc_widget.c @@ -259,6 +259,8 @@ int vc_widget_deinitialize(vc_h vc_w) return VC_ERROR_INVALID_STATE; } + g_w_prepare_canceled = 1; + vc_state_e state; vc_widget_client_get_state(vc_w, &state); vc_widget_s* widget = widget_get(vc_w); @@ -513,13 +515,14 @@ static void __start_prepare_thread(void *data, Ecore_Thread *thread) static void __end_prepare_thread(void *data, Ecore_Thread *thread) { + g_w_prepare_thread = NULL; SLOG(LOG_DEBUG, TAG_VCW, "@@@ End prepare thread"); } static void __cancel_prepare_thread(void *data, Ecore_Thread *thread) { SLOG(LOG_DEBUG, TAG_VCW, "@@@ Cancel prepare thread"); - + g_w_prepare_thread = NULL; g_w_prepare_canceled = 1; } -- 2.7.4 From 3e290f816309ba40c97dd60ea9039e88786a375d Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Fri, 14 Dec 2018 15:28:10 +0900 Subject: [PATCH 16/16] Add farfield audio type Change-Id: I0ef337a100611b06ccf13d311b37fd46f12ccc71 Signed-off-by: Wonnam Jang (cherry picked from commit 1257cfae82c1f3f4c44f08f43c80ea37d65766cc) --- CMakeLists.txt | 2 +- packaging/voice-control.spec | 1 + server/vcd_recorder.c | 76 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b555f38..ffeca96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,7 @@ INCLUDE(FindPkgConfig) IF("${_TV_PRODUCT}" STREQUAL "TRUE") pkg_check_modules(pkgs REQUIRED aul capi-appfw-app-control capi-appfw-app-manager capi-base-common capi-media-audio-io capi-media-sound-manager ecore-wayland - capi-network-bluetooth capi-network-bluetooth-tv capi-system-info cynara-client cynara-session dbus-1 db-util dlog ecore glib-2.0 json-glib-1.0 libgum libtzplatform-config libxml-2.0 sqlite3 vconf msfapi + capi-network-bluetooth capi-network-bluetooth-tv capi-system-info cynara-client cynara-session dbus-1 db-util dlog ecore glib-2.0 json-glib-1.0 libgum libtzplatform-config libxml-2.0 sqlite3 vconf msfapi farfield-voice-api ) ELSE() pkg_check_modules(pkgs REQUIRED diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec index 06035f5..1115948 100644 --- a/packaging/voice-control.spec +++ b/packaging/voice-control.spec @@ -36,6 +36,7 @@ BuildRequires: pkgconfig(pkgmgr-installer) BuildRequires: pkgconfig(capi-network-bluetooth) BuildRequires: pkgconfig(capi-network-bluetooth-tv) BuildRequires: pkgconfig(msfapi) +BuildRequires: pkgconfig(farfield-voice-api) %endif BuildRequires: pkgconfig(vconf) BuildRequires: cmake diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index 8151e00..fdc76a2 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -17,6 +17,7 @@ #ifdef TV_PRODUCT #define TV_BT_MODE #define TV_MSF_WIFI_MODE +#define TV_FFV_MODE #endif #include @@ -30,6 +31,9 @@ #ifdef TV_MSF_WIFI_MODE #include #endif +#ifdef TV_FFV_MODE +#include +#endif #endif #include "vcd_client_data.h" @@ -45,6 +49,7 @@ #define FOCUS_SERVER_READY "/tmp/.focus_server_ready" #define VCE_AUDIO_ID_NONE "VC_AUDIO_ID_NONE" /**< None audio id */ +#define VCE_AUDIO_ID_FFV "VC_FARFIELD_VOICE_VD" static vcd_recorder_state_e g_recorder_state = VCD_RECORDER_STATE_READY; @@ -74,6 +79,10 @@ static int g_buffer_count; static int g_device_id = -1; +#ifdef TV_FFV_MODE +farfield_voice_h g_farfieldvoice_h = NULL; +#endif + static sound_stream_info_h g_stream_for_volume_h = NULL; static virtual_sound_stream_h g_virtual_sound_stream_h = NULL; @@ -212,7 +221,28 @@ static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void #endif return; } +#endif +#ifdef TV_FFV_MODE +static void _ffv_audio_function_cb(void* data, unsigned int length, void* user_data) +{ + if (0 != strncmp(g_current_audio_type, VCE_AUDIO_ID_FFV, sizeof(VCE_AUDIO_ID_FFV))) { + vcd_state_e state = vcd_config_get_service_state(); + if (VCD_STATE_READY == state) { + vcd_recorder_set(VCE_AUDIO_ID_FFV, VCE_AUDIO_TYPE_PCM_S16_LE, 16000, 1); + } else { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] current audio type is (%s)", g_current_audio_type); + return; + } + } + + if (NULL != g_audio_cb) { + if (0 != g_audio_cb(data, length)) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio"); + vcd_recorder_stop(); + } + } +} #endif #if 1 @@ -419,6 +449,19 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb g_interrupt_cb = interrupt_cb; g_recorder_state = VCD_RECORDER_STATE_READY; +#ifdef TV_FFV_MODE + g_farfieldvoice_h = farfield_voice_init(); + if (NULL == g_farfieldvoice_h) + { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to init farfield_voice_init"); + } + + if (g_farfieldvoice_h) + { + farfield_voice_register_audio_cb(g_farfieldvoice_h, _ffv_audio_function_cb, NULL); + } +#endif + #ifdef TV_BT_MODE bool is_bt_failed = false; @@ -490,6 +533,15 @@ int vcd_recorder_destroy() if (0 != ret) SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to audio in destroy, ret(%d)", ret); +#ifdef TV_FFV_MODE + if (NULL != g_farfieldvoice_h) + { + farfield_voice_unregister_audio_cb(g_farfieldvoice_h); + farfield_voice_final(g_farfieldvoice_h); + g_farfieldvoice_h = NULL; + } +#endif + #ifdef TV_BT_MODE bt_hid_unset_audio_data_receive_cb(); @@ -538,8 +590,10 @@ int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, in if (NULL != g_current_audio_type) { if ((!strncmp(g_current_audio_type, VCE_AUDIO_ID_NONE, strlen(g_current_audio_type)) && strncmp(audio_type, VCE_AUDIO_ID_BLUETOOTH, strlen(audio_type)) && + strncmp(audio_type, VCE_AUDIO_ID_FFV, strlen(audio_type)) && strncmp(audio_type, VCE_AUDIO_ID_WIFI, strlen(audio_type))) || (strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, strlen(g_current_audio_type)) && + strncmp(g_current_audio_type, VCE_AUDIO_ID_FFV, strlen(g_current_audio_type)) && strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, strlen(g_current_audio_type)) && strncmp(g_current_audio_type, VCE_AUDIO_ID_NONE, strlen(g_current_audio_type)) && !strncmp(audio_type, VCE_AUDIO_ID_NONE, strlen(audio_type)))) { @@ -573,6 +627,13 @@ int vcd_recorder_set(const char* audio_type, vce_audio_type_e type, int rate, in } g_current_audio_type = strdup(audio_type); + } else if (0 == strncmp(VCE_AUDIO_ID_FFV, audio_type, strlen(VCE_AUDIO_ID_FFV))) { + if (NULL != g_current_audio_type) { + free(g_current_audio_type); + g_current_audio_type = NULL; + } + + g_current_audio_type = strdup(audio_type); } else { if (false == g_is_valid_audio_in) { SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio-in is NOT valid"); @@ -1005,6 +1066,9 @@ int vcd_recorder_start() g_bt_extend_count = 0; #endif + } else if (0 == strncmp(VCE_AUDIO_ID_FFV, g_current_audio_type, strlen(VCE_AUDIO_ID_FFV))) { + SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] call FARFIELD() function"); + started = true; } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, g_current_audio_type, strlen(VCE_AUDIO_ID_WIFI))) { SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] call RegisterMSFAudioCallback() function"); #ifdef TV_MSF_WIFI_MODE @@ -1129,6 +1193,7 @@ int vcd_recorder_stop() } if (NULL != g_current_audio_type && (!strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, sizeof(VCE_AUDIO_ID_BLUETOOTH)) || + !strncmp(g_current_audio_type, VCE_AUDIO_ID_FFV, sizeof(VCE_AUDIO_ID_FFV)) || !strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, sizeof(VCE_AUDIO_ID_WIFI)))) { SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] Recorder reset to NONE"); vcd_recorder_set(VCE_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel); @@ -1139,6 +1204,17 @@ int vcd_recorder_stop() return VCD_ERROR_OPERATION_FAILED; } #endif + } else if (0 == strncmp(VCE_AUDIO_ID_FFV, g_current_audio_type, strlen(VCE_AUDIO_ID_FFV))) { + SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] FFV"); + if (NULL != g_current_audio_type && + (!strncmp(g_current_audio_type, VCE_AUDIO_ID_BLUETOOTH, sizeof(VCE_AUDIO_ID_BLUETOOTH)) || + !strncmp(g_current_audio_type, VCE_AUDIO_ID_FFV, sizeof(VCE_AUDIO_ID_FFV)) || + !strncmp(g_current_audio_type, VCE_AUDIO_ID_WIFI, sizeof(VCE_AUDIO_ID_WIFI)))) { + SLOG(LOG_DEBUG, TAG_VCD, "[DEBUG] Recorder reset to NONE"); + vcd_recorder_set(VCE_AUDIO_ID_NONE, g_audio_type, g_audio_rate, g_audio_channel); + } + stoped = true; + } else if (0 == strncmp(VCE_AUDIO_ID_WIFI, g_current_audio_type, strlen(VCE_AUDIO_ID_WIFI))) { #ifdef TV_MSF_WIFI_MODE UnRegisterMSFAudioCallback(); -- 2.7.4