#define STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_DEVICES "SetStreamRouteDevices"
#define STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_OPTION "SetStreamRouteOption"
#define STREAM_MANAGER_METHOD_NAME_SET_STREAM_PREFERRED_DEVICE "SetStreamPreferredDevice"
+#define STREAM_MANAGER_METHOD_NAME_GET_STREAM_PREFERRED_DEVICE "GetStreamPreferredDevice"
#define STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL "SetVolumeLevel"
#define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL "GetVolumeLevel"
#define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MAX_LEVEL "GetVolumeMaxLevel"
METHOD_HANDLER_SET_STREAM_ROUTE_DEVICES,
METHOD_HANDLER_SET_STREAM_ROUTE_OPTION,
METHOD_HANDLER_SET_STREAM_PREFERRED_DEVICE,
+ METHOD_HANDLER_GET_STREAM_PREFERRED_DEVICE,
METHOD_HANDLER_SET_VOLUME_LEVEL,
METHOD_HANDLER_GET_VOLUME_LEVEL,
METHOD_HANDLER_GET_VOLUME_MAX_LEVEL,
" <arg name=\"device_id\" direction=\"in\" type=\"u\"/>" \
" <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>" \
" </method>" \
+ " <method name=\"STREAM_MANAGER_METHOD_NAME_GET_STREAM_PREFERRED_DEVICE\">" \
+ " <arg name=\"parent_id\" direction=\"in\" type=\"u\"/>" \
+ " <arg name=\"in_device_id\" direction=\"out\" type=\"u\"/>" \
+ " <arg name=\"out_device_id\" direction=\"out\" type=\"u\"/>" \
+ " <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>" \
+ " </method>" \
" <method name=\"STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL\">" \
" <arg name=\"io_direction\" direction=\"in\" type=\"s\"/>" \
" <arg name=\"type\" direction=\"in\" type=\"s\"/>" \
static void handle_set_stream_route_devices(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void handle_set_stream_route_option(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void handle_set_stream_preferred_device(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_stream_preferred_device(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void handle_set_volume_level(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void handle_get_volume_level(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void handle_get_volume_max_level(DBusConnection *conn, DBusMessage *msg, void *userdata);
{ "io_direction", "s", "in" },
{ "device_id", "u", "in" },
{ "ret_msg", "s", "out" } };
+static pa_dbus_arg_info get_stream_preferred_device_args[] = { { "parent_id", "u", "in" },
+ { "in_device_id", "u", "out" },
+ { "out_device_id", "u", "out" },
+ { "ret_msg", "s", "out" } };
static pa_dbus_arg_info set_volume_level_args[] = { { "io_direction", "s", "in" },
{ "type", "s", "in" },
{ "level", "u", "in" },
"uauau", /* METHOD_HANDLER_SET_STREAM_ROUTE_DEVICES */
"usi", /* METHOD_HANDLER_SET_STREAM_ROUTE_OPTION */
"usu", /* METHOD_HANDLER_SET_STREAM_PREFERRED_DEVICE */
+ "u", /* METHOD_HANDLER_GET_STREAM_PREFERRED_DEVICE */
"ssu", /* METHOD_HANDLER_SET_VOLUME_LEVEL */
"ss", /* METHOD_HANDLER_GET_VOLUME_LEVEL */
"ss", /* METHOD_HANDLER_GET_VOLUME_MAX_LEVEL */
.arguments = set_stream_preferred_device_args,
.n_arguments = sizeof(set_stream_preferred_device_args) / sizeof(pa_dbus_arg_info),
.receive_cb = handle_set_stream_preferred_device },
+ [METHOD_HANDLER_GET_STREAM_PREFERRED_DEVICE] = {
+ .method_name = STREAM_MANAGER_METHOD_NAME_GET_STREAM_PREFERRED_DEVICE,
+ .arguments = get_stream_preferred_device_args,
+ .n_arguments = sizeof(get_stream_preferred_device_args) / sizeof(pa_dbus_arg_info),
+ .receive_cb = handle_get_stream_preferred_device },
[METHOD_HANDLER_SET_VOLUME_LEVEL] = {
.method_name = STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL,
.arguments = set_volume_level_args,
/* get default role of the device */
device_role = pa_tz_device_get_role(device, NULL);
- sp->preferred_device.roles[direction] = pa_safe_streq(device_role, DEVICE_ROLE_NORMAL) ? NULL : device_role;
- sp->preferred_device.types[direction] = sp->preferred_device.roles[direction] ? device->type : NULL;
+ if (device_id == 0) {
+ sp->preferred_device.types[direction] = NULL;
+ sp->preferred_device.roles[direction] = NULL;
+ } else {
+ sp->preferred_device.types[direction] = device->type;
+ sp->preferred_device.roles[direction] = device_role;
+ }
pa_log_info("preferred device role is set to [%s] of device type[%s], direction[%s]",
sp->preferred_device.roles[direction], device->type, direction == STREAM_DIRECTION_OUT ? "out" : "in");
stream_index = (direction == STREAM_DIRECTION_OUT) ?
PA_SINK_INPUT(stream)->index : PA_SOURCE_OUTPUT(stream)->index;
- if (pa_safe_streq(device_role, DEVICE_ROLE_NORMAL))
+ if (device_id == 0)
pa_proplist_unset(props, PA_PROP_MEDIA_ROUTE_AUTO_PREFERRED_DEVICE_ROLE);
else
pa_proplist_sets(props, PA_PROP_MEDIA_ROUTE_AUTO_PREFERRED_DEVICE_ROLE, device_role);
dbus_message_unref(reply);
}
+static void handle_get_stream_preferred_device(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+ stream_parent *sp = NULL;
+ uint32_t sp_id = 0;
+ uint32_t in_device_id = 0;
+ uint32_t out_device_id = 0;
+ const char *pref_in_type, *pref_out_type;
+ const char *pref_in_role, *pref_out_role;
+ pa_idxset *dm_device_list;
+ pa_tz_device *dm_device;
+ dm_device_direction_t dm_direction;
+ uint32_t idx = 0;
+ ret_msg_t ret = RET_MSG_OK;
+ 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_UINT32, &sp_id,
+ DBUS_TYPE_INVALID));
+ pa_log_info("stream parent id[%u]", sp_id);
+
+ pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+ if (!(sp = pa_hashmap_get(m->stream_parents, (const void*)sp_id))) {
+ pa_log_error("could not find matching client for this parent_id[%u]", sp_id);
+ ret = RET_MSG_ERROR_INTERNAL;
+ goto finish;
+ }
+
+ pref_in_type = sp->preferred_device.types[STREAM_DIRECTION_IN];
+ pref_in_role = sp->preferred_device.roles[STREAM_DIRECTION_IN];
+ pref_out_type = sp->preferred_device.types[STREAM_DIRECTION_OUT];
+ pref_out_role = sp->preferred_device.roles[STREAM_DIRECTION_OUT];
+
+ /* get device ids of preferred in/out device respectively */
+ dm_device_list = pa_device_manager_get_device_list(m->dm);
+ PA_IDXSET_FOREACH(dm_device, dm_device_list, idx) {
+ dm_direction = pa_tz_device_get_direction(dm_device);
+ if (!in_device_id && dm_direction & DM_DEVICE_DIRECTION_IN) {
+ if (pa_safe_streq(pref_in_type, pa_tz_device_get_type(dm_device))) {
+ if (pa_safe_streq(pref_in_role, pa_tz_device_get_role(dm_device, pref_in_role)))
+ in_device_id = pa_tz_device_get_id(dm_device);
+ }
+ }
+ if (!out_device_id && dm_direction & DM_DEVICE_DIRECTION_OUT) {
+ if (pa_safe_streq(pref_out_type, pa_tz_device_get_type(dm_device))) {
+ if (pa_safe_streq(pref_out_role, pa_tz_device_get_role(dm_device, pref_out_role)))
+ out_device_id = pa_tz_device_get_id(dm_device);
+ }
+ }
+ }
+
+ pa_log_info("preferred IN device: type[%s] role[%s] id[%u]", pref_in_type, pref_in_role, in_device_id);
+ pa_log_info("preferred OUT device: type[%s] role[%s] id[%u]", pref_out_type, pref_out_role, out_device_id);
+
+finish:
+ pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, &in_device_id, DBUS_TYPE_INVALID));
+ pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, &out_device_id, DBUS_TYPE_INVALID));
+ pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[ret], DBUS_TYPE_INVALID));
+ pa_assert_se(dbus_connection_send(conn, reply, NULL));
+ dbus_message_unref(reply);
+}
+
static void handle_set_volume_level(DBusConnection *conn, DBusMessage *msg, void *userdata) {
const char *direction = NULL;
const char *type = NULL;