diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2012-10-26 13:41:27 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-10-30 15:35:58 +0100 |
commit | 0ca6ae1b4b142dfa947bec45c833388f86cc9709 (patch) | |
tree | babbea5b0360bb252154903ee9487589d2a5e789 /src/mm-plugin-manager.c | |
parent | e5b4b4d0e5ab11a581504ce88be2a1aa317524e8 (diff) |
plugin-manager,plugin: run pre-probing filters early
For each port, we will construct the list of plugins to test with. In that list
we will include those plugins which are likely to handle a given port, so we
will skip all those which aren't.
To see if a plugin is likely or not, we will run the pre-probing filters before
adding them to the list, with the new `mm_plugin_discard_port_early()'. This
method will return one of these hints:
* UNSUPPORTED: The plugin will not be able to handle this port.
* MAYBE: The plugin may handle this port.
* LIKELY: The plugin may (very likely) handle this port.
* SUPPORTED: If any plugin should support the port, this is it.
Plugins reported to be 'likely' supporting the port will be probed before the
ones reported just as 'maybe'.
If a plugin reports 'supported' only that one and the fallback generic ones will
be tried.
Diffstat (limited to 'src/mm-plugin-manager.c')
-rw-r--r-- | src/mm-plugin-manager.c | 119 |
1 files changed, 86 insertions, 33 deletions
diff --git a/src/mm-plugin-manager.c b/src/mm-plugin-manager.c index d5759b65..56290e19 100644 --- a/src/mm-plugin-manager.c +++ b/src/mm-plugin-manager.c @@ -42,9 +42,12 @@ G_DEFINE_TYPE_EXTENDED (MMPluginManager, mm_plugin_manager, G_TYPE_OBJECT, 0, initable_iface_init)); struct _MMPluginManagerPrivate { - /* The list of plugins. It is loaded once when the program starts, and the - * list is NOT expected to change after that. */ + /* This list contains all plugins except for the generic one, order is not + * important. It is loaded once when the program starts, and the list is NOT + * expected to change after that.*/ GList *plugins; + /* Last, the generic plugin. */ + MMPlugin *generic; }; /*****************************************************************************/ @@ -65,6 +68,7 @@ typedef struct { FindDeviceSupportContext *parent_ctx; GUdevDevice *port; + GList *plugins; GList *current; MMPlugin *best_plugin; MMPlugin *suggested_plugin; @@ -86,6 +90,8 @@ port_probe_context_free (PortProbeContext *ctx) g_object_unref (ctx->best_plugin); if (ctx->suggested_plugin) g_object_unref (ctx->suggested_plugin); + if (ctx->plugins) + g_list_free_full (ctx->plugins, (GDestroyNotify)g_object_unref); g_object_unref (ctx->port); g_slice_free (PortProbeContext, ctx); } @@ -426,6 +432,62 @@ port_probe_context_step (PortProbeContext *port_probe_ctx) port_probe_ctx); } +static GList * +build_plugins_list (MMPluginManager *self, + MMDevice *device, + GUdevDevice *port) +{ + GList *list = NULL; + GList *l; + gboolean supported_found = FALSE; + + for (l = self->priv->plugins; l && !supported_found; l = g_list_next (l)) { + MMPluginSupportsHint hint; + + hint = mm_plugin_discard_port_early (MM_PLUGIN (l->data), device, port); + switch (hint) { + case MM_PLUGIN_SUPPORTS_HINT_UNSUPPORTED: + /* Fully discard */ + break; + case MM_PLUGIN_SUPPORTS_HINT_MAYBE: + /* Maybe supported, add to tail of list */ + list = g_list_append (list, g_object_ref (l->data)); + break; + case MM_PLUGIN_SUPPORTS_HINT_LIKELY: + /* Likely supported, add to head of list */ + list = g_list_prepend (list, g_object_ref (l->data)); + break; + case MM_PLUGIN_SUPPORTS_HINT_SUPPORTED: + /* Really supported, clean existing list and add it alone */ + if (list) { + g_list_free_full (list, (GDestroyNotify)g_object_unref); + list = NULL; + } + list = g_list_prepend (list, g_object_ref (l->data)); + /* This will end the loop as well */ + supported_found = TRUE; + break; + default: + g_assert_not_reached(); + } + } + + /* Add the generic plugin at the end of the list */ + if (self->priv->generic) + list = g_list_append (list, g_object_ref (self->priv->generic)); + + mm_info ("(Plugin Manager) [%s] Found '%u' plugins to try...", + g_udev_device_get_name (port), + g_list_length (list)); + for (l = list; l; l = g_list_next (l)) { + mm_info ("(Plugin Manager) [%s] Will try with plugin '%s'", + g_udev_device_get_name (port), + mm_plugin_get_name (MM_PLUGIN (l->data))); + } + + return list; +} + static void device_port_grabbed_cb (MMDevice *device, GUdevDevice *port, @@ -433,17 +495,15 @@ device_port_grabbed_cb (MMDevice *device, { PortProbeContext *port_probe_ctx; - mm_dbg ("(%s/%s) Launching port support check", - g_udev_device_get_subsystem (port), - g_udev_device_get_name (port)); /* Launch probing task on this port with the first plugin of the list */ port_probe_ctx = g_slice_new0 (PortProbeContext); port_probe_ctx->parent_ctx = ctx; port_probe_ctx->port = g_object_ref (port); - /* Set first plugin to check */ - port_probe_ctx->current = ctx->self->priv->plugins; + /* Setup plugins to probe and first one to check */ + port_probe_ctx->plugins = build_plugins_list (ctx->self, device, port); + port_probe_ctx->current = port_probe_ctx->plugins; /* If we got one suggested, it will be the first one */ port_probe_ctx->suggested_plugin = (!!mm_device_peek_plugin (device) ? @@ -585,9 +645,7 @@ load_plugins (MMPluginManager *self, { GDir *dir = NULL; const gchar *fname; - MMPlugin *generic_plugin = NULL; gchar *plugindir_display = NULL; - GList *l; if (!g_module_supported ()) { g_set_error (error, @@ -622,27 +680,25 @@ load_plugins (MMPluginManager *self, plugin = load_plugin (path); g_free (path); - if (plugin) { - if (g_str_equal (mm_plugin_get_name (plugin), - MM_PLUGIN_GENERIC_NAME)) - generic_plugin = plugin; - else - self->priv->plugins = g_list_append (self->priv->plugins, - plugin); - } - } + if (!plugin) + continue; + + mm_info ("Loaded plugin '%s'", mm_plugin_get_name (plugin)); - /* Sort last plugins that request it */ - self->priv->plugins = g_list_sort (self->priv->plugins, - (GCompareFunc)mm_plugin_cmp); + if (g_str_equal (mm_plugin_get_name (plugin), MM_PLUGIN_GENERIC_NAME)) + /* Generic plugin */ + self->priv->generic = plugin; + else + /* Vendor specific plugin */ + self->priv->plugins = g_list_append (self->priv->plugins, plugin); + } - /* Make sure the generic plugin is last */ - if (generic_plugin) - self->priv->plugins = g_list_append (self->priv->plugins, - generic_plugin); + /* Check the generic plugin once all looped */ + if (!self->priv->generic) + mm_warn ("Generic plugin not loaded"); /* Treat as error if we don't find any plugin */ - if (!self->priv->plugins) { + if (!self->priv->plugins && !self->priv->generic) { g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NO_PLUGINS, @@ -651,20 +707,16 @@ load_plugins (MMPluginManager *self, goto out; } - /* Now report about all the found plugins, in the same order they will be - * used while checking support */ - for (l = self->priv->plugins; l; l = g_list_next (l)) - mm_info ("Loaded plugin '%s'", mm_plugin_get_name (MM_PLUGIN (l->data))); - mm_info ("Successfully loaded %u plugins", - g_list_length (self->priv->plugins)); + g_list_length (self->priv->plugins) + !!self->priv->generic); out: if (dir) g_dir_close (dir); g_free (plugindir_display); - return !!self->priv->plugins; + /* Return TRUE if at least one plugin found */ + return (self->priv->plugins || self->priv->generic); } MMPluginManager * @@ -704,6 +756,7 @@ dispose (GObject *object) g_list_free_full (self->priv->plugins, (GDestroyNotify)g_object_unref); self->priv->plugins = NULL; } + g_clear_object (&self->priv->generic); G_OBJECT_CLASS (mm_plugin_manager_parent_class)->dispose (object); } |