stream-manager-dbus: Add new DBus methods to set/get volume rate 36/203336/2
authorSangchul Lee <sc11.lee@samsung.com>
Fri, 5 Apr 2019 05:18:05 +0000 (14:18 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Fri, 12 Apr 2019 02:49:43 +0000 (11:49 +0900)
  server          : org.pulseaudio.Server
  object path     : /org/pulseaudio/StreamManager
  interface       : org.pulseaudio.StreamManager

  method name     : SetVolumeRate
  method argument : string for direction ('in' or 'out')
                    unsigned int for stream index
                    double for rate (0.0 ~ 1.0)
  return value    : string for return message
                    - success          : "STREAM_MANAGER_RETURN_OK"
                    - no match found   : "STREAM_MANAGER_RETURN_ERROR_NO_STREAM"
                    - internal error   : "STREAM_MANAGER_RETURN_ERROR_INTERNAL"

  method name     : GetVolumeRate
  method argument : string for direction ('in' or 'out')
                    unsigned int for stream index
  return value    : double for rate (0.0 ~ 1.0)
                    string for return message
                    - success          : "STREAM_MANAGER_RETURN_OK"
                    - no match found   : "STREAM_MANAGER_RETURN_ERROR_NO_STREAM"

[Version] 11.1.40
[Issue type] New feature

Change-Id: I8a5b3ce87af5851c208df3a4ffa39ab6c8949a09
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
packaging/pulseaudio-modules-tizen.spec
src/stream-manager-dbus-priv.h
src/stream-manager-dbus.c
src/stream-manager-volume-priv.h
src/stream-manager-volume.c

index c44a3b8..5a975f2 100644 (file)
@@ -1,6 +1,6 @@
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          11.1.39
+Version:          11.1.40
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index d464a36..45eb105 100644 (file)
@@ -35,6 +35,8 @@
 #define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MAX_LEVEL              "GetVolumeMaxLevel"
 #define STREAM_MANAGER_METHOD_NAME_SET_VOLUME_MUTE                   "SetVolumeMute"
 #define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MUTE                   "GetVolumeMute"
+#define STREAM_MANAGER_METHOD_NAME_SET_VOLUME_RATE                   "SetVolumeRate"
+#define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_RATE                   "GetVolumeRate"
 #define STREAM_MANAGER_METHOD_NAME_GET_CURRENT_VOLUME_TYPE           "GetCurrentVolumeType" /* The type that belongs to the stream of the current max priority */
 #define STREAM_MANAGER_METHOD_NAME_GET_CURRENT_MEDIA_ROUTING_PATH    "GetCurrentMediaRoutingPath"
 #define STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS               "UpdateFocusStatus"
@@ -60,6 +62,8 @@ enum method_handler_index {
     METHOD_HANDLER_GET_VOLUME_MAX_LEVEL,
     METHOD_HANDLER_SET_VOLUME_MUTE,
     METHOD_HANDLER_GET_VOLUME_MUTE,
+    METHOD_HANDLER_SET_VOLUME_RATE,
+    METHOD_HANDLER_GET_VOLUME_RATE,
     METHOD_HANDLER_GET_CURRENT_VOLUME_TYPE,
     METHOD_HANDLER_GET_CURRENT_MEDIA_ROUTING_PATH,
     METHOD_HANDLER_UPDATE_FOCUS_STATUS,
@@ -148,6 +152,18 @@ pa_dbus_interface_info stream_manager_interface_info = {
     "   <arg name=\"on\" direction=\"out\" type=\"u\"/>"                     \
     "   <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>"                \
     "  </method>"                                                            \
+    "  <method name=\"STREAM_MANAGER_METHOD_NAME_SET_VOLUME_RATE\">"         \
+    "   <arg name=\"io_direction\" direction=\"in\" type=\"s\"/>"            \
+    "   <arg name=\"idx\" direction=\"in\" type=\"u\"/>"                     \
+    "   <arg name=\"rate\" direction=\"in\" type=\"d\"/>"                    \
+    "   <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>"                \
+    "  </method>"                                                            \
+    "  <method name=\"STREAM_MANAGER_METHOD_NAME_GET_VOLUME_RATE\">"         \
+    "   <arg name=\"io_direction\" direction=\"in\" type=\"s\"/>"            \
+    "   <arg name=\"idx\" direction=\"in\" type=\"u\"/>"                     \
+    "   <arg name=\"rate\" direction=\"out\" type=\"d\"/>"                   \
+    "   <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>"                \
+    "  </method>"                                                            \
     "  <method name=\"STREAM_MANAGER_METHOD_NAME_GET_CURRENT_VOLUME_TYPE\">" \
     "   <arg name=\"io_direction\" direction=\"in\" type=\"s\"/>"            \
     "   <arg name=\"type\" direction=\"out\" type=\"s\"/>"                   \
index ea8eece..6256280 100644 (file)
@@ -50,6 +50,8 @@ static void handle_get_volume_level(DBusConnection *conn, DBusMessage *msg, void
 static void handle_get_volume_max_level(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_set_volume_mute(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_volume_mute(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_volume_rate(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_volume_rate(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_current_volume_type(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_current_media_routing_path(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_update_focus_status(DBusConnection *conn, DBusMessage *msg, void *userdata);
@@ -100,6 +102,14 @@ static pa_dbus_arg_info get_volume_mute_args[]  = { { "io_direction", "s", "in"
                                                             { "type", "s", "in" },
                                                              { "on", "u", "out" },
                                                       { "ret_msg", "s", "out" } };
+static pa_dbus_arg_info set_volume_rate_args[]  = { { "io_direction", "s", "in" },
+                                                             { "idx", "u", "in" },
+                                                            { "rate", "d", "in" },
+                                                      { "ret_msg", "s", "out" } };
+static pa_dbus_arg_info get_volume_rate_args[]  = { { "io_direction", "s", "in" },
+                                                             { "idx", "u", "in" },
+                                                           { "rate", "d", "out" },
+                                                      { "ret_msg", "s", "out" } };
 static pa_dbus_arg_info get_current_volume_type_args[]  = { { "io_direction", "s", "in" },
                                                                    { "type", "s", "out" },
                                                               { "ret_msg", "s", "out" } };
@@ -133,10 +143,10 @@ static pa_dbus_arg_info check_stream_exist_by_pid_args[]  = { { "pid", "u", "in"
                                                      { "io_direction", "s", "in" },
                                                        { "ret_msg", "s", "out" } };
 static pa_dbus_arg_info get_pid_of_latest_stream_args[]  = { { "io_direction", "s", "in" },
-                                                   { "stream_types", "as", "in" },
-                                                             { "pid", "u", "out" },
-                                                       { "ret_msg", "s", "out" } };
-static const char* signature_args_for_in[] = { "s", "", "uauau", "usi", "ssu", "ss", "ss", "ssu", "ss", "s", "s", "uu", "iu", "su", "s", "ssss", "s", "sss", "uss","sas"};
+                                                            { "stream_types", "as", "in" },
+                                                                     { "pid", "u", "out" },
+                                                               { "ret_msg", "s", "out" } };
+static const char* signature_args_for_in[] = { "s", "", "uauau", "usi", "ssu", "ss", "ss", "ssu", "ss", "sud", "su", "s", "s", "uu", "iu", "su", "s", "ssss", "s", "sss", "uss","sas"};
 
 static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
     [METHOD_HANDLER_GET_STREAM_INFO] = {
@@ -184,6 +194,16 @@ static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
         .arguments = get_volume_mute_args,
         .n_arguments = sizeof(get_volume_mute_args) / sizeof(pa_dbus_arg_info),
         .receive_cb = handle_get_volume_mute },
+    [METHOD_HANDLER_SET_VOLUME_RATE] = {
+        .method_name = STREAM_MANAGER_METHOD_NAME_SET_VOLUME_RATE,
+        .arguments = set_volume_rate_args,
+        .n_arguments = sizeof(set_volume_rate_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_set_volume_rate },
+    [METHOD_HANDLER_GET_VOLUME_RATE] = {
+        .method_name = STREAM_MANAGER_METHOD_NAME_GET_VOLUME_RATE,
+        .arguments = get_volume_rate_args,
+        .n_arguments = sizeof(get_volume_rate_args) / sizeof(pa_dbus_arg_info),
+        .receive_cb = handle_get_volume_rate },
     [METHOD_HANDLER_GET_CURRENT_VOLUME_TYPE] = {
         .method_name = STREAM_MANAGER_METHOD_NAME_GET_CURRENT_VOLUME_TYPE,
         .arguments = get_current_volume_type_args,
@@ -782,6 +802,106 @@ fail:
     dbus_message_unref(reply);
 }
 
+static void handle_set_volume_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    const char *direction = NULL;
+    uint32_t idx;
+    double rate;
+    stream_type_t stream_type = STREAM_SINK_INPUT;
+    DBusMessage *reply = NULL;
+    pa_stream_manager *m = (pa_stream_manager*)userdata;
+    int ret = 0;
+    ret_msg_t ret_msg = RET_MSG_ERROR_INTERNAL;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL,
+                                       DBUS_TYPE_STRING, &direction,
+                                       DBUS_TYPE_UINT32, &idx,
+                                       DBUS_TYPE_DOUBLE, &rate,
+                                       DBUS_TYPE_INVALID));
+    pa_log_info("direction[%s], idx[%u], rate[%f]", direction, idx, rate);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    if (pa_safe_streq(direction, "in"))
+        stream_type = STREAM_SOURCE_OUTPUT;
+    else if (pa_safe_streq(direction, "out"))
+        stream_type = STREAM_SINK_INPUT;
+    else {
+        pa_log_error("invalid direction[%s]", direction);
+        goto invalid_argument;
+    }
+
+    /* Check the rate range (0.0 ~ 1.0) */
+    if (rate < 0 || rate > 1) {
+        pa_log_error("invalid range, rate[%f]", rate);
+        goto invalid_argument;
+    }
+
+    if ((ret = set_volume_rate_by_idx(m, stream_type, idx, rate))) {
+        if (ret == -2)
+            ret_msg = RET_MSG_ERROR_NO_STREAM;
+        pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[ret_msg], DBUS_TYPE_INVALID));
+    } else {
+        pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_OK], DBUS_TYPE_INVALID));
+    }
+
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+    return;
+
+invalid_argument:
+    pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_ERROR_INVALID_ARGUMENT],
+                     DBUS_TYPE_INVALID));
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
+static void handle_get_volume_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    const char *direction = NULL;
+    uint32_t idx = 0;
+    double rate;
+    stream_type_t stream_type = STREAM_SINK_INPUT;
+    DBusMessage *reply = NULL;
+    pa_stream_manager *m = (pa_stream_manager*)userdata;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(m);
+
+    pa_assert_se(dbus_message_get_args(msg, NULL,
+                                       DBUS_TYPE_STRING, &direction,
+                                       DBUS_TYPE_UINT32, &idx,
+                                       DBUS_TYPE_INVALID));
+    pa_log_info("direction[%s], idx[%u]", direction, idx);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    if (pa_safe_streq(direction, "in"))
+        stream_type = STREAM_SOURCE_OUTPUT;
+    else if (pa_safe_streq(direction, "out"))
+        stream_type = STREAM_SINK_INPUT;
+    else {
+        pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_DOUBLE, 0, DBUS_TYPE_INVALID));
+        pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_ERROR_INVALID_ARGUMENT], DBUS_TYPE_INVALID));
+        goto finish;
+    }
+
+    if (get_volume_rate_by_idx(m, stream_type, idx, &rate)) {
+        pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_DOUBLE, &rate, DBUS_TYPE_INVALID));
+        pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_ERROR_NO_STREAM], DBUS_TYPE_INVALID));
+    } else {
+        pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_DOUBLE, &rate, DBUS_TYPE_INVALID));
+        pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_OK], DBUS_TYPE_INVALID));
+    }
+
+finish:
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
 static void handle_get_current_volume_type(DBusConnection *conn, DBusMessage *msg, void *userdata) {
     const char *direction = NULL;
     const char *type = NULL;
index 097d5e5..8d4ab47 100644 (file)
@@ -43,6 +43,8 @@ int32_t set_volume_level_by_type(pa_stream_manager *m, stream_type_t stream_type
 int32_t get_volume_level_by_type(pa_stream_manager *m, pa_volume_get_command_t command, stream_type_t stream_type, const char *volume_type, uint32_t *volume_level);
 int32_t set_volume_level_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t idx, uint32_t volume_level);
 int32_t set_volume_level_with_new_data(pa_stream_manager *m, void *stream, stream_type_t stream_type, uint32_t volume_level);
+int32_t set_volume_rate_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t idx, double rate);
+int32_t get_volume_rate_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t idx, double *rate);
 int32_t set_volume_mute_by_type(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, bool volume_mute);
 int32_t get_volume_mute_by_type(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, bool *volume_mute);
 int32_t set_volume_mute_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t stream_idx, bool volume_mute);
