[gnome-software/wip/hughsie/xdg-app] Add initial untested xdg-app support
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/hughsie/xdg-app] Add initial untested xdg-app support
- Date: Mon, 2 Feb 2015 10:42:15 +0000 (UTC)
commit 128af6621d123278bb317dfed921900c659032b0
Author: Richard Hughes <richard hughsie com>
Date: Mon Feb 2 10:41:53 2015 +0000
Add initial untested xdg-app support
src/gs-cmd.c | 12 +-
src/gs-plugin-loader-sync.c | 48 +++++
src/gs-plugin-loader-sync.h | 4 +
src/gs-plugin-loader.c | 108 +++++++++++
src/gs-plugin-loader.h | 8 +
src/gs-plugin.h | 8 +
src/plugins/Makefile.am | 6 +
src/plugins/gs-plugin-appstream.c | 2 +
src/plugins/gs-plugin-xdg-app.c | 377 +++++++++++++++++++++++++++++++++++++
9 files changed, 572 insertions(+), 1 deletions(-)
---
diff --git a/src/gs-cmd.c b/src/gs-cmd.c
index c810d21..27d96f0 100644
--- a/src/gs-cmd.c
+++ b/src/gs-cmd.c
@@ -280,6 +280,16 @@ main (int argc, char **argv)
if (!ret)
break;
}
+ } else if (argc == 3 && g_strcmp0 (argv[1], "launch") == 0) {
+ app = gs_app_new (argv[2]);
+ for (i = 0; i < repeat; i++) {
+ ret = gs_plugin_loader_app_launch (plugin_loader,
+ app,
+ NULL,
+ &error);
+ if (!ret)
+ break;
+ }
} else if (argc == 3 && g_strcmp0 (argv[1], "filename-to-app") == 0) {
app = gs_plugin_loader_filename_to_app (plugin_loader,
argv[2],
@@ -384,7 +394,7 @@ main (int argc, char **argv)
"Did not recognise option, use 'installed', "
"'updates', 'popular', 'get-categories', "
"'get-category-apps', 'filename-to-app', "
- "'sources', or 'search'");
+ "'sources', 'launch', or 'search'");
}
if (!ret) {
g_print ("Failed: %s\n", error->message);
diff --git a/src/gs-plugin-loader-sync.c b/src/gs-plugin-loader-sync.c
index 94c085c..2d5541a 100644
--- a/src/gs-plugin-loader-sync.c
+++ b/src/gs-plugin-loader-sync.c
@@ -474,6 +474,54 @@ gs_plugin_loader_app_refine (GsPluginLoader *plugin_loader,
}
/**
+ * gs_plugin_loader_app_launch_finish_sync:
+ **/
+static void
+gs_plugin_loader_app_launch_finish_sync (GsPluginLoader *plugin_loader,
+ GAsyncResult *res,
+ GsPluginLoaderHelper *helper)
+{
+ helper->ret = gs_plugin_loader_app_launch_finish (plugin_loader,
+ res,
+ helper->error);
+ g_main_loop_quit (helper->loop);
+}
+
+/**
+ * gs_plugin_loader_app_launch:
+ **/
+gboolean
+gs_plugin_loader_app_launch (GsPluginLoader *plugin_loader,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GsPluginLoaderHelper helper;
+
+ /* create temp object */
+ helper.context = g_main_context_new ();
+ helper.loop = g_main_loop_new (helper.context, FALSE);
+ helper.error = error;
+
+ g_main_context_push_thread_default (helper.context);
+
+ /* run async method */
+ gs_plugin_loader_app_launch_async (plugin_loader,
+ app,
+ cancellable,
+ (GAsyncReadyCallback) gs_plugin_loader_app_launch_finish_sync,
+ &helper);
+ g_main_loop_run (helper.loop);
+
+ g_main_context_pop_thread_default (helper.context);
+
+ g_main_loop_unref (helper.loop);
+ g_main_context_unref (helper.context);
+
+ return helper.ret;
+}
+
+/**
* gs_plugin_loader_app_action_finish_sync:
**/
static void
diff --git a/src/gs-plugin-loader-sync.h b/src/gs-plugin-loader-sync.h
index 33771db..3be5870 100644
--- a/src/gs-plugin-loader-sync.h
+++ b/src/gs-plugin-loader-sync.h
@@ -69,6 +69,10 @@ gboolean gs_plugin_loader_app_refine (GsPluginLoader *plugin_loader,
GsPluginRefineFlags flags,
GCancellable *cancellable,
GError **error);
+gboolean gs_plugin_loader_app_launch (GsPluginLoader *plugin_loader,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error);
gboolean gs_plugin_loader_app_action (GsPluginLoader *plugin_loader,
GsApp *app,
GsPluginLoaderAction action,
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index f86795e..79dff31 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -326,6 +326,36 @@ out:
}
/**
+ * gs_plugin_loader_run_launch:
+ **/
+static gboolean
+gs_plugin_loader_run_launch (GsPluginLoader *plugin_loader,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GsPluginLaunchFunc plugin_func = NULL;
+ GsPlugin *plugin;
+ gboolean ret = TRUE;
+ guint i;
+
+ /* run each plugin */
+ for (i = 0; i < plugin_loader->priv->plugins->len; i++) {
+ plugin = g_ptr_array_index (plugin_loader->priv->plugins, i);
+ if (!plugin->enabled)
+ continue;
+ if (!g_module_symbol (plugin->module,
+ "gs_plugin_launch",
+ (gpointer *) &plugin_func))
+ continue;
+ ret = plugin_func (plugin, app, cancellable, error);
+ if (!ret)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
* gs_plugin_loader_run_results_plugin:
**/
static gboolean
@@ -2095,6 +2125,84 @@ gs_plugin_loader_app_refine_finish (GsPluginLoader *plugin_loader,
/******************************************************************************/
+/**
+ * gs_plugin_loader_app_launch_thread_cb:
+ **/
+static void
+gs_plugin_loader_app_launch_thread_cb (GTask *task,
+ gpointer object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ GError *error = NULL;
+ GsPluginLoaderAsyncState *state = (GsPluginLoaderAsyncState *) task_data;
+ GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (object);
+ gboolean ret;
+
+ ret = gs_plugin_loader_run_launch (plugin_loader,
+ state->app,
+ cancellable,
+ &error);
+ if (!ret) {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ /* success */
+ g_task_return_boolean (task, TRUE);
+}
+
+/**
+ * gs_plugin_loader_app_launch_async:
+ *
+ * This method calls all plugins that implement the gs_plugin_launch()
+ * function.
+ **/
+void
+gs_plugin_loader_app_launch_async (GsPluginLoader *plugin_loader,
+ GsApp *app,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GsPluginLoaderAsyncState *state;
+ _cleanup_object_unref_ GTask *task = NULL;
+
+ g_return_if_fail (GS_IS_PLUGIN_LOADER (plugin_loader));
+ g_return_if_fail (GS_IS_APP (app));
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ /* save state */
+ state = g_slice_new0 (GsPluginLoaderAsyncState);
+ state->app = g_object_ref (app);
+
+ /* run in a thread */
+ task = g_task_new (plugin_loader, cancellable, callback, user_data);
+ g_task_set_task_data (task, state, (GDestroyNotify) gs_plugin_loader_free_async_state);
+ g_task_set_return_on_cancel (task, TRUE);
+ g_task_run_in_thread (task, gs_plugin_loader_app_launch_thread_cb);
+}
+
+/**
+ * gs_plugin_loader_app_launch_finish:
+ *
+ * Return value: success
+ **/
+gboolean
+gs_plugin_loader_app_launch_finish (GsPluginLoader *plugin_loader,
+ GAsyncResult *res,
+ GError **error)
+{
+ g_return_val_if_fail (GS_IS_PLUGIN_LOADER (plugin_loader), FALSE);
+ g_return_val_if_fail (G_IS_TASK (res), FALSE);
+ g_return_val_if_fail (g_task_is_valid (res, plugin_loader), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+/******************************************************************************/
+
static gboolean
emit_pending_apps_idle (gpointer loader)
{
diff --git a/src/gs-plugin-loader.h b/src/gs-plugin-loader.h
index 474de8a..3e58155 100644
--- a/src/gs-plugin-loader.h
+++ b/src/gs-plugin-loader.h
@@ -175,6 +175,14 @@ void gs_plugin_loader_app_refine_async (GsPluginLoader
*plugin_loader,
gboolean gs_plugin_loader_app_refine_finish (GsPluginLoader *plugin_loader,
GAsyncResult *res,
GError **error);
+void gs_plugin_loader_app_launch_async (GsPluginLoader *plugin_loader,
+ GsApp *app,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean gs_plugin_loader_app_launch_finish (GsPluginLoader *plugin_loader,
+ GAsyncResult *res,
+ GError **error);
void gs_plugin_loader_app_action_async (GsPluginLoader *plugin_loader,
GsApp *app,
GsPluginLoaderAction a,
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index 84ee6f4..65e5f6b 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -143,6 +143,10 @@ typedef gboolean (*GsPluginRefineFunc) (GsPlugin *plugin,
GsPluginRefineFlags flags,
GCancellable *cancellable,
GError **error);
+typedef gboolean (*GsPluginLaunchFunc) (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error);
typedef gboolean (*GsPluginRefreshFunc ) (GsPlugin *plugin,
guint cache_age,
GsPluginRefreshFlags flags,
@@ -222,6 +226,10 @@ gboolean gs_plugin_refine (GsPlugin *plugin,
GsPluginRefineFlags flags,
GCancellable *cancellable,
GError **error);
+gboolean gs_plugin_launch (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error);
gboolean gs_plugin_app_install (GsPlugin *plugin,
GsApp *app,
GCancellable *cancellable,
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index de60263..4ddd455 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -26,6 +26,7 @@ noinst_LTLIBRARIES = \
plugindir = $(libdir)/gs-plugins-${GS_PLUGIN_API_VERSION}
plugin_LTLIBRARIES = \
+ libgs_plugin_xdg_app.la \
libgs_plugin_appstream.la \
libgs_plugin_hardcoded-featured.la \
libgs_plugin_hardcoded-categories.la \
@@ -80,6 +81,11 @@ libgs_plugin_appstream_la_LIBADD = $(GS_PLUGIN_LIBS) $(APPSTREAM_LIBS)
libgs_plugin_appstream_la_LDFLAGS = -module -avoid-version
libgs_plugin_appstream_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+libgs_plugin_xdg_app_la_SOURCES = gs-plugin-xdg-app.c
+libgs_plugin_xdg_app_la_LIBADD = $(GS_PLUGIN_LIBS)
+libgs_plugin_xdg_app_la_LDFLAGS = -module -avoid-version
+libgs_plugin_xdg_app_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+
libgs_plugin_moduleset_la_SOURCES = \
gs-moduleset.c \
gs-moduleset.h \
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index 50c9423..f571f9b 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -92,6 +92,8 @@ gs_plugin_initialize (GsPlugin *plugin)
G_CALLBACK (gs_plugin_appstream_store_changed_cb),
plugin);
+gs_plugin_set_enabled (plugin, FALSE);
+
/* AppInstall does not ever give us a long description */
if (gs_plugin_check_distro_id (plugin, "debian") ||
gs_plugin_check_distro_id (plugin, "ubuntu")) {
diff --git a/src/plugins/gs-plugin-xdg-app.c b/src/plugins/gs-plugin-xdg-app.c
new file mode 100644
index 0000000..0887fda
--- /dev/null
+++ b/src/plugins/gs-plugin-xdg-app.c
@@ -0,0 +1,377 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2015 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/* Notes:
+ *
+ * All GsApp's created have management-plugin set to XgdApp
+ * Some GsApp's created have have XgdApp::type of app or runtime
+ * The GsApp:source is the remote name, e.g. test-repo
+ */
+
+#include <config.h>
+
+#include <gs-plugin.h>
+
+struct GsPluginPrivate {
+ guint dummy;
+};
+
+/**
+ * gs_plugin_get_name:
+ */
+const gchar *
+gs_plugin_get_name (void)
+{
+ return "xdg-app";
+}
+
+/**
+ * gs_plugin_initialize:
+ */
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+ /* create private area */
+ plugin->priv = GS_PLUGIN_GET_PRIVATE (GsPluginPrivate);
+ plugin->priv->dummy = 999;
+}
+
+/**
+ * gs_plugin_destroy:
+ */
+void
+gs_plugin_destroy (GsPlugin *plugin)
+{
+ plugin->priv->dummy = 0;
+}
+
+/**
+ * gs_plugin_xdg_app_exec:
+ */
+static gchar **
+gs_plugin_xdg_app_exec (const gchar **args, GError **error)
+{
+ GPtrArray *results = NULL;
+ gboolean ret;
+ gint exit_status = 0;
+ guint i;
+ guint len;
+ _cleanup_free_ gchar *standard_error = NULL;
+ _cleanup_free_ gchar *standard_output = NULL;
+ _cleanup_strv_free_ gchar **argv = NULL;
+ _cleanup_strv_free_ gchar **lines = NULL;
+
+ /* create argv */
+ len = g_strv_length ((gchar **) args);
+ argv = g_new0 (gchar *, len + 2);
+ argv[0] = g_strdup ("xdg-app");
+ for (i = 0; i < len; i++)
+ argv[i + 1] = g_strdup (args[i]);
+
+ /* run tool */
+ ret = g_spawn_sync (NULL, (gchar **) argv, (gchar **) NULL,
+ G_SPAWN_SEARCH_PATH |
+ G_SPAWN_CLOEXEC_PIPES,
+ NULL, NULL,
+ &standard_output, &standard_error,
+ &exit_status, error);
+ if (!ret)
+ return NULL;
+ if (exit_status != 0) {
+ _cleanup_free_ gchar *tmp = g_strjoinv (" ", (gchar **) argv);
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "Failed to launch '%s': %s",
+ tmp, standard_error);
+ return NULL;
+ }
+
+ /* only return valid lines */
+ lines = g_strsplit (standard_output, "\n", -1);
+ results = g_ptr_array_new ();
+ for (i = 0; lines[i] != NULL; i++) {
+ g_debug ("line %i: '%s'", i, lines[i]);
+ if (lines[i][0] == '\0')
+ continue;
+ if (g_strstr_len (lines[i], -1, "MESSAGE") != NULL)
+ continue;
+ if (g_strstr_len (lines[i], -1, "DEBUG") != NULL)
+ continue;
+ g_ptr_array_add (results, g_strdup (lines[i]));
+ }
+ g_ptr_array_add (results, NULL);
+ return (gchar **) g_ptr_array_free (results, FALSE);
+}
+
+/**
+ * gs_plugin_add_search:
+ */
+gboolean
+gs_plugin_add_search (GsPlugin *plugin,
+ gchar **values,
+ GList **list,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return TRUE;
+}
+
+/**
+ * gs_plugin_add_installed:
+ */
+gboolean
+gs_plugin_add_installed (GsPlugin *plugin,
+ GList **list,
+ GCancellable *cancellable,
+ GError **error)
+{
+ const gchar *args_apps[] = { "--user", "list-apps", NULL };
+ const gchar *args_runt[] = { "--user", "list-runtimes", NULL };
+ guint i;
+ _cleanup_strv_free_ gchar **results_apps = NULL;
+ _cleanup_strv_free_ gchar **results_runt = NULL;
+
+ /* get apps */
+ results_apps = gs_plugin_xdg_app_exec (args_apps, error);
+ if (results_apps == NULL)
+ return FALSE;
+ for (i = 0; results_apps[i] != NULL; i++) {
+ _cleanup_object_unref_ GsApp *app = NULL;
+ app = gs_app_new (results_apps[i]);
+ gs_app_set_management_plugin (app, "XgdApp");
+ gs_app_set_metadata (app, "XgdApp::type", "app");
+ gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "GNOME Builder");
+ gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "GNOME BUILDER");
+ gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
+ gs_app_set_kind (app, GS_APP_KIND_NORMAL);
+ gs_app_set_id_kind (app, AS_ID_KIND_DESKTOP);
+ //FIXME need to refine using AppData
+ gs_app_set_pixbuf (app, gdk_pixbuf_new_from_file
("/usr/share/icons/hicolor/48x48/apps/gnome-boxes.png", NULL));
+ gs_plugin_add_app (list, app);
+ }
+
+ /* get runtimes */
+ results_runt = gs_plugin_xdg_app_exec (args_runt, error);
+ if (results_runt == NULL)
+ return FALSE;
+ for (i = 0; results_runt[i] != NULL; i++) {
+ _cleanup_object_unref_ GsApp *app = NULL;
+ app = gs_app_new (results_runt[i]);
+ gs_app_set_management_plugin (app, "XgdApp");
+ gs_app_set_metadata (app, "XgdApp::type", "runtime");
+ gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "GNOME Platform");
+ gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "GNOME PLATFORM");
+ gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
+ gs_app_set_kind (app, GS_APP_KIND_NORMAL);
+ gs_app_set_id_kind (app, AS_ID_KIND_DESKTOP);
+ //FIXME need to refine using AppData
+ gs_app_set_pixbuf (app, gdk_pixbuf_new_from_file
("/usr/share/icons/hicolor/48x48/apps/gnome-boxes.png", NULL));
+ gs_plugin_add_app (list, app);
+ }
+ return TRUE;
+}
+
+/**
+ * gs_plugin_add_sources:
+ */
+gboolean
+gs_plugin_add_sources (GsPlugin *plugin,
+ GList **list,
+ GCancellable *cancellable,
+ GError **error)
+{
+ const gchar *args[] = { "--user", "list-remotes", NULL };
+ guint i;
+ _cleanup_strv_free_ gchar **results = NULL;
+
+ /* get remotes */
+ results = gs_plugin_xdg_app_exec (args, error);
+ if (results == NULL)
+ return FALSE;
+ for (i = 0; results[i] != NULL; i++) {
+ _cleanup_object_unref_ GsApp *app = NULL;
+ app = gs_app_new (results[i]);
+ gs_app_set_management_plugin (app, "XgdApp");
+ gs_app_set_kind (app, GS_APP_KIND_SOURCE);
+ gs_app_set_state (app, AS_APP_STATE_INSTALLED);
+ //FIXME: need this from the keyfile / AppStream
+ gs_app_set_name (app,
+ GS_APP_QUALITY_LOWEST,
+ results[i]);
+ //FIXME: need this from the keyfile
+ gs_app_set_summary (app,
+ GS_APP_QUALITY_LOWEST,
+ results[i]);
+ gs_plugin_add_app (list, app);
+ }
+ return TRUE;
+}
+
+/**
+ * gs_plugin_add_updates:
+ */
+gboolean
+gs_plugin_add_updates (GsPlugin *plugin,
+ GList **list,
+ GCancellable *cancellable,
+ GError **error)
+{
+ //FIXME: hardcoded remote
+ const gchar *args[] = { "--user", "--updates", "repo-contents",
+ "test-repo", NULL };
+ guint i;
+ _cleanup_strv_free_ gchar **results = NULL;
+
+ /* get updates */
+ results = gs_plugin_xdg_app_exec (args, error);
+ if (results == NULL)
+ return FALSE;
+ for (i = 0; results[i] != NULL; i++) {
+ _cleanup_object_unref_ GsApp *app = NULL;
+ app = gs_app_new (results[i]);
+ gs_app_set_management_plugin (app, "XgdApp");
+ gs_app_set_state (app, AS_APP_STATE_UPDATABLE);
+ gs_app_set_kind (app, GS_APP_KIND_PACKAGE);
+ gs_plugin_add_app (list, app);
+ //FIXME: need this from the keyfile / AppStream
+ gs_app_set_name (app,
+ GS_APP_QUALITY_LOWEST,
+ results[i]);
+ //FIXME: need this from the keyfile
+ gs_app_set_summary (app,
+ GS_APP_QUALITY_LOWEST,
+ results[i]);
+ gs_plugin_add_app (list, app);
+ }
+ return TRUE;
+}
+
+/**
+ * gs_plugin_refine_item:
+ */
+static gboolean
+gs_plugin_refine_item (GsPlugin *plugin, GsApp *app, GError **error)
+{
+ /* only process this app if was created by this plugin */
+ if (g_strcmp0 (gs_app_get_management_plugin (app), "XgdApp") != 0)
+ return TRUE;
+
+ //FIXME need to set to remote somehow
+ gs_app_add_source (app, "test-repo");
+ return TRUE;
+}
+
+/**
+ * gs_plugin_refine:
+ */
+gboolean
+gs_plugin_refine (GsPlugin *plugin,
+ GList **list,
+ GsPluginRefineFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GList *l;
+ GsApp *app;
+
+ for (l = *list; l != NULL; l = l->next) {
+ app = GS_APP (l->data);
+ if (!gs_plugin_refine_item (plugin, app, error))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * gs_plugin_launch:
+ */
+gboolean
+gs_plugin_launch (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
+{
+ const gchar *args[] = { "run", gs_app_get_id (app), NULL };
+ _cleanup_strv_free_ gchar **results = NULL;
+
+ /* run tool sync */
+ results = gs_plugin_xdg_app_exec (args, error);
+ if (results == NULL)
+ return FALSE;
+ return TRUE;
+}
+
+/**
+ * gs_plugin_app_remove:
+ */
+gboolean
+gs_plugin_app_remove (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
+{
+ const gchar *args[] = { "--user", "uninstall-app", gs_app_get_id (app), NULL };
+ _cleanup_strv_free_ gchar **results = NULL;
+
+ /* only process this app if was created by this plugin */
+ if (g_strcmp0 (gs_app_get_management_plugin (app), "XgdApp") != 0)
+ return TRUE;
+
+ /* this should be much less common */
+ if (g_strcmp0 (gs_app_get_metadata_item (app, "XgdApp::type"), "runtime") == 0)
+ args[1] = "uninstall-runtime";
+
+ /* run tool sync */
+ results = gs_plugin_xdg_app_exec (args, error);
+ if (results == NULL)
+ return FALSE;
+ return TRUE;
+}
+
+/**
+ * gs_plugin_app_install:
+ */
+gboolean
+gs_plugin_app_install (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
+{
+ const gchar *args[] = { "--user", "install-app",
+ gs_app_get_source_default (app),
+ gs_app_get_id (app), NULL };
+ _cleanup_strv_free_ gchar **results = NULL;
+
+ /* only process this app if was created by this plugin */
+ if (g_strcmp0 (gs_app_get_management_plugin (app), "XgdApp") != 0)
+ return TRUE;
+
+ /* this should be much less common */
+ if (g_strcmp0 (gs_app_get_metadata_item (app, "XgdApp::type"), "runtime") == 0)
+ args[1] = "install-runtime";
+
+ /* run tool sync */
+ results = gs_plugin_xdg_app_exec (args, error);
+ if (results == NULL)
+ return FALSE;
+ return TRUE;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]