mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	media-session: add flatpak module
Add a module that gives full access to flatpak apps. Later we should do something more restrictive.
This commit is contained in:
		
							parent
							
								
									9caccb6125
								
							
						
					
					
						commit
						cbc579825c
					
				
					 3 changed files with 186 additions and 1 deletions
				
			
		
							
								
								
									
										182
									
								
								src/examples/media-session/access-flatpak.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								src/examples/media-session/access-flatpak.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,182 @@
 | 
				
			||||||
 | 
					/* PipeWire
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright © 2020 Wim Taymans
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission is hereby granted, free of charge, to any person obtaining a
 | 
				
			||||||
 | 
					 * copy of this software and associated documentation files (the "Software"),
 | 
				
			||||||
 | 
					 * to deal in the Software without restriction, including without limitation
 | 
				
			||||||
 | 
					 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | 
				
			||||||
 | 
					 * and/or sell copies of the Software, and to permit persons to whom the
 | 
				
			||||||
 | 
					 * Software is furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The above copyright notice and this permission notice (including the next
 | 
				
			||||||
 | 
					 * paragraph) shall be included in all copies or substantial portions of the
 | 
				
			||||||
 | 
					 * Software.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | 
				
			||||||
 | 
					 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
				
			||||||
 | 
					 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
				
			||||||
 | 
					 * DEALINGS IN THE SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <math.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "pipewire/pipewire.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "media-session.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NAME		"access-flatpak"
 | 
				
			||||||
 | 
					#define SESSION_KEY	"access-flatpak"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct impl {
 | 
				
			||||||
 | 
						struct sm_media_session *session;
 | 
				
			||||||
 | 
						struct spa_hook listener;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct pw_context *context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct spa_list client_list;
 | 
				
			||||||
 | 
						int seq;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct client {
 | 
				
			||||||
 | 
						struct sm_client *obj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t id;
 | 
				
			||||||
 | 
						struct impl *impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct spa_list link;		/**< link in impl client_list */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct spa_hook listener;
 | 
				
			||||||
 | 
						unsigned int active:1;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void object_update(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct client *client = data;
 | 
				
			||||||
 | 
						struct impl *impl = client->impl;
 | 
				
			||||||
 | 
						const char *str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pw_log_debug(NAME" %p: client %p %08x", impl, client, client->obj->obj.changed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (client->obj->obj.avail & SM_CLIENT_CHANGE_MASK_INFO &&
 | 
				
			||||||
 | 
						    !client->active) {
 | 
				
			||||||
 | 
							struct pw_permission permissions[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (client->obj->info == NULL || client->obj->info->props == NULL ||
 | 
				
			||||||
 | 
							    (str = spa_dict_lookup(client->obj->info->props, "pipewire.access")) == NULL ||
 | 
				
			||||||
 | 
							    strcmp(str, "flatpak") != 0)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* full access for now */
 | 
				
			||||||
 | 
							permissions[0] = PW_PERMISSION_INIT(PW_ID_ANY, PW_PERM_RWX);
 | 
				
			||||||
 | 
							pw_client_update_permissions(client->obj->obj.proxy,
 | 
				
			||||||
 | 
									1, permissions);
 | 
				
			||||||
 | 
							client->active = true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct sm_object_events object_events = {
 | 
				
			||||||
 | 
						SM_VERSION_OBJECT_EVENTS,
 | 
				
			||||||
 | 
						.update = object_update
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					handle_client(struct impl *impl, struct sm_object *object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct client *client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pw_log_debug(NAME" %p: client", impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						client = sm_object_add_data(object, SESSION_KEY, sizeof(struct client));
 | 
				
			||||||
 | 
						client->obj = (struct sm_client*)object;
 | 
				
			||||||
 | 
						client->id = object->id;
 | 
				
			||||||
 | 
						client->impl = impl;
 | 
				
			||||||
 | 
						spa_list_append(&impl->client_list, &client->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						client->obj->obj.mask |= SM_CLIENT_CHANGE_MASK_INFO;
 | 
				
			||||||
 | 
						sm_object_add_listener(&client->obj->obj, &client->listener, &object_events, client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void destroy_client(struct impl *impl, struct client *client)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						spa_list_remove(&client->link);
 | 
				
			||||||
 | 
						sm_object_remove_data((struct sm_object*)client->obj, SESSION_KEY);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void session_create(void *data, struct sm_object *object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pw_log_debug(NAME " %p: create global '%d'", impl, object->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (strcmp(object->type, PW_TYPE_INTERFACE_Client) == 0)
 | 
				
			||||||
 | 
							res = handle_client(impl, object);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							res = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (res < 0)
 | 
				
			||||||
 | 
							pw_log_warn(NAME" %p: can't handle global %d", impl, object->id);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void session_remove(void *data, struct sm_object *object)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
						pw_log_debug(NAME " %p: remove global '%d'", impl, object->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (strcmp(object->type, PW_TYPE_INTERFACE_Client) == 0) {
 | 
				
			||||||
 | 
							struct client *client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((client = sm_object_get_data(object, SESSION_KEY)) != NULL)
 | 
				
			||||||
 | 
								destroy_client(impl, client);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void session_destroy(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
						struct client *client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_list_consume(client, &impl->client_list, link)
 | 
				
			||||||
 | 
							destroy_client(impl, client);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_hook_remove(&impl->listener);
 | 
				
			||||||
 | 
						free(impl);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct sm_media_session_events session_events = {
 | 
				
			||||||
 | 
						SM_VERSION_MEDIA_SESSION_EVENTS,
 | 
				
			||||||
 | 
						.create = session_create,
 | 
				
			||||||
 | 
						.remove = session_remove,
 | 
				
			||||||
 | 
						.destroy = session_destroy,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sm_access_flatpak_start(struct sm_media_session *session)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct impl *impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						impl = calloc(1, sizeof(struct impl));
 | 
				
			||||||
 | 
						if (impl == NULL)
 | 
				
			||||||
 | 
							return -errno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						impl->session = session;
 | 
				
			||||||
 | 
						impl->context = session->context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_list_init(&impl->client_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sm_media_session_add_listener(impl->session,
 | 
				
			||||||
 | 
								&impl->listener,
 | 
				
			||||||
 | 
								&session_events, impl);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -66,6 +66,7 @@
 | 
				
			||||||
#define sm_media_session_emit_rescan(s,seq)		sm_media_session_emit(s, rescan, 0, seq)
 | 
					#define sm_media_session_emit_rescan(s,seq)		sm_media_session_emit(s, rescan, 0, seq)
 | 
				
			||||||
#define sm_media_session_emit_destroy(s)		sm_media_session_emit(s, destroy, 0)
 | 
					#define sm_media_session_emit_destroy(s)		sm_media_session_emit(s, destroy, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sm_access_flatpak_start(struct sm_media_session *sess);
 | 
				
			||||||
int sm_metadata_start(struct sm_media_session *sess);
 | 
					int sm_metadata_start(struct sm_media_session *sess);
 | 
				
			||||||
int sm_alsa_midi_start(struct sm_media_session *sess);
 | 
					int sm_alsa_midi_start(struct sm_media_session *sess);
 | 
				
			||||||
int sm_v4l2_monitor_start(struct sm_media_session *sess);
 | 
					int sm_v4l2_monitor_start(struct sm_media_session *sess);
 | 
				
			||||||
| 
						 | 
					@ -1767,7 +1768,7 @@ static void do_quit(void *data, int signal_number)
 | 
				
			||||||
	pw_main_loop_quit(impl->loop);
 | 
						pw_main_loop_quit(impl->loop);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DEFAULT_ENABLED		"alsa-pcm,alsa-seq,v4l2,bluez5,metadata,suspend-node,policy-node"
 | 
					#define DEFAULT_ENABLED		"flatpak,alsa-pcm,alsa-seq,v4l2,bluez5,metadata,suspend-node,policy-node"
 | 
				
			||||||
#define DEFAULT_DISABLED	""
 | 
					#define DEFAULT_DISABLED	""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct {
 | 
					static const struct {
 | 
				
			||||||
| 
						 | 
					@ -1777,6 +1778,7 @@ static const struct {
 | 
				
			||||||
	const char *props;
 | 
						const char *props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} modules[] = {
 | 
					} modules[] = {
 | 
				
			||||||
 | 
						{ "flatpak", "manage flatpak access", sm_access_flatpak_start, NULL },
 | 
				
			||||||
	{ "metadata", "export metadata API", sm_metadata_start, NULL },
 | 
						{ "metadata", "export metadata API", sm_metadata_start, NULL },
 | 
				
			||||||
	{ "alsa-seq", "alsa seq midi support", sm_alsa_midi_start, NULL },
 | 
						{ "alsa-seq", "alsa seq midi support", sm_alsa_midi_start, NULL },
 | 
				
			||||||
	{ "alsa-pcm", "alsa pcm udev detection", sm_alsa_monitor_start, NULL },
 | 
						{ "alsa-pcm", "alsa pcm udev detection", sm_alsa_monitor_start, NULL },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,6 +67,7 @@ executable('export-spa-device',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if alsa_dep.found()
 | 
					if alsa_dep.found()
 | 
				
			||||||
  executable('pipewire-media-session',
 | 
					  executable('pipewire-media-session',
 | 
				
			||||||
 | 
					    'media-session/access-flatpak.c',
 | 
				
			||||||
    'media-session/alsa-midi.c',
 | 
					    'media-session/alsa-midi.c',
 | 
				
			||||||
    'media-session/alsa-monitor.c',
 | 
					    'media-session/alsa-monitor.c',
 | 
				
			||||||
    'media-session/alsa-endpoint.c',
 | 
					    'media-session/alsa-endpoint.c',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue