[gnome-software] flatpak: Return the correct installed state for user/system remotes



commit 28293b122274a77aa0d6a06c3bce4ed8b1574b02
Author: Richard Hughes <richard hughsie com>
Date:   Tue Jul 11 14:59:42 2017 +0100

    flatpak: Return the correct installed state for user/system remotes

 plugins/flatpak/gs-flatpak.c        |  186 ++++++++++---------------
 plugins/flatpak/gs-flatpak.h        |   17 ++-
 plugins/flatpak/gs-plugin-flatpak.c |  263 +++++++++++++++++++++++++++++++----
 3 files changed, 324 insertions(+), 142 deletions(-)
---
diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c
index 1c66ac8..b18eff1 100644
--- a/plugins/flatpak/gs-flatpak.c
+++ b/plugins/flatpak/gs-flatpak.c
@@ -900,6 +900,58 @@ gs_flatpak_add_sources (GsFlatpak *self, GsAppList *list,
        return TRUE;
 }
 
+gboolean
+gs_flatpak_find_source_by_url (GsFlatpak *self,
+                              const gchar *url,
+                              GsAppList *list,
+                              GCancellable *cancellable,
+                              GError **error)
+{
+       g_autoptr(GPtrArray) xremotes = NULL;
+       xremotes = flatpak_installation_list_remotes (self->installation, cancellable, error);
+       if (xremotes == NULL)
+               return FALSE;
+       for (guint i = 0; i < xremotes->len; i++) {
+               FlatpakRemote *xremote = g_ptr_array_index (xremotes, i);
+               g_autofree gchar *url_tmp = flatpak_remote_get_url (xremote);
+               if (g_strcmp0 (url, url_tmp) == 0) {
+                       g_autoptr(GsApp) app = gs_flatpak_create_source (self, xremote);
+                       gs_app_list_add (list, app);
+               }
+       }
+       return TRUE;
+}
+
+gboolean
+gs_flatpak_find_app_by_ref_display (GsFlatpak *self,
+                               const gchar *ref_display,
+                               GsAppList *list,
+                               GCancellable *cancellable,
+                               GError **error)
+{
+       g_autoptr(GPtrArray) xrefs = NULL;
+
+       /* get all the installed apps (no network I/O) */
+       xrefs = flatpak_installation_list_installed_refs (self->installation,
+                                                         cancellable,
+                                                         error);
+       if (xrefs == NULL) {
+               gs_flatpak_error_convert (error);
+               return FALSE;
+       }
+
+       /* look at each installed xref */
+       for (guint i = 0; i < xrefs->len; i++) {
+               FlatpakRef *xref = g_ptr_array_index (xrefs, i);
+               g_autofree gchar *ref_tmp = flatpak_ref_format_ref (xref);
+               if (g_strcmp0 (ref_tmp, ref_display) == 0) {
+                       g_autoptr(GsApp) app = gs_flatpak_create_app (self, xref);
+                       gs_app_list_add (list, app);
+               }
+       }
+       return TRUE;
+}
+
 static gboolean
 gs_flatpak_app_install_source (GsFlatpak *self, GsApp *app,
                               GCancellable *cancellable,
@@ -2801,9 +2853,8 @@ gs_flatpak_update_app (GsFlatpak *self,
        return TRUE;
 }
 
-static gboolean
+GsApp *
 gs_flatpak_file_to_app_bundle (GsFlatpak *self,
-                              GsAppList *list,
                               GFile *file,
                               GCancellable *cancellable,
                               GError **error)
@@ -2821,7 +2872,7 @@ gs_flatpak_file_to_app_bundle (GsFlatpak *self,
        if (xref_bundle == NULL) {
                gs_flatpak_error_convert (error);
                g_prefix_error (error, "error loading bundle: ");
-               return FALSE;
+               return NULL;
        }
 
        /* load metadata */
@@ -2836,7 +2887,7 @@ gs_flatpak_file_to_app_bundle (GsFlatpak *self,
                                          g_bytes_get_data (metadata, NULL),
                                          g_bytes_get_size (metadata),
                                          error))
-               return FALSE;
+               return NULL;
 
        /* load AppStream */
        appstream_gz = flatpak_bundle_ref_get_appstream (xref_bundle);
@@ -2853,7 +2904,7 @@ gs_flatpak_file_to_app_bundle (GsFlatpak *self,
                decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
                stream_gz = g_memory_input_stream_new_from_bytes (appstream_gz);
                if (stream_gz == NULL)
-                       return FALSE;
+                       return NULL;
                stream_data = g_converter_input_stream_new (stream_gz,
                                                            G_CONVERTER (decompressor));
 
@@ -2863,12 +2914,12 @@ gs_flatpak_file_to_app_bundle (GsFlatpak *self,
                                                       error);
                if (appstream == NULL) {
                        gs_flatpak_error_convert (error);
-                       return FALSE;
+                       return NULL;
                }
                store = as_store_new ();
                if (!as_store_from_bytes (store, appstream, cancellable, error)) {
                        gs_flatpak_error_convert (error);
-                       return FALSE;
+                       return NULL;
                }
 
                /* allow peeking into this for debugging */
@@ -2886,7 +2937,7 @@ gs_flatpak_file_to_app_bundle (GsFlatpak *self,
                                             GS_PLUGIN_ERROR,
                                             GS_PLUGIN_ERROR_NOT_SUPPORTED,
                                             "no apps found in AppStream data");
-                       return FALSE;
+                       return NULL;
                }
                g_debug ("%u applications found in AppStream data",
                         as_store_get_size (store));
@@ -2900,12 +2951,12 @@ gs_flatpak_file_to_app_bundle (GsFlatpak *self,
                                     GS_PLUGIN_ERROR_INVALID_FORMAT,
                                     "application %s not found",
                                     id);
-                       return FALSE;
+                       return NULL;
                }
 
                /* copy details from AppStream to app */
                if (!gs_appstream_refine_app (self->plugin, app, item, error))
