Bug 621213 – GDBusProxy and well-known names
[platform/upstream/glib.git] / gio / gdbusmethodinvocation.c
1 /* GDBus - GLib D-Bus Library
2  *
3  * Copyright (C) 2008-2010 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: David Zeuthen <davidz@redhat.com>
21  */
22
23 #include "config.h"
24
25 #include <stdlib.h>
26
27 #include "gdbusutils.h"
28 #include "gdbusconnection.h"
29 #include "gdbusmessage.h"
30 #include "gdbusmethodinvocation.h"
31 #include "gdbusintrospection.h"
32 #include "gdbuserror.h"
33 #include "gdbusprivate.h"
34
35 #include "glibintl.h"
36 #include "gioalias.h"
37
38 /**
39  * SECTION:gdbusmethodinvocation
40  * @short_description: Object for handling remote calls
41  * @include: gio/gio.h
42  *
43  * Instances of the #GDBusMethodInvocation class are used when
44  * handling D-Bus method calls. It provides a way to asynchronously
45  * return results and errors.
46  *
47  * The normal way to obtain a #GDBusMethodInvocation object is to receive
48  * it as an argument to the handle_method_call() function in a
49  * #GDBusInterfaceVTable that was passed to g_dbus_connection_register_object().
50  */
51
52 struct _GDBusMethodInvocationPrivate
53 {
54   /* construct-only properties */
55   gchar           *sender;
56   gchar           *object_path;
57   gchar           *interface_name;
58   gchar           *method_name;
59   const GDBusMethodInfo *method_info;
60   GDBusConnection *connection;
61   GDBusMessage    *message;
62   GVariant        *parameters;
63   gpointer         user_data;
64 };
65
66 G_DEFINE_TYPE (GDBusMethodInvocation, g_dbus_method_invocation, G_TYPE_OBJECT);
67
68 static void
69 g_dbus_method_invocation_finalize (GObject *object)
70 {
71   GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (object);
72
73   g_free (invocation->priv->sender);
74   g_free (invocation->priv->object_path);
75   g_free (invocation->priv->interface_name);
76   g_free (invocation->priv->method_name);
77   g_object_unref (invocation->priv->connection);
78   g_object_unref (invocation->priv->message);
79   g_variant_unref (invocation->priv->parameters);
80
81   G_OBJECT_CLASS (g_dbus_method_invocation_parent_class)->finalize (object);
82 }
83
84 static void
85 g_dbus_method_invocation_class_init (GDBusMethodInvocationClass *klass)
86 {
87   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
88
89   gobject_class->finalize = g_dbus_method_invocation_finalize;
90
91   g_type_class_add_private (klass, sizeof (GDBusMethodInvocationPrivate));
92 }
93
94 static void
95 g_dbus_method_invocation_init (GDBusMethodInvocation *invocation)
96 {
97   invocation->priv = G_TYPE_INSTANCE_GET_PRIVATE (invocation,
98                                                   G_TYPE_DBUS_METHOD_INVOCATION,
99                                                   GDBusMethodInvocationPrivate);
100 }
101
102 /**
103  * g_dbus_method_invocation_get_sender:
104  * @invocation: A #GDBusMethodInvocation.
105  *
106  * Gets the bus name that invoked the method.
107  *
108  * Returns: A string. Do not free, it is owned by @invocation.
109  *
110  * Since: 2.26
111  */
112 const gchar *
113 g_dbus_method_invocation_get_sender (GDBusMethodInvocation *invocation)
114 {
115   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
116   return invocation->priv->sender;
117 }
118
119 /**
120  * g_dbus_method_invocation_get_object_path:
121  * @invocation: A #GDBusMethodInvocation.
122  *
123  * Gets the object path the method was invoked on.
124  *
125  * Returns: A string. Do not free, it is owned by @invocation.
126  *
127  * Since: 2.26
128  */
129 const gchar *
130 g_dbus_method_invocation_get_object_path (GDBusMethodInvocation *invocation)
131 {
132   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
133   return invocation->priv->object_path;
134 }
135
136 /**
137  * g_dbus_method_invocation_get_interface_name:
138  * @invocation: A #GDBusMethodInvocation.
139  *
140  * Gets the name of the D-Bus interface the method was invoked on.
141  *
142  * Returns: A string. Do not free, it is owned by @invocation.
143  *
144  * Since: 2.26
145  */
146 const gchar *
147 g_dbus_method_invocation_get_interface_name (GDBusMethodInvocation *invocation)
148 {
149   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
150   return invocation->priv->interface_name;
151 }
152
153 /**
154  * g_dbus_method_invocation_get_method_info:
155  * @invocation: A #GDBusMethodInvocation.
156  *
157  * Gets information about the method call, if any.
158  *
159  * Returns: A #GDBusMethodInfo or %NULL. Do not free, it is owned by @invocation.
160  *
161  * Since: 2.26
162  */
163 const GDBusMethodInfo *
164 g_dbus_method_invocation_get_method_info (GDBusMethodInvocation *invocation)
165 {
166   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
167   return invocation->priv->method_info;
168 }
169
170 /**
171  * g_dbus_method_invocation_get_method_name:
172  * @invocation: A #GDBusMethodInvocation.
173  *
174  * Gets the name of the method that was invoked.
175  *
176  * Returns: A string. Do not free, it is owned by @invocation.
177  *
178  * Since: 2.26
179  */
180 const gchar *
181 g_dbus_method_invocation_get_method_name (GDBusMethodInvocation *invocation)
182 {
183   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
184   return invocation->priv->method_name;
185 }
186
187 /**
188  * g_dbus_method_invocation_get_connection:
189  * @invocation: A #GDBusMethodInvocation.
190  *
191  * Gets the #GDBusConnection the method was invoked on.
192  *
193  * Returns: A #GDBusConnection. Do not free, it is owned by @invocation.
194  *
195  * Since: 2.26
196  */
197 GDBusConnection *
198 g_dbus_method_invocation_get_connection (GDBusMethodInvocation *invocation)
199 {
200   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
201   return invocation->priv->connection;
202 }
203
204 /**
205  * g_dbus_method_invocation_get_message:
206  * @invocation: A #GDBusMethodInvocation.
207  *
208  * Gets the #GDBusMessage for the method invocation. This is useful if
209  * you need to use low-level protocol features, such as UNIX file
210  * descriptor passing, that cannot be properly expressed in the
211  * #GVariant API.
212  *
213  * See <xref linkend="gdbus-server"/> and <xref
214  * linkend="gdbus-unix-fd-client"/> for an example of how to use this
215  * low-level API to send and receive UNIX file descriptors.
216  *
217  * Returns: A #GDBusMessage. Do not free, it is owned by @invocation.
218  *
219  * Since: 2.26
220  */
221 GDBusMessage *
222 g_dbus_method_invocation_get_message (GDBusMethodInvocation *invocation)
223 {
224   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
225   return invocation->priv->message;
226 }
227
228 /**
229  * g_dbus_method_invocation_get_parameters:
230  * @invocation: A #GDBusMethodInvocation.
231  *
232  * Gets the parameters of the method invocation.
233  *
234  * Returns: A #GVariant. Do not free, it is owned by @invocation.
235  *
236  * Since: 2.26
237  */
238 GVariant *
239 g_dbus_method_invocation_get_parameters (GDBusMethodInvocation *invocation)
240 {
241   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
242   return invocation->priv->parameters;
243 }
244
245 /**
246  * g_dbus_method_invocation_get_user_data:
247  * @invocation: A #GDBusMethodInvocation.
248  *
249  * Gets the @user_data #gpointer passed to g_dbus_connection_register_object().
250  *
251  * Returns: A #gpointer.
252  *
253  * Since: 2.26
254  */
255 gpointer
256 g_dbus_method_invocation_get_user_data (GDBusMethodInvocation *invocation)
257 {
258   g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL);
259   return invocation->priv->user_data;
260 }
261
262 /**
263  * g_dbus_method_invocation_new:
264  * @sender: The bus name that invoked the method or %NULL if @connection is not a bus connection.
265  * @object_path: The object path the method was invoked on.
266  * @interface_name: The name of the D-Bus interface the method was invoked on.
267  * @method_name: The name of the method that was invoked.
268  * @method_info: Information about the method call or %NULL.
269  * @connection: The #GDBusConnection the method was invoked on.
270  * @message: The D-Bus message as a #GDBusMessage.
271  * @parameters: The parameters as a #GVariant tuple.
272  * @user_data: The @user_data #gpointer passed to g_dbus_connection_register_object().
273  *
274  * Creates a new #GDBusMethodInvocation object.
275  *
276  * Returns: A #GDBusMethodInvocation. Free with g_object_unref().
277  *
278  * Since: 2.26
279  */
280 GDBusMethodInvocation *
281 g_dbus_method_invocation_new (const gchar           *sender,
282                               const gchar           *object_path,
283                               const gchar           *interface_name,
284                               const gchar           *method_name,
285                               const GDBusMethodInfo *method_info,
286                               GDBusConnection       *connection,
287                               GDBusMessage          *message,
288                               GVariant              *parameters,
289                               gpointer               user_data)
290 {
291   GDBusMethodInvocation *invocation;
292   GDBusMethodInvocationPrivate *priv;
293
294   g_return_val_if_fail (sender == NULL || g_dbus_is_name (sender), NULL);
295   g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
296   g_return_val_if_fail (interface_name == NULL || g_dbus_is_interface_name (interface_name), NULL);
297   g_return_val_if_fail (g_dbus_is_member_name (method_name), NULL);
298   g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
299   g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
300   g_return_val_if_fail (g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE), NULL);
301
302   invocation = G_DBUS_METHOD_INVOCATION (g_object_new (G_TYPE_DBUS_METHOD_INVOCATION, NULL));
303
304   priv = invocation->priv;
305   priv->sender = g_strdup (sender);
306   priv->object_path = g_strdup (object_path);
307   priv->interface_name = g_strdup (interface_name);
308   priv->method_name = g_strdup (method_name);
309   priv->method_info = g_dbus_method_info_ref ((GDBusMethodInfo *)method_info);
310   priv->connection = g_object_ref (connection);
311   priv->message = g_object_ref (message);
312   priv->parameters = g_variant_ref (parameters);
313   priv->user_data = user_data;
314
315   return invocation;
316 }
317
318 /* ---------------------------------------------------------------------------------------------------- */
319
320 /**
321  * g_dbus_method_invocation_return_value:
322  * @invocation: A #GDBusMethodInvocation.
323  * @parameters: A #GVariant tuple with out parameters for the method or %NULL if not passing any parameters.
324  *
325  * Finishes handling a D-Bus method call by returning @parameters.
326  * If the @parameters GVariant is floating, it is consumed.
327  *
328  * It is an error if @parameters is not of the right format.
329  *
330  * This method will free @invocation, you cannot use it afterwards.
331  *
332  * Since: 2.26
333  */
334 void
335 g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation,
336                                        GVariant              *parameters)
337 {
338   GDBusMessage *reply;
339   GError *error;
340
341   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
342   g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));
343
344   if (parameters == NULL)
345     parameters = g_variant_new_tuple (NULL, 0);
346
347   /* if we have introspection data, check that the signature of @parameters is correct */
348   if (invocation->priv->method_info != NULL)
349     {
350       GVariantType *type;
351
352       type = _g_dbus_compute_complete_signature (invocation->priv->method_info->out_args);
353
354       if (!g_variant_is_of_type (parameters, type))
355         {
356           gchar *type_string = g_variant_type_dup_string (type);
357
358           g_warning (_("Type of return value is incorrect, got `%s', expected `%s'"),
359                      g_variant_get_type_string (parameters), type_string);
360           g_variant_type_free (type);
361           g_free (type_string);
362           goto out;
363         }
364       g_variant_type_free (type);
365     }
366
367   reply = g_dbus_message_new_method_reply (invocation->priv->message);
368   g_dbus_message_set_body (reply, parameters);
369   error = NULL;
370   if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, NULL, &error))
371     {
372       g_warning (_("Error sending message: %s"), error->message);
373       g_error_free (error);
374     }
375   g_object_unref (reply);
376
377  out:
378   g_object_unref (invocation);
379 }
380
381 /* ---------------------------------------------------------------------------------------------------- */
382
383 /**
384  * g_dbus_method_invocation_return_error:
385  * @invocation: A #GDBusMethodInvocation.
386  * @domain: A #GQuark for the #GError error domain.
387  * @code: The error code.
388  * @format: printf()-style format.
389  * @...: Parameters for @format.
390  *
391  * Finishes handling a D-Bus method call by returning an error.
392  *
393  * See g_dbus_error_encode_gerror() for details about what error name
394  * will be returned on the wire. In a nutshell, if the given error is
395  * registered using g_dbus_error_register_error() the name given
396  * during registration is used. Otherwise, a name of the form
397  * <literal>org.gtk.GDBus.UnmappedGError.Quark...</literal> is
398  * used. This provides transparent mapping of #GError between
399  * applications using GDBus.
400  *
401  * If you are writing an application intended to be portable,
402  * <emphasis>always</emphasis> register errors with g_dbus_error_register_error()
403  * or use g_dbus_method_invocation_return_dbus_error().
404  *
405  * This method will free @invocation, you cannot use it afterwards.
406  *
407  * Since: 2.26
408  */
409 void
410 g_dbus_method_invocation_return_error (GDBusMethodInvocation *invocation,
411                                        GQuark                 domain,
412                                        gint                   code,
413                                        const gchar           *format,
414                                        ...)
415 {
416   va_list var_args;
417
418   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
419   g_return_if_fail (format != NULL);
420
421   va_start (var_args, format);
422   g_dbus_method_invocation_return_error_valist (invocation,
423                                                 domain,
424                                                 code,
425                                                 format,
426                                                 var_args);
427   va_end (var_args);
428 }
429
430 /**
431  * g_dbus_method_invocation_return_error_valist:
432  * @invocation: A #GDBusMethodInvocation.
433  * @domain: A #GQuark for the #GError error domain.
434  * @code: The error code.
435  * @format: printf()-style format.
436  * @var_args: #va_list of parameters for @format.
437  *
438  * Like g_dbus_method_invocation_return_error() but intended for
439  * language bindings.
440  *
441  * This method will free @invocation, you cannot use it afterwards.
442  *
443  * Since: 2.26
444  */
445 void
446 g_dbus_method_invocation_return_error_valist (GDBusMethodInvocation *invocation,
447                                               GQuark                 domain,
448                                               gint                   code,
449                                               const gchar           *format,
450                                               va_list                var_args)
451 {
452   gchar *literal_message;
453
454   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
455   g_return_if_fail (format != NULL);
456
457   literal_message = g_strdup_vprintf (format, var_args);
458   g_dbus_method_invocation_return_error_literal (invocation,
459                                                  domain,
460                                                  code,
461                                                  literal_message);
462   g_free (literal_message);
463 }
464
465 /**
466  * g_dbus_method_invocation_return_error_literal:
467  * @invocation: A #GDBusMethodInvocation.
468  * @domain: A #GQuark for the #GError error domain.
469  * @code: The error code.
470  * @message: The error message.
471  *
472  * Like g_dbus_method_invocation_return_error() but without printf()-style formatting.
473  *
474  * This method will free @invocation, you cannot use it afterwards.
475  *
476  * Since: 2.26
477  */
478 void
479 g_dbus_method_invocation_return_error_literal (GDBusMethodInvocation *invocation,
480                                                GQuark                 domain,
481                                                gint                   code,
482                                                const gchar           *message)
483 {
484   GError *error;
485
486   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
487   g_return_if_fail (message != NULL);
488
489   error = g_error_new_literal (domain, code, message);
490   g_dbus_method_invocation_return_gerror (invocation, error);
491   g_error_free (error);
492 }
493
494 /**
495  * g_dbus_method_invocation_return_gerror:
496  * @invocation: A #GDBusMethodInvocation.
497  * @error: A #GError.
498  *
499  * Like g_dbus_method_invocation_return_error() but takes a #GError
500  * instead of the error domain, error code and message.
501  *
502  * This method will free @invocation, you cannot use it afterwards.
503  *
504  * Since: 2.26
505  */
506 void
507 g_dbus_method_invocation_return_gerror (GDBusMethodInvocation *invocation,
508                                         const GError          *error)
509 {
510   gchar *dbus_error_name;
511
512   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
513   g_return_if_fail (error != NULL);
514
515   dbus_error_name = g_dbus_error_encode_gerror (error);
516
517   g_dbus_method_invocation_return_dbus_error (invocation,
518                                               dbus_error_name,
519                                               error->message);
520   g_free (dbus_error_name);
521 }
522
523 /**
524  * g_dbus_method_invocation_return_dbus_error:
525  * @invocation: A #GDBusMethodInvocation.
526  * @error_name: A valid D-Bus error name.
527  * @error_message: A valid D-Bus error message.
528  *
529  * Finishes handling a D-Bus method call by returning an error.
530  *
531  * This method will free @invocation, you cannot use it afterwards.
532  *
533  * Since: 2.26
534  */
535 void
536 g_dbus_method_invocation_return_dbus_error (GDBusMethodInvocation *invocation,
537                                             const gchar           *error_name,
538                                             const gchar           *error_message)
539 {
540   GDBusMessage *reply;
541
542   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
543   g_return_if_fail (error_name != NULL && g_dbus_is_name (error_name));
544   g_return_if_fail (error_message != NULL);
545
546   reply = g_dbus_message_new_method_error_literal (invocation->priv->message,
547                                                    error_name,
548                                                    error_message);
549   g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, NULL, NULL);
550   g_object_unref (reply);
551
552   g_object_unref (invocation);
553 }
554
555 #define __G_DBUS_METHOD_INVOCATION_C__
556 #include "gioaliasdef.c"