GDBusConnection: allow async property handling

The existing advice in the documentation to "simply" register the
"org.freedesktop.DBus.Properties" interface if you want to handle
properties asynchronously is pretty unreasonable.  If you want to handle
this interface you have to deal with all properties for all interfaces
on the path, and you have to do all of the checking for yourself.  You
also have to provide your own introspection data.

Introduce a new convention for dealing with properties asynchronously.

If the user provides NULL for their get_property() or set_property()
functions in the vtable and has properties registered then the
properties are sent to the method_call() handler.  We get lucky here
that this function takes an "interface_name" parameter that we can set
to "org.freedesktop.DBus.Properties".

We also do the user the favour of setting the GDBusPropertyInfo on the
GDBusMethodInvocation for their convenience (for much the same reasons
as they might want the already-available GDBusMethodInfo).

Add a testcase as well as a bunch of documentation about this new
feature.

https://bugzilla.gnome.org/show_bug.cgi?id=698375
This commit is contained in:
Ryan Lortie
2013-04-17 09:30:15 -04:00
parent c691f7b6ca
commit f754c4e85b
4 changed files with 268 additions and 15 deletions

View File

@@ -340,9 +340,38 @@ typedef gboolean (*GDBusInterfaceSetPropertyFunc) (GDBusConnection *conne
* Virtual table for handling properties and method calls for a D-Bus
* interface.
*
* If you want to handle getting/setting D-Bus properties asynchronously, simply
* register an object with the <literal>org.freedesktop.DBus.Properties</literal>
* D-Bus interface using g_dbus_connection_register_object().
* Since 2.38, if you want to handle getting/setting D-Bus properties
* asynchronously, give %NULL as your get_property() or set_property()
* function. The D-Bus call will be directed to your @method_call
* function, with the provided @interface_name set to
* <literal>"org.freedesktop.DBus.Properties"</literal>.
*
* The usual checks on the validity of the calls is performed. For
* <literal>'Get'</literal> calls, an error is automatically returned if
* the property does not exist or the permissions do not allow access.
* The same checks are performed for <literal>'Set'</literal> calls, and
* the provided value is also checked for being the correct type.
*
* For both <literal>'Get'</literal> and <literal>'Set'</literal> calls,
* the #GDBusMethodInvocation passed to the method_call handler can be
* queried with g_dbus_method_invocation_get_property_info() to get a
* pointer to the #GDBusPropertyInfo of the property.
*
* If you have readable properties specified in your interface info, you
* must ensure that you either provide a non-%NULL @get_property()
* function or provide implementations of both the
* <literal>'Get'</literal> and <literal>'GetAll'</literal> methods on
* the <literal>'org.freedesktop.DBus.Properties'</literal> interface in
* your @method_call function. Note that the required return type of
* the <literal>'Get'</literal> call is <literal>(v)</literal>, not the
* type of the property. <literal>'GetAll'</literal> expects a return
* value of type <literal>a{sv}<literal>.
*
* If you have writable properties specified in your interface info, you
* must ensure that you either provide a non-%NULL @set_property()
* function or provide an implementation of the <literal>'Set'</literal>
* call. If implementing the call, you must return the value of type
* %G_VARIANT_TYPE_UNIT.
*
* Since: 2.26
*/