#define STREAM_MANAGER_OBJECT_PATH "/org/pulseaudio/StreamManager"
#define STREAM_MANAGER_INTERFACE "org.pulseaudio.StreamManager"
/* method */
-#define STREAM_MANAGER_METHOD_NAME_GET_STREAM_INFO "GetStreamInfo"
-#define STREAM_MANAGER_METHOD_NAME_GET_STREAM_LIST "GetStreamList"
-#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_VOLUME_LEVEL "SetVolumeLevel"
-#define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL "GetVolumeLevel"
-#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_GET_CURRENT_VOLUME_TYPE "GetCurrentVolumeType" /* the type that belongs to the stream of the current max priority */
-#define STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS "UpdateFocusStatus"
-#define STREAM_MANAGER_METHOD_NAME_UPDATE_RESTRICTION "UpdateRestriction"
+#define STREAM_MANAGER_METHOD_NAME_GET_STREAM_INFO "GetStreamInfo"
+#define STREAM_MANAGER_METHOD_NAME_GET_STREAM_LIST "GetStreamList"
+#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_VOLUME_LEVEL "SetVolumeLevel"
+#define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL "GetVolumeLevel"
+#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_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"
+#define STREAM_MANAGER_METHOD_NAME_UPDATE_RESTRICTION "UpdateRestriction"
/* signal */
-#define STREAM_MANAGER_SIGNAL_NAME_VOLUME_CHANGED "VolumeChanged"
-#define STREAM_MANAGER_SIGNAL_NAME_COMMAND "Command"
+#define STREAM_MANAGER_SIGNAL_NAME_VOLUME_CHANGED "VolumeChanged"
+#define STREAM_MANAGER_SIGNAL_NAME_COMMAND "Command"
+
+#define IS_AVAILABLE_DIRECTION(stream_type, device_direction) \
+ ((stream_type == STREAM_SINK_INPUT) ? (device_direction & DM_DEVICE_DIRECTION_OUT) : (device_direction & DM_DEVICE_DIRECTION_IN))
static DBusHandlerResult method_handler_for_vt(DBusConnection *c, DBusMessage *m, void *userdata);
static DBusHandlerResult handle_introspect(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_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);
static void handle_update_restriction(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void send_volume_changed_signal(DBusConnection *conn, const char *direction, const char *volume_type, const uint32_t volume_level);
METHOD_HANDLER_SET_VOLUME_MUTE,
METHOD_HANDLER_GET_VOLUME_MUTE,
METHOD_HANDLER_GET_CURRENT_VOLUME_TYPE,
+ METHOD_HANDLER_GET_CURRENT_MEDIA_ROUTING_PATH,
METHOD_HANDLER_UPDATE_FOCUS_STATUS,
METHOD_HANDLER_UPDATE_RESTRICTION,
METHOD_HANDLER_MAX
static pa_dbus_arg_info get_current_volume_type_args[] = { { "io_direction", "s", "in" },
{ "type", "s", "out" },
{ "ret_msg", "s", "out" } };
+static pa_dbus_arg_info get_current_media_routing_path_args[] = { { "io_direction", "s", "in" },
+ { "device_type", "s", "out" },
+ { "ret_msg", "s", "out" } };
static pa_dbus_arg_info update_focus_status_args[] = { { "parent_id", "u", "in" },
{ "focus_status", "u", "in" },
{ "ret_msg", "s", "out" } };
static pa_dbus_arg_info update_restriction_args[] = { { "name", "s", "in" },
{ "value", "u", "in" },
{ "ret_msg", "s", "out" } };
-static const char* signature_args_for_in[] = { "s", "", "uauau", "usi", "ssu", "ss", "ss", "ssu", "ss", "s", "uu", "su"};
+static const char* signature_args_for_in[] = { "s", "", "uauau", "usi", "ssu", "ss", "ss", "ssu", "ss", "s", "s", "uu", "su"};
static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
[METHOD_HANDLER_GET_STREAM_INFO] = {
.arguments = get_current_volume_type_args,
.n_arguments = sizeof(get_current_volume_type_args) / sizeof(pa_dbus_arg_info),
.receive_cb = handle_get_current_volume_type },
+ [METHOD_HANDLER_GET_CURRENT_MEDIA_ROUTING_PATH] = {
+ .method_name = STREAM_MANAGER_METHOD_NAME_GET_CURRENT_MEDIA_ROUTING_PATH,
+ .arguments = get_current_media_routing_path_args,
+ .n_arguments = sizeof(get_current_media_routing_path_args) / sizeof(pa_dbus_arg_info),
+ .receive_cb = handle_get_current_media_routing_path },
[METHOD_HANDLER_UPDATE_FOCUS_STATUS] = {
.method_name = STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS,
.arguments = update_focus_status_args,
" <arg name=\"type\" direction=\"out\" type=\"s\"/>" \
" <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>" \
" </method>" \
+ " <method name=\"STREAM_MANAGER_METHOD_NAME_GET_CURRENT_MEDIA_ROUTING_PATH\">" \
+ " <arg name=\"io_direction\" direction=\"in\" type=\"s\"/>" \
+ " <arg name=\"device_type\" direction=\"out\" type=\"s\"/>" \
+ " <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>" \
+ " </method>" \
" <method name=\"STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS\">" \
" <arg name=\"parent_id\" direction=\"in\" type=\"u\"/>" \
" <arg name=\"focus_status\" direction=\"in\" type=\"u\"/>" \
dbus_message_unref(reply);
}
+static void handle_get_current_media_routing_path(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+ const char *direction = NULL;
+ const char *device_type = NULL;
+ const char *dm_device_type = NULL;
+ dm_device_direction_t dm_device_direction = DM_DEVICE_DIRECTION_NONE;
+ stream_info *s = NULL;
+ stream_type_t stream_type = STREAM_SINK_INPUT;
+ DBusMessage *reply = NULL;
+ uint32_t idx = 0;
+ uint32_t conn_idx = 0;
+ pa_idxset *conn_devices = NULL;
+ pa_tz_device *device = NULL;
+ pa_tz_device *latest_device = NULL;
+ pa_stream_manager *m = (pa_stream_manager*)userdata;
+ pa_usec_t creation_time = 0;
+ pa_usec_t latest_creation_time = 0;
+
+ pa_assert(conn);
+ pa_assert(msg);
+ pa_assert(m);
+
+ pa_assert_se(dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_STRING, &direction,
+ DBUS_TYPE_INVALID));
+ pa_log_info("handle_get_current_media_routing_path(), direction[%s]", direction);
+
+ pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+ if (pa_streq(direction, "in"))
+ stream_type = STREAM_SOURCE_OUTPUT;
+ else if (pa_streq(direction, "out"))
+ stream_type = STREAM_SINK_INPUT;
+ else {
+ pa_log_error("invalid stream type[%s]", direction);
+ goto fail;
+ }
+
+ if ((s = pa_hashmap_get(m->stream_infos, STREAM_ROLE_MEDIA))) {
+ /* get current connected devices */
+ conn_devices = pa_device_manager_get_device_list(m->dm);
+
+ if (s->route_type == STREAM_ROUTE_TYPE_AUTO) {
+ PA_IDXSET_FOREACH(device_type, (stream_type == STREAM_SINK_INPUT) ? s->idx_avail_out_devices : s->idx_avail_in_devices, idx) {
+ PA_IDXSET_FOREACH(device, conn_devices, conn_idx) {
+ dm_device_type = pa_tz_device_get_type(device);
+ dm_device_direction = pa_tz_device_get_direction(device);
+ if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(stream_type, dm_device_direction))
+ goto success;
+ }
+ }
+ pa_log_error("could not found matched device");
+ } else if (s->route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) {
+ PA_IDXSET_FOREACH(device_type, (stream_type == STREAM_SINK_INPUT) ? s->idx_avail_out_devices : s->idx_avail_in_devices, idx) {
+ PA_IDXSET_FOREACH(device, conn_devices, conn_idx) {
+ dm_device_type = pa_tz_device_get_type(device);
+ dm_device_direction = pa_tz_device_get_direction(device);
+ creation_time = pa_tz_device_get_creation_time(device);
+ if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(stream_type, dm_device_direction)) {
+ if (!latest_device || (latest_creation_time <= creation_time)) {
+ latest_device = device;
+ latest_creation_time = creation_time;
+ }
+ }
+ }
+ }
+ if (latest_device) {
+ device_type = pa_tz_device_get_type(latest_device);
+ goto success;
+ }
+ pa_log_error("could not found matched device");
+ } else
+ pa_log_error("unexpected routing type for media[%d]", s->route_type);
+
+ } else
+ pa_log_error("could not find media role");
+
+fail:
+ pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &dbus_str_none, DBUS_TYPE_INVALID));
+ pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID));
+ pa_assert_se(dbus_connection_send(conn, reply, NULL));
+ dbus_message_unref(reply);
+ return;
+success:
+ pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &device_type, DBUS_TYPE_INVALID));
+ pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID));
+ pa_assert_se(dbus_connection_send(conn, reply, NULL));
+ dbus_message_unref(reply);
+}
+
static void handle_update_focus_status(DBusConnection *conn, DBusMessage *msg, void *userdata) {
uint32_t id = 0;
uint32_t idx = 0;