mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-10-25 14:32:16 +02:00
Merge branch 'snap-document-portal-launch' into 'main'
GDesktopAppInfo: Use document portal to open all the URIs for snaps See merge request GNOME/glib!4822
This commit is contained in:
@@ -461,6 +461,7 @@ const char * const exec_key_match_blocklist[] = {
|
||||
"bash",
|
||||
"env",
|
||||
"flatpak",
|
||||
"snap",
|
||||
"gjs",
|
||||
"pkexec",
|
||||
"python",
|
||||
@@ -2950,6 +2951,7 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
|
||||
gboolean completed = FALSE;
|
||||
GList *old_uris;
|
||||
GList *dup_uris;
|
||||
GList *ruris = NULL;
|
||||
|
||||
char **argv, **envp;
|
||||
int argc;
|
||||
@@ -2963,6 +2965,30 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
|
||||
else
|
||||
envp = g_get_environ ();
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
if (uris && info->keyfile)
|
||||
{
|
||||
char *snap_instance;
|
||||
char *app_id = NULL;
|
||||
|
||||
snap_instance = g_desktop_app_info_get_string (info, "X-SnapInstanceName");
|
||||
|
||||
if (snap_instance && *snap_instance)
|
||||
app_id = g_strconcat ("snap.", snap_instance, NULL);
|
||||
|
||||
g_free (snap_instance);
|
||||
|
||||
if (app_id)
|
||||
{
|
||||
ruris = g_document_portal_add_documents (uris, app_id, NULL);
|
||||
if (ruris != NULL)
|
||||
uris = ruris;
|
||||
}
|
||||
|
||||
g_clear_pointer (&app_id, g_free);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The GList* passed to expand_application_parameters() will be modified
|
||||
* internally by expand_macro(), so we need to pass a copy of it instead,
|
||||
* and also use that copy to control the exit condition of the loop below.
|
||||
@@ -3152,6 +3178,7 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
|
||||
out:
|
||||
g_strfreev (argv);
|
||||
g_strfreev (envp);
|
||||
g_list_free_full (ruris, g_free);
|
||||
|
||||
return completed;
|
||||
}
|
||||
@@ -3337,12 +3364,27 @@ g_desktop_app_info_launch_uris_with_dbus (GDesktopAppInfo *info,
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
app_id = g_desktop_app_info_get_string (info, "X-Flatpak");
|
||||
|
||||
if (!app_id)
|
||||
{
|
||||
char *snap_instance;
|
||||
|
||||
snap_instance = g_desktop_app_info_get_string (info, "X-SnapInstanceName");
|
||||
|
||||
if (snap_instance && *snap_instance)
|
||||
app_id = g_strconcat ("snap.", snap_instance, NULL);
|
||||
|
||||
g_free (snap_instance);
|
||||
}
|
||||
|
||||
if (app_id && *app_id)
|
||||
{
|
||||
ruris = g_document_portal_add_documents (uris, app_id, NULL);
|
||||
if (ruris == NULL)
|
||||
ruris = uris;
|
||||
}
|
||||
|
||||
g_clear_pointer (&app_id, g_free);
|
||||
#endif
|
||||
|
||||
launch_uris_with_dbus (info, session_bus, ruris, launch_context,
|
||||
@@ -3351,8 +3393,6 @@ g_desktop_app_info_launch_uris_with_dbus (GDesktopAppInfo *info,
|
||||
if (ruris != uris)
|
||||
g_list_free_full (ruris, g_free);
|
||||
|
||||
g_free (app_id);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -291,15 +291,20 @@ test_dbus_appinfo (void)
|
||||
g_object_unref (app);
|
||||
}
|
||||
|
||||
static GType test_flatpak_application_get_type (void);
|
||||
typedef GApplication TestFlatpakApplication;
|
||||
typedef GApplicationClass TestFlatpakApplicationClass;
|
||||
G_DEFINE_TYPE (TestFlatpakApplication, test_flatpak_application, G_TYPE_APPLICATION)
|
||||
typedef struct {
|
||||
GApplication parent;
|
||||
|
||||
gboolean opened;
|
||||
} TestSandboxedApplication;
|
||||
|
||||
static GType test_sandboxed_application_get_type (void);
|
||||
typedef GApplicationClass TestSandboxedApplicationClass;
|
||||
G_DEFINE_TYPE (TestSandboxedApplication, test_sandboxed_application, G_TYPE_APPLICATION)
|
||||
|
||||
static void
|
||||
on_flatpak_launch_uris_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
on_sandboxed_app_launch_uris_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GApplication *app = user_data;
|
||||
GError *error = NULL;
|
||||
@@ -313,110 +318,139 @@ on_flatpak_launch_uris_finish (GObject *object,
|
||||
}
|
||||
|
||||
static void
|
||||
on_flatpak_activate (GApplication *app,
|
||||
gpointer user_data)
|
||||
on_sandboxed_app_activate (GApplication *app,
|
||||
gpointer user_data)
|
||||
{
|
||||
GAppLaunchContext *ctx;
|
||||
GDesktopAppInfo *flatpak_appinfo = user_data;
|
||||
GDesktopAppInfo *sandboxed_app_appinfo = user_data;
|
||||
char *uri;
|
||||
GList *uris;
|
||||
|
||||
/* The app will be released in on_flatpak_launch_uris_finish */
|
||||
/* The app will be released in on_sandboxed_app_launch_uris_finish */
|
||||
g_application_hold (app);
|
||||
|
||||
uri = g_filename_to_uri (g_desktop_app_info_get_filename (flatpak_appinfo), NULL, NULL);
|
||||
uri = g_filename_to_uri (g_desktop_app_info_get_filename (sandboxed_app_appinfo), NULL, NULL);
|
||||
g_assert_nonnull (uri);
|
||||
uris = g_list_prepend (NULL, uri);
|
||||
ctx = g_object_new (test_app_launch_context_get_type (), NULL);
|
||||
requested_startup_id = FALSE;
|
||||
saw_startup_id = FALSE;
|
||||
g_app_info_launch_uris_async (G_APP_INFO (flatpak_appinfo), uris, ctx,
|
||||
NULL, on_flatpak_launch_uris_finish, app);
|
||||
g_app_info_launch_uris_async (G_APP_INFO (sandboxed_app_appinfo), uris, ctx,
|
||||
NULL, on_sandboxed_app_launch_uris_finish, app);
|
||||
g_object_unref (ctx);
|
||||
g_list_free (uris);
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
static void
|
||||
on_flatpak_open (GApplication *app,
|
||||
GFile **files,
|
||||
gint n_files,
|
||||
const char *hint,
|
||||
gpointer user_data)
|
||||
on_sandboxed_app_open (GApplication *app,
|
||||
GFile **files,
|
||||
gint n_files,
|
||||
const char *hint,
|
||||
gpointer user_data)
|
||||
{
|
||||
GFakeDocumentPortalThread *portal = user_data;
|
||||
TestSandboxedApplication *sandboxed_app = (TestSandboxedApplication *) app;
|
||||
GFile *f;
|
||||
char *desktop_id;
|
||||
|
||||
g_assert_cmpint (n_files, ==, 1);
|
||||
g_test_message ("on_flatpak_open received file '%s'", g_file_peek_path (files[0]));
|
||||
g_test_message ("on_sandboxed_app_open received file '%s'", g_file_peek_path (files[0]));
|
||||
|
||||
desktop_id = g_strconcat (g_application_get_application_id (app), ".desktop", NULL);
|
||||
|
||||
/* The file has been exported via the document portal */
|
||||
f = g_file_new_build_filename (g_fake_document_portal_thread_get_mount_point (portal),
|
||||
"document-id-0",
|
||||
"org.gtk.test.dbusappinfo.flatpak.desktop",
|
||||
desktop_id,
|
||||
NULL);
|
||||
g_assert_cmpstr (g_file_peek_path (files[0]), == , g_file_peek_path (f));
|
||||
g_assert_true (g_file_equal (files[0], f));
|
||||
sandboxed_app->opened = TRUE;
|
||||
|
||||
g_object_unref (f);
|
||||
g_free (desktop_id);
|
||||
}
|
||||
|
||||
static void
|
||||
test_flatpak_application_init (TestApplication *app)
|
||||
test_sandboxed_application_init (TestSandboxedApplication *app)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
test_flatpak_application_class_init (GApplicationClass *class)
|
||||
test_sandboxed_application_class_init (GApplicationClass *class)
|
||||
{
|
||||
class->before_emit = test_application_before_emit;
|
||||
}
|
||||
|
||||
static void
|
||||
test_flatpak_doc_export (void)
|
||||
test_sandboxed_application_doc_export (const char *app_id,
|
||||
const char *expected_portal_app_id)
|
||||
{
|
||||
const gchar *argv[] = { "myapp", NULL };
|
||||
gchar *desktop_file = NULL;
|
||||
GDesktopAppInfo *flatpak_appinfo;
|
||||
gchar *desktop_id;
|
||||
GDesktopAppInfo *appinfo;
|
||||
GApplication *app;
|
||||
int status;
|
||||
GFakeDocumentPortalThread *thread = NULL;
|
||||
|
||||
g_test_summary ("Test that files launched via Flatpak apps are made available via the document portal.");
|
||||
int status;
|
||||
|
||||
/* Run a fake-document-portal */
|
||||
thread = g_fake_document_portal_thread_new (session_bus_get_address (),
|
||||
"org.gtk.test.dbusappinfo.flatpak");
|
||||
expected_portal_app_id);
|
||||
g_fake_document_portal_thread_run (thread);
|
||||
|
||||
desktop_file = g_test_build_filename (G_TEST_DIST,
|
||||
"org.gtk.test.dbusappinfo.flatpak.desktop",
|
||||
NULL);
|
||||
flatpak_appinfo = g_desktop_app_info_new_from_filename (desktop_file);
|
||||
g_assert_nonnull (flatpak_appinfo);
|
||||
desktop_id = g_strconcat (app_id, ".desktop", NULL);
|
||||
desktop_file = g_test_build_filename (G_TEST_DIST, desktop_id, NULL);
|
||||
appinfo = g_desktop_app_info_new_from_filename (desktop_file);
|
||||
g_assert_nonnull (appinfo);
|
||||
g_free (desktop_file);
|
||||
g_free (desktop_id);
|
||||
|
||||
app = g_object_new (test_flatpak_application_get_type (),
|
||||
"application-id", "org.gtk.test.dbusappinfo.flatpak",
|
||||
app = g_object_new (test_sandboxed_application_get_type (),
|
||||
"application-id", app_id,
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
NULL);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (on_flatpak_activate),
|
||||
flatpak_appinfo);
|
||||
g_signal_connect_object (app, "open", G_CALLBACK (on_flatpak_open), thread,
|
||||
G_CONNECT_DEFAULT);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (on_sandboxed_app_activate),
|
||||
appinfo);
|
||||
g_signal_connect_object (app, "open", G_CALLBACK (on_sandboxed_app_open),
|
||||
thread, G_CONNECT_DEFAULT);
|
||||
|
||||
g_assert_false (((TestSandboxedApplication *) app)->opened);
|
||||
status = g_application_run (app, 1, (gchar **) argv);
|
||||
g_assert_cmpint (status, ==, 0);
|
||||
g_assert_true (((TestSandboxedApplication *) app)->opened);
|
||||
|
||||
g_object_unref (app);
|
||||
g_object_unref (flatpak_appinfo);
|
||||
g_object_unref (appinfo);
|
||||
g_fake_document_portal_thread_stop (thread);
|
||||
g_clear_object (&thread);
|
||||
}
|
||||
|
||||
static void
|
||||
on_flatpak_launch_invalid_uri_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
test_flatpak_doc_export (void)
|
||||
{
|
||||
g_test_summary ("Test that files opened by launching flatpak apps are made "
|
||||
"available via the document portal.");
|
||||
|
||||
test_sandboxed_application_doc_export ("org.gtk.test.dbusappinfo.flatpak",
|
||||
"org.gtk.test.dbusappinfo.flatpak");
|
||||
}
|
||||
|
||||
static void
|
||||
test_snap_doc_export (void)
|
||||
{
|
||||
g_test_summary ("Test that files opened by launching snap apps are made "
|
||||
"available via the document portal.");
|
||||
|
||||
test_sandboxed_application_doc_export ("org.gtk.test.dbusappinfo.snap",
|
||||
"snap.snap-app");
|
||||
}
|
||||
|
||||
static void
|
||||
on_sandboxed_app_launch_invalid_uri_finish (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GApplication *app = user_data;
|
||||
GError *error = NULL;
|
||||
@@ -430,84 +464,104 @@ on_flatpak_launch_invalid_uri_finish (GObject *object,
|
||||
}
|
||||
|
||||
static void
|
||||
on_flatpak_activate_invalid_uri (GApplication *app,
|
||||
gpointer user_data)
|
||||
on_sandboxed_app_activate_invalid_uri (GApplication *app,
|
||||
gpointer user_data)
|
||||
{
|
||||
GAppLaunchContext *ctx;
|
||||
GDesktopAppInfo *flatpak_appinfo = user_data;
|
||||
GDesktopAppInfo *sandboxed_app_appinfo = user_data;
|
||||
GList *uris;
|
||||
|
||||
/* The app will be released in on_flatpak_launch_uris_finish */
|
||||
/* The app will be released in on_sandboxed_app_launch_uris_finish */
|
||||
g_application_hold (app);
|
||||
|
||||
uris = g_list_prepend (NULL, "file:///hopefully/an/invalid/path.desktop");
|
||||
ctx = g_object_new (test_app_launch_context_get_type (), NULL);
|
||||
requested_startup_id = FALSE;
|
||||
saw_startup_id = FALSE;
|
||||
g_app_info_launch_uris_async (G_APP_INFO (flatpak_appinfo), uris, ctx,
|
||||
NULL, on_flatpak_launch_invalid_uri_finish, app);
|
||||
g_app_info_launch_uris_async (G_APP_INFO (sandboxed_app_appinfo), uris, ctx,
|
||||
NULL, on_sandboxed_app_launch_invalid_uri_finish, app);
|
||||
g_object_unref (ctx);
|
||||
g_list_free (uris);
|
||||
}
|
||||
|
||||
static void
|
||||
on_flatpak_open_invalid_uri (GApplication *app,
|
||||
GFile **files,
|
||||
gint n_files,
|
||||
const char *hint)
|
||||
on_sandboxed_app_open_invalid_uri (GApplication *app,
|
||||
GFile **files,
|
||||
gint n_files,
|
||||
const char *hint)
|
||||
{
|
||||
GFile *f;
|
||||
|
||||
g_assert_cmpint (n_files, ==, 1);
|
||||
g_test_message ("on_flatpak_open received file '%s'", g_file_peek_path (files[0]));
|
||||
g_test_message ("on_sandboxed_app_open received file '%s'", g_file_peek_path (files[0]));
|
||||
|
||||
/* The file has been exported via the document portal */
|
||||
f = g_file_new_for_uri ("file:///hopefully/an/invalid/path.desktop");
|
||||
g_assert_cmpstr (g_file_peek_path (files[0]), == , g_file_peek_path (f));
|
||||
g_assert_true (g_file_equal (files[0], f));
|
||||
g_object_unref (f);
|
||||
}
|
||||
|
||||
static void
|
||||
test_flatpak_missing_doc_export (void)
|
||||
test_sandboxed_app_missing_doc_export (const char *app_id)
|
||||
{
|
||||
const gchar *argv[] = { "myapp", NULL };
|
||||
gchar *desktop_file = NULL;
|
||||
GDesktopAppInfo *flatpak_appinfo;
|
||||
gchar *desktop_id;
|
||||
GDesktopAppInfo *appinfo;
|
||||
GApplication *app;
|
||||
int status;
|
||||
GFakeDocumentPortalThread *thread = NULL;
|
||||
|
||||
g_test_summary ("Test that files launched via Flatpak apps are made available via the document portal.");
|
||||
|
||||
/* Run a fake-document-portal */
|
||||
thread = g_fake_document_portal_thread_new (session_bus_get_address (),
|
||||
"NO_PORTAL_CALLED");
|
||||
"%%_NO_PORTAL_CALLED_%%");
|
||||
g_fake_document_portal_thread_run (thread);
|
||||
|
||||
desktop_file = g_test_build_filename (G_TEST_DIST,
|
||||
"org.gtk.test.dbusappinfo.flatpak.desktop",
|
||||
NULL);
|
||||
flatpak_appinfo = g_desktop_app_info_new_from_filename (desktop_file);
|
||||
g_assert_nonnull (flatpak_appinfo);
|
||||
desktop_id = g_strconcat (app_id, ".desktop", NULL);
|
||||
desktop_file = g_test_build_filename (G_TEST_DIST, desktop_id, NULL);
|
||||
appinfo = g_desktop_app_info_new_from_filename (desktop_file);
|
||||
g_assert_nonnull (appinfo);
|
||||
|
||||
app = g_object_new (test_flatpak_application_get_type (),
|
||||
"application-id", "org.gtk.test.dbusappinfo.flatpak",
|
||||
app = g_object_new (test_sandboxed_application_get_type (),
|
||||
"application-id", app_id,
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
NULL);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (on_flatpak_activate_invalid_uri),
|
||||
flatpak_appinfo);
|
||||
g_signal_connect (app, "open", G_CALLBACK (on_flatpak_open_invalid_uri), NULL);
|
||||
g_signal_connect (app, "activate", G_CALLBACK (on_sandboxed_app_activate_invalid_uri),
|
||||
appinfo);
|
||||
g_signal_connect (app, "open", G_CALLBACK (on_sandboxed_app_open_invalid_uri), NULL);
|
||||
|
||||
g_assert_false (((TestSandboxedApplication *) app)->opened);
|
||||
status = g_application_run (app, 1, (gchar **) argv);
|
||||
g_assert_cmpint (status, ==, 0);
|
||||
g_assert_false (((TestSandboxedApplication *) app)->opened);
|
||||
|
||||
g_object_unref (app);
|
||||
g_object_unref (flatpak_appinfo);
|
||||
g_object_unref (appinfo);
|
||||
g_free (desktop_file);
|
||||
g_free (desktop_id);
|
||||
g_fake_document_portal_thread_stop (thread);
|
||||
g_clear_object (&thread);
|
||||
}
|
||||
|
||||
static void
|
||||
test_flatpak_missing_doc_export (void)
|
||||
{
|
||||
g_test_summary ("Test that files opened by launching flatpak apps are not made "
|
||||
"available via the document portal.");
|
||||
|
||||
test_sandboxed_app_missing_doc_export ("org.gtk.test.dbusappinfo.flatpak");
|
||||
}
|
||||
|
||||
static void
|
||||
test_snap_missing_doc_export (void)
|
||||
{
|
||||
g_test_summary ("Test that files opened by launching snap apps are not made "
|
||||
"available via the document portal.");
|
||||
|
||||
test_sandboxed_app_missing_doc_export ("org.gtk.test.dbusappinfo.snap");
|
||||
}
|
||||
|
||||
static void
|
||||
check_portal_openuri_call (const char *expected_uri,
|
||||
GFakeDesktopPortalThread *thread)
|
||||
@@ -713,6 +767,8 @@ main (int argc, char **argv)
|
||||
g_test_add_func ("/appinfo/dbusappinfo", test_dbus_appinfo);
|
||||
g_test_add_func ("/appinfo/flatpak-doc-export", test_flatpak_doc_export);
|
||||
g_test_add_func ("/appinfo/flatpak-missing-doc-export", test_flatpak_missing_doc_export);
|
||||
g_test_add_func ("/appinfo/snap-doc-export", test_snap_doc_export);
|
||||
g_test_add_func ("/appinfo/snap-missing-doc-export", test_snap_missing_doc_export);
|
||||
g_test_add_func ("/appinfo/portal-open-file", test_portal_open_file);
|
||||
g_test_add_func ("/appinfo/portal-open-uri", test_portal_open_uri);
|
||||
g_test_add_func ("/appinfo/portal-open-file-async", test_portal_open_file_async);
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "fake-document-portal.h"
|
||||
#include "gdbus-sessionbus.h"
|
||||
|
||||
G_DECLARE_FINAL_TYPE (TestLaunchContext, test_launch_context, TEST,
|
||||
LAUNCH_CONTEXT, GAppLaunchContext);
|
||||
|
||||
@@ -1127,6 +1130,22 @@ on_launch_failed (GAppLaunchContext *context, const char *startup_notify_id, gpo
|
||||
*invoked = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
wait_child_completed (GDesktopAppInfo *appinfo,
|
||||
GPid pid,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean *child_waited = user_data;
|
||||
int wait_status = 0;
|
||||
GError *error = NULL;
|
||||
|
||||
while (waitpid (pid, &wait_status, 0) != pid);
|
||||
g_spawn_check_wait_status (wait_status, &error);
|
||||
g_assert_no_error (error);
|
||||
g_clear_error (&error);
|
||||
*child_waited = TRUE;
|
||||
}
|
||||
|
||||
/* Test g_desktop_app_info_launch_uris_as_manager() and
|
||||
* g_desktop_app_info_launch_uris_as_manager_with_fds()
|
||||
*/
|
||||
@@ -1140,6 +1159,7 @@ test_launch_as_manager (void)
|
||||
gboolean invoked = FALSE;
|
||||
gboolean launched = FALSE;
|
||||
gboolean failed = FALSE;
|
||||
gboolean child_waited = FALSE;
|
||||
GAppLaunchContext *context;
|
||||
|
||||
path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL);
|
||||
@@ -1156,29 +1176,38 @@ test_launch_as_manager (void)
|
||||
g_signal_connect (context, "launch-failed",
|
||||
G_CALLBACK (on_launch_failed),
|
||||
&failed);
|
||||
retval = g_desktop_app_info_launch_uris_as_manager (appinfo, NULL, context, 0,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
retval = g_desktop_app_info_launch_uris_as_manager (appinfo, NULL, context,
|
||||
G_SPAWN_DO_NOT_REAP_CHILD,
|
||||
NULL,
|
||||
NULL,
|
||||
wait_child_completed,
|
||||
&child_waited,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (retval);
|
||||
g_assert_true (invoked);
|
||||
g_assert_true (launched);
|
||||
g_assert_true (child_waited);
|
||||
g_assert_false (failed);
|
||||
|
||||
invoked = FALSE;
|
||||
launched = FALSE;
|
||||
failed = FALSE;
|
||||
child_waited = FALSE;
|
||||
retval = g_desktop_app_info_launch_uris_as_manager_with_fds (appinfo,
|
||||
NULL, context, 0,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, context,
|
||||
G_SPAWN_DO_NOT_REAP_CHILD,
|
||||
NULL,
|
||||
NULL,
|
||||
wait_child_completed,
|
||||
&child_waited,
|
||||
-1, -1, -1,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (retval);
|
||||
g_assert_true (invoked);
|
||||
g_assert_true (launched);
|
||||
g_assert_true (child_waited);
|
||||
g_assert_false (failed);
|
||||
|
||||
g_object_unref (appinfo);
|
||||
@@ -1196,6 +1225,7 @@ test_launch_as_manager_fail (void)
|
||||
gboolean launch_started = FALSE;
|
||||
gboolean launched = FALSE;
|
||||
gboolean failed = FALSE;
|
||||
gboolean child_waited = FALSE;
|
||||
|
||||
g_test_summary ("Tests that launch-errors are properly handled, we force " \
|
||||
"this by using invalid FD's values when launching as manager");
|
||||
@@ -1216,15 +1246,19 @@ test_launch_as_manager_fail (void)
|
||||
&failed);
|
||||
|
||||
retval = g_desktop_app_info_launch_uris_as_manager_with_fds (appinfo,
|
||||
NULL, context, 0,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, context,
|
||||
G_SPAWN_DO_NOT_REAP_CHILD,
|
||||
NULL,
|
||||
NULL,
|
||||
wait_child_completed,
|
||||
&child_waited,
|
||||
3000, 3001, 3002,
|
||||
&error);
|
||||
g_assert_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED);
|
||||
g_assert_false (retval);
|
||||
g_assert_true (launch_started);
|
||||
g_assert_false (launched);
|
||||
g_assert_false (child_waited);
|
||||
g_assert_true (failed);
|
||||
|
||||
g_clear_error (&error);
|
||||
@@ -1401,6 +1435,76 @@ test_default_uri_handler_async (void)
|
||||
g_free (file_path);
|
||||
}
|
||||
|
||||
static void
|
||||
launch_snap_uris_with_portal (void)
|
||||
{
|
||||
GDesktopAppInfo *appinfo;
|
||||
GError *error = NULL;
|
||||
gboolean retval;
|
||||
const gchar *path;
|
||||
const gchar *path2;
|
||||
gboolean invoked = FALSE;
|
||||
gboolean launched = FALSE;
|
||||
gboolean failed = FALSE;
|
||||
gboolean child_waited = FALSE;
|
||||
GAppLaunchContext *context;
|
||||
GList *uris = NULL;
|
||||
GFakeDocumentPortalThread *thread = NULL;
|
||||
|
||||
/* Run a fake-document-portal */
|
||||
session_bus_up ();
|
||||
thread = g_fake_document_portal_thread_new (session_bus_get_address (),
|
||||
"snap.snap-app");
|
||||
g_fake_document_portal_thread_run (thread);
|
||||
|
||||
path = g_test_get_filename (G_TEST_BUILT, "snap-app_appinfo-test.desktop", NULL);
|
||||
appinfo = g_desktop_app_info_new_from_filename (path);
|
||||
g_assert_true (G_IS_APP_INFO (appinfo));
|
||||
|
||||
path2 = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL);
|
||||
g_assert_true (g_file_test (path2, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR));
|
||||
|
||||
context = g_object_new (test_launch_context_get_type (), NULL);
|
||||
g_signal_connect (context, "launch-started",
|
||||
G_CALLBACK (on_launch_started),
|
||||
&invoked);
|
||||
g_signal_connect (context, "launched",
|
||||
G_CALLBACK (on_launched),
|
||||
&launched);
|
||||
g_signal_connect (context, "launch-failed",
|
||||
G_CALLBACK (on_launch_failed),
|
||||
&failed);
|
||||
g_app_launch_context_setenv (context, "DOCUMENT_PORTAL_MOUNT_POINT",
|
||||
g_fake_document_portal_thread_get_mount_point (thread));
|
||||
|
||||
uris = g_list_append (uris, g_strconcat ("file://", path, NULL));
|
||||
uris = g_list_append (uris, g_strconcat ("file://", path2, NULL));
|
||||
|
||||
retval = g_desktop_app_info_launch_uris_as_manager (appinfo, uris,
|
||||
context,
|
||||
G_SPAWN_DO_NOT_REAP_CHILD,
|
||||
NULL,
|
||||
NULL,
|
||||
wait_child_completed,
|
||||
&child_waited,
|
||||
&error);
|
||||
|
||||
g_assert_no_error (error);
|
||||
g_assert_true (retval);
|
||||
g_assert_true (invoked);
|
||||
g_assert_true (launched);
|
||||
g_assert_true (child_waited);
|
||||
g_assert_false (failed);
|
||||
|
||||
g_clear_list (&uris, g_free);
|
||||
g_object_unref (appinfo);
|
||||
g_assert_finalize_object (context);
|
||||
|
||||
g_fake_document_portal_thread_stop (thread);
|
||||
g_clear_object (&thread);
|
||||
session_bus_down ();
|
||||
}
|
||||
|
||||
/* Test if Desktop-File Id is correctly formed */
|
||||
static void
|
||||
test_id (void)
|
||||
@@ -2031,6 +2135,7 @@ main (int argc,
|
||||
g_test_add_func ("/desktop-app-info/launch-as-manager/fail", test_launch_as_manager_fail);
|
||||
g_test_add_func ("/desktop-app-info/launch-default-uri-handler", test_default_uri_handler);
|
||||
g_test_add_func ("/desktop-app-info/launch-default-uri-handler-async", test_default_uri_handler_async);
|
||||
g_test_add_func ("/desktop-app-info/launch-snap-uri-with-portal", launch_snap_uris_with_portal);
|
||||
g_test_add_func ("/desktop-app-info/id", test_id);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (supported_terminals); i++)
|
||||
|
||||
@@ -370,13 +370,6 @@ if host_machine.system() != 'windows'
|
||||
'install' : false,
|
||||
'extra_programs' : ['appinfo-test'],
|
||||
},
|
||||
'desktop-app-info' : {
|
||||
'install' : false,
|
||||
'depends' : gio_launch_desktop,
|
||||
'extra_programs' : ['apps', 'appinfo-test'],
|
||||
# FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/3148
|
||||
'can_fail' : host_system == 'gnu',
|
||||
},
|
||||
}
|
||||
endif
|
||||
|
||||
@@ -384,6 +377,7 @@ if host_machine.system() != 'windows'
|
||||
'basic-application' : {},
|
||||
'dbus-launch' : {},
|
||||
'appinfo-test' : {},
|
||||
'snapinfo-test' : {},
|
||||
}
|
||||
|
||||
if not glib_have_cocoa
|
||||
@@ -622,6 +616,14 @@ if host_machine.system() != 'windows'
|
||||
'dbus-appinfo' : {
|
||||
'extra_sources' : [extra_sources, fake_document_portal_sources],
|
||||
},
|
||||
'desktop-app-info' : {
|
||||
'install' : false,
|
||||
'depends' : gio_launch_desktop,
|
||||
'extra_programs' : ['apps', 'appinfo-test', 'snapinfo-test'],
|
||||
# FIXME: https://gitlab.gnome.org/GNOME/glib/-/issues/3148
|
||||
'can_fail' : host_system == 'gnu',
|
||||
'extra_sources' : [extra_sources, fake_document_portal_sources],
|
||||
},
|
||||
}
|
||||
endif
|
||||
|
||||
@@ -750,6 +752,7 @@ appinfo_test_desktop_files = [
|
||||
'appinfo-test-path',
|
||||
'appinfo-test',
|
||||
'appinfo-test2',
|
||||
'snap-app_appinfo-test',
|
||||
]
|
||||
|
||||
foreach appinfo_test_desktop_file : appinfo_test_desktop_files
|
||||
@@ -789,6 +792,7 @@ if installed_tests_enabled
|
||||
'file.c',
|
||||
'org.gtk.test.dbusappinfo.desktop',
|
||||
'org.gtk.test.dbusappinfo.flatpak.desktop',
|
||||
'org.gtk.test.dbusappinfo.snap.desktop',
|
||||
'test1.overlay',
|
||||
install_dir : installed_tests_execdir,
|
||||
install_tag : 'tests',
|
||||
|
||||
11
gio/tests/org.gtk.test.dbusappinfo.snap.desktop
Normal file
11
gio/tests/org.gtk.test.dbusappinfo.snap.desktop
Normal file
@@ -0,0 +1,11 @@
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
# SPDX-FileCopyrightText: 2025 Marco Trevisan (Treviño)
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Version=1.0
|
||||
Name=Test
|
||||
X-SnapInstanceName=snap-app
|
||||
X-SnapAppName=dbusappinfo
|
||||
X-SnapCommonID=org.gtk.test.dbusappinfo.snap
|
||||
DBusActivatable=true
|
||||
StartupNotify=true
|
||||
12
gio/tests/snap-app_appinfo-test.desktop.in
Normal file
12
gio/tests/snap-app_appinfo-test.desktop.in
Normal file
@@ -0,0 +1,12 @@
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
# SPDX-FileCopyrightText: 2025 Marco Trevisan (Treviño)
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Version=1.0
|
||||
Name=Snap Test
|
||||
X-SnapInstanceName=snap-app
|
||||
X-SnapAppName=appinfo-test
|
||||
X-SnapCommonID=org.gio.snap-app.appinfo-test
|
||||
DBusActivatable=false
|
||||
Exec=@installed_tests_dir@/snapinfo-test %U
|
||||
StartupNotify=true
|
||||
51
gio/tests/snapinfo-test.c
Normal file
51
gio/tests/snapinfo-test.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* SPDX-FileCopyrightText: 2025 Marco Trevisan (Treviño)
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
const char *envvar;
|
||||
const char *document_portal_mount;
|
||||
char *expected;
|
||||
char *expected_files[3] = {0};
|
||||
gint pid_from_env;
|
||||
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
envvar = g_getenv ("GIO_LAUNCHED_DESKTOP_FILE");
|
||||
g_assert_nonnull (envvar);
|
||||
|
||||
expected = g_test_build_filename (G_TEST_BUILT, "snap-app_appinfo-test.desktop", NULL);
|
||||
g_assert_cmpstr (envvar, ==, expected);
|
||||
g_free (expected);
|
||||
|
||||
envvar = g_getenv ("GIO_LAUNCHED_DESKTOP_FILE_PID");
|
||||
g_assert (envvar != NULL);
|
||||
pid_from_env = atoi (envvar);
|
||||
g_assert_cmpint (pid_from_env, ==, getpid ());
|
||||
|
||||
document_portal_mount = g_getenv ("DOCUMENT_PORTAL_MOUNT_POINT");
|
||||
g_assert_nonnull (document_portal_mount);
|
||||
|
||||
expected_files[0] = g_build_filename (document_portal_mount,
|
||||
"document-id-0", "snap-app_appinfo-test.desktop",
|
||||
NULL);
|
||||
expected_files[1] = g_build_filename (document_portal_mount,
|
||||
"document-id-1", "appinfo-test.desktop",
|
||||
NULL);
|
||||
|
||||
g_assert_cmpint (argc, ==, 3);
|
||||
|
||||
for (size_t i = 0; i < G_N_ELEMENTS (expected_files); ++i)
|
||||
{
|
||||
g_assert_cmpstr (argv[i+1], ==, expected_files[i]);
|
||||
g_clear_pointer (&expected_files[i], g_free);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user