Add get error message and apply sound stream 59/90959/1
authorKwangyoun Kim <ky85.kim@samsung.com>
Wed, 5 Oct 2016 07:10:39 +0000 (16:10 +0900)
committerKwangyoun Kim <ky85.kim@samsung.com>
Wed, 5 Oct 2016 07:11:11 +0000 (16:11 +0900)
Change-Id: I0e1161c997444fe66656ed2fc4f84ecabfb5e893

client/vc_mgr.c
client/vc_mgr_client.c
client/vc_mgr_client.h
include/voice_control_manager.h
server/vcd_recorder.c

index 603e112..0469551 100644 (file)
@@ -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;
index 90d5b9e..4f01521 100644 (file)
@@ -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);
index 15cd295..51088c5 100644 (file)
@@ -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);
index bdef272..abcd864 100644 (file)
@@ -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
index 764a7a4..bcda93e 100644 (file)
@@ -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;
 }