#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"
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,
" <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\"/>" \
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);
{ "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" } };
{ "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] = {
.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,
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;
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;