[gnome-software/wip/ubuntu] Decide if an app is graphical by looking if it uses a graphical snap interface



commit 80aa3b7e0e95cf8bedf33078bf82fa2e0b8bf9a8
Author: Robert Ancell <robert ancell canonical com>
Date:   Mon Oct 3 12:00:26 2016 +1300

    Decide if an app is graphical by looking if it uses a graphical snap interface

 src/plugins/gs-plugin-snap.c |   46 +++++++++++++++++++++++++++++--
 src/plugins/gs-snapd.c       |   44 ++++++++++++++++++++++++++++++
 src/plugins/gs-snapd.h       |   61 ++++++++++++++++++++++--------------------
 3 files changed, 119 insertions(+), 32 deletions(-)
---
diff --git a/src/plugins/gs-plugin-snap.c b/src/plugins/gs-plugin-snap.c
index 262ae4d..f5da6de 100644
--- a/src/plugins/gs-plugin-snap.c
+++ b/src/plugins/gs-plugin-snap.c
@@ -307,6 +307,44 @@ gs_plugin_app_install (GsPlugin *plugin,
        return TRUE;
 }
 
+// Check if an app is graphical by checking if it uses a known GUI interface.
+// This doesn't necessarily mean that every binary uses this interfaces, but is probably true.
+// https://bugs.launchpad.net/bugs/1595023
+static gboolean
+is_graphical (GsApp *app, GCancellable *cancellable)
+{
+       g_autoptr(JsonObject) result = NULL;
+       JsonArray *plugs;
+       guint i;
+       g_autoptr(GError) error = NULL;
+
+       result = gs_snapd_get_interfaces (cancellable, &error);
+       if (result == NULL) {
+               g_warning ("Failed to check interfaces: %s", error->message);
+               return FALSE;
+       }
+
+       plugs = json_object_get_array_member (result, "plugs");
+       for (i = 0; i < json_array_get_length (plugs); i++) {
+               JsonObject *plug = json_array_get_object_element (plugs, i);
+               const gchar *interface;
+
+               // Only looks at the plugs for this snap
+               g_printerr ("~%s\n", json_object_get_string_member (plug, "snap"));
+               if (g_strcmp0 (json_object_get_string_member (plug, "snap"), gs_app_get_id (app)) != 0)
+                       continue;
+
+               interface = json_object_get_string_member (plug, "interface");
+               if (interface == NULL)
+                       continue;
+
+               if (strcmp (interface, "unity7") == 0 || strcmp (interface, "x11") == 0 || strcmp (interface, 
"mir") == 0)
+                       return TRUE;
+       }
+
+       return FALSE;
+}
+
 gboolean
 gs_plugin_launch (GsPlugin *plugin,
                  GsApp *app,
@@ -315,8 +353,10 @@ gs_plugin_launch (GsPlugin *plugin,
 {
        const gchar *launch_name;
        g_autofree gchar *binary_name = NULL;
+       GAppInfoCreateFlags flags = G_APP_INFO_CREATE_NONE;
        g_autoptr(GAppInfo) info = NULL;
 
+
        /* We can only launch apps we know of */
        if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0)
                return TRUE;
@@ -330,9 +370,9 @@ gs_plugin_launch (GsPlugin *plugin,
        else
                binary_name = g_strdup_printf ("/snap/bin/%s.%s", gs_app_get_id (app), launch_name);
 
-       // FIXME: Since we don't currently know if this app needs a terminal or not we launch everything with 
one
-       // https://bugs.launchpad.net/bugs/1595023
-       info = g_app_info_create_from_commandline (binary_name, NULL, G_APP_INFO_CREATE_NEEDS_TERMINAL, 
error);
+       if (!is_graphical (app, cancellable))
+               flags |= G_APP_INFO_CREATE_NEEDS_TERMINAL;
+       info = g_app_info_create_from_commandline (binary_name, NULL, flags, error);
        if (info == NULL)
                return FALSE;
 
diff --git a/src/plugins/gs-snapd.c b/src/plugins/gs-snapd.c
index 082c27b..c4e902a 100644
--- a/src/plugins/gs-snapd.c
+++ b/src/plugins/gs-snapd.c
@@ -538,6 +538,50 @@ gs_snapd_find (gchar **values,
        return json_array_ref (result);
 }
 
+JsonObject *
+gs_snapd_get_interfaces (GCancellable *cancellable, GError **error)
+{
+       guint status_code;
+       g_autofree gchar *reason_phrase = NULL;
+       g_autofree gchar *response_type = NULL;
+       g_autofree gchar *response = NULL;
+       g_autoptr(JsonParser) parser = NULL;
+       JsonObject *root;
+       JsonObject *result;
+
+       if (!send_request ("GET", "/v2/interfaces", NULL,
+                          TRUE, NULL, NULL,
+                          TRUE, NULL, NULL,
+                          &status_code, &reason_phrase,
+                          &response_type, &response, NULL,
+                          cancellable, error))
+               return NULL;
+
+       if (status_code != SOUP_STATUS_OK) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_FAILED,
+                            "snapd returned status code %u: %s",
+                            status_code, reason_phrase);
+               return NULL;
+       }
+
+       parser = parse_result (response, response_type, error);
+       if (parser == NULL)
+               return NULL;
+       root = json_node_get_object (json_parser_get_root (parser));
+       result = json_object_get_object_member (root, "result");
+       if (result == NULL) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_FAILED,
+                            "snapd returned no result");
+               return NULL;
+       }
+
+       return json_object_ref (result);
+}
+
 static JsonObject *
 get_changes (const gchar *macaroon, gchar **discharges,
             const gchar *change_id,
diff --git a/src/plugins/gs-snapd.h b/src/plugins/gs-snapd.h
index d93b756..0edb1ec 100644
--- a/src/plugins/gs-snapd.h
+++ b/src/plugins/gs-snapd.h
@@ -27,41 +27,44 @@
 
 typedef void (*GsSnapdProgressCallback) (JsonObject *object, gpointer user_data);
 
-gboolean gs_snapd_exists       (void);
+gboolean gs_snapd_exists               (void);
 
-gchar *gs_snapd_login          (const gchar    *username,
-                                const gchar    *password,
-                                const gchar    *otp,
-                                guint          *status_code,
-                                GCancellable   *cancellable,
-                                GError         **error);
+gchar *gs_snapd_login                  (const gchar    *username,
+                                        const gchar    *password,
+                                        const gchar    *otp,
+                                        guint          *status_code,
+                                        GCancellable   *cancellable,
+                                        GError         **error);
 
-JsonObject *gs_snapd_list_one  (const gchar    *name,
-                                GCancellable   *cancellable,
-                                GError         **error);
+JsonObject *gs_snapd_list_one          (const gchar    *name,
+                                        GCancellable   *cancellable,
+                                        GError         **error);
 
-JsonArray *gs_snapd_list       (GCancellable   *cancellable,
-                                GError         **error);
+JsonArray *gs_snapd_list               (GCancellable   *cancellable,
+                                        GError         **error);
 
-JsonArray *gs_snapd_find       (gchar          **values,
-                                GCancellable   *cancellable,
-                                GError         **error);
+JsonArray *gs_snapd_find               (gchar          **values,
+                                        GCancellable   *cancellable,
+                                        GError         **error);
 
-gboolean gs_snapd_install      (const gchar    *name,
-                                GsSnapdProgressCallback callback,
-                                gpointer        user_data,
-                                GCancellable   *cancellable,
-                                GError         **error);
+JsonObject *gs_snapd_get_interfaces    (GCancellable   *cancellable,
+                                        GError         **error);
 
-gboolean gs_snapd_remove       (const gchar    *name,
-                                GsSnapdProgressCallback callback,
-                                gpointer        user_data,
-                                GCancellable   *cancellable,
-                                GError         **error);
+gboolean gs_snapd_install              (const gchar    *name,
+                                        GsSnapdProgressCallback callback,
+                                        gpointer        user_data,
+                                        GCancellable   *cancellable,
+                                        GError         **error);
 
-gchar *gs_snapd_get_resource   (const gchar    *path,
-                                gsize          *data_length,
-                                GCancellable   *cancellable,
-                                GError         **error);
+gboolean gs_snapd_remove               (const gchar    *name,
+                                        GsSnapdProgressCallback callback,
+                                        gpointer        user_data,
+                                        GCancellable   *cancellable,
+                                        GError         **error);
+
+gchar *gs_snapd_get_resource           (const gchar    *path,
+                                        gsize          *data_length,
+                                        GCancellable   *cancellable,
+                                        GError         **error);
 
 #endif /* __GS_SNAPD_H__ */


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