Add a testcase for DBusActivatable=true
[platform/upstream/glib.git] / gio / tests / dbus-appinfo.c
1 /*
2  * Copyright © 2013 Canonical Limited
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published
6  * by the Free Software Foundation; either version 2 of the licence or (at
7  * your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General
15  * Public License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * Authors: Ryan Lortie <desrt@desrt.ca>
20  */
21
22 #include <gio/gio.h>
23 #include <gio/gdesktopappinfo.h>
24
25 #include "gdbus-sessionbus.h"
26
27 static GDesktopAppInfo *appinfo;
28 static int current_state;
29 static gboolean saw_startup_id;
30 static gboolean requested_startup_id;
31
32
33 static GType test_app_launch_context_get_type (void);
34 typedef GAppLaunchContext TestAppLaunchContext;
35 typedef GAppLaunchContextClass TestAppLaunchContextClass;
36 G_DEFINE_TYPE (TestAppLaunchContext, test_app_launch_context, G_TYPE_APP_LAUNCH_CONTEXT)
37
38 static gchar *
39 test_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
40                                                GAppInfo          *info,
41                                                GList             *uris)
42 {
43   requested_startup_id = TRUE;
44   return g_strdup ("expected startup id");
45 }
46
47 static void
48 test_app_launch_context_init (TestAppLaunchContext *ctx)
49 {
50 }
51
52 static void
53 test_app_launch_context_class_init (GAppLaunchContextClass *class)
54 {
55   class->get_startup_notify_id = test_app_launch_context_get_startup_notify_id;
56 }
57
58 static GType test_application_get_type (void);
59 typedef GApplication TestApplication;
60 typedef GApplicationClass TestApplicationClass;
61 G_DEFINE_TYPE (TestApplication, test_application, G_TYPE_APPLICATION)
62
63 static void
64 saw_action (const gchar *action)
65 {
66   /* This is the main driver of the test.  It's a bit of a state
67    * machine.
68    *
69    * Each time some event arrives on the app, it calls here to report
70    * which event it was.  The initial activation of the app is what
71    * starts everything in motion (starting from state 0).  At each
72    * state, we assert that we receive the expected event, send the next
73    * event, then update the current_state variable so we do the correct
74    * thing next time.
75    */
76
77   switch (current_state)
78     {
79       case 0: g_assert_cmpstr (action, ==, "activate");
80
81       /* Let's try another activation... */
82       g_app_info_launch (G_APP_INFO (appinfo), NULL, NULL, NULL);
83       current_state = 1; return; case 1: g_assert_cmpstr (action, ==, "activate");
84
85
86       /* Now let's try opening some files... */
87       {
88         GList *files;
89
90         files = g_list_prepend (NULL, g_file_new_for_uri ("file:///a/b"));
91         files = g_list_append (files, g_file_new_for_uri ("file:///c/d"));
92         g_app_info_launch (G_APP_INFO (appinfo), files, NULL, NULL);
93         g_list_free_full (files, g_object_unref);
94       }
95       current_state = 2; return; case 2: g_assert_cmpstr (action, ==, "open");
96
97       /* Now action activations... */
98       g_desktop_app_info_launch_action (appinfo, "frob", NULL);
99       current_state = 3; return; case 3: g_assert_cmpstr (action, ==, "frob");
100
101       g_desktop_app_info_launch_action (appinfo, "tweak", NULL);
102       current_state = 4; return; case 4: g_assert_cmpstr (action, ==, "tweak");
103
104       g_desktop_app_info_launch_action (appinfo, "twiddle", NULL);
105       current_state = 5; return; case 5: g_assert_cmpstr (action, ==, "twiddle");
106
107       /* Now launch the app with startup notification */
108       {
109         GAppLaunchContext *ctx;
110
111         g_assert (saw_startup_id == FALSE);
112         ctx = g_object_new (test_app_launch_context_get_type (), NULL);
113         g_app_info_launch (G_APP_INFO (appinfo), NULL, ctx, NULL);
114         g_assert (requested_startup_id);
115         requested_startup_id = FALSE;
116         g_object_unref (ctx);
117       }
118       current_state = 6; return; case 6: g_assert_cmpstr (action, ==, "activate"); g_assert (saw_startup_id);
119       saw_startup_id = FALSE;
120
121       /* Now do the same for an action */
122       {
123         GAppLaunchContext *ctx;
124
125         g_assert (saw_startup_id == FALSE);
126         ctx = g_object_new (test_app_launch_context_get_type (), NULL);
127         g_desktop_app_info_launch_action (appinfo, "frob", ctx);
128         g_assert (requested_startup_id);
129         requested_startup_id = FALSE;
130         g_object_unref (ctx);
131       }
132       current_state = 7; return; case 7: g_assert_cmpstr (action, ==, "frob"); g_assert (saw_startup_id);
133       saw_startup_id = FALSE;
134
135       /* Now quit... */
136       g_desktop_app_info_launch_action (appinfo, "quit", NULL);
137       current_state = 8; return; case 8: g_assert_not_reached ();
138     }
139 }
140
141 static void
142 test_application_frob (GSimpleAction *action,
143                        GVariant      *parameter,
144                        gpointer       user_data)
145 {
146   g_assert (parameter == NULL);
147   saw_action ("frob");
148 }
149
150 static void
151 test_application_tweak (GSimpleAction *action,
152                         GVariant      *parameter,
153                         gpointer       user_data)
154 {
155   g_assert (parameter == NULL);
156   saw_action ("tweak");
157 }
158
159 static void
160 test_application_twiddle (GSimpleAction *action,
161                           GVariant      *parameter,
162                           gpointer       user_data)
163 {
164   g_assert (parameter == NULL);
165   saw_action ("twiddle");
166 }
167
168 static void
169 test_application_quit (GSimpleAction *action,
170                        GVariant      *parameter,
171                        gpointer       user_data)
172 {
173   GApplication *application = user_data;
174
175   g_application_quit (application);
176 }
177
178 static const GActionEntry app_actions[] = {
179   { "frob",         test_application_frob              },
180   { "tweak",        test_application_tweak             },
181   { "twiddle",      test_application_twiddle           },
182   { "quit",         test_application_quit              }
183 };
184
185 static void
186 test_application_activate (GApplication *application)
187 {
188   /* Unbalanced, but that's OK because we will quit() */
189   g_application_hold (application);
190
191   saw_action ("activate");
192 }
193
194 static void
195 test_application_open (GApplication  *application,
196                        GFile        **files,
197                        gint           n_files,
198                        const gchar   *hint)
199 {
200   GFile *f;
201
202   g_assert_cmpstr (hint, ==, "");
203
204   g_assert_cmpint (n_files, ==, 2);
205   f = g_file_new_for_uri ("file:///a/b");
206   g_assert (g_file_equal (files[0], f));
207   g_object_unref (f);
208   f = g_file_new_for_uri ("file:///c/d");
209   g_assert (g_file_equal (files[1], f));
210   g_object_unref (f);
211
212   saw_action ("open");
213 }
214
215 static void
216 test_application_startup (GApplication *application)
217 {
218   G_APPLICATION_CLASS (test_application_parent_class)
219     ->startup (application);
220
221   g_action_map_add_action_entries (G_ACTION_MAP (application), app_actions, G_N_ELEMENTS (app_actions), application);
222 }
223
224 static void
225 test_application_before_emit (GApplication *application,
226                               GVariant     *platform_data)
227 {
228   const gchar *startup_id;
229
230   g_assert (!saw_startup_id);
231
232   if (!g_variant_lookup (platform_data, "desktop-startup-id", "&s", &startup_id))
233     return;
234
235   g_assert_cmpstr (startup_id, ==, "expected startup id");
236   saw_startup_id = TRUE;
237 }
238
239 static void
240 test_application_init (TestApplication *app)
241 {
242 }
243
244 static void
245 test_application_class_init (GApplicationClass *class)
246 {
247   class->before_emit = test_application_before_emit;
248   class->startup = test_application_startup;
249   class->activate = test_application_activate;
250   class->open = test_application_open;
251 }
252
253 static void
254 test_dbus_appinfo (void)
255 {
256   const gchar *argv[] = { "myapp", NULL };
257   TestApplication *app;
258   int status;
259
260   appinfo = g_desktop_app_info_new_from_filename (g_test_build_filename (G_TEST_DIST,
261                                                                          "org.gtk.test.dbusappinfo.desktop",
262                                                                          NULL));
263   g_assert (appinfo != NULL);
264
265   app = g_object_new (test_application_get_type (),
266                       "application-id", "org.gtk.test.dbusappinfo",
267                       "flags", G_APPLICATION_HANDLES_OPEN,
268                       NULL);
269   status = g_application_run (app, 1, (gchar **) argv);
270
271   g_assert_cmpint (status, ==, 0);
272   g_assert_cmpint (current_state, ==, 8);
273
274   g_object_unref (appinfo);
275   g_object_unref (app);
276 }
277
278 int
279 main (int argc, char **argv)
280 {
281   g_test_init (&argc, &argv, NULL);
282
283   session_bus_up ();
284
285   g_test_add_func ("/appinfo/dbusappinfo", test_dbus_appinfo);
286
287   session_bus_down ();
288
289   return g_test_run ();
290 }