From bcb4e8072318031d5f0e1ed80e2719f91f9cdacf Mon Sep 17 00:00:00 2001 From: George Kiagiadakis Date: Thu, 24 Nov 2022 13:33:30 +0200 Subject: [PATCH] m-std-event-source: use type-specific event names and multiple object managers It is better to have type-specific event names to minimize the amount of constraint string matches we do on hooks, as most hooks (if not all) are interested on specific types of objects only. Similarly, use a different object manager for each object type to minimize the performance impact of iterations and lookups, as all such actions are interested in only 1 object type every time. Port all existing hooks to the new event names and the get-object-manager API. --- modules/module-default-nodes-api.c | 12 +- modules/module-default-nodes.c | 33 +-- modules/module-default-profile.c | 9 +- modules/module-standard-event-source.c | 208 ++++++++++++------ src/scripts/create-item.lua | 18 +- src/scripts/lib/policy-utils.lua | 4 +- src/scripts/policy-bluetooth.lua | 15 +- .../policy-desktop/filter-forward-format.lua | 6 +- src/scripts/policy-desktop/prepare-link.lua | 6 +- src/scripts/policy-desktop/rescan.lua | 15 +- src/scripts/policy-device-profile.lua | 11 +- src/scripts/policy-device-routes.lua | 6 +- src/scripts/restore-stream.lua | 21 +- 13 files changed, 193 insertions(+), 171 deletions(-) diff --git a/modules/module-default-nodes-api.c b/modules/module-default-nodes-api.c index aa58ae9f..04f4675e 100644 --- a/modules/module-default-nodes-api.c +++ b/modules/module-default-nodes-api.c @@ -154,8 +154,7 @@ wp_default_nodes_api_enable (WpPlugin * plugin, WpTransition * transition) WP_EVENT_HOOK_PRIORITY_NORMAL, WP_EVENT_HOOK_EXEC_TYPE_ON_EVENT, g_cclosure_new ((GCallback) on_metadata_added, self, NULL)); wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-added", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "metadata-added", WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default", NULL); wp_event_dispatcher_register_hook (dispatcher, hook); @@ -167,24 +166,21 @@ wp_default_nodes_api_enable (WpPlugin * plugin, WpTransition * transition) g_cclosure_new ((GCallback) on_metadata_changed_hook, self, NULL)); wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "metadata-changed", WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s", "default.audio.sink", WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default", NULL); wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "metadata-changed", WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s", "default.video.sink", WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default", NULL); wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "metadata-changed", WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s", "default.audio.source", WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default", diff --git a/modules/module-default-nodes.c b/modules/module-default-nodes.c index a3382221..0fb55cd8 100644 --- a/modules/module-default-nodes.c +++ b/modules/module-default-nodes.c @@ -595,8 +595,7 @@ wp_default_nodes_enable (WpPlugin * plugin, WpTransition * transition) WP_EVENT_HOOK_PRIORITY_NORMAL, WP_EVENT_HOOK_EXEC_TYPE_ON_EVENT, g_cclosure_new ((GCallback) on_metadata_added, self, NULL)); wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-added", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "metadata-added", WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default", NULL); wp_event_dispatcher_register_hook (dispatcher, hook); @@ -608,24 +607,21 @@ wp_default_nodes_enable (WpPlugin * plugin, WpTransition * transition) g_cclosure_new ((GCallback) on_metadata_changed, self, NULL)); wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "metadata-changed", WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s", "default.configured.audio.sink", WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default", NULL); wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "metadata-changed", WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s", "default.configured.video.sink", WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default", NULL); wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "metadata-changed", WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s", "default.configured.audio.source", WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default", @@ -641,53 +637,46 @@ wp_default_nodes_enable (WpPlugin * plugin, WpTransition * transition) /* default.configured.audio.sink changed */ wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "metadata-changed", WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s", "default.configured.audio.sink", WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default", NULL); /* default.configured.video.sink changed */ wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "metadata-changed", WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s", "default.configured.video.sink", WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default", NULL); /* default.configured.audio.source changed */ wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-changed", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "metadata", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "metadata-changed", WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.key", "=s", "default.configured.audio.source", WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "metadata.name", "=s", "default", NULL); /* new video device node added */ wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-added", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "node", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "node-added", WP_CONSTRAINT_TYPE_PW_PROPERTY, "media.class", "#s", "Video/*", NULL); /* new audio device node added */ wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-added", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "node", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "node-added", WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "media.class", "#s", "Audio/*", NULL); /* video device node removed */ wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-removed", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "node", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "node-removed", WP_CONSTRAINT_TYPE_PW_PROPERTY, "media.class", "#s", "Video/*", NULL); /* audio device node removed */ wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-removed", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "node", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "node-removed", WP_CONSTRAINT_TYPE_PW_PROPERTY, "media.class", "#s", "Audio/*", NULL); diff --git a/modules/module-default-profile.c b/modules/module-default-profile.c index c55ec636..9c610245 100644 --- a/modules/module-default-profile.c +++ b/modules/module-default-profile.c @@ -272,8 +272,7 @@ wp_default_profile_enable (WpPlugin * plugin, WpTransition * transition) WP_EVENT_HOOK_PRIORITY_NORMAL, WP_EVENT_HOOK_EXEC_TYPE_ON_EVENT, g_cclosure_new ((GCallback) on_device_added, self, NULL)); wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "object-added", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "device", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "device-added", NULL); wp_event_dispatcher_register_hook (dispatcher, hook); g_clear_object (&hook); @@ -283,13 +282,11 @@ wp_default_profile_enable (WpPlugin * plugin, WpTransition * transition) WP_EVENT_HOOK_PRIORITY_NORMAL, WP_EVENT_HOOK_EXEC_TYPE_ON_EVENT, g_cclosure_new ((GCallback) on_device_params_changed_hook, self, NULL)); wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "params-changed", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "device", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "device-params-changed", WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.param-id", "=s", "EnumProfile", NULL); wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "params-changed", - WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.type", "=s", "device", + WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "device-params-changed", WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.subject.param-id", "=s", "Profile", NULL); wp_event_dispatcher_register_hook (dispatcher, hook); diff --git a/modules/module-standard-event-source.c b/modules/module-standard-event-source.c index 0222a090..6302358f 100644 --- a/modules/module-standard-event-source.c +++ b/modules/module-standard-event-source.c @@ -14,21 +14,32 @@ */ enum { - PROP_0, - PROP_OBJECT_MANAGER, -}; - -enum { + ACTION_GET_OBJECT_MANAGER, ACTION_PUSH_EVENT, ACTION_SCHEDULE_RESCAN, N_SIGNALS }; +typedef enum { + OBJECT_TYPE_PORT, + OBJECT_TYPE_LINK, + OBJECT_TYPE_NODE, + OBJECT_TYPE_SESSION_ITEM, + OBJECT_TYPE_ENDPOINT, + OBJECT_TYPE_CLIENT, + OBJECT_TYPE_DEVICE, + OBJECT_TYPE_METADATA, + N_OBJECT_TYPES, + OBJECT_TYPE_INVALID = N_OBJECT_TYPES +} ObjectType; + struct _WpStandardEventSource { WpPlugin parent; - WpObjectManager *om; + WpObjectManager *oms[N_OBJECT_TYPES]; + WpEventHook *rescan_done_hook; gboolean rescan_scheduled; + gint n_oms_installed; }; static guint signals[N_SIGNALS] = {0}; @@ -42,22 +53,46 @@ wp_standard_event_source_init (WpStandardEventSource * self) { } -static void -wp_standard_event_source_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) +static GType +object_type_to_gtype (ObjectType type) { - WpStandardEventSource *self = WP_STANDARD_EVENT_SOURCE (object); - - switch (property_id) { - case PROP_OBJECT_MANAGER: - g_value_set_object (value, self->om); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; + switch (type) { + case OBJECT_TYPE_PORT: return WP_TYPE_PORT; + case OBJECT_TYPE_LINK: return WP_TYPE_LINK; + case OBJECT_TYPE_NODE: return WP_TYPE_NODE; + case OBJECT_TYPE_SESSION_ITEM: return WP_TYPE_SESSION_ITEM; + case OBJECT_TYPE_ENDPOINT: return WP_TYPE_ENDPOINT; + case OBJECT_TYPE_CLIENT: return WP_TYPE_CLIENT; + case OBJECT_TYPE_DEVICE: return WP_TYPE_DEVICE; + case OBJECT_TYPE_METADATA: return WP_TYPE_METADATA; + default: + g_assert_not_reached (); } } +static ObjectType +type_str_to_object_type (const gchar * type_str) +{ + if (!g_strcmp0 (type_str, "port")) + return OBJECT_TYPE_PORT; + else if (!g_strcmp0 (type_str, "link")) + return OBJECT_TYPE_LINK; + else if (!g_strcmp0 (type_str, "node")) + return OBJECT_TYPE_NODE; + else if (!g_strcmp0 (type_str, "session-item")) + return OBJECT_TYPE_SESSION_ITEM; + else if (!g_strcmp0 (type_str, "endpoint")) + return OBJECT_TYPE_ENDPOINT; + else if (!g_strcmp0 (type_str, "client")) + return OBJECT_TYPE_CLIENT; + else if (!g_strcmp0 (type_str, "device")) + return OBJECT_TYPE_DEVICE; + else if (!g_strcmp0 (type_str, "metadata")) + return OBJECT_TYPE_METADATA; + else + return OBJECT_TYPE_INVALID; +} + static const gchar * get_object_type (gpointer obj, WpProperties **properties) { @@ -89,47 +124,57 @@ get_object_type (gpointer obj, WpProperties **properties) return "device"; else if (WP_IS_METADATA (obj)) return "metadata"; - else if (WP_IS_FACTORY (obj)) - return "factory"; wp_debug_object (obj, "Unknown global proxy type"); return G_OBJECT_TYPE_NAME (obj); } static gint -get_default_event_priority (const gchar *event_type, const gchar *subject_type) +get_default_event_priority (const gchar *event_type) { - if (!g_strcmp0 (event_type, "object-added") || - !g_strcmp0 (event_type, "object-removed")) - { - if (!g_strcmp0 (subject_type, "client")) - return 200; - else if (!g_strcmp0 (subject_type, "device")) - return 170; - else if (!g_strcmp0 (subject_type, "port")) - return 150; - else if (!g_strcmp0 (subject_type, "node")) - return 130; - else if (!g_strcmp0 (subject_type, "session-item")) - return 110; - else - return 20; - } - else if (!g_strcmp0 (event_type, "find-si-target-and-link")) + if (!g_strcmp0 (event_type, "find-target-si-and-link")) return 500; else if (!g_strcmp0 (event_type, "rescan-session")) return -500; else if (!g_strcmp0 (event_type, "node-state-changed")) return 50; - else if (!g_strcmp0 (event_type, "params-changed")) - return 50; else if (!g_strcmp0 (event_type, "metadata-changed")) return 50; + else if (g_str_has_suffix (event_type, "-params-changed")) + return 50; + else if (g_str_has_prefix (event_type, "client-")) + return 200; + else if (g_str_has_prefix (event_type, "device-")) + return 170; + else if (g_str_has_prefix (event_type, "port-")) + return 150; + else if (g_str_has_prefix (event_type, "node-")) + return 130; + else if (g_str_has_prefix (event_type, "session-item-")) + return 110; + else if (g_str_has_suffix (event_type, "-added") || + g_str_has_suffix (event_type, "-removed")) + return 20; wp_debug ("Unknown event type: %s, using priority 0", event_type); return 0; } +static WpObjectManager * +wp_standard_event_get_object_manager (WpStandardEventSource *self, + const gchar * type_str) +{ + ObjectType type = type_str_to_object_type (type_str); + + if (G_UNLIKELY (type == OBJECT_TYPE_INVALID)) { + wp_critical_object (self, "object type '%s' is not valid", type_str); + return NULL; + } + + g_return_val_if_fail (self->oms[type], NULL); + return g_object_ref (self->oms[type]); +} + static void wp_standard_event_source_push_event (WpStandardEventSource *self, const gchar *event_type, gpointer subject, WpProperties *misc_properties) @@ -140,16 +185,21 @@ wp_standard_event_source_push_event (WpStandardEventSource *self, wp_event_dispatcher_get_instance (core); g_return_if_fail (dispatcher); g_autoptr (WpProperties) properties = wp_properties_new_empty (); + g_autofree gchar *full_event_type = NULL; const gchar *subject_type = subject ? get_object_type (subject, &properties) : NULL; - gint priority = get_default_event_priority (event_type, subject_type); - if (subject_type) + if (subject_type) { wp_properties_set (properties, "event.subject.type", subject_type); + full_event_type = g_strdup_printf ("%s-%s", subject_type, event_type); + event_type = full_event_type; + } if (misc_properties) wp_properties_add (properties, misc_properties); + gint priority = get_default_event_priority (event_type); + wp_debug_object (self, "pushing event '%s', prio %d, subject " WP_OBJECT_FORMAT " (%s)", event_type, priority, WP_OBJECT_ARGS (subject), subject_type); @@ -179,8 +229,7 @@ on_metadata_changed (WpMetadata *obj, guint32 subject, wp_properties_set (properties, "event.subject.spa_type", spa_type); wp_properties_set (properties, "event.subject.value", value); - wp_standard_event_source_push_event (self, "metadata-changed", obj, - properties); + wp_standard_event_source_push_event (self, "changed", obj, properties); } static void @@ -201,14 +250,14 @@ on_node_state_changed (WpNode *obj, WpNodeState old_state, "event.subject.old-state", g_enum_to_string (WP_TYPE_NODE_STATE, old_state), "event.subject.new-state", g_enum_to_string (WP_TYPE_NODE_STATE, new_state), NULL); - wp_standard_event_source_push_event (self, "node-state-changed", obj, + wp_standard_event_source_push_event (self, "state-changed", obj, properties); } static void on_object_added (WpObjectManager *om, WpObject *obj, WpStandardEventSource *self) { - wp_standard_event_source_push_event (self, "object-added", obj, NULL); + wp_standard_event_source_push_event (self, "added", obj, NULL); if (WP_IS_PIPEWIRE_OBJECT (obj)) { g_signal_connect_object (obj, "params-changed", @@ -228,13 +277,14 @@ on_object_added (WpObjectManager *om, WpObject *obj, WpStandardEventSource *self static void on_object_removed (WpObjectManager *om, WpObject *obj, WpStandardEventSource *self) { - wp_standard_event_source_push_event (self, "object-removed", obj, NULL); + wp_standard_event_source_push_event (self, "removed", obj, NULL); } static void on_om_installed (WpObjectManager * om, WpStandardEventSource * self) { - wp_object_update_features (WP_OBJECT (self), WP_PLUGIN_FEATURE_ENABLED, 0); + if (++self->n_oms_installed == N_OBJECT_TYPES) + wp_object_update_features (WP_OBJECT (self), WP_PLUGIN_FEATURE_ENABLED, 0); } static void @@ -252,52 +302,66 @@ wp_standard_event_source_enable (WpPlugin * plugin, WpTransition * transition) g_autoptr (WpEventDispatcher) dispatcher = wp_event_dispatcher_get_instance (core); g_return_if_fail (dispatcher); - g_autoptr (WpEventHook) hook = NULL; - self->om = wp_object_manager_new (); - wp_object_manager_add_interest (self->om, WP_TYPE_GLOBAL_PROXY, NULL); - wp_object_manager_add_interest (self->om, WP_TYPE_SESSION_ITEM, NULL); - wp_object_manager_request_object_features (self->om, - WP_TYPE_GLOBAL_PROXY, WP_OBJECT_FEATURES_ALL); - g_signal_connect_object (self->om, "object-added", - G_CALLBACK (on_object_added), self, 0); - g_signal_connect_object (self->om, "object-removed", - G_CALLBACK (on_object_removed), self, 0); - g_signal_connect_object (self->om, "installed", - G_CALLBACK (on_om_installed), self, 0); - wp_core_install_object_manager (core, self->om); + /* install object managers */ + self->n_oms_installed = 0; + for (gint i = 0; i < N_OBJECT_TYPES; i++) { + GType gtype = object_type_to_gtype (i); + self->oms[i] = wp_object_manager_new (); + wp_object_manager_add_interest (self->oms[i], gtype, NULL); + wp_object_manager_request_object_features (self->oms[i], + gtype, WP_OBJECT_FEATURES_ALL); + g_signal_connect_object (self->oms[i], "object-added", + G_CALLBACK (on_object_added), self, 0); + g_signal_connect_object (self->oms[i], "object-removed", + G_CALLBACK (on_object_removed), self, 0); + g_signal_connect_object (self->oms[i], "installed", + G_CALLBACK (on_om_installed), self, 0); + wp_core_install_object_manager (core, self->oms[i]); + } - hook = wp_simple_event_hook_new ("rescan-done@std-event-source", + /* install hook to restore the rescan_scheduled state after rescanning */ + self->rescan_done_hook = wp_simple_event_hook_new ( + "rescan-done@std-event-source", WP_EVENT_HOOK_PRIORITY_LOWEST, WP_EVENT_HOOK_EXEC_TYPE_ON_EVENT, g_cclosure_new_object ((GCallback) on_rescan_done, G_OBJECT (self))); - wp_interest_event_hook_add_interest (WP_INTEREST_EVENT_HOOK (hook), + wp_interest_event_hook_add_interest ( + WP_INTEREST_EVENT_HOOK (self->rescan_done_hook), WP_CONSTRAINT_TYPE_PW_PROPERTY, "event.type", "=s", "rescan-session", NULL); - wp_event_dispatcher_register_hook (dispatcher, hook); + wp_event_dispatcher_register_hook (dispatcher, self->rescan_done_hook); } static void wp_standard_event_source_disable (WpPlugin * plugin) { WpStandardEventSource * self = WP_STANDARD_EVENT_SOURCE (plugin); - g_clear_object (&self->om); + g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (plugin)); + g_return_if_fail (core); + g_autoptr (WpEventDispatcher) dispatcher = + wp_event_dispatcher_get_instance (core); + + for (gint i = 0; i < N_OBJECT_TYPES; i++) + g_clear_object (&self->oms[i]); + + if (dispatcher) + wp_event_dispatcher_unregister_hook (dispatcher, self->rescan_done_hook); + g_clear_object (&self->rescan_done_hook); } static void wp_standard_event_source_class_init (WpStandardEventSourceClass * klass) { - GObjectClass *object_class = (GObjectClass *) klass; WpPluginClass *plugin_class = (WpPluginClass *) klass; - object_class->get_property = wp_standard_event_source_get_property; - plugin_class->enable = wp_standard_event_source_enable; plugin_class->disable = wp_standard_event_source_disable; - g_object_class_install_property (object_class, PROP_OBJECT_MANAGER, - g_param_spec_string ("object-manager", "object-manager", - "The WpObjectManager instance that is used to generate events", NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + signals[ACTION_GET_OBJECT_MANAGER] = g_signal_new_class_handler ( + "get-object-manager", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + (GCallback) wp_standard_event_get_object_manager, + NULL, NULL, NULL, WP_TYPE_OBJECT_MANAGER, 1, G_TYPE_STRING); signals[ACTION_PUSH_EVENT] = g_signal_new_class_handler ( "push-event", G_TYPE_FROM_CLASS (klass), diff --git a/src/scripts/create-item.lua b/src/scripts/create-item.lua index ca032098..b1ed27ff 100644 --- a/src/scripts/create-item.lua +++ b/src/scripts/create-item.lua @@ -71,18 +71,15 @@ AsyncEventHook { priority = HookPriority.LOW, interests = { EventInterest { - Constraint { "event.type", "=", "object-added" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-added" }, Constraint { "media.class", "#", "Stream/*", type = "pw-global" }, }, EventInterest { - Constraint { "event.type", "=", "object-added" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-added" }, Constraint { "media.class", "#", "Video/*", type = "pw-global" }, }, EventInterest { - Constraint { "event.type", "=", "object-added" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-added" }, Constraint { "media.class", "#", "Audio/*", type = "pw-global" }, Constraint { "wireplumber.is-endpoint", "-", type = "pw" }, }, @@ -146,18 +143,15 @@ SimpleEventHook { priority = HookPriority.LOW, interests = { EventInterest { - Constraint { "event.type", "=", "object-removed" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-removed" }, Constraint { "media.class", "#", "Stream/*", type = "pw-global" }, }, EventInterest { - Constraint { "event.type", "=", "object-removed" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-removed" }, Constraint { "media.class", "#", "Video/*", type = "pw-global" }, }, EventInterest { - Constraint { "event.type", "=", "object-removed" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-removed" }, Constraint { "media.class", "#", "Audio/*", type = "pw-global" }, Constraint { "wireplumber.is-endpoint", "-", type = "pw" }, }, diff --git a/src/scripts/lib/policy-utils.lua b/src/scripts/lib/policy-utils.lua index 341ffff3..010c2447 100644 --- a/src/scripts/lib/policy-utils.lua +++ b/src/scripts/lib/policy-utils.lua @@ -33,10 +33,10 @@ function putils.unwrap_find_target_event (self, event) local source = event:get_source () local si = event:get_subject () local target = event:get_data ("target") + local om = source:call ("get-object-manager", "session-item") local si_id = si.id - return source, source ["object-manager"], - si, si.properties, self:get_flags (si_id), target + return source, om, si, si.properties, self:get_flags (si_id), target end function putils.canPassthrough (si, si_target) diff --git a/src/scripts/policy-bluetooth.lua b/src/scripts/policy-bluetooth.lua index a7084532..b70c5f88 100644 --- a/src/scripts/policy-bluetooth.lua +++ b/src/scripts/policy-bluetooth.lua @@ -391,8 +391,7 @@ SimpleEventHook { priority = HookPriority.NORMAL, interests = { EventInterest { - Constraint { "event.type", "=", "object-removed" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-removed" }, Constraint { "media.class", "matches", "Stream/Input/Audio", type = "pw-global" }, }, }, @@ -410,15 +409,13 @@ SimpleEventHook { priority = HookPriority.NORMAL, interests = { EventInterest { - Constraint { "event.type", "=", "state-changed" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-state-changed" }, Constraint { "media.class", "#", "Stream/Input/Audio", type = "pw-global" }, -- Do not consider monitor streams Constraint { "stream.monitor", "!", "true" } }, EventInterest { - Constraint { "event.type", "=", "params-changed" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-params-changed" }, Constraint { "media.class", "#", "Stream/Input/Audio", type = "pw-global" }, -- Do not consider monitor streams Constraint { "stream.monitor", "!", "true" } @@ -435,8 +432,7 @@ SimpleEventHook { priority = HookPriority.VERY_LOW, interests = { EventInterest { - Constraint { "event.type", "=", "object-added" }, - Constraint { "event.subject.type", "=", "device" }, + Constraint { "event.type", "=", "device-added" }, Constraint { "device.api", "=", "bluez5" }, }, }, @@ -456,8 +452,7 @@ SimpleEventHook { priority = HookPriority.VERY_LOW, interests = { EventInterest { - Constraint { "event.type", "=", "object-changed" }, - Constraint { "event.subject.type", "=", "metadata" }, + Constraint { "event.type", "=", "metadata-changed" }, Constraint { "metadata.name", "=", "default" }, Constraint { "event.subject.key", "=", "default.audio.sink" }, Constraint { "event.subject.id", "=", "0" }, diff --git a/src/scripts/policy-desktop/filter-forward-format.lua b/src/scripts/policy-desktop/filter-forward-format.lua index d5597f4e..d90bc01a 100644 --- a/src/scripts/policy-desktop/filter-forward-format.lua +++ b/src/scripts/policy-desktop/filter-forward-format.lua @@ -21,7 +21,7 @@ function findAssociatedLinkGroupNode (si) end local std_event_source = Plugin.find ("standard-event-source") - local om = std_event_source ["object-manager"] + local om = std_event_source:call ("get-object-manager", "session-item") -- get the associated media class local assoc_direction = cutils.getTargetDirection (si_props) @@ -84,8 +84,8 @@ SimpleEventHook { priority = HookPriority.NORMAL, interests = { EventInterest { - Constraint { "event.type", "=", "object-added" }, - Constraint { "event.subject.type", "=", "linkable" }, + Constraint { "event.type", "=", "session-item-added" }, + Constraint { "event.session-item.interface", "=", "linkable" }, Constraint { "item.factory.name", "c", "si-audio-adapter", "si-node" }, Constraint { "media.class", "#", "Stream/*", type = "pw-global" }, Constraint { "active-features", "!", 0, type = "gobject" }, diff --git a/src/scripts/policy-desktop/prepare-link.lua b/src/scripts/policy-desktop/prepare-link.lua index 5994d5d2..b1af0b30 100644 --- a/src/scripts/policy-desktop/prepare-link.lua +++ b/src/scripts/policy-desktop/prepare-link.lua @@ -21,7 +21,7 @@ SimpleEventHook { }, }, execute = function (event) - local source, om, si, si_props, si_flags, target = + local source, _, si, si_props, si_flags, target = putils:unwrap_find_target_event (event) local reconnect = not cutils.parseBool (si_props ["node.dont-reconnect"]) @@ -104,8 +104,8 @@ SimpleEventHook { local client_id = node.properties ["client.id"] if client_id then - local client = om:lookup { - type = "client", + local clients_om = source:call ("get-object-manager", "client") + local client = clients_om:lookup { Constraint { "bound-id", "=", client_id, type = "gobject" } } if client then diff --git a/src/scripts/policy-desktop/rescan.lua b/src/scripts/policy-desktop/rescan.lua index f0e4f6f7..b393b7b8 100644 --- a/src/scripts/policy-desktop/rescan.lua +++ b/src/scripts/policy-desktop/rescan.lua @@ -36,14 +36,14 @@ SimpleEventHook { priority = HookPriority.VERY_LOW, interests = { EventInterest { - Constraint { "event.type", "=", "object-removed" }, - Constraint { "event.subject.type", "=", "linkable" }, + Constraint { "event.type", "=", "session-item-removed" }, + Constraint { "event.session-item.interface", "=", "linkable" }, }, }, execute = function (event) local si = event:get_subject () local source = event:get_source () - local om = source ["object-manager"] + local om = source:call ("get-object-manager", "session-item") local si_id = si.id local valid, si_props = checkLinkable (si, om, true) if not valid then @@ -91,7 +91,7 @@ SimpleEventHook { }, execute = function (event) local source = event:get_source () - local om = source ["object-manager"] + local om = source:call ("get-object-manager", "session-item") Log.info ("rescanning...") @@ -125,14 +125,13 @@ SimpleEventHook { interests = { -- on linkable added or removed, where linkable is adapter or plain node EventInterest { - Constraint { "event.type", "c", "object-added", "object-removed" }, - Constraint { "event.subject.type", "=", "linkable" }, + Constraint { "event.type", "c", "session-item-added", "session-item-removed" }, + Constraint { "event.session-item.interface", "=", "linkable" }, Constraint { "item.factory.name", "c", "si-audio-adapter", "si-node" }, }, -- on device Routes changed EventInterest { - Constraint { "event.type", "=", "params-changed" }, - Constraint { "event.subject.type", "=", "device" }, + Constraint { "event.type", "=", "device-params-changed" }, Constraint { "event.subject.param-id", "=", "Route" }, }, }, diff --git a/src/scripts/policy-device-profile.lua b/src/scripts/policy-device-profile.lua index 1aa63579..48746efd 100644 --- a/src/scripts/policy-device-profile.lua +++ b/src/scripts/policy-device-profile.lua @@ -107,19 +107,17 @@ SimpleEventHook { priority = HookPriority.LOW, interests = { EventInterest { - Constraint { "event.type", "=", "object-added" }, - Constraint { "event.subject.type", "=", "device" }, + Constraint { "event.type", "=", "device-added" }, }, EventInterest { - Constraint { "event.type", "=", "params-changed" }, - Constraint { "event.subject.type", "=", "device" }, + Constraint { "event.type", "=", "device-params-changed" }, Constraint { "event.subject.param-id", "=", "EnumProfile" }, }, }, execute = function (event) local device = event:get_subject () local event_properties = event:get_properties () - local new_device = (event_properties ["event.type"] == "object-added") + local new_device = (event_properties ["event.type"] == "device-added") local dev_id = device ["bound-id"] local dev_name = device.properties ["device.name"] @@ -172,8 +170,7 @@ SimpleEventHook { priority = HookPriority.NORMAL, interests = { EventInterest { - Constraint { "event.type", "=", "object-removed" }, - Constraint { "event.subject.type", "=", "device" }, + Constraint { "event.type", "=", "device-removed" }, }, }, execute = function (event) diff --git a/src/scripts/policy-device-routes.lua b/src/scripts/policy-device-routes.lua index bf089cad..a1c81672 100644 --- a/src/scripts/policy-device-routes.lua +++ b/src/scripts/policy-device-routes.lua @@ -515,13 +515,11 @@ SimpleEventHook { priority = HookPriority.ULTRA_LOW, interests = { EventInterest { - Constraint { "event.type", "=", "params-changed" }, - Constraint { "event.subject.type", "=", "device" }, + Constraint { "event.type", "=", "device-params-changed" }, Constraint { "event.subject.param-id", "=", "Route" }, }, EventInterest { - Constraint { "event.type", "=", "params-changed" }, - Constraint { "event.subject.type", "=", "device" }, + Constraint { "event.type", "=", "device-params-changed" }, Constraint { "event.subject.param-id", "=", "EnumRoute" }, }, }, diff --git a/src/scripts/restore-stream.lua b/src/scripts/restore-stream.lua index 1061f23e..8f15026d 100644 --- a/src/scripts/restore-stream.lua +++ b/src/scripts/restore-stream.lua @@ -349,8 +349,7 @@ local function handleRestoreTargetSetting (enable) priority = HookPriority.ULTRA_LOW, interests = { EventInterest { - Constraint { "event.type", "=", "object-added" }, - Constraint { "event.subject.type", "=", "metadata" }, + Constraint { "event.type", "=", "metadata-added" }, Constraint { "metadata.name", "=", "default" }, }, }, @@ -473,20 +472,17 @@ local function handleRestoreStreamSetting (enable) priority = HookPriority.NORMAL, interests = { EventInterest { - Constraint { "event.type", "=", "object-added" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-added" }, Constraint { "media.class", "matches", "Stream/*", type = "pw-global" }, }, -- and device nodes that are not associated with any routes EventInterest { - Constraint { "event.type", "=", "object-added" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-added" }, Constraint { "media.class", "matches", "Audio/*", type = "pw-global" }, Constraint { "device.routes", "is-absent", type = "pw" }, }, EventInterest { - Constraint { "event.type", "=", "object-added" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-added" }, Constraint { "media.class", "matches", "Audio/*", type = "pw-global" }, Constraint { "device.routes", "equals", "0", type = "pw" }, }, @@ -503,22 +499,19 @@ local function handleRestoreStreamSetting (enable) priority = HookPriority.NORMAL, interests = { EventInterest { - Constraint { "event.type", "=", "params-changed" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-params-changed" }, Constraint { "event.subject.param-id", "=", "Props" }, Constraint { "media.class", "matches", "Stream/*", type = "pw-global" }, }, -- and device nodes that are not associated with any routes EventInterest { - Constraint { "event.type", "=", "params-changed" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-params-changed" }, Constraint { "event.subject.param-id", "=", "Props" }, Constraint { "media.class", "matches", "Audio/*", type = "pw-global" }, Constraint { "device.routes", "is-absent", type = "pw" }, }, EventInterest { - Constraint { "event.type", "=", "params-changed" }, - Constraint { "event.subject.type", "=", "node" }, + Constraint { "event.type", "=", "node-params-changed" }, Constraint { "event.subject.param-id", "=", "Props" }, Constraint { "media.class", "matches", "Audio/*", type = "pw-global" }, Constraint { "device.routes", "equals", "0", type = "pw" },