From d5c09c6efb56e158fdec39b5986ed36dd1cff4e1 Mon Sep 17 00:00:00 2001 From: Seungbae Shin Date: Tue, 18 Aug 2020 18:56:15 +0900 Subject: [PATCH] tunnel-sink(source)-new: modification for remote-audio - receive stream event to update access permission of the sink(source) - set remote name from target device name vconf - set default remote access permission as denied - set device api property with 'tunnel' [Version] 13.0-15 [Issue Type] Update Change-Id: Iae64a8805b6befa088b0c5ffce678894114a8bba --- configure.ac | 6 +++ packaging/pulseaudio.spec | 3 +- src/Makefile.am | 8 ++-- src/modules/module-tunnel-sink-new.c | 80 +++++++++++++++++++++++++++++++++ src/modules/module-tunnel-source-new.c | 81 ++++++++++++++++++++++++++++++++++ src/pulse/def.h | 1 + src/pulsecore/proplist-util.c | 8 ++++ src/pulsecore/proplist-util.h | 1 + 8 files changed, 183 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 796e994..e8d81de 100644 --- a/configure.ac +++ b/configure.ac @@ -1053,6 +1053,12 @@ AC_SUBST(LIRC_CFLAGS) AC_SUBST(LIRC_LIBS) AM_CONDITIONAL([HAVE_LIRC], [test "x$HAVE_LIRC" = x1]) + +#### VCONF +PKG_CHECK_MODULES(VCONF, vconf) +AC_SUBST(VCONF_CFLAGS) +AC_SUBST(VCONF_LIBS) + #### D-Bus support (optional) #### AC_ARG_ENABLE([dbus], diff --git a/packaging/pulseaudio.spec b/packaging/pulseaudio.spec index d3c15c0..e5275b0 100644 --- a/packaging/pulseaudio.spec +++ b/packaging/pulseaudio.spec @@ -3,7 +3,7 @@ Name: pulseaudio Summary: Improved Linux sound server Version: 13.0 -Release: 14 +Release: 15 Group: Multimedia/Audio License: LGPL-2.1 URL: http://pulseaudio.org @@ -28,6 +28,7 @@ BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(cynara-client) BuildRequires: pkgconfig(cynara-creds-socket) BuildRequires: pkgconfig(cynara-session) +BuildRequires: pkgconfig(vconf) BuildRequires: systemd-devel BuildRequires: libcap-devel %if "%{tizen_profile_name}" == "tv" diff --git a/src/Makefile.am b/src/Makefile.am index 89aeab5..e4eb0c8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1942,13 +1942,13 @@ module_match_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_match module_tunnel_sink_new_la_SOURCES = modules/module-tunnel-sink-new.c module_tunnel_sink_new_la_LDFLAGS = $(MODULE_LDFLAGS) -module_tunnel_sink_new_la_LIBADD = $(MODULE_LIBADD) -module_tunnel_sink_new_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_tunnel_sink_new +module_tunnel_sink_new_la_LIBADD = $(MODULE_LIBADD) $(VCONF_LIBS) +module_tunnel_sink_new_la_CFLAGS = $(AM_CFLAGS) $(VCONF_CFLAGS) -DPA_MODULE_NAME=module_tunnel_sink_new module_tunnel_source_new_la_SOURCES = modules/module-tunnel-source-new.c module_tunnel_source_new_la_LDFLAGS = $(MODULE_LDFLAGS) -module_tunnel_source_new_la_LIBADD = $(MODULE_LIBADD) -module_tunnel_source_new_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_tunnel_source_new +module_tunnel_source_new_la_LIBADD = $(MODULE_LIBADD) $(VCONF_LIBS) +module_tunnel_source_new_la_CFLAGS = $(AM_CFLAGS) $(VCONF_CFLAGS) -DPA_MODULE_NAME=module_tunnel_source_new module_tunnel_sink_la_SOURCES = modules/module-tunnel.c module_tunnel_sink_la_CFLAGS = -DTUNNEL_SINK=1 $(AM_CFLAGS) $(X11_CFLAGS) -DPA_MODULE_NAME=module_tunnel_sink diff --git a/src/modules/module-tunnel-sink-new.c b/src/modules/module-tunnel-sink-new.c index 802e6a5..dfd333f 100644 --- a/src/modules/module-tunnel-sink-new.c +++ b/src/modules/module-tunnel-sink-new.c @@ -39,7 +39,12 @@ #include #include #include + +#ifdef __TIZEN__ #include +#include +#include +#endif PA_MODULE_AUTHOR("Alexander Couzens"); PA_MODULE_DESCRIPTION("Create a network sink which connects via a stream to a remote PulseAudio server"); @@ -60,11 +65,20 @@ PA_MODULE_USAGE( #define MAX_LATENCY_USEC (200 * PA_USEC_PER_MSEC) #define TUNNEL_THREAD_FAILED_MAINLOOP 1 +#ifdef __TIZEN__ +enum { + SINK_MESSAGE_STREAM_PROPLIST_UPDATED = PA_SINK_MESSAGE_MAX +}; +#endif + static void stream_state_cb(pa_stream *stream, void *userdata); static void stream_changed_buffer_attr_cb(pa_stream *stream, void *userdata); static void stream_set_buffer_attr_cb(pa_stream *stream, int success, void *userdata); static void context_state_cb(pa_context *c, void *userdata); static void sink_update_requested_latency_cb(pa_sink *s); +#ifdef __TIZEN__ +static void stream_event_cb(pa_stream *stream, const char *name, pa_proplist *pl, void *userdata); +#endif struct userdata { pa_module *module; @@ -85,6 +99,9 @@ struct userdata { char *cookie_file; char *remote_server; char *remote_sink_name; +#ifdef __TIZEN__ + char *device_name; +#endif }; static const char* const valid_modargs[] = { @@ -135,6 +152,9 @@ static pa_proplist* tunnel_new_proplist(struct userdata *u) { pa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "PulseAudio"); pa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "org.PulseAudio.PulseAudio"); pa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, PACKAGE_VERSION); +#ifdef __TIZEN__ + pa_proplist_remote_init(proplist, u->device_name); +#endif pa_init_proplist(proplist); return proplist; @@ -287,6 +307,28 @@ static void stream_set_buffer_attr_cb(pa_stream *stream, int success, void *user stream_changed_buffer_attr_cb(stream, userdata); } +#ifdef __TIZEN__ +static void stream_event_cb(pa_stream *stream, const char *name, pa_proplist *pl, void *userdata) { + char *t; + struct userdata *u = userdata; + + pa_assert(stream); + pa_assert(name); + pa_assert(pl); + + t = pa_proplist_to_string_sep(pl, ", "); + pa_log_info("Got event '%s', properties '%s'", name, t); + + if (pa_safe_streq(name, PA_STREAM_EVENT_UPDATE_MEDIA_REMOTE_ACCESS)) { + pa_log_info("post message to update sink[%s] proplist[%s]", u->sink->name, t); + pa_asyncmsgq_post(u->thread_mq->outq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_STREAM_PROPLIST_UPDATED, + pa_proplist_copy(pl), 0, NULL, NULL); + } + + pa_xfree(t); +} +#endif + static void context_state_cb(pa_context *c, void *userdata) { struct userdata *u = userdata; pa_assert(u); @@ -335,6 +377,10 @@ static void context_state_cb(pa_context *c, void *userdata) { pa_stream_set_state_callback(u->stream, stream_state_cb, userdata); pa_stream_set_buffer_attr_callback(u->stream, stream_changed_buffer_attr_cb, userdata); +#ifdef __TIZEN__ + pa_stream_set_event_callback(u->stream, stream_event_cb, userdata); +#endif + if (pa_stream_connect_playback(u->stream, u->remote_sink_name, &bufferattr, @@ -429,6 +475,28 @@ static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t of *((int64_t*) data) = remote_latency; return 0; } +#ifdef __TIZEN__ + case SINK_MESSAGE_STREAM_PROPLIST_UPDATED: { + pa_proplist *pl = (pa_proplist *)data; + void *s; + uint32_t idx; + + pa_log_info("SINK_MESSAGE_STREAM_PROPLIST_UPDATED : %p", pl); + + pa_sink_update_proplist(u->sink, PA_UPDATE_REPLACE, pl); + + if (!pa_proplist_remote_is_allowed(pl)) { + PA_IDXSET_FOREACH(s, u->sink->inputs, idx) { + pa_log_info(" -- kill sink-input(%p, %u)", s, ((pa_sink_input *) s)->index); + pa_sink_input_kill((pa_sink_input *) s); + } + } + + pa_proplist_free(pl); + + return 0; + } +#endif } return pa_sink_process_msg(o, code, data, offset, chunk); } @@ -509,6 +577,9 @@ int pa__init(pa_module *m) { u->thread_mainloop_api = pa_mainloop_get_api(u->thread_mainloop); u->cookie_file = pa_xstrdup(pa_modargs_get_value(ma, "cookie", NULL)); u->remote_sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); +#ifdef __TIZEN__ + u->device_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR); +#endif u->thread_mq = pa_xnew0(pa_thread_mq, 1); @@ -544,6 +615,10 @@ int pa__init(pa_module *m) { _("Tunnel to %s/%s"), remote_server, pa_strempty(u->remote_sink_name)); +#ifdef __TIZEN__ + pa_proplist_remote_init(sink_data.proplist, u->device_name); + pa_proplist_sets(sink_data.proplist, PA_PROP_DEVICE_API, "tunnel"); +#endif if (pa_modargs_get_proplist(ma, "sink_properties", sink_data.proplist, PA_UPDATE_REPLACE) < 0) { pa_log("Invalid properties"); @@ -623,6 +698,11 @@ void pa__done(pa_module *m) { if (u->remote_server) pa_xfree(u->remote_server); +#ifdef __TIZEN__ + if (u->device_name) + pa_xfree(u->device_name); +#endif + if (u->sink) pa_sink_unref(u->sink); diff --git a/src/modules/module-tunnel-source-new.c b/src/modules/module-tunnel-source-new.c index b41f53e..c25684b 100644 --- a/src/modules/module-tunnel-source-new.c +++ b/src/modules/module-tunnel-source-new.c @@ -39,7 +39,12 @@ #include #include #include + +#ifdef __TIZEN__ #include +#include +#include +#endif PA_MODULE_AUTHOR("Alexander Couzens"); PA_MODULE_DESCRIPTION("Create a network source which connects via a stream to a remote PulseAudio server"); @@ -59,10 +64,19 @@ PA_MODULE_USAGE( #define TUNNEL_THREAD_FAILED_MAINLOOP 1 +#ifdef __TIZEN__ +enum { + SOURCE_MESSAGE_STREAM_PROPLIST_UPDATED = PA_SOURCE_MESSAGE_MAX +}; +#endif + static void stream_state_cb(pa_stream *stream, void *userdata); static void stream_read_cb(pa_stream *s, size_t length, void *userdata); static void context_state_cb(pa_context *c, void *userdata); static void source_update_requested_latency_cb(pa_source *s); +#ifdef __TIZEN__ +static void stream_event_cb(pa_stream *s, const char *name, pa_proplist *pl, void *userdata); +#endif struct userdata { pa_module *module; @@ -83,6 +97,9 @@ struct userdata { char *cookie_file; char *remote_server; char *remote_source_name; +#ifdef __TIZEN__ + char *device_name; +#endif }; static const char* const valid_modargs[] = { @@ -124,6 +141,9 @@ static pa_proplist* tunnel_new_proplist(struct userdata *u) { pa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "PulseAudio"); pa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "org.PulseAudio.PulseAudio"); pa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, PACKAGE_VERSION); +#ifdef __TIZEN__ + pa_proplist_remote_init(proplist, u->device_name); +#endif pa_init_proplist(proplist); return proplist; @@ -134,6 +154,28 @@ static void stream_read_cb(pa_stream *s, size_t length, void *userdata) { u->new_data = true; } +#ifdef __TIZEN__ +static void stream_event_cb(pa_stream *s, const char *name, pa_proplist *pl, void *userdata) { + char *t; + struct userdata *u = userdata; + + pa_assert(s); + pa_assert(name); + pa_assert(pl); + + t = pa_proplist_to_string_sep(pl, ", "); + pa_log("Got event '%s', properties '%s'", name, t); + + if (pa_safe_streq(name, PA_STREAM_EVENT_UPDATE_MEDIA_REMOTE_ACCESS)) { + pa_log("post message to update source[%s] proplist[%s]", u->source->name, t); + pa_asyncmsgq_post(u->thread_mq->outq, PA_MSGOBJECT(u->source), SOURCE_MESSAGE_STREAM_PROPLIST_UPDATED, + pa_proplist_copy(pl), 0, NULL, NULL); + } + + pa_xfree(t); +} +#endif + /* called from io context to read samples from the stream into our source */ static void read_new_samples(struct userdata *u) { const void *p; @@ -333,6 +375,10 @@ static void context_state_cb(pa_context *c, void *userdata) { pa_stream_set_state_callback(u->stream, stream_state_cb, userdata); pa_stream_set_read_callback(u->stream, stream_read_cb, userdata); +#ifdef __TIZEN__ + pa_stream_set_event_callback(u->stream, stream_event_cb, userdata); +#endif + if (pa_stream_connect_record(u->stream, u->remote_source_name, &bufferattr, @@ -428,6 +474,29 @@ static int source_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t return 0; } + +#ifdef __TIZEN__ + case SOURCE_MESSAGE_STREAM_PROPLIST_UPDATED: { + pa_proplist *pl = (pa_proplist *)data; + void *s; + uint32_t idx; + + pa_log_info("SOURCE_MESSAGE_STREAM_PROPLIST_UPDATED : %p", pl); + + pa_source_update_proplist(u->source, PA_UPDATE_REPLACE, pl); + + if (!pa_proplist_remote_is_allowed(pl)) { + PA_IDXSET_FOREACH(s, u->source->outputs, idx) { + pa_log_info(" -- kill source-output(%p, %u)", s, ((pa_source_output *) s)->index); + pa_source_output_kill((pa_source_output *) s); + } + } + + pa_proplist_free(pl); + + return 0; + } +#endif } return pa_source_process_msg(o, code, data, offset, chunk); } @@ -508,6 +577,9 @@ int pa__init(pa_module *m) { u->thread_mainloop_api = pa_mainloop_get_api(u->thread_mainloop); u->cookie_file = pa_xstrdup(pa_modargs_get_value(ma, "cookie", NULL)); u->remote_source_name = pa_xstrdup(pa_modargs_get_value(ma, "source", NULL)); +#ifdef __TIZEN__ + u->device_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR); +#endif u->thread_mq = pa_xnew0(pa_thread_mq, 1); @@ -540,6 +612,10 @@ int pa__init(pa_module *m) { _("Tunnel to %s/%s"), remote_server, pa_strempty(u->remote_source_name)); +#ifdef __TIZEN__ + pa_proplist_remote_init(source_data.proplist, u->device_name); + pa_proplist_sets(source_data.proplist, PA_PROP_DEVICE_API, "tunnel"); +#endif if (pa_modargs_get_proplist(ma, "source_properties", source_data.proplist, PA_UPDATE_REPLACE) < 0) { pa_log("Invalid properties"); @@ -617,6 +693,11 @@ void pa__done(pa_module *m) { if (u->remote_server) pa_xfree(u->remote_server); +#ifdef __TIZEN__ + if (u->device_name) + pa_xfree(u->device_name); +#endif + if (u->source) pa_source_unref(u->source); diff --git a/src/pulse/def.h b/src/pulse/def.h index a06db2f..83e7a58 100644 --- a/src/pulse/def.h +++ b/src/pulse/def.h @@ -1055,6 +1055,7 @@ typedef void (*pa_free_cb_t)(void *p); #ifdef __TIZEN__ #define PA_STREAM_EVENT_POP_TIMEOUT "pop-timeout" +#define PA_STREAM_EVENT_UPDATE_MEDIA_REMOTE_ACCESS "update-media-remote-access" #endif #ifndef __INCLUDED_FROM_PULSE_AUDIO diff --git a/src/pulsecore/proplist-util.c b/src/pulsecore/proplist-util.c index 84a6c4b..20ebd32 100644 --- a/src/pulsecore/proplist-util.c +++ b/src/pulsecore/proplist-util.c @@ -281,6 +281,14 @@ char *pa_proplist_get_stream_group(pa_proplist *p, const char *prefix, const cha static const char *access_str[] = { REMOTE_ACCESS_PERMISSION_DENIED, REMOTE_ACCESS_PERMISSION_ALLOWED }; +void pa_proplist_remote_init(pa_proplist *p, const char *remote_name) { + if (!p) + return; + + pa_proplist_sets(p, PA_PROP_MEDIA_REMOTE_NAME, pa_strnull(remote_name)); + pa_proplist_sets(p, PA_PROP_MEDIA_REMOTE_ACCESS, REMOTE_ACCESS_PERMISSION_DENIED); +} + bool pa_proplist_has_remote_name(pa_proplist *p) { bool is_remote = false; diff --git a/src/pulsecore/proplist-util.h b/src/pulsecore/proplist-util.h index 3253f05..9d9ae4d 100644 --- a/src/pulsecore/proplist-util.h +++ b/src/pulsecore/proplist-util.h @@ -29,6 +29,7 @@ void pa_init_proplist(pa_proplist *p); char *pa_proplist_get_stream_group(pa_proplist *pl, const char *prefix, const char *cache); #ifdef __TIZEN__ +void pa_proplist_remote_init(pa_proplist *p, const char *remote_name); bool pa_proplist_has_remote_name(pa_proplist *p); int pa_proplist_set_remote_access_permission(pa_proplist *p, bool allowed); bool pa_proplist_remote_is_allowed(pa_proplist *p); -- 2.7.4