Branch data Line data Source code
1 : : /* GLib testing framework examples and tests
2 : : *
3 : : * Copyright © 2013 Red Hat, Inc.
4 : : * Copyright © 2015, 2017, 2018 Endless Mobile, Inc.
5 : : *
6 : : * SPDX-License-Identifier: LGPL-2.1-or-later
7 : : *
8 : : * This library is free software; you can redistribute it and/or
9 : : * modify it under the terms of the GNU Lesser General Public
10 : : * License as published by the Free Software Foundation; either
11 : : * version 2.1 of the License, or (at your option) any later version.
12 : : *
13 : : * This library is distributed in the hope that it will be useful,
14 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : : * Lesser General Public License for more details.
17 : : *
18 : : * You should have received a copy of the GNU Lesser General
19 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 : : */
21 : :
22 : : #include <gio/gio.h>
23 : : #include <gstdio.h>
24 : :
25 : : #if defined (G_OS_UNIX) && !defined (__APPLE__)
26 : : #include <gio/gdesktopappinfo.h>
27 : : #endif
28 : :
29 : : typedef struct
30 : : {
31 : : gchar *applications_dir;
32 : : } Fixture;
33 : :
34 : : static void
35 : 1 : setup (Fixture *fixture,
36 : : gconstpointer user_data)
37 : : {
38 : 1 : fixture->applications_dir = g_build_filename (g_get_user_data_dir (), "applications", NULL);
39 : 1 : g_assert_no_errno (g_mkdir_with_parents (fixture->applications_dir, 0755));
40 : :
41 : 1 : g_test_message ("Using data directory: %s", g_get_user_data_dir ());
42 : 1 : }
43 : :
44 : : static void
45 : 1 : teardown (Fixture *fixture,
46 : : gconstpointer user_data)
47 : : {
48 : 1 : g_assert_no_errno (g_rmdir (fixture->applications_dir));
49 : 1 : g_clear_pointer (&fixture->applications_dir, g_free);
50 : 1 : }
51 : :
52 : : #if defined (G_OS_UNIX) && !defined (__APPLE__)
53 : : static gboolean
54 : 1 : create_app (gpointer data)
55 : : {
56 : 1 : const gchar *path = data;
57 : 1 : GError *error = NULL;
58 : 1 : const gchar *contents =
59 : : "[Desktop Entry]\n"
60 : : "Name=Application\n"
61 : : "Version=1.0\n"
62 : : "Type=Application\n"
63 : : "Exec=true\n";
64 : :
65 : 1 : g_file_set_contents (path, contents, -1, &error);
66 : 1 : g_assert_no_error (error);
67 : :
68 : 1 : return G_SOURCE_REMOVE;
69 : : }
70 : :
71 : : static void
72 : 1 : delete_app (gpointer data)
73 : : {
74 : 1 : const gchar *path = data;
75 : :
76 : 1 : g_remove (path);
77 : 1 : }
78 : :
79 : : static void
80 : 2 : changed_cb (GAppInfoMonitor *monitor,
81 : : gpointer user_data)
82 : : {
83 : 2 : gboolean *changed_fired = user_data;
84 : :
85 : 2 : *changed_fired = TRUE;
86 : 2 : g_main_context_wakeup (g_main_context_get_thread_default ());
87 : 2 : }
88 : :
89 : : static gboolean
90 : 0 : timeout_cb (gpointer user_data)
91 : : {
92 : 0 : gboolean *timed_out = user_data;
93 : :
94 : 0 : g_assert (!*timed_out);
95 : 0 : *timed_out = TRUE;
96 : 0 : g_main_context_wakeup (g_main_context_get_thread_default ());
97 : :
98 : 0 : return G_SOURCE_REMOVE;
99 : : }
100 : : #endif /* defined (G_OS_UNIX) && !defined (__APPLE__) */
101 : :
102 : : static void
103 : 1 : test_app_monitor (Fixture *fixture,
104 : : gconstpointer user_data)
105 : : {
106 : : #if defined (G_OS_UNIX) && !defined (__APPLE__)
107 : : gchar *app_path;
108 : : GAppInfoMonitor *monitor;
109 : 1 : GMainContext *context = NULL; /* use the global default main context */
110 : 1 : GSource *timeout_source = NULL;
111 : 1 : GDesktopAppInfo *app = NULL;
112 : 1 : gboolean changed_fired = FALSE;
113 : 1 : gboolean timed_out = FALSE;
114 : :
115 : 1 : app_path = g_build_filename (fixture->applications_dir, "app.desktop", NULL);
116 : :
117 : : /* FIXME: this shouldn't be required */
118 : 1 : g_list_free_full (g_app_info_get_all (), g_object_unref);
119 : :
120 : : /* Create an app monitor and check that its ::changed signal is emitted when
121 : : * a new app is installed. */
122 : 1 : monitor = g_app_info_monitor_get ();
123 : :
124 : 1 : g_signal_connect (monitor, "changed", G_CALLBACK (changed_cb), &changed_fired);
125 : :
126 : 1 : g_idle_add (create_app, app_path);
127 : 1 : timeout_source = g_timeout_source_new_seconds (3);
128 : 1 : g_source_set_callback (timeout_source, timeout_cb, &timed_out, NULL);
129 : 1 : g_source_attach (timeout_source, NULL);
130 : :
131 : 3 : while (!changed_fired && !timed_out)
132 : 2 : g_main_context_iteration (context, TRUE);
133 : :
134 : 1 : g_assert_true (changed_fired);
135 : 1 : changed_fired = FALSE;
136 : :
137 : 1 : g_source_destroy (timeout_source);
138 : 1 : g_clear_pointer (&timeout_source, g_source_unref);
139 : :
140 : : /* Check that the app is now queryable. This has the side-effect of re-arming
141 : : * the #GAppInfoMonitor::changed signal for the next part of the test. */
142 : 1 : app = g_desktop_app_info_new ("app.desktop");
143 : 1 : g_assert_nonnull (app);
144 : 1 : g_clear_object (&app);
145 : :
146 : : /* Now check that ::changed is emitted when an app is uninstalled. */
147 : 1 : timeout_source = g_timeout_source_new_seconds (3);
148 : 1 : g_source_set_callback (timeout_source, timeout_cb, &timed_out, NULL);
149 : 1 : g_source_attach (timeout_source, NULL);
150 : :
151 : 1 : delete_app (app_path);
152 : :
153 : 2 : while (!changed_fired && !timed_out)
154 : 1 : g_main_context_iteration (context, TRUE);
155 : :
156 : 1 : g_assert_true (changed_fired);
157 : :
158 : 1 : g_source_destroy (timeout_source);
159 : 1 : g_clear_pointer (&timeout_source, g_source_unref);
160 : 1 : g_remove (app_path);
161 : :
162 : 1 : g_object_unref (monitor);
163 : :
164 : 1 : g_free (app_path);
165 : : #elif defined (__APPLE__)
166 : : g_test_skip (".desktop monitor on macos");
167 : : #else /* if !(defined (G_OS_UNIX) && !defined (__APPLE__)) */
168 : : g_test_skip (".desktop monitor on win32");
169 : : #endif /* !(defined (G_OS_UNIX) && !defined (__APPLE__)) */
170 : 1 : }
171 : :
172 : : int
173 : 1 : main (int argc, char *argv[])
174 : : {
175 : 1 : g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
176 : :
177 : 1 : g_test_add ("/monitor/app", Fixture, NULL, setup, test_app_monitor, teardown);
178 : :
179 : 1 : return g_test_run ();
180 : : }
|