[gnome-software/wip/ubuntu] Decide if an app is graphical by looking if it uses a graphical snap interface
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/ubuntu] Decide if an app is graphical by looking if it uses a graphical snap interface
- Date: Sun, 2 Oct 2016 23:00:40 +0000 (UTC)
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]