aboutsummaryrefslogtreecommitdiff
path: root/src/mm-plugin-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mm-plugin-manager.c')
-rw-r--r--src/mm-plugin-manager.c119
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);
}