index bbb7c90..c5b475e 100644 (file)
@@ -571,6 +571,96 @@ int32_t set_volume_level_with_new_data(pa_stream_manager *m, void *stream, strea
     return 0;
 }
 
+int32_t set_volume_rate_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t idx, double rate) {
+    bool is_hal_volume = false;
+    void *s = NULL;
+    void *volumes = NULL;
+    volume_info *v = NULL;
+    uint32_t volume_level;
+    pa_cvolume cv;
+    double volume_linear = 1.0;
+    double *modifier_gain_value = NULL;
+    const char *volume_type_str = NULL;
+    const char *modifier_gain = NULL;
+
+    pa_assert(m);
+
+    if (!(s = pa_idxset_get_by_index(stream_type == STREAM_SINK_INPUT ? m->core->sink_inputs : m->core->source_outputs, idx))) {
+        pa_log_error("failed to get stream...[%u]", idx);
+        return -2;
+    }
+
+    if (!(volume_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) {
+        pa_log_debug("idx[%u] doesn't have volume type", idx);
+        return -1;
+    }
+
+    /* Check if it is related to HAL volume */
+    if (is_hal_volume_by_type(m, volume_type_str, &is_hal_volume)) {
+        pa_log_error("failed to is_hal_volume_by_type(), volume_type[%s]", volume_type_str);
+        return -1;
+     }
+
+    /* Get current level of this volume type */
+    volumes = m->volume_infos;
+    if (!(v = pa_hashmap_get(volumes, volume_type_str))) {
+        pa_log_error("could not get volume_info, stream_type[%d], volume_type[%s]", stream_type, volume_type_str);
+        return -1;
+    }
+    volume_level = v->values[stream_type].current_level;
+
+    /* Get volume value */
+    if (get_volume_value(m, stream_type, is_hal_volume, volume_type_str, volume_level, &volume_linear))
+        return -1;
+
+    /* Get modifier for gain */
+    modifier_gain = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_GAIN_TYPE);
+    if (modifier_gain) {
+        if ((modifier_gain_value = pa_hashmap_get(m->volume_modifiers, modifier_gain))) {
+            volume_linear *= (*modifier_gain_value);
+            pa_log_info("apply the modifier for the gain value[%s=>%f], result volume_linear[%f]",
+                        modifier_gain, *modifier_gain_value, volume_linear);
+        }
+    }
+
+    if (stream_type == STREAM_SINK_INPUT)
+        ((pa_sink_input*)s)->individual_volume_ratio = rate;
+    else
+        ((pa_source_output*)s)->individual_volume_ratio = rate;
+    apply_individual_ratio(m, s, volume_linear, &cv);
+
+    if (stream_type == STREAM_SINK_INPUT)
+        pa_sink_input_set_volume((pa_sink_input*)s, &cv, true, true);
+    else if (stream_type == STREAM_SOURCE_OUTPUT)
+        pa_source_output_set_volume((pa_source_output*)s, &cv, true, true);
+
+    pa_log_debug("stream_type[%d], idx[%u]=>volume_type[%s], level[%u], rate[%f], value[%f]",
+                 stream_type, idx, volume_type_str, volume_level, rate, volume_linear);
+
+    return 0;
+}
+
+int32_t get_volume_rate_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t idx, double *rate) {
+    void *s = NULL;
+
+    pa_assert(m);
+    pa_assert(rate);
+
+    if (!(s = pa_idxset_get_by_index(stream_type == STREAM_SINK_INPUT ? m->core->sink_inputs : m->core->source_outputs, idx))) {
+        pa_log_error("failed to get stream...[%u]", idx);
+        return -1;
+    }
+
+    if (stream_type == STREAM_SINK_INPUT)
+        *rate = ((pa_sink_input*)s)->individual_volume_ratio;
+    else
+        *rate = ((pa_source_output*)s)->individual_volume_ratio;
+
+    pa_log_info("individual ratio of stream[idx:%u] is [%f]", idx, *rate);
+
+    return 0;
+}
+
 int32_t set_volume_mute_by_type(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, bool volume_mute) {
     bool is_hal_volume = false;
     volume_info *v = NULL;