ladishd: properly handle stopping and removal of apps with a2j ports
This commit is contained in:
parent
7d3acd7331
commit
79c75fd07b
|
@ -1786,6 +1786,37 @@ ladish_port_handle ladish_graph_find_port_by_jack_id(ladish_graph_handle graph_h
|
|||
return port_ptr->port;
|
||||
}
|
||||
|
||||
bool ladish_graph_client_has_visible_app_port(ladish_graph_handle graph_handle, ladish_client_handle client_handle, const uuid_t app_uuid)
|
||||
{
|
||||
struct ladish_graph_client * client_ptr;
|
||||
struct list_head * node_ptr;
|
||||
struct ladish_graph_port * port_ptr;
|
||||
|
||||
client_ptr = ladish_graph_find_client(graph_ptr, client_handle);
|
||||
if (client_ptr == NULL)
|
||||
{
|
||||
ASSERT_NO_PASS;
|
||||
return false;
|
||||
}
|
||||
|
||||
list_for_each(node_ptr, &client_ptr->ports)
|
||||
{
|
||||
port_ptr = list_entry(node_ptr, struct ladish_graph_port, siblings_client);
|
||||
if (port_ptr->hidden)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ladish_port_belongs_to_app(port_ptr->port, app_uuid))
|
||||
{
|
||||
ASSERT(!client_ptr->hidden);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ladish_client_handle
|
||||
ladish_graph_remove_port(
|
||||
ladish_graph_handle graph_handle,
|
||||
|
|
|
@ -174,6 +174,7 @@ void ladish_graph_show_connection(ladish_graph_handle graph_handle, uint64_t con
|
|||
void ladish_try_connect_hidden_connections(ladish_graph_handle graph_handle);
|
||||
void ladish_graph_hide_non_virtual(ladish_graph_handle graph_handle);
|
||||
void ladish_graph_get_port_uuid(ladish_graph_handle graph, ladish_port_handle port, uuid_t uuid_ptr);
|
||||
bool ladish_graph_client_has_visible_app_port(ladish_graph_handle graph, ladish_client_handle client, const uuid_t app_uuid);
|
||||
|
||||
void ladish_graph_dump(ladish_graph_handle graph_handle);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ struct ladish_port
|
|||
{
|
||||
int refcount;
|
||||
uuid_t uuid; /* The UUID of the port */
|
||||
uuid_t app_uuid; /* The UUID of the app that owns this client */
|
||||
bool link; /* Whether the port is studio-room link port */
|
||||
uint64_t jack_id; /* JACK port ID. */
|
||||
uint64_t jack_id_room; /* JACK port ID in room. valid only for link ports */
|
||||
|
@ -71,6 +72,8 @@ ladish_port_create(
|
|||
uuid_copy(port_ptr->uuid, uuid_ptr);
|
||||
}
|
||||
|
||||
uuid_clear(port_ptr->app_uuid);
|
||||
|
||||
port_ptr->jack_id = 0;
|
||||
port_ptr->jack_id_room = 0;
|
||||
port_ptr->link = link;
|
||||
|
@ -169,4 +172,35 @@ void * ladish_port_get_vgraph(ladish_port_handle port_handle)
|
|||
return port_ptr->vgraph;
|
||||
}
|
||||
|
||||
void ladish_port_set_app(ladish_port_handle port_handle, const uuid_t app_uuid)
|
||||
{
|
||||
uuid_copy(port_ptr->app_uuid, app_uuid);
|
||||
}
|
||||
|
||||
bool ladish_port_get_app(ladish_port_handle port_handle, uuid_t app_uuid)
|
||||
{
|
||||
if (uuid_is_null(port_ptr->app_uuid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uuid_copy(app_uuid, port_ptr->app_uuid);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ladish_port_has_app(ladish_port_handle port_handle)
|
||||
{
|
||||
return !uuid_is_null(port_ptr->app_uuid);
|
||||
}
|
||||
|
||||
bool ladish_port_belongs_to_app(ladish_port_handle port_handle, const uuid_t app_uuid)
|
||||
{
|
||||
if (uuid_is_null(port_ptr->app_uuid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return uuid_compare(port_ptr->app_uuid, app_uuid) == 0;
|
||||
}
|
||||
|
||||
#undef port_ptr
|
||||
|
|
|
@ -50,4 +50,9 @@ bool ladish_port_is_link(ladish_port_handle port_handle);
|
|||
void ladish_port_set_vgraph(ladish_port_handle port_handle, void * vgraph);
|
||||
void * ladish_port_get_vgraph(ladish_port_handle port_handle);
|
||||
|
||||
void ladish_port_set_app(ladish_port_handle port, const uuid_t app_uuid);
|
||||
bool ladish_port_get_app(ladish_port_handle port, uuid_t app_uuid);
|
||||
bool ladish_port_has_app(ladish_port_handle port);
|
||||
bool ladish_port_belongs_to_app(ladish_port_handle port, const uuid_t app_uuid);
|
||||
|
||||
#endif /* #ifndef PORT_H__62F81E7C_91FA_44AB_94A9_E0E2D226ED58__INCLUDED */
|
||||
|
|
|
@ -216,7 +216,6 @@ lookup_port(
|
|||
ladish_graph_handle * vgraph_ptr)
|
||||
{
|
||||
ladish_port_handle port;
|
||||
ladish_client_handle jclient;
|
||||
ladish_graph_handle vgraph;
|
||||
|
||||
port = ladish_graph_find_port_by_jack_id(virtualizer_ptr->jack_graph, port_id, true, true);
|
||||
|
@ -226,14 +225,7 @@ lookup_port(
|
|||
return false;
|
||||
}
|
||||
|
||||
jclient = ladish_graph_get_port_client(virtualizer_ptr->jack_graph, port);
|
||||
if (jclient == NULL)
|
||||
{
|
||||
log_error("Port %"PRIu64" without jack client was (dis)connected", port_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
vgraph = ladish_client_get_vgraph(jclient);
|
||||
vgraph = ladish_port_get_vgraph(port);
|
||||
if (vgraph == NULL)
|
||||
{
|
||||
vgraph = find_link_port_vgraph_by_jack_id(virtualizer_ptr, port_id, NULL);
|
||||
|
@ -627,6 +619,13 @@ port_appeared(
|
|||
goto free_alsa_names;
|
||||
}
|
||||
|
||||
/* for normal ports, one can find the app_uuid through the jack client,
|
||||
but for a2j ports the jack client is shared between graphs */
|
||||
if (has_app)
|
||||
{
|
||||
ladish_port_set_app(port, app_uuid);
|
||||
}
|
||||
|
||||
ladish_client_set_jack_id(vclient, client_id);
|
||||
ladish_graph_adjust_port(vgraph, port, type, flags);
|
||||
ladish_graph_show_port(vgraph, port);
|
||||
|
@ -642,9 +641,13 @@ port_appeared(
|
|||
/* set port jack id so invisible connections to/from it can be restored */
|
||||
ladish_port_set_jack_id(port, port_id);
|
||||
|
||||
/* for normal ports, one can find the vgraph through the jack client,
|
||||
/* for normal ports, one can find the vgraph and app_uuid through the jack client,
|
||||
but for a2j ports the jack client is shared between graphs */
|
||||
ladish_port_set_vgraph(port, vgraph);
|
||||
if (has_app)
|
||||
{
|
||||
ladish_port_set_app(port, app_uuid);
|
||||
}
|
||||
|
||||
if (!ladish_graph_add_port(virtualizer_ptr->jack_graph, jack_client, port, jack_port_name, type, flags, false))
|
||||
{
|
||||
|
@ -1099,6 +1102,19 @@ ladish_virtualizer_get_our_clients_count(
|
|||
return virtualizer_ptr->our_clients_count;
|
||||
}
|
||||
|
||||
static bool app_has_a2j_ports(ladish_graph_handle jack_graph, const uuid_t app_uuid)
|
||||
{
|
||||
ladish_client_handle a2jclient;
|
||||
|
||||
a2jclient = ladish_graph_find_client_by_uuid(jack_graph, g_a2j_uuid);
|
||||
if (a2jclient == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ladish_graph_client_has_visible_app_port(jack_graph, a2jclient, app_uuid);
|
||||
}
|
||||
|
||||
bool
|
||||
ladish_virtualizer_is_hidden_app(
|
||||
ladish_graph_handle jack_graph,
|
||||
|
@ -1115,6 +1131,12 @@ ladish_virtualizer_is_hidden_app(
|
|||
|
||||
//ladish_graph_dump(g_studio.jack_graph);
|
||||
|
||||
if (app_has_a2j_ports(jack_graph, app_uuid))
|
||||
{
|
||||
log_info("app '%s' still has a2j ports", app_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
jclient = ladish_graph_find_client_by_app(jack_graph, app_uuid);
|
||||
if (jclient == NULL)
|
||||
{
|
||||
|
@ -1177,6 +1199,68 @@ ladish_virtualizer_is_hidden_app(
|
|||
return true;
|
||||
}
|
||||
|
||||
struct app_remove_context
|
||||
{
|
||||
uuid_t app_uuid;
|
||||
const char * app_name;
|
||||
};
|
||||
|
||||
#define app_info_ptr ((struct app_remove_context *)context)
|
||||
|
||||
static
|
||||
bool
|
||||
remove_app_port(
|
||||
void * context,
|
||||
ladish_graph_handle graph_handle,
|
||||
void * client_iteration_context_ptr,
|
||||
ladish_client_handle client_handle,
|
||||
const char * client_name,
|
||||
ladish_port_handle port_handle,
|
||||
const char * port_name,
|
||||
uint32_t port_type,
|
||||
uint32_t port_flags)
|
||||
{
|
||||
ladish_graph_handle vgraph;
|
||||
ladish_client_handle vclient;
|
||||
|
||||
if (!ladish_port_belongs_to_app(port_handle, app_info_ptr->app_uuid))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//log_info("removing port '%s':'%s' (JACK) of app '%s'", client_name, port_name, app_info_ptr->app_name);
|
||||
|
||||
vgraph = ladish_port_get_vgraph(port_handle);
|
||||
if (vgraph == NULL)
|
||||
{
|
||||
log_error("port '%s':'%s' of app '5s' has no vgraph", client_name, port_name, app_info_ptr->app_name);
|
||||
ASSERT_NO_PASS;
|
||||
return true;
|
||||
}
|
||||
|
||||
vclient = ladish_graph_get_port_client(vgraph, port_handle);
|
||||
if (vgraph == NULL)
|
||||
{
|
||||
log_error("app port '%s':'%s' not found in vgraph '%s'", client_name, port_name, ladish_graph_get_description(vgraph));
|
||||
ASSERT_NO_PASS;
|
||||
return true;
|
||||
}
|
||||
|
||||
log_info(
|
||||
"removing %s %s port %p of app '%s' ('%s':'%s' in %s)",
|
||||
port_type == JACKDBUS_PORT_TYPE_AUDIO ? "audio" : "midi",
|
||||
JACKDBUS_PORT_IS_INPUT(port_flags) ? "input" : "output",
|
||||
port_handle,
|
||||
app_info_ptr->app_name,
|
||||
ladish_graph_get_client_name(vgraph, vclient),
|
||||
ladish_graph_get_port_name(vgraph, port_handle),
|
||||
ladish_graph_get_description(vgraph));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef app_info_ptr
|
||||
|
||||
void
|
||||
ladish_virtualizer_remove_app(
|
||||
ladish_graph_handle jack_graph,
|
||||
|
@ -1190,9 +1274,15 @@ ladish_virtualizer_remove_app(
|
|||
bool is_empty;
|
||||
uuid_t jclient_uuid;
|
||||
bool is_a2j;
|
||||
struct app_remove_context ctx;
|
||||
|
||||
//ladish_graph_dump(g_studio.jack_graph);
|
||||
|
||||
uuid_copy(ctx.app_uuid, app_uuid);
|
||||
ctx.app_name = app_name;
|
||||
|
||||
ladish_graph_iterate_nodes(jack_graph, false, NULL, &ctx, NULL, remove_app_port, NULL);
|
||||
|
||||
jclient = ladish_graph_find_client_by_app(jack_graph, app_uuid);
|
||||
if (jclient == NULL)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue