From 14eb3b4d4d85cb8d9b7502eeddd38ff9323fcdb5 Mon Sep 17 00:00:00 2001 From: Wonnam Jang Date: Mon, 1 Oct 2018 19:23:52 +0900 Subject: [PATCH] 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