From e5cc3d6163b7d7a0a3ed3ff0a103c3ffa1e9ba4c Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Thu, 8 Dec 2016 17:04:26 +0900 Subject: [PATCH] stream-manager: Add Dbus interface for getting current media routing path server : org.pulseaudio.Server object path : /org/pulseaudio/StreamManager interface : org.pulseaudio.StreamManager method name : GetCurrentMediaRoutingPath method argument : #1 string for direction ("in" or "out") return value : #1 string for device type #2 string for error message [Version] 5.0.101 [Profile] Common [Issue Type] Feature enhancement Change-Id: I539ee848abb61426ff1dc0db10bd2a8c8a8ea4f4 Signed-off-by: Sangchul Lee (cherry picked from commit 78d04114f812e6a3aebea831bf5822999a863537) --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/stream-manager.c | 138 ++++++++++++++++++++++++++++---- src/stream-manager.h | 1 + 3 files changed, 125 insertions(+), 16 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 56e5768..cdacead 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 5.0.100 +Version: 5.0.101 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/stream-manager.c b/src/stream-manager.c index 1dfc829..34e298a 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -51,21 +51,25 @@ #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); @@ -80,6 +84,7 @@ static void handle_get_volume_max_level(DBusConnection *conn, DBusMessage *msg, 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); @@ -96,6 +101,7 @@ enum method_handler_index { 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 @@ -141,13 +147,16 @@ static pa_dbus_arg_info get_volume_mute_args[] = { { "io_direction", "s", "in" 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] = { @@ -200,6 +209,11 @@ static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = { .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, @@ -299,6 +313,11 @@ static pa_dbus_interface_info stream_manager_interface_info = { " " \ " " \ " " \ + " " \ + " " \ + " " \ + " " \ + " " \ " " \ " " \ " " \ @@ -1085,6 +1104,95 @@ fail: 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; diff --git a/src/stream-manager.h b/src/stream-manager.h index 4779fc7..e2865c0 100644 --- a/src/stream-manager.h +++ b/src/stream-manager.h @@ -39,6 +39,7 @@ #define GET_STREAM_PROPLIST(stream, type) \ (type == STREAM_SINK_INPUT ? ((pa_sink_input*)stream)->proplist : ((pa_source_output*)stream)->proplist) +#define STREAM_ROLE_MEDIA "media" #define STREAM_ROLE_RINGTONE_CALL "ringtone-call" #define STREAM_ROLE_CALL_VOICE "call-voice" #define STREAM_ROLE_CALL_VIDEO "call-video" -- 2.7.4