From: Kwangyoun Kim Date: Wed, 5 Oct 2016 07:10:39 +0000 (+0900) Subject: Add get error message and apply sound stream X-Git-Tag: accepted/tizen/3.0/ivi/20161028.151315~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=aca9db44d7920db763fe552444849cd4c8b99c8f;p=platform%2Fcore%2Fuifw%2Fvoice-control.git Add get error message and apply sound stream Change-Id: I0e1161c997444fe66656ed2fc4f84ecabfb5e893 --- diff --git a/client/vc_mgr.c b/client/vc_mgr.c index 603e112..0469551 100644 --- a/client/vc_mgr.c +++ b/client/vc_mgr.c @@ -47,6 +47,8 @@ static int g_daemon_pid = 0; static int g_feature_enabled = -1; +static bool g_err_callback_status = false; + static Eina_Bool __vc_mgr_notify_state_changed(void *data); static Eina_Bool __vc_mgr_notify_error(void *data); static Eina_Bool __vc_mgr_notify_result(void *data); @@ -2176,6 +2178,32 @@ int vc_mgr_unset_pre_result_cb() return 0; } +int vc_mgr_get_error_message(char** err_msg) +{ + SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Get error message"); + + if (NULL == err_msg) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] invalid parameter"); + return VC_ERROR_INVALID_PARAMETER; + } + + if (false == g_err_callback_status) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Not in error callback"); + return VC_ERROR_OPERATION_FAILED; + } + + int ret; + ret = vc_mgr_client_get_error_message(g_vc_m, err_msg); + if (0 != ret) { + SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get error message"); + } + + SLOG(LOG_DEBUG, TAG_VCM, "====="); + SLOG(LOG_DEBUG, TAG_VCM, " "); + + return ret; +} + static Eina_Bool __vc_mgr_notify_error(void *data) { vc_h vc_m = (vc_h)data; @@ -2189,7 +2217,9 @@ static Eina_Bool __vc_mgr_notify_error(void *data) if (NULL != callback) { vc_mgr_client_use_callback(vc_m); + g_err_callback_status = true; callback(reason, user_data); + g_err_callback_status = false; vc_mgr_client_not_use_callback(vc_m); SLOG(LOG_DEBUG, TAG_VCM, "Error callback is called"); } else { @@ -2227,6 +2257,7 @@ int __vc_mgr_cb_error(int reason, int daemon_pid, char* msg) SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Error reason(%d), msg(%s)", reason, msg); vc_mgr_client_set_error(g_vc_m, reason); + vc_mgr_client_set_error_message(g_vc_m, msg); __vc_mgr_notify_error(g_vc_m); return 0; diff --git a/client/vc_mgr_client.c b/client/vc_mgr_client.c index 90d5b9e..4f01521 100644 --- a/client/vc_mgr_client.c +++ b/client/vc_mgr_client.c @@ -77,6 +77,7 @@ typedef struct { /* error data */ int reason; + char* err_msg; /* Authorized */ GSList* authorized_client_list; @@ -184,6 +185,7 @@ int vc_mgr_client_create(vc_h* vc) client->recognition_mode = VC_RECOGNITION_MODE_STOP_BY_SILENCE; client->reason = 0; + client->err_msg = NULL; client->cb_ref_count = 0; @@ -232,6 +234,10 @@ int vc_mgr_client_destroy(vc_h vc) free(data->all_result_text); } + if (NULL != data->err_msg) { + free(data->err_msg); + } + free(data); free(vc); @@ -685,6 +691,41 @@ int vc_mgr_client_get_error(vc_h vc, int* reason) return 0; } +int vc_mgr_client_set_error_message(vc_h vc, const char* err_msg) +{ + vc_mgr_client_s* client = __mgr_client_get(vc); + + /* check handle */ + if (NULL == client) + return VC_ERROR_INVALID_PARAMETER; + + if (NULL != client->err_msg) { + free(client->err_msg); + client->err_msg = NULL; + } + + if (NULL != err_msg) { + client->err_msg = strdup(err_msg); + } + + return 0; +} + +int vc_mgr_client_get_error_message(vc_h vc, char** err_msg) +{ + vc_mgr_client_s* client = __mgr_client_get(vc); + + /* check handle */ + if (NULL == client) + return VC_ERROR_INVALID_PARAMETER; + + if (NULL != client->err_msg) { + *err_msg = strdup(client->err_msg); + } + + return 0; +} + int vc_mgr_client_set_exclusive_command(vc_h vc, bool value) { vc_mgr_client_s* client = __mgr_client_get(vc); diff --git a/client/vc_mgr_client.h b/client/vc_mgr_client.h index 15cd295..51088c5 100644 --- a/client/vc_mgr_client.h +++ b/client/vc_mgr_client.h @@ -99,6 +99,10 @@ int vc_mgr_client_set_error(vc_h vc, int reason); int vc_mgr_client_get_error(vc_h vc, int* reason); +int vc_mgr_client_set_error_message(vc_h vc, const char* err_msg); + +int vc_mgr_client_get_error_message(vc_h vc, char** err_msg); + int vc_mgr_client_set_exclusive_command(vc_h vc, bool value); bool vc_mgr_client_get_exclusive_command(vc_h vc); diff --git a/include/voice_control_manager.h b/include/voice_control_manager.h index bdef272..abcd864 100644 --- a/include/voice_control_manager.h +++ b/include/voice_control_manager.h @@ -902,6 +902,24 @@ int vc_mgr_set_current_language_changed_cb(vc_current_language_changed_cb callba int vc_mgr_unset_current_language_changed_cb(); /** +* @brief Gets the current error message. +* +* @remarks This function should be called during as stt error callback. If not, the error as operation failure will be returned. \n +* If the function succeeds, @a err_msg must be released using free() when it is no longer required. +* +* @param[out] err_msg The current error message +* +* @return 0 on success, otherwise a negative error value +* @retval #VC_ERROR_NONE Successful +* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #VC_ERROR_INVALID_STATE Invalid state +* @retval $VC_ERROR_OPERATION_FAILED Operation failure +* +* @see vc_error_cb() +*/ +int vc_mgr_get_error_message(char** err_msg); + +/** * @brief Registers a callback function to be called when an error occurred. * * @param[in] callback Callback function to register diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c index 764a7a4..bcda93e 100644 --- a/server/vcd_recorder.c +++ b/server/vcd_recorder.c @@ -50,6 +50,8 @@ static vcd_recorder_interrupt_cb g_interrupt_cb = NULL; static audio_in_h g_audio_h; +static sound_stream_info_h g_stream_info_h; + static vcp_audio_type_e g_audio_type; static unsigned int g_audio_rate; @@ -192,6 +194,51 @@ static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void #endif +static const char* __get_focus_changed_reason_code(sound_stream_focus_change_reason_e reason) +{ + switch (reason) { + case SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA: return "SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA"; + case SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM: return "SOUND_STREAM_FOCUS_CHANGED_BY_SYSTEM"; + case SOUND_STREAM_FOCUS_CHANGED_BY_ALARM: return "SOUND_STREAM_FOCUS_CHANGED_BY_ALARM"; + case SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION: return "SOUND_STREAM_FOCUS_CHANGED_BY_NOTIFICATION"; + case SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY: return "SOUND_STREAM_FOCUS_CHANGED_BY_EMERGENCY"; + case SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION: return "SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_INFORMATION"; + case SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_RECOGNITION: return "SOUND_STREAM_FOCUS_CHANGED_BY_VOICE_RECOGNITION"; + case SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE: return "SOUND_STREAM_FOCUS_CHANGED_BY_RINGTONE"; + case SOUND_STREAM_FOCUS_CHANGED_BY_VOIP: return "SOUND_STREAM_FOCUS_CHANGED_BY_VOIP"; + case SOUND_STREAM_FOCUS_CHANGED_BY_CALL: return "SOUND_STREAM_FOCUS_CHANGED_BY_CALL"; + case SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY: return "SOUND_STREAM_FOCUS_CHANGED_BY_MEDIA_EXTERNAL_ONLY"; + default: return "Undefined reason code"; + } +} + +static void __recorder_focus_state_cb(sound_stream_info_h stream_info, sound_stream_focus_change_reason_e reason, const char *extra_info, void *user_data) +{ + SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Focus state changed cb"); + + if (stream_info != g_stream_info_h) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid stream info handle"); + return; + } + + int ret; + sound_stream_focus_state_e state_for_recording; + ret = sound_manager_get_focus_state(g_stream_info_h, NULL, &state_for_recording); + if (SOUND_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to get focus state"); + return; + } + + SLOG(LOG_WARN, TAG_VCD, "[Recorder] focus state chagned to (%d) with reason (%s)", (int)state_for_recording, __get_focus_changed_reason_code(reason)); + + if (VCD_RECORDER_STATE_RECORDING == g_recorder_state && SOUND_STREAM_FOCUS_STATE_RELEASED == state_for_recording) { + SLOG(LOG_WARN, TAG_VCD, "[Recorder] Focus released as interrupt"); + if (NULL != g_interrupt_cb) { + g_interrupt_cb(); + } + } +} + int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb interrupt_cb) { if (NULL == audio_cb || NULL == interrupt_cb) { @@ -240,6 +287,10 @@ int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb g_is_valid_audio_in = false; } + if (0 != sound_manager_create_stream_information(SOUND_STREAM_TYPE_VOICE_RECOGNITION, __recorder_focus_state_cb, NULL, &g_stream_info_h)) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create stream info"); + } + g_audio_cb = audio_cb; g_interrupt_cb = interrupt_cb; g_recorder_state = VCD_RECORDER_STATE_READY; @@ -298,6 +349,10 @@ int vcd_recorder_destroy() g_recorder_state = VCD_RECORDER_STATE_READY; } + if (0 != sound_manager_destroy_stream_information(g_stream_info_h)) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to destroy stream info"); + } + audio_in_destroy(g_audio_h); #ifdef TV_BT_MODE @@ -568,6 +623,16 @@ int vcd_recorder_start() SLOG(LOG_ERROR, TAG_VCD, "[Recorder] started = %d", started); if (false == started) { + ret = sound_manager_acquire_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL); + if (SOUND_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to acquire focus : %d", ret); + } else { + ret = audio_in_set_stream_info(g_audio_h, g_stream_info_h); + if (AUDIO_IO_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set stream info : %d", ret); + } + } + ret = audio_in_prepare(g_audio_h); if (AUDIO_IO_ERROR_NONE != ret) { if (AUDIO_IO_ERROR_SOUND_POLICY == ret) { @@ -654,6 +719,11 @@ int vcd_recorder_stop() SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop audio : %d", ret); return VCD_ERROR_OPERATION_FAILED; } + + ret = sound_manager_release_focus(g_stream_info_h, SOUND_STREAM_FOCUS_FOR_RECORDING, NULL); + if (SOUND_MANAGER_ERROR_NONE != ret) { + SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to release focus : %d", ret); + } } return 0; }