404652e3d1bb1f826156d9f447cbbef5c55aa9e6
[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  *
327  * It is an error if @parameters is not of the right format.
328  *
329  * This method will free @invocation, you cannot use it afterwards.
330  *
331  * Since: 2.26
332  */
333 void
334 g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation,
335                                        GVariant              *parameters)
336 {
337   GDBusMessage *reply;
338   GError *error;
339
340   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
341   g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE));
342
343   if (parameters != NULL)
344     g_variant_ref_sink (parameters);
345
346   /* if we have introspection data, check that the signature of @parameters is correct */
347   if (invocation->priv->method_info != NULL)
348     {
349       gchar *signature;
350       const gchar *type_string;
351
352       type_string = "()";
353       if (parameters != NULL)
354         type_string = g_variant_get_type_string (parameters);
355       signature = _g_dbus_compute_complete_signature (invocation->priv->method_info->out_args, TRUE);
356
357       if (g_strcmp0 (type_string, signature) != 0)
358         {
359           g_warning (_("Type of return value is incorrect, got `%s', expected  `%s'"),
360                      type_string,
361                      signature);
362           g_free (signature);
363           goto out;
364         }
365       g_free (signature);
366     }
367
368   reply = g_dbus_message_new_method_reply (invocation->priv->message);
369   g_dbus_message_set_body (reply, parameters);
370   error = NULL;
371   if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, NULL, &error))
372     {
373       g_warning (_("Error sending message: %s"), error->message);
374       g_error_free (error);
375     }
376   g_object_unref (reply);
377
378  out:
379   g_object_unref (invocation);
380   if (parameters != NULL)
381     g_variant_unref (parameters);
382 }
383
384 /* ---------------------------------------------------------------------------------------------------- */
385
386 /**
387  * g_dbus_method_invocation_return_error:
388  * @invocation: A #GDBusMethodInvocation.
389  * @domain: A #GQuark for the #GError error domain.
390  * @code: The error code.
391  * @format: printf()-style format.
392  * @...: Parameters for @format.
393  *
394  * Finishes handling a D-Bus method call by returning an error.
395  *
396  * See g_dbus_error_encode_gerror() for details about what error name
397  * will be returned on the wire. In a nutshell, if the given error is
398  * registered using g_dbus_error_register_error() the name given
399  * during registration is used. Otherwise, a name of the form
400  * <literal>org.gtk.GDBus.UnmappedGError.Quark...</literal> is
401  * used. This provides transparent mapping of #GError between
402  * applications using GDBus.
403  *
404  * If you are writing an application intended to be portable,
405  * <emphasis>always</emphasis> register errors with g_dbus_error_register_error()
406  * or use g_dbus_method_invocation_return_dbus_error().
407  *
408  * This method will free @invocation, you cannot use it afterwards.
409  *
410  * Since: 2.26
411  */
412 void
413 g_dbus_method_invocation_return_error (GDBusMethodInvocation *invocation,
414                                        GQuark                 domain,
415                                        gint                   code,
416                                        const gchar           *format,
417                                        ...)
418 {
419   va_list var_args;
420
421   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
422   g_return_if_fail (format != NULL);
423
424   va_start (var_args, format);
425   g_dbus_method_invocation_return_error_valist (invocation,
426                                                 domain,
427                                                 code,
428                                                 format,
429                                                 var_args);
430   va_end (var_args);
431 }
432
433 /**
434  * g_dbus_method_invocation_return_error_valist:
435  * @invocation: A #GDBusMethodInvocation.
436  * @domain: A #GQuark for the #GError error domain.
437  * @code: The error code.
438  * @format: printf()-style format.
439  * @var_args: #va_list of parameters for @format.
440  *
441  * Like g_dbus_method_invocation_return_error() but intended for
442  * language bindings.
443  *
444  * This method will free @invocation, you cannot use it afterwards.
445  *
446  * Since: 2.26
447  */
448 void
449 g_dbus_method_invocation_return_error_valist (GDBusMethodInvocation *invocation,
450                                               GQuark                 domain,
451                                               gint                   code,
452                                               const gchar           *format,
453                                               va_list                var_args)
454 {
455   gchar *literal_message;
456
457   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
458   g_return_if_fail (format != NULL);
459
460   literal_message = g_strdup_vprintf (format, var_args);
461   g_dbus_method_invocation_return_error_literal (invocation,
462                                                  domain,
463                                                  code,
464                                                  literal_message);
465   g_free (literal_message);
466 }
467
468 /**
469  * g_dbus_method_invocation_return_error_literal:
470  * @invocation: A #GDBusMethodInvocation.
471  * @domain: A #GQuark for the #GError error domain.
472  * @code: The error code.
473  * @message: The error message.
474  *
475  * Like g_dbus_method_invocation_return_error() but without printf()-style formatting.
476  *
477  * This method will free @invocation, you cannot use it afterwards.
478  *
479  * Since: 2.26
480  */
481 void
482 g_dbus_method_invocation_return_error_literal (GDBusMethodInvocation *invocation,
483                                                GQuark                 domain,
484                                                gint                   code,
485                                                const gchar           *message)
486 {
487   GError *error;
488
489   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
490   g_return_if_fail (message != NULL);
491
492   error = g_error_new_literal (domain, code, message);
493   g_dbus_method_invocation_return_gerror (invocation, error);
494   g_error_free (error);
495 }
496
497 /**
498  * g_dbus_method_invocation_return_gerror:
499  * @invocation: A #GDBusMethodInvocation.
500  * @error: A #GError.
501  *
502  * Like g_dbus_method_invocation_return_error() but takes a #GError
503  * instead of the error domain, error code and message.
504  *
505  * This method will free @invocation, you cannot use it afterwards.
506  *
507  * Since: 2.26
508  */
509 void
510 g_dbus_method_invocation_return_gerror (GDBusMethodInvocation *invocation,
511                                         const GError          *error)
512 {
513   gchar *dbus_error_name;
514
515   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
516   g_return_if_fail (error != NULL);
517
518   dbus_error_name = g_dbus_error_encode_gerror (error);
519
520   g_dbus_method_invocation_return_dbus_error (invocation,
521                                               dbus_error_name,
522                                               error->message);
523   g_free (dbus_error_name);
524 }
525
526 /**
527  * g_dbus_method_invocation_return_dbus_error:
528  * @invocation: A #GDBusMethodInvocation.
529  * @error_name: A valid D-Bus error name.
530  * @error_message: A valid D-Bus error message.
531  *
532  * Finishes handling a D-Bus method call by returning an error.
533  *
534  * This method will free @invocation, you cannot use it afterwards.
535  *
536  * Since: 2.26
537  */
538 void
539 g_dbus_method_invocation_return_dbus_error (GDBusMethodInvocation *invocation,
540                                             const gchar           *error_name,
541                                             const gchar           *error_message)
542 {
543   GDBusMessage *reply;
544
545   g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
546   g_return_if_fail (error_name != NULL && g_dbus_is_name (error_name));
547   g_return_if_fail (error_message != NULL);
548
549   reply = g_dbus_message_new_method_error_literal (invocation->priv->message,
550                                                    error_name,
551                                                    error_message);
552   g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, NULL, NULL);
553   g_object_unref (reply);
554
555   g_object_unref (invocation);
556 }
557
558 #define __G_DBUS_METHOD_INVOCATION_C__
559 #include "gioaliasdef.c"