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:
Marco Trevisan
2025-10-17 04:00:20 +02:00
7 changed files with 368 additions and 89 deletions

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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++)

View File

@@ -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',

View 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

View 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
View 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;
}