From 5352327d3cea01a0dfb5477832542e19f81488cb Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Mon, 18 Nov 2019 14:28:07 +0900 Subject: [PATCH] Add ducking state to prevent invalid operation. - Previously, ducking command(activation or deactivation) could be sent although it's already sent but the operation is not completed. [Version] 11.1.89 [Profile] Common [Issue Type] Bug fix Change-Id: If7c57b2bae38663ae206dd1b55343b10daa5359d Signed-off-by: Jeongmo Yang --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/stream-manager-dbus.c | 44 ++++++++++++++++++++++----------- src/stream-manager-priv.h | 11 ++++++++- src/stream-manager.c | 36 ++++++++++++++++++++------- 4 files changed, 67 insertions(+), 26 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 3194b96..c2b212d 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.88 +Version: 11.1.89 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/stream-manager-dbus.c b/src/stream-manager-dbus.c index a54b4e9..da1cfdc 100644 --- a/src/stream-manager-dbus.c +++ b/src/stream-manager-dbus.c @@ -1876,6 +1876,7 @@ static void handle_activate_ducking(DBusConnection *conn, DBusMessage *msg, void stream_ducking *sd = NULL; bool target_matched = false; hal_ducking_activation_info ducking_activation_info; + ret_msg_t ret_msg = RET_MSG_OK; pa_assert(conn); pa_assert(msg); @@ -1898,12 +1899,16 @@ static void handle_activate_ducking(DBusConnection *conn, DBusMessage *msg, void sd = pa_hashmap_get(m->stream_duckings, (const void*)id); if (!sd) { pa_log_error("no matched stream ducking for id[%u]", id); + ret_msg = RET_MSG_ERROR_INTERNAL; + goto _ACTIVATE_DUCKING_DONE; + } - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_ERROR_INTERNAL], DBUS_TYPE_INVALID)); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); - - return; + /* check operating now */ + if (sd->state == STREAM_DUCKING_STATE_DUCKING || + sd->state == STREAM_DUCKING_STATE_UNDUCKING) { + pa_log_error("now ducking or unducking (state:%u)", sd->state); + ret_msg = RET_MSG_ERROR_INVALID_STATE; + goto _ACTIVATE_DUCKING_DONE; } sd->duration = duration; @@ -1911,8 +1916,11 @@ static void handle_activate_ducking(DBusConnection *conn, DBusMessage *msg, void sd->set_vol = PA_VOLUME_NORM * ratio; if (enable) { + sd->state = STREAM_DUCKING_STATE_DUCKING; snprintf(sd->vol_key, VOLUME_KEY_LENGTH, "stream_ducking_%u_%s", id, target_stream); snprintf(sd->target_role, STREAM_ROLE_STR_MAX, "%s", target_stream); + } else { + sd->state = STREAM_DUCKING_STATE_UNDUCKING; } /* set volume ramp factor to target stream */ @@ -1960,11 +1968,14 @@ static void handle_activate_ducking(DBusConnection *conn, DBusMessage *msg, void pa_log_info("ducking stream count(%p,%d)", sd, sd->ducking_stream_count); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_OK], DBUS_TYPE_INVALID)); - +_ACTIVATE_DUCKING_DONE: + pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[ret_msg], DBUS_TYPE_INVALID)); pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); + if (ret_msg != RET_MSG_OK) + return; + /* notify ducking activation */ ducking_activation_info.target_role = target_stream; ducking_activation_info.duration = duration; @@ -1976,11 +1987,14 @@ static void handle_activate_ducking(DBusConnection *conn, DBusMessage *msg, void if (target_matched == false) { /* change ducking state and send signal here, because ramp_finish_cb could not be called in this case */ - sd->is_ducked = enable; + if (enable) + sd->state = STREAM_DUCKING_STATE_DUCKED; + else + sd->state = STREAM_DUCKING_STATE_UNDUCKED; - pa_log_info("send signal for ramp finished(but, no stream matched) - is_ducked(%d)", sd->is_ducked); + pa_log_info("send signal for ramp finished(but, no stream matched) - state(%u)", sd->state); - send_ducking_state_changed_signal(pa_dbus_connection_get(m->dbus_conn), sd->trigger_index, sd->is_ducked); + send_ducking_state_changed_signal(pa_dbus_connection_get(m->dbus_conn), sd->trigger_index, is_stream_ducked(sd)); } } @@ -1990,7 +2004,7 @@ static void handle_get_ducking_state(DBusConnection *conn, DBusMessage *msg, voi pa_stream_manager *m = (pa_stream_manager*)userdata; stream_ducking *sd = NULL; dbus_bool_t is_ducked = FALSE; - ret_msg_t msg_index = RET_MSG_OK; + ret_msg_t ret_msg = RET_MSG_OK; pa_assert(conn); pa_assert(msg); @@ -2005,15 +2019,15 @@ static void handle_get_ducking_state(DBusConnection *conn, DBusMessage *msg, voi /* get stream_ducking */ sd = pa_hashmap_get(m->stream_duckings, (const void *)id); if (sd) { - is_ducked = (dbus_bool_t)sd->is_ducked; - pa_log_info("id[%u], is_ducked[%p,%u]", id, sd, sd->is_ducked); + is_ducked = (dbus_bool_t)is_stream_ducked(sd); + pa_log_info("id[%u], is_ducked[%p,%d]", id, sd, is_ducked); } else { - msg_index = RET_MSG_ERROR_INTERNAL; + ret_msg = RET_MSG_ERROR_INTERNAL; pa_log_error("no matched stream ducking for id[%u]", id); } pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &is_ducked, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[msg_index], DBUS_TYPE_INVALID)); + pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[ret_msg], DBUS_TYPE_INVALID)); pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); diff --git a/src/stream-manager-priv.h b/src/stream-manager-priv.h index 9c0620f..2173f2e 100644 --- a/src/stream-manager-priv.h +++ b/src/stream-manager-priv.h @@ -43,6 +43,7 @@ typedef enum { RET_MSG_ERROR_INVALID_ARGUMENT, RET_MSG_ERROR_DEVICE_NOT_FOUND, RET_MSG_ERROR_POLICY, + RET_MSG_ERROR_INVALID_STATE } ret_msg_t; typedef enum _focus_acquired_status { @@ -84,6 +85,13 @@ typedef enum _notify_command_type { NOTIFY_COMMAND_INFORM_STREAM_DISCONNECTED, } notify_command_type_t; +typedef enum _stream_ducking_state { + STREAM_DUCKING_STATE_UNDUCKED, + STREAM_DUCKING_STATE_DUCKING, + STREAM_DUCKING_STATE_DUCKED, + STREAM_DUCKING_STATE_UNDUCKING +} stream_ducking_state_t; + #define GET_STREAM_NEW_SAMPLE_SPEC_PTR(stream, type) \ (type == STREAM_SINK_INPUT ? &(((pa_sink_input_new_data*)stream)->sample_spec) : &(((pa_source_output_new_data*)stream)->sample_spec)) @@ -195,7 +203,7 @@ typedef struct _stream_parent { } stream_parent; typedef struct _stream_ducking { - bool is_ducked; + stream_ducking_state_t state; int trigger_index; int ducking_stream_count; char vol_key[VOLUME_KEY_LENGTH]; @@ -272,6 +280,7 @@ struct _stream_manager { bool stream_is_call_family(pa_object *stream); bool is_active_device_of_stream(const void *stream, stream_type_t stream_type, const char *device_type); +bool is_stream_ducked(stream_ducking *sd); int32_t get_route_type(void *stream, stream_type_t stream_type, bool is_new_data, stream_route_type_t *stream_route_type); int32_t get_stream_info(pa_stream_manager *m, const char *stream_role, stream_info_per_type *info); int32_t get_available_streams(pa_stream_manager *m, stream_list *list); diff --git a/src/stream-manager.c b/src/stream-manager.c index 0815d10..519c279 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -549,6 +549,22 @@ bool is_active_device_of_stream(const void *stream, stream_type_t stream_type, c return false; } +bool is_stream_ducked(stream_ducking *sd) { + pa_assert(sd); + + pa_log_info("state : %u", sd->state); + + switch (sd->state) { + case STREAM_DUCKING_STATE_DUCKED: + case STREAM_DUCKING_STATE_UNDUCKING: + return true; + case STREAM_DUCKING_STATE_UNDUCKED: + case STREAM_DUCKING_STATE_DUCKING: + default: + return false; + } +} + static void set_media_active_device(pa_stream_manager *m) { pa_tz_device *playback_device, *capture_device; stream_info *media_info; @@ -2385,8 +2401,8 @@ static void remove_sink_input_from_ducking_streams(pa_stream_manager *m, pa_sink if (stream != i) continue; - if ((strlen(sd->target_role) && !sd->is_ducked) || - (!strlen(sd->target_role) && sd->is_ducked)) + if (sd->state == STREAM_DUCKING_STATE_DUCKING || + sd->state == STREAM_DUCKING_STATE_UNDUCKING) pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_RAMP_FINISH], i); pa_log_error("remove stream(idx:%u,%p) from idx_ducking_streams, trigger_index(%u)", @@ -2538,7 +2554,6 @@ static pa_hook_result_t sink_input_move_finish_cb(pa_core *core, pa_sink_input * } static pa_hook_result_t sink_input_ramp_finish_cb(pa_core *core, pa_sink_input *i, pa_stream_manager *m) { - bool is_ducked = false; stream_ducking *sd = NULL; pa_sink_input *stream = NULL; uint32_t idx; @@ -2573,19 +2588,22 @@ static pa_hook_result_t sink_input_ramp_finish_cb(pa_core *core, pa_sink_input * return PA_HOOK_OK; } - is_ducked = i->thread_info.ramp.ramps[0].start > i->thread_info.ramp.ramps[0].end; - /* Remove trigger when unducked */ - if (is_ducked == false) + if (sd->state == STREAM_DUCKING_STATE_UNDUCKING) pa_idxset_remove_by_data(sd->idx_ducking_streams, (void *)i, NULL); /* Send signal when all streams are ducked. * Note that the condition of increasing count value below is located in * handle_activate_ducking() of DBus handler. */ if (sd->ducking_stream_count > 0 && --sd->ducking_stream_count == 0) { - pa_log_info("send signal for ramp finished - is_ducked(%p,%d)", sd, is_ducked); - sd->is_ducked = is_ducked; - send_ducking_state_changed_signal(pa_dbus_connection_get(m->dbus_conn), sd->trigger_index, sd->is_ducked); + if (sd->state == STREAM_DUCKING_STATE_DUCKING) + sd->state = STREAM_DUCKING_STATE_DUCKED; + else + sd->state = STREAM_DUCKING_STATE_UNDUCKED; + + pa_log_info("send signal for ramp finished - state(%p,%d)", sd, sd->state); + + send_ducking_state_changed_signal(pa_dbus_connection_get(m->dbus_conn), sd->trigger_index, is_stream_ducked(sd)); } return PA_HOOK_OK; -- 2.7.4