[gnome-software] Install the xdg-app runtime as required
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Install the xdg-app runtime as required
- Date: Wed, 17 Feb 2016 09:49:39 +0000 (UTC)
commit 1aa568a92d9eb626da5abeb4c7a4d1f80c4287eb
Author: Richard Hughes <richard hughsie com>
Date: Wed Feb 17 09:47:50 2016 +0000
Install the xdg-app runtime as required
Also, include the runtime size if not yet installed on the app details page.
src/plugins/gs-plugin-xdg-app.c | 533 ++++++++++++++++++++++++++++++---------
1 files changed, 418 insertions(+), 115 deletions(-)
---
diff --git a/src/plugins/gs-plugin-xdg-app.c b/src/plugins/gs-plugin-xdg-app.c
index b9af1c7..6991792 100644
--- a/src/plugins/gs-plugin-xdg-app.c
+++ b/src/plugins/gs-plugin-xdg-app.c
@@ -22,12 +22,11 @@
/* Notes:
*
* All GsApp's created have management-plugin set to XgdApp
- * Some GsApp's created have have XgdApp::type of app or runtime
+ * Some GsApp's created have have XgdApp::kind of app or runtime
* The GsApp:origin is the remote name, e.g. test-repo
*
* Some outstanding notes:
*
- * - How can I get the AppStream metadata using libxdgapp?
* - Where is the privaledge elevation helper?
*/
@@ -87,6 +86,46 @@ gs_plugin_destroy (GsPlugin *plugin)
g_object_unref (plugin->priv->monitor);
}
+/* helpers */
+#define gs_app_get_xdgapp_kind_as_str(app) gs_app_get_metadata_item(app,"XgdApp::kind")
+#define gs_app_get_xdgapp_name(app) gs_app_get_metadata_item(app,"XgdApp::name")
+#define gs_app_get_xdgapp_arch(app) gs_app_get_metadata_item(app,"XgdApp::arch")
+#define gs_app_get_xdgapp_branch(app) gs_app_get_metadata_item(app,"XgdApp::branch")
+#define gs_app_get_xdgapp_commit(app) gs_app_get_metadata_item(app,"XgdApp::commit")
+#define gs_app_set_xdgapp_name(app,val) gs_app_set_metadata(app,"XgdApp::name",val)
+#define gs_app_set_xdgapp_arch(app,val) gs_app_set_metadata(app,"XgdApp::arch",val)
+#define gs_app_set_xdgapp_branch(app,val) gs_app_set_metadata(app,"XgdApp::branch",val)
+#define gs_app_set_xdgapp_commit(app,val) gs_app_set_metadata(app,"XgdApp::commit",val)
+
+/**
+ * gs_app_get_xdgapp_kind:
+ */
+static XdgAppRefKind
+gs_app_get_xdgapp_kind (GsApp *app)
+{
+ const gchar *kind = gs_app_get_metadata_item (app, "XgdApp::kind");
+ if (g_strcmp0 (kind, "app") == 0)
+ return XDG_APP_REF_KIND_APP;
+ if (g_strcmp0 (kind, "runtime") == 0)
+ return XDG_APP_REF_KIND_RUNTIME;
+ g_warning ("unknown xdg-app kind: %s", kind);
+ return XDG_APP_REF_KIND_APP;
+}
+
+/**
+ * gs_app_set_xdgapp_kind:
+ */
+static void
+gs_app_set_xdgapp_kind (GsApp *app, XdgAppRefKind kind)
+{
+ if (kind == XDG_APP_REF_KIND_APP)
+ gs_app_set_metadata (app, "XgdApp::kind", "app");
+ else if (kind == XDG_APP_REF_KIND_RUNTIME)
+ gs_app_set_metadata (app, "XgdApp::kind", "runtime");
+ else
+ g_assert_not_reached ();
+}
+
#ifndef HAVE_PACKAGEKIT
/**
* gs_plugin_add_popular:
@@ -262,25 +301,11 @@ static void
gs_plugin_xdg_app_set_metadata (GsApp *app, XdgAppRef *xref)
{
gs_app_set_management_plugin (app, "XgdApp");
- gs_app_set_metadata (app, "XgdApp::branch",
- xdg_app_ref_get_branch (xref));
- gs_app_set_metadata (app, "XgdApp::commit",
- xdg_app_ref_get_commit (xref));
- gs_app_set_metadata (app, "XgdApp::name",
- xdg_app_ref_get_name (xref));
- gs_app_set_metadata (app, "XgdApp::arch",
- xdg_app_ref_get_arch (xref));
-
- switch (xdg_app_ref_get_kind (xref)) {
- case XDG_APP_REF_KIND_APP:
- gs_app_set_metadata (app, "XgdApp::type", "app");
- break;
- case XDG_APP_REF_KIND_RUNTIME:
- gs_app_set_metadata (app, "XgdApp::type", "runtime");
- break;
- default:
- break;
- }
+ gs_app_set_xdgapp_kind (app, xdg_app_ref_get_kind (xref));
+ gs_app_set_xdgapp_name (app, xdg_app_ref_get_name (xref));
+ gs_app_set_xdgapp_arch (app, xdg_app_ref_get_arch (xref));
+ gs_app_set_xdgapp_branch (app, xdg_app_ref_get_branch (xref));
+ gs_app_set_xdgapp_commit (app, xdg_app_ref_get_commit (xref));
}
/**
@@ -323,6 +348,17 @@ gs_plugin_xdg_app_set_metadata_installed (GsApp *app, XdgAppInstalledRef *xref)
}
/**
+ * gs_plugin_xdg_app_build_id:
+ */
+static gchar *
+gs_plugin_xdg_app_build_id (XdgAppRef *xref)
+{
+ if (xdg_app_ref_get_kind (xref) == XDG_APP_REF_KIND_APP)
+ return g_strdup_printf ("%s.desktop", xdg_app_ref_get_name (xref));
+ return g_strdup_printf ("%s.runtime", xdg_app_ref_get_name (xref));
+}
+
+/**
* gs_plugin_xdg_app_create_installed:
*/
static GsApp *
@@ -354,20 +390,17 @@ gs_plugin_xdg_app_create_installed (GsPlugin *plugin,
}
/* create new object */
- app = gs_app_new (NULL);
+ id = gs_plugin_xdg_app_build_id (XDG_APP_REF (xref));
+ app = gs_app_new (id);
gs_app_set_kind (app, GS_APP_KIND_NORMAL);
gs_plugin_xdg_app_set_metadata_installed (app, xref);
switch (xdg_app_ref_get_kind (XDG_APP_REF(xref))) {
case XDG_APP_REF_KIND_APP:
- id = g_strdup_printf ("%s.desktop",
- xdg_app_ref_get_name (XDG_APP_REF(xref)));
gs_app_set_id_kind (app, AS_ID_KIND_DESKTOP);
break;
case XDG_APP_REF_KIND_RUNTIME:
- id = g_strdup_printf ("%s.runtime",
- xdg_app_ref_get_name (XDG_APP_REF(xref)));
- gs_app_set_metadata (app, "XgdApp::type", "runtime");
+ gs_app_set_xdgapp_kind (app, XDG_APP_REF_KIND_RUNTIME);
gs_app_set_id_kind (app, AS_ID_KIND_RUNTIME);
gs_app_set_name (app, GS_APP_QUALITY_NORMAL,
xdg_app_ref_get_name (XDG_APP_REF (xref)));
@@ -385,9 +418,6 @@ gs_plugin_xdg_app_create_installed (GsPlugin *plugin,
"XdgAppRefKind not known");
return NULL;
}
-
- /* we know the full application ID now */
- gs_app_set_id (app, id);
return g_object_ref (app);
}
@@ -619,13 +649,13 @@ gs_plugin_refresh (GsPlugin *plugin,
}
/**
- * gs_plugin_refine_item_origin:
+ * gs_plugin_refine_item_origin_ui:
*/
static gboolean
-gs_plugin_refine_item_origin (GsPlugin *plugin,
- GsApp *app,
- GCancellable *cancellable,
- GError **error)
+gs_plugin_refine_item_origin_ui (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
{
const gchar *origin;
guint i;
@@ -639,7 +669,7 @@ gs_plugin_refine_item_origin (GsPlugin *plugin,
return TRUE;
/* ensure we can set up the repo */
- ptask = as_profile_start_literal (plugin->profile, "xdg-app::refine-origin");
+ ptask = as_profile_start_literal (plugin->profile, "xdg-app::refine-origin-ui");
if (!gs_plugin_ensure_installation (plugin, cancellable, error))
return FALSE;
@@ -652,7 +682,7 @@ gs_plugin_refine_item_origin (GsPlugin *plugin,
for (i = 0; i < xremotes->len; i++) {
XdgAppRemote *xremote = g_ptr_array_index (xremotes, i);
if (g_strcmp0 (gs_app_get_origin (app),
- xdg_app_remote_get_name (xremote)) == 0) {
+ xdg_app_remote_get_name (xremote)) == 0) {
gs_app_set_origin_ui (app, xdg_app_remote_get_title (xremote));
break;
}
@@ -662,6 +692,63 @@ gs_plugin_refine_item_origin (GsPlugin *plugin,
}
/**
+ * gs_plugin_refine_item_origin:
+ */
+static gboolean
+gs_plugin_refine_item_origin (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
+{
+ guint i;
+ g_autoptr(GError) error_local = NULL;
+ g_autoptr(GPtrArray) xremotes = NULL;
+ g_autoptr(AsProfileTask) ptask = NULL;
+
+ /* already set */
+ if (gs_app_get_origin (app) != NULL)
+ return TRUE;
+
+ /* ensure we can set up the repo */
+ ptask = as_profile_start_literal (plugin->profile, "xdg-app::refine-origin");
+ if (!gs_plugin_ensure_installation (plugin, cancellable, error))
+ return FALSE;
+
+ /* find list of remotes */
+ xremotes = xdg_app_installation_list_remotes (plugin->priv->installation,
+ cancellable,
+ error);
+ if (xremotes == NULL)
+ return FALSE;
+ for (i = 0; i < xremotes->len; i++) {
+ const gchar *remote_name;
+ XdgAppRemote *xremote = g_ptr_array_index (xremotes, i);
+ g_autoptr(XdgAppRemoteRef) xref = NULL;
+ remote_name = xdg_app_remote_get_name (xremote);
+ xref = xdg_app_installation_fetch_remote_ref_sync (plugin->priv->installation,
+ remote_name,
+ XDG_APP_REF_KIND_RUNTIME,
+ gs_app_get_xdgapp_name (app),
+ gs_app_get_xdgapp_arch (app),
+ gs_app_get_xdgapp_branch (app),
+ cancellable,
+ NULL);
+ if (xref != NULL) {
+ gs_app_set_origin (app, remote_name);
+ return TRUE;
+ }
+ }
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_NOT_SUPPORTED,
+ "Not found %s/%s/%s",
+ gs_app_get_xdgapp_name (app),
+ gs_app_get_xdgapp_arch (app),
+ gs_app_get_xdgapp_branch (app));
+ return NULL;
+}
+
+/**
* gs_plugin_refine_item_commit:
*/
static gboolean
@@ -670,75 +757,97 @@ gs_plugin_refine_item_commit (GsPlugin *plugin,
GCancellable *cancellable,
GError **error)
{
- XdgAppRefKind kind = XDG_APP_REF_KIND_APP;
g_autoptr(AsProfileTask) ptask = NULL;
g_autoptr(XdgAppRemoteRef) xref_remote = NULL;
- if (gs_app_get_metadata_item (app, "XgdApp::commit") != NULL)
+ if (gs_app_get_xdgapp_commit (app) != NULL)
return TRUE;
- if (g_strcmp0 (gs_app_get_metadata_item (app, "XgdApp::type"), "runtime") == 0)
- kind = XDG_APP_REF_KIND_RUNTIME;
+ if (gs_app_get_origin (app) == NULL) {
+ g_debug ("no origin got commit, so refining origin first");
+ if (!gs_plugin_refine_item_origin (plugin, app, cancellable, error))
+ return FALSE;
+ }
ptask = as_profile_start_literal (plugin->profile, "xdg-app::fetch-remote-ref");
xref_remote = xdg_app_installation_fetch_remote_ref_sync (plugin->priv->installation,
gs_app_get_origin (app),
- kind,
- gs_app_get_metadata_item (app,
"XgdApp::name"),
- gs_app_get_metadata_item (app,
"XgdApp::arch"),
- gs_app_get_metadata_item (app,
"XgdApp::branch"),
+ gs_app_get_xdgapp_kind (app),
+ gs_app_get_xdgapp_name (app),
+ gs_app_get_xdgapp_arch (app),
+ gs_app_get_xdgapp_branch (app),
cancellable,
error);
if (xref_remote == NULL)
return FALSE;
- gs_app_set_metadata (app, "XgdApp::commit",
- xdg_app_ref_get_commit (XDG_APP_REF (xref_remote)));
+ gs_app_set_xdgapp_commit (app, xdg_app_ref_get_commit (XDG_APP_REF (xref_remote)));
return TRUE;
}
/**
- * gs_plugin_refine_item_size:
+ * gs_plugin_xdg_app_is_xref:
*/
static gboolean
-gs_plugin_refine_item_size (GsPlugin *plugin,
- GsApp *app,
- GCancellable *cancellable,
- GError **error)
+gs_plugin_xdg_app_is_xref (GsApp *app, XdgAppRef *xref)
{
- gboolean ret;
- guint64 download_size;
- guint64 installed_size;
- g_autoptr(GError) error_local = NULL;
- g_autoptr(AsProfileTask) ptask = NULL;
+ g_autofree gchar *id = NULL;
- if (gs_app_get_size (app) > 0)
+ /* check ID */
+ id = gs_plugin_xdg_app_build_id (xref);
+ if (g_strcmp0 (id, gs_app_get_id (app)) == 0)
return TRUE;
- /* need commit */
- if (!gs_plugin_refine_item_commit (plugin, app, cancellable, error))
- return FALSE;
+ /* check source ID */
+// if (g_strcmp0 (id, gs_app_get_id (app)) == 0)
+// return TRUE;
+
+ /* do all the metadata items match? */
+ if (g_strcmp0 (gs_app_get_xdgapp_name (app),
+ xdg_app_ref_get_name (xref)) == 0 &&
+ g_strcmp0 (gs_app_get_xdgapp_arch (app),
+ xdg_app_ref_get_arch (xref)) == 0 &&
+ g_strcmp0 (gs_app_get_xdgapp_branch (app),
+ xdg_app_ref_get_branch (xref)) == 0)
+ return TRUE;
- ptask = as_profile_start_literal (plugin->profile, "xdg-app::refine-size");
- ret = xdg_app_installation_fetch_remote_size_sync (plugin->priv->installation,
- gs_app_get_origin (app),
- gs_app_get_metadata_item (app, "XgdApp::commit"),
- &download_size,
- &installed_size,
- cancellable, &error_local);
- if (!ret) {
- g_warning ("libxdgapp failed to return application size: %s",
- error_local->message);
- installed_size = GS_APP_SIZE_MISSING;
- }
- gs_app_set_size (app, installed_size);
+ /* sad panda */
+ return FALSE;
+}
+/**
+ * gs_plugin_refine_item_metadata:
+ */
+static gboolean
+gs_plugin_refine_item_metadata (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_autoptr(XdgAppRef) xref = NULL;
+
+ /* already set */
+ if (gs_app_get_metadata_item (app, "XgdApp::kind") != NULL)
+ return TRUE;
+
+ /* AppStream sets the source to appname/arch/branch, if this isn't set
+ * we can't break out the fields */
+ if (gs_app_get_source_default (app) == NULL)
+ return TRUE;
+
+ /* parse the ref */
+ xref = xdg_app_ref_parse (gs_app_get_source_default (app), error);
+ if (xref == NULL)
+ return FALSE;
+ gs_plugin_xdg_app_set_metadata (app, xref);
+
+ /* success */
return TRUE;
}
/**
- * gs_plugin_refine_item_action:
+ * gs_plugin_refine_item_state:
*/
static gboolean
-gs_plugin_refine_item_action (GsPlugin *plugin,
+gs_plugin_refine_item_state (GsPlugin *plugin,
GsApp *app,
GCancellable *cancellable,
GError **error)
@@ -748,10 +857,13 @@ gs_plugin_refine_item_action (GsPlugin *plugin,
g_autoptr(AsProfileTask) ptask = NULL;
/* already found */
- if (gs_app_get_metadata_item (app, "XgdApp::type") != NULL &&
- gs_app_get_state (app) != AS_APP_STATE_UNKNOWN)
+ if (gs_app_get_state (app) != AS_APP_STATE_UNKNOWN)
return TRUE;
+ /* need broken out metadata */
+ if (!gs_plugin_refine_item_metadata (plugin, app, cancellable, error))
+ return FALSE;
+
/* get apps and runtimes */
ptask = as_profile_start_literal (plugin->profile, "xdg-app::refine-action");
xrefs = xdg_app_installation_list_installed_refs (plugin->priv->installation,
@@ -759,17 +871,15 @@ gs_plugin_refine_item_action (GsPlugin *plugin,
if (xrefs == NULL)
return FALSE;
for (i = 0; i < xrefs->len; i++) {
- g_autofree gchar *id = NULL;
XdgAppInstalledRef *xref = g_ptr_array_index (xrefs, i);
- if (xdg_app_ref_get_kind (XDG_APP_REF(xref)) != XDG_APP_REF_KIND_APP)
- continue;
- id = g_strdup_printf ("%s.desktop",
- xdg_app_ref_get_name (XDG_APP_REF(xref)));
- if (g_strcmp0 (id, gs_app_get_id (app)) != 0)
+
+ /* check xref is app */
+ if (!gs_plugin_xdg_app_is_xref (app, XDG_APP_REF(xref)))
continue;
- /* 'claim' this application for our own */
- g_debug ("claiming %s for xdg-app", gs_app_get_id (app));
+ /* mark as installed */
+ g_debug ("marking %s as installed with xdg-app",
+ gs_app_get_id (app));
gs_plugin_xdg_app_set_metadata_installed (app, xref);
if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN)
gs_app_set_state (app, AS_APP_STATE_INSTALLED);
@@ -778,15 +888,173 @@ gs_plugin_refine_item_action (GsPlugin *plugin,
/* since xdg-app can't 'disable' a repo, if we have an AppStream entry
* with the correct bundle type that's not installed we can assume it
* is available for install */
- if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN) {
- g_autoptr(XdgAppRef) xref = NULL;
- xref = xdg_app_ref_parse (gs_app_get_source_default (app), error);
- if (xref == NULL)
- return FALSE;
- gs_plugin_xdg_app_set_metadata (app, xref);
+ if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN)
gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
+
+ /* success */
+ return TRUE;
+}
+
+/**
+ * gs_plugin_refine_item_runtime:
+ */
+static gboolean
+gs_plugin_refine_item_runtime (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
+{
+ const gchar *commit;
+ const gchar *str;
+ gsize len = -1;
+ g_autofree gchar *contents = NULL;
+ g_autofree gchar *install_path = NULL;
+ g_autofree gchar *runtime = NULL;
+ g_autofree gchar *source = NULL;
+ g_autoptr(GBytes) data = NULL;
+ g_autoptr(GKeyFile) kf = NULL;
+ g_autoptr(GsApp) app_runtime = NULL;
+ g_autoptr(XdgAppInstalledRef) xref = NULL;
+
+ /* not applicable */
+ if (gs_app_get_xdgapp_kind (app) != XDG_APP_REF_KIND_APP)
+ return TRUE;
+
+ /* already exists */
+ if (gs_app_get_runtime (app) != NULL)
+ return TRUE;
+
+ /* this is quicker than doing network IO */
+ install_path = g_build_filename (g_get_home_dir (),
+ ".local",
+ "share", //FIXME: use xdg_app_installation_get_path()
+ "xdg-app",
+ gs_app_get_xdgapp_kind_as_str (app),
+ gs_app_get_xdgapp_name (app),
+ gs_app_get_xdgapp_arch (app),
+ gs_app_get_xdgapp_branch (app),
+ "active",
+ "metadata",
+ NULL);
+ if (g_file_test (install_path, G_FILE_TEST_EXISTS)) {
+ if (!g_file_get_contents (install_path, &contents, &len, error))
+ return FALSE;
+ str = contents;
+ } else {
+
+ /* need commit */
+ if (!gs_plugin_refine_item_commit (plugin, app, cancellable, error))
+ return FALSE;
+
+ /* fetch from the server */
+ commit = gs_app_get_xdgapp_commit (app);
+ data = xdg_app_installation_fetch_remote_metadata_sync (plugin->priv->installation,
+ gs_app_get_origin (app),
+ commit,
+ cancellable,
+ error);
+ if (data == NULL)
+ return FALSE;
+ str = g_bytes_get_data (data, &len);
}
+ /* parse key file */
+ kf = g_key_file_new ();
+ if (!g_key_file_load_from_data (kf, str, len, G_KEY_FILE_NONE, error))
+ return FALSE;
+ runtime = g_key_file_get_string (kf, "Application", "runtime", error);
+ if (runtime == NULL)
+ return FALSE;
+ g_debug ("runtime for %s is %s", gs_app_get_id (app), runtime);
+
+ /* create runtime */
+ app_runtime = gs_app_new (runtime);
+ source = g_strdup_printf ("runtime/%s", runtime);
+ gs_app_add_source (app_runtime, source);
+ gs_app_set_id_kind (app_runtime, AS_ID_KIND_RUNTIME);
+ gs_app_set_runtime (app, app_runtime);
+ return TRUE;
+}
+
+/**
+ * gs_plugin_refine_item_size:
+ */
+static gboolean
+gs_plugin_refine_item_size (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret;
+ guint64 download_size;
+ guint64 installed_size;
+ guint64 size = 0;
+ g_auto(GStrv) split = NULL;
+ g_autoptr(AsProfileTask) ptask = NULL;
+ g_autoptr(GError) error_local = NULL;
+
+ if (gs_app_get_size (app) > 0)
+ return TRUE;
+
+ /* need commit */
+ if (!gs_plugin_refine_item_commit (plugin, app, cancellable, error))
+ return FALSE;
+
+ /* calculate the platform size too if the app is not installed */
+ if (gs_app_get_state (app) == AS_APP_STATE_AVAILABLE &&
+ gs_app_get_xdgapp_kind (app) == XDG_APP_REF_KIND_APP) {
+ GsApp *app_runtime;
+
+ /* find out what runtime the application depends on */
+ if (!gs_plugin_refine_item_runtime (plugin,
+ app,
+ cancellable,
+ error))
+ return FALSE;
+
+ /* is the app_runtime already installed? */
+ app_runtime = gs_app_get_runtime (app);
+ if (!gs_plugin_refine_item_state (plugin,
+ app_runtime,
+ cancellable,
+ error))
+ return FALSE;
+ if (gs_app_get_state (app_runtime) == AS_APP_STATE_INSTALLED) {
+ g_debug ("runtime %s is already installed, so not adding size",
+ gs_app_get_id (app_runtime));
+ } else {
+ if (!gs_plugin_refine_item_size (plugin,
+ app_runtime,
+ cancellable,
+ error))
+ return FALSE;
+ g_debug ("runtime %s is not installed, so adding download",
+ gs_app_get_id (app_runtime));
+ size += gs_app_get_size (app_runtime);
+ }
+ }
+
+ /* just get the size of the runtime */
+ ptask = as_profile_start_literal (plugin->profile, "xdg-app::refine-size");
+ ret = xdg_app_installation_fetch_remote_size_sync (plugin->priv->installation,
+ gs_app_get_origin (app),
+ gs_app_get_xdgapp_commit (app),
+ &download_size,
+ &installed_size,
+ cancellable, &error_local);
+ if (!ret) {
+ g_warning ("libxdgapp failed to return application size: %s",
+ error_local->message);
+ } else {
+ if (gs_app_get_state (app) == AS_APP_STATE_INSTALLED) {
+ size += installed_size;
+ } else {
+ size += download_size;
+ }
+ }
+ if (size == 0)
+ size = GS_APP_SIZE_MISSING;
+ gs_app_set_size (app, size);
return TRUE;
}
@@ -811,15 +1079,19 @@ gs_plugin_refine_item (GsPlugin *plugin,
"xdg-app::refine{%s}",
gs_app_get_id (app));
- /* check if this desktop ID can be handled by the plugin */
- if (!gs_plugin_refine_item_action (plugin, app, cancellable, error))
+ /* AppStream sets the source to appname/arch/branch */
+ if (!gs_plugin_refine_item_metadata (plugin, app, cancellable, error))
+ return FALSE;
+
+ /* check the installed state */
+ if (!gs_plugin_refine_item_state (plugin, app, cancellable, error))
return FALSE;
/* version fallback */
if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_VERSION) {
if (gs_app_get_version (app) == NULL) {
const gchar *branch;
- branch = gs_app_get_metadata_item (app, "XgdApp::branch");
+ branch = gs_app_get_xdgapp_branch (app);
gs_app_set_version (app, branch);
}
}
@@ -832,7 +1104,13 @@ gs_plugin_refine_item (GsPlugin *plugin,
/* origin */
if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN) {
- if (!gs_plugin_refine_item_origin (plugin, app, cancellable, error))
+ if (!gs_plugin_refine_item_origin_ui (plugin, app, cancellable, error))
+ return FALSE;
+ }
+
+ /* runtime */
+ if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SETUP_ACTION) {
+ if (!gs_plugin_refine_item_runtime (plugin, app, cancellable, error))
return FALSE;
}
@@ -883,11 +1161,11 @@ gs_plugin_launch (GsPlugin *plugin,
if (!gs_plugin_ensure_installation (plugin, cancellable, error))
return FALSE;
- branch = gs_app_get_metadata_item (app, "XgdApp::branch");
+ branch = gs_app_get_xdgapp_branch (app);
if (branch == NULL)
branch = "master";
return xdg_app_installation_launch (plugin->priv->installation,
- gs_app_get_metadata_item (app, "XgdApp::name"),
+ gs_app_get_xdgapp_name (app),
NULL,
branch,
NULL,
@@ -922,9 +1200,9 @@ gs_plugin_app_remove (GsPlugin *plugin,
gs_app_set_state (app, AS_APP_STATE_REMOVING);
return xdg_app_installation_uninstall (plugin->priv->installation,
XDG_APP_REF_KIND_APP,
- gs_app_get_metadata_item (app, "XgdApp::name"),
- gs_app_get_metadata_item (app, "XgdApp::arch"),
- gs_app_get_metadata_item (app, "XgdApp::branch"),
+ gs_app_get_xdgapp_name (app),
+ gs_app_get_xdgapp_arch (app),
+ gs_app_get_xdgapp_branch (app),
gs_plugin_xdg_app_progress_cb, &helper,
cancellable, error);
}
@@ -955,12 +1233,42 @@ gs_plugin_app_install (GsPlugin *plugin,
/* install */
gs_app_set_state (app, AS_APP_STATE_INSTALLING);
+
+ /* install required runtime if not already installed */
+ if (gs_app_get_id_kind (app) == AS_ID_KIND_DESKTOP) {
+ GsApp *runtime;
+ runtime = gs_app_get_runtime (app);
+ if (gs_app_get_state (runtime) != AS_APP_STATE_INSTALLED) {
+ g_debug ("%s is not already installed, so installing",
+ gs_app_get_id (runtime));
+ gs_app_set_state (runtime, AS_APP_STATE_INSTALLING);
+ xref = xdg_app_installation_install (plugin->priv->installation,
+ gs_app_get_origin (runtime),
+ gs_app_get_xdgapp_kind (runtime),
+ gs_app_get_xdgapp_name (runtime),
+ gs_app_get_xdgapp_arch (runtime),
+ gs_app_get_xdgapp_branch (runtime),
+ gs_plugin_xdg_app_progress_cb, &helper,
+ cancellable, error);
+ if (xref == NULL) {
+ gs_app_set_state (runtime, AS_APP_STATE_AVAILABLE);
+ return FALSE;
+ }
+ gs_app_set_state (app, AS_APP_STATE_INSTALLED);
+ } else {
+ g_debug ("%s is already installed, so skipping",
+ gs_app_get_id (runtime));
+ }
+ }
+
+ /* now the main application */
+ g_debug ("installing %s", gs_app_get_id (app));
xref = xdg_app_installation_install (plugin->priv->installation,
gs_app_get_origin (app),
- XDG_APP_REF_KIND_APP,
- gs_app_get_metadata_item (app, "XgdApp::name"),
- gs_app_get_metadata_item (app, "XgdApp::arch"),
- gs_app_get_metadata_item (app, "XgdApp::branch"),
+ gs_app_get_xdgapp_kind (app),
+ gs_app_get_xdgapp_name (app),
+ gs_app_get_xdgapp_arch (app),
+ gs_app_get_xdgapp_branch (app),
gs_plugin_xdg_app_progress_cb, &helper,
cancellable, error);
return xref != NULL;
@@ -969,7 +1277,7 @@ gs_plugin_app_install (GsPlugin *plugin,
/**
* gs_plugin_app_update:
*
- * This is only called when updating device firmware live.
+ * This is only called when updating live.
*/
gboolean
gs_plugin_app_update (GsPlugin *plugin,
@@ -978,7 +1286,6 @@ gs_plugin_app_update (GsPlugin *plugin,
GError **error)
{
GsPluginHelper helper;
- XdgAppRefKind kind = XDG_APP_REF_KIND_APP;
g_autoptr(XdgAppInstalledRef) xref = NULL;
/* only process this app if was created by this plugin */
@@ -993,18 +1300,14 @@ gs_plugin_app_update (GsPlugin *plugin,
helper.app = app;
helper.plugin = plugin;
- /* special case */
- if (g_strcmp0 (gs_app_get_metadata_item (app, "XgdApp::type"), "runtime") == 0)
- kind = XDG_APP_REF_KIND_RUNTIME;
-
/* install */
gs_app_set_state (app, AS_APP_STATE_INSTALLING);
xref = xdg_app_installation_update (plugin->priv->installation,
XDG_APP_UPDATE_FLAGS_NONE,
- kind,
- gs_app_get_metadata_item (app, "XgdApp::name"),
- gs_app_get_metadata_item (app, "XgdApp::arch"),
- gs_app_get_metadata_item (app, "XgdApp::branch"),
+ gs_app_get_xdgapp_kind (app),
+ gs_app_get_xdgapp_name (app),
+ gs_app_get_xdgapp_arch (app),
+ gs_app_get_xdgapp_branch (app),
gs_plugin_xdg_app_progress_cb, &helper,
cancellable, error);
return xref != NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]