Add ducking state to prevent invalid operation. 91/217991/1
authorJeongmo Yang <jm80.yang@samsung.com>
Mon, 18 Nov 2019 05:28:07 +0000 (14:28 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Mon, 18 Nov 2019 09:10:13 +0000 (18:10 +0900)
- Previously, ducking command(activation or deactivation) could be sent
  although it's already sent but the operation is not completed.

[Version] 11.1.88
[Profile] Common
[Issue Type] Bug fix

Change-Id: If7c57b2bae38663ae206dd1b55343b10daa5359d
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
packaging/pulseaudio-modules-tizen.spec
src/stream-manager-dbus.c
src/stream-manager-priv.h
src/stream-manager.c

index a011caa61b3709e9a86258350fef6846356e24a3..3194b96da8332ad4653252b97c06508bfa8ef1c8 100644 (file)
@@ -1,6 +1,6 @@
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          11.1.87
+Version:          11.1.88
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index 972c6d6f3c5944d6bed7cb123c6c52198011358a..816afab03417fc8d28b52c1f5b442e542943ec08 100644 (file)
@@ -1872,6 +1872,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);
@@ -1894,12 +1895,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;
@@ -1907,8 +1912,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 */
@@ -1956,11 +1964,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;
@@ -1972,11 +1983,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));
     }
 }
 
@@ -1986,7 +2000,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);
@@ -2001,15 +2015,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);
index 9c0620fbd9c0751fef25ddeaa37700a5509b911c..2173f2e19d2f44d70555a18b29d5bb8383ef3f15 100644 (file)
@@ -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);
index 0815d10b8658740fdda22a196f9ffa883f5e05af..519c27984117da88e4d57efa86edc941d886819f 100644 (file)
@@ -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;