-                       return FALSE;
+                       return NULL;
        } else {
                g_warning ("no appstream metadata in file");
                gs_app_set_name (app, GS_APP_QUALITY_LOWEST,
@@ -2926,7 +2977,7 @@ gs_flatpak_file_to_app_bundle (GsFlatpak *self,
                pixbuf = gdk_pixbuf_new_from_stream (stream_icon, cancellable, error);
                if (pixbuf == NULL) {
                        gs_utils_error_convert_gdk_pixbuf (error);
-                       return FALSE;
+                       return NULL;
                }
                gs_app_set_pixbuf (app, pixbuf);
        } else {
@@ -2942,50 +2993,11 @@ gs_flatpak_file_to_app_bundle (GsFlatpak *self,
                gs_app_add_quirk (app, AS_APP_QUIRK_HAS_SOURCE);
 
        /* success */
-       gs_app_list_add (list, app);
-       return TRUE;
-}
-
-static gboolean
-gs_flatpak_file_to_app_repo (GsFlatpak *self,
-                            GsAppList *list,
-                            GFile *file,
-                            GCancellable *cancellable,
-                            GError **error)
-{
-       g_autoptr(GsApp) app = NULL;
-       g_autoptr(FlatpakRemote) xremote = NULL;
-
-       /* create app */
-       app = gs_flatpak_app_new_from_repo_file (file, cancellable, error);
-       if (app == NULL)
-               return FALSE;
-       gs_app_set_flatpak_object_id (app, gs_flatpak_get_id (self));
-       gs_app_set_management_plugin (app, gs_plugin_get_name (self->plugin));
-
-       /* check to see if the repo ID already exists */
-       xremote = flatpak_installation_get_remote_by_name (self->installation,
-                                                          gs_app_get_id (app),
-                                                          cancellable, NULL);
-       if (xremote != NULL) {
-               g_debug ("repo %s already exists", gs_app_get_id (app));
-               gs_app_set_state (app, AS_APP_STATE_UNKNOWN);
-               gs_app_set_state (app, AS_APP_STATE_INSTALLED);
-       } else {
-               gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
-       }
-
-       /* save to the cache */
-       gs_plugin_cache_add (self->plugin, NULL, app);
-
-       /* success */
-       gs_app_list_add (list, app);
-       return TRUE;
+       return g_steal_pointer (&app);
 }
 
-static gboolean
+GsApp *
 gs_flatpak_file_to_app_ref (GsFlatpak *self,
-                           GsAppList *list,
                            GFile *file,
                            GCancellable *cancellable,
                            GError **error)
@@ -3016,14 +3028,14 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self,
                                   NULL,
                                   error)) {
                gs_utils_error_convert_gio (error);
-               return FALSE;
+               return NULL;
        }
 
        /* load the file */
        kf = g_key_file_new ();
        if (!g_key_file_load_from_data (kf, contents, len, G_KEY_FILE_NONE, error)) {
                gs_utils_error_convert_gio (error);
-               return FALSE;
+               return NULL;
        }
 
        /* check version */
@@ -3034,7 +3046,7 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self,
                                     GS_PLUGIN_ERROR,
                                     GS_PLUGIN_ERROR_NOT_SUPPORTED,
                                     "unsupported version %" G_GUINT64_FORMAT, ver);
-                       return FALSE;
+                       return NULL;
                }
        }
 
@@ -3042,7 +3054,7 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self,
        ref_name = g_key_file_get_string (kf, "Flatpak Ref", "Name", error);
        if (ref_name == NULL) {
                gs_utils_error_convert_gio (error);
-               return FALSE;
+               return NULL;
        }
 
        /* remove old version from the remote config */
@@ -3062,7 +3074,7 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self,
                                                                 cancellable,
                                                                 error)) {
                                gs_flatpak_error_convert (error);
-                               return FALSE;
+                               return NULL;
                        }
                } else {
                        g_debug ("no previous %s remote to remove", remote_name_tmp);
@@ -3081,7 +3093,7 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self,
                                                      error);
        if (xref == NULL) {
                gs_flatpak_error_convert (error);
-               return FALSE;
+               return NULL;
        }
 
        /* load metadata */
@@ -3124,7 +3136,7 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self,
                                                           error);
        if (xremote == NULL) {
                gs_flatpak_error_convert (error);
-               return FALSE;
+               return NULL;
        }
        origin_url = flatpak_remote_get_url (xremote);
        if (origin_url == NULL) {
@@ -3133,7 +3145,7 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self,
                             GS_PLUGIN_ERROR_INVALID_FORMAT,
                             "no URL for remote %s",
                             flatpak_remote_get_name (xremote));
-               return FALSE;
+               return NULL;
        }
        gs_app_set_origin (app, remote_name);
        gs_app_set_origin_hostname (app, origin_url);
@@ -3151,62 +3163,14 @@ gs_flatpak_file_to_app_ref (GsFlatpak *self,
 
        /* get this now, as it's not going to be available at install time */
        if (!gs_plugin_refine_item_metadata (self, app, cancellable, error))
-               return FALSE;
+               return NULL;
 
        /* parse it */
        if (!gs_flatpak_add_apps_from_xremote (self, xremote, cancellable, error))
-               return FALSE;
+               return NULL;
 
        /* success */
-       gs_app_list_add (list, app);
-       return TRUE;
-}
-
-gboolean
-gs_flatpak_file_to_app (GsFlatpak *self,
-                       GsAppList *list,
-                       GFile *file,
-                       GCancellable *cancellable,
-                       GError **error)
-{
-       g_autofree gchar *content_type = NULL;
-       const gchar *mimetypes_bundle[] = {
-               "application/vnd.flatpak",
-               NULL };
-       const gchar *mimetypes_repo[] = {
-               "application/vnd.flatpak.repo",
-               NULL };
-       const gchar *mimetypes_ref[] = {
-               "application/vnd.flatpak.ref",
-               NULL };
-
-       /* does this match any of the mimetypes_bundle we support */
-       content_type = gs_utils_get_content_type (file, cancellable, error);
-       if (content_type == NULL)
-               return FALSE;
-       if (g_strv_contains (mimetypes_bundle, content_type)) {
-               return gs_flatpak_file_to_app_bundle (self,
-                                                     list,
-                                                     file,
-                                                     cancellable,
-                                                     error);
-       }
-       if (g_strv_contains (mimetypes_repo, content_type)) {
-               return gs_flatpak_file_to_app_repo (self,
-                                                   list,
-                                                   file,
-                                                   cancellable,
-                                                   error);
-       }
-       if (self->flags & GS_FLATPAK_FLAG_IS_TEMPORARY &&
-           g_strv_contains (mimetypes_ref, content_type)) {
-               return gs_flatpak_file_to_app_ref (self,
-                                                  list,
-                                                  file,
-                                                  cancellable,
-                                                  error);
-       }
-       return TRUE;
+       return g_steal_pointer (&app);
 }
 
 gboolean
diff --git a/plugins/flatpak/gs-flatpak.h b/plugins/flatpak/gs-flatpak.h
index 4c7a796..aa07ed9 100644
--- a/plugins/flatpak/gs-flatpak.h
+++ b/plugins/flatpak/gs-flatpak.h
@@ -97,11 +97,24 @@ gboolean    gs_flatpak_update_app           (GsFlatpak              *self,
                                                 GsApp                  *app,
                                                 GCancellable           *cancellable,
                                                 GError                 **error);
-gboolean       gs_flatpak_file_to_app          (GsFlatpak              *self,
-                                                GsAppList              *list,
+GsApp          *gs_flatpak_file_to_app_ref     (GsFlatpak              *self,
                                                 GFile                  *file,
                                                 GCancellable           *cancellable,
                                                 GError                 **error);
+GsApp          *gs_flatpak_file_to_app_bundle  (GsFlatpak              *self,
+                                                GFile                  *file,
+                                                GCancellable           *cancellable,
+                                                GError                 **error);
+gboolean        gs_flatpak_find_source_by_url  (GsFlatpak              *self,
+                                                const gchar            *name,
+                                                GsAppList              *list,
+                                                GCancellable           *cancellable,
+                                                GError                 **error);
+gboolean        gs_flatpak_find_app_by_ref_display     (GsFlatpak              *self,
+                                                const gchar            *ref_display,
+                                                GsAppList              *list,
+                                                GCancellable           *cancellable,
+                                                GError                 **error);
 gboolean       gs_flatpak_search               (GsFlatpak              *self,
                                                 gchar                  **values,
                                                 GsAppList              *list,
diff --git a/plugins/flatpak/gs-plugin-flatpak.c b/plugins/flatpak/gs-plugin-flatpak.c
index e3be3d9..0639222 100644
--- a/plugins/flatpak/gs-plugin-flatpak.c
+++ b/plugins/flatpak/gs-plugin-flatpak.c
@@ -459,50 +459,255 @@ gs_plugin_update_app (GsPlugin *plugin,
        return gs_flatpak_update_app (flatpak, app, cancellable, error);
 }
 
-gboolean
-gs_plugin_file_to_app (GsPlugin *plugin,
-                      GsAppList *list,
-                      GFile *file,
-                      GCancellable *cancellable,
-                      GError **error)
+static gboolean
+gs_plugin_flatpak_file_to_app_repo (GsPlugin *plugin,
+                                   GsAppList *list,
+                                   GFile *file,
+                                   GCancellable *cancellable,
+                                   GError **error)
 {
        GsPluginData *priv = gs_plugin_get_data (plugin);
-       g_autoptr(GsAppList) list_new = gs_app_list_new ();
+       g_autoptr(GsApp) app_tmp = NULL;
+       g_autoptr(GsAppList) list_tmp = NULL;
 
-       /* only use the temporary GsFlatpak to avoid the auth dialog */
+       /* parse the repo file */
+       app_tmp = gs_flatpak_app_new_from_repo_file (file, cancellable, error);
+       if (app_tmp == NULL)
+               return FALSE;
+
+       /* does already exist in either the user or system scope */
+       list_tmp = gs_app_list_new ();
        for (guint i = 0; i < priv->flatpaks->len; i++) {
                GsFlatpak *flatpak = g_ptr_array_index (priv->flatpaks, i);
-               if (gs_flatpak_get_flags (flatpak) & GS_FLATPAK_FLAG_IS_TEMPORARY) {
-                       if (!gs_flatpak_file_to_app (flatpak, list_new, file,
-                                                    cancellable, error)) {
-                               return FALSE;
-                       }
+               if (gs_flatpak_get_flags (flatpak) & GS_FLATPAK_FLAG_IS_TEMPORARY)
+                       continue;
+               if (!gs_flatpak_find_source_by_url (flatpak,
+                                                   gs_app_get_metadata_item (app_tmp, "flatpak::url"),
+                                                   list_tmp, cancellable, error))
+                       return FALSE;
+       }
+       for (guint i = 0; i < gs_app_list_length (list_tmp); i++) {
+               GsApp *app_old = gs_app_list_index (list_tmp, i);
+               if (gs_app_get_state (app_old) == AS_APP_STATE_INSTALLED) {
+                       g_debug ("already have %s, using instead of %s",
+                                gs_app_get_unique_id (app_old),
+                                gs_app_get_unique_id (app_tmp));
+                       gs_app_list_add (list, app_old);
+                       return TRUE;
+               } else {
+                       g_warning ("non-installed source %s : %s",
+                                  gs_app_get_name (app_old),
+                                  as_app_state_to_string (gs_app_get_state (app_old)));
                }
        }
 
-       /* force these to be 'any' scope for installation */
-       for (guint i = 0; i < gs_app_list_length (list_new); i++) {
-               GsApp *app_tmp = gs_app_list_index (list_new, i);
-               gs_app_set_scope (app_tmp, AS_APP_SCOPE_UNKNOWN);
+       /* this is new */
+       gs_app_list_add (list, app_tmp);
+       gs_app_set_management_plugin (app_tmp, gs_plugin_get_name (plugin));
+       return TRUE;
+}
+
+static GsFlatpak *
+gs_plugin_flatpak_find_temporary (GsPlugin *plugin)
+{
+       GsPluginData *priv = gs_plugin_get_data (plugin);
+       for (guint i = 0; i < priv->flatpaks->len; i++) {
+               GsFlatpak *flatpak = g_ptr_array_index (priv->flatpaks, i);
+               if (gs_flatpak_get_flags (flatpak) & GS_FLATPAK_FLAG_IS_TEMPORARY)
+                       return flatpak;
+       }
+       return NULL;
+}
+
+static gboolean
+gs_plugin_flatpak_file_to_app_bundle (GsPlugin *plugin,
+                                     GsAppList *list,
+                                     GFile *file,
+                                     GCancellable *cancellable,
+                                     GError **error)
+{
+       GsPluginData *priv = gs_plugin_get_data (plugin);
+       GsFlatpak *flatpak_tmp;
+       g_autoptr(GsApp) app_tmp = NULL;
+       g_autoptr(GsAppList) list_tmp = NULL;
+
+       /* only use the temporary GsFlatpak to avoid the auth dialog */
+       flatpak_tmp = gs_plugin_flatpak_find_temporary (plugin);
+       if (flatpak_tmp == NULL) {
+               g_set_error_literal (error,
+                                    GS_PLUGIN_ERROR,
+                                    GS_PLUGIN_ERROR_NOT_SUPPORTED,
+                                    "no temporary scope for bundle install");
+               return FALSE;
        }
 
-       /* are any of the new list already installed? */
-       for (guint i = 0; i < gs_app_list_length (list_new); i++) {
-               GsApp *app_tmp = gs_app_list_index (list_new, i);
-               g_autoptr(GsApp) app = NULL;
-               app = gs_plugin_cache_lookup (plugin, gs_app_get_unique_id (app_tmp));
-               if (app != NULL) {
-                       g_debug ("found existing %s for %s, using",
-                                gs_app_get_unique_id (app),
+       /* add object */
+       app_tmp = gs_flatpak_file_to_app_bundle (flatpak_tmp, file, cancellable, error);
+       if (app_tmp == NULL)
+               return FALSE;
+
+       /* does already exist in either the user or system scope */
+       list_tmp = gs_app_list_new ();
+       for (guint i = 0; i < priv->flatpaks->len; i++) {
+               GsFlatpak *flatpak = g_ptr_array_index (priv->flatpaks, i);
+               if (gs_flatpak_get_flags (flatpak) & GS_FLATPAK_FLAG_IS_TEMPORARY)
+                       continue;
+               if (!gs_flatpak_find_app_by_ref_display (flatpak,
+                                                        gs_app_get_flatpak_ref_display (app_tmp),
+                                                        list_tmp, cancellable, error))
+                       return FALSE;
+       }
+       for (guint i = 0; i < gs_app_list_length (list_tmp); i++) {
+               GsApp *app_old = gs_app_list_index (list_tmp, i);
+               if (gs_app_get_state (app_old) == AS_APP_STATE_INSTALLED) {
+                       g_debug ("already have %s, using instead of %s",
+                                gs_app_get_unique_id (app_old),
                                 gs_app_get_unique_id (app_tmp));
-                       gs_app_list_add (list, app);
-               } else {
-                       g_debug ("no existing %s in plugin cache",
+                       gs_app_list_add (list, app_old);
+                       return TRUE;
+               }
+       }
+
+       /* force this to be 'any' scope for installation */
+       gs_app_set_scope (app_tmp, AS_APP_SCOPE_UNKNOWN);
+
+       /* this is new */
+       gs_app_list_add (list, app_tmp);
+       gs_app_set_management_plugin (app_tmp, gs_plugin_get_name (plugin));
+       return TRUE;
+}
+
+static gboolean
+gs_plugin_flatpak_file_to_app_ref (GsPlugin *plugin,
+                                  GsAppList *list,
+                                  GFile *file,
+                                  GCancellable *cancellable,
+                                  GError **error)
+{
+       GsPluginData *priv = gs_plugin_get_data (plugin);
+       GsApp *runtime_app;
+       GsFlatpak *flatpak_tmp;
+       g_autoptr(GsApp) app_tmp = NULL;
+       g_autoptr(GsAppList) list_tmp = NULL;
+
+       /* only use the temporary GsFlatpak to avoid the auth dialog */
+       flatpak_tmp = gs_plugin_flatpak_find_temporary (plugin);
+       if (flatpak_tmp == NULL) {
+               g_set_error_literal (error,
+                                    GS_PLUGIN_ERROR,
+                                    GS_PLUGIN_ERROR_NOT_SUPPORTED,
+                                    "no temporary scope for bundle install");
+               return FALSE;
+       }
+
+       /* add object */
+       app_tmp = gs_flatpak_file_to_app_ref (flatpak_tmp, file, cancellable, error);
+       if (app_tmp == NULL)
+               return FALSE;
+
+       /* does already exist in either the user or system scope */
+       list_tmp = gs_app_list_new ();
+       for (guint i = 0; i < priv->flatpaks->len; i++) {
+               GsFlatpak *flatpak = g_ptr_array_index (priv->flatpaks, i);
+               if (gs_flatpak_get_flags (flatpak) & GS_FLATPAK_FLAG_IS_TEMPORARY)
+                       continue;
+               if (!gs_flatpak_find_app_by_ref_display (flatpak,
+                                                        gs_app_get_flatpak_ref_display (app_tmp),
+                                                        list_tmp, cancellable, error))
+                       return FALSE;
+       }
+       for (guint i = 0; i < gs_app_list_length (list_tmp); i++) {
+               GsApp *app_old = gs_app_list_index (list_tmp, i);
+               if (gs_app_get_state (app_old) == AS_APP_STATE_INSTALLED) {
+                       g_debug ("already have %s, using instead of %s",
+                                gs_app_get_unique_id (app_old),
                                 gs_app_get_unique_id (app_tmp));
-                       gs_app_list_add (list, app_tmp);
+                       gs_app_list_add (list, app_old);
+                       return TRUE;
+               }
+       }
+
+       /* force this to be 'any' scope for installation */
+       gs_app_set_scope (app_tmp, AS_APP_SCOPE_UNKNOWN);
+
+       /* do we have a system runtime available */
+       runtime_app = gs_app_get_runtime (app_tmp);
+       if (runtime_app != NULL &&
+           gs_app_get_state (runtime_app) != AS_APP_STATE_INSTALLED) {
+               g_autoptr(GsAppList) list_system_runtimes = NULL;
+               for (guint i = 0; i < priv->flatpaks->len; i++) {
+                       GsFlatpak *flatpak = g_ptr_array_index (priv->flatpaks, i);
+                       if (gs_flatpak_get_flags (flatpak) & GS_FLATPAK_FLAG_IS_TEMPORARY)
+                               continue;
+                       if (gs_flatpak_get_scope (flatpak) != AS_APP_SCOPE_SYSTEM)
+                               continue;
+                       if (!gs_flatpak_find_app_by_ref_display (flatpak,
+                                                                gs_app_get_flatpak_ref_display (runtime_app),
+                                                                list_system_runtimes,
+                                                                cancellable, error))
+                               return FALSE;
+               }
+               for (guint i = 0; i < gs_app_list_length (list_system_runtimes); i++) {
+                       GsApp *runtime_old = gs_app_list_index (list_system_runtimes, i);
+                       if (gs_app_get_state (runtime_old) == AS_APP_STATE_INSTALLED) {
+                               g_error ("already have %s, using instead of %s",
+                                        gs_app_get_unique_id (runtime_old),
+                                        gs_app_get_unique_id (runtime_app));
+                               gs_app_set_runtime (app_tmp, runtime_old);
+                               break;;
+                       }
                }
        }
 
+       /* this is new */
+       gs_app_list_add (list, app_tmp);
+       gs_app_set_management_plugin (app_tmp, gs_plugin_get_name (plugin));
+       return TRUE;
+}
+
+gboolean
+gs_plugin_file_to_app (GsPlugin *plugin,
+                      GsAppList *list,
+                      GFile *file,
+                      GCancellable *cancellable,
+                      GError **error)
+{
+       g_autofree gchar *content_type = NULL;
+       const gchar *mimetypes_bundle[] = {
+               "application/vnd.flatpak",
+               NULL };
+       const gchar *mimetypes_repo[] = {
+               "application/vnd.flatpak.repo",
+               NULL };
+       const gchar *mimetypes_ref[] = {
+               "application/vnd.flatpak.ref",
+               NULL };
+
+       /* does this match any of the mimetypes_bundle we support */
+       content_type = gs_utils_get_content_type (file, cancellable, error);
+       if (content_type == NULL)
+               return FALSE;
+       if (g_strv_contains (mimetypes_bundle, content_type)) {
+               return gs_plugin_flatpak_file_to_app_bundle (plugin,
+                                                            list,
+                                                            file,
+                                                            cancellable,
+                                                            error);
+       }
+       if (g_strv_contains (mimetypes_repo, content_type)) {
+               return gs_plugin_flatpak_file_to_app_repo (plugin,
+                                                          list,
+                                                          file,
+                                                          cancellable,
+                                                          error);
+       }
+       if (g_strv_contains (mimetypes_ref, content_type)) {
+               return gs_plugin_flatpak_file_to_app_ref (plugin,
+                                                         list,
+                                                         file,
+                                                         cancellable,
+                                                         error);
+       }
        return TRUE;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]