dbus-marshal-validate: Check brackets in signature nest correctly
[platform/upstream/dbus.git] / doc / dbus-api-design.duck
1 = D-Bus API Design Guidelines
2 @link[guide >index]
3 @credit[type="author copyright"]
4   @name Philip Withnall
5   @email philip.withnall@collabora.co.uk
6   @years 2015
7 @desc Guidelines for writing high quality D-Bus APIs
8 @revision[date=2015-02-05 status=draft]
9
10 [synopsis]
11   [title]
12   Summary
13
14   The most common use for D-Bus is in implementing a service which will be
15   consumed by multiple client programs, and hence all interfaces exported on the
16   bus form a public API. Designing a D-Bus API is like designing any other API:
17   there is a lot of flexibility, but there are design patterns to follow and
18   anti-patterns to avoid.
19
20   This guide aims to explain the best practices for writing D-Bus APIs. These
21   have been refined over several years of use of D-Bus in many projects.
22   Pointers will be given for implementing APIs using common D-Bus
23   libraries like
24   $link[>>https://developer.gnome.org/gio/stable/gdbus-convenience.html](GDBus),
25   but detailed implementation instructions are left to the libraries’
26   documentation. Note that you should $em(not) use dbus-glib to implement D-Bus
27   services as it is deprecated and unmaintained. Most services should also avoid
28   libdbus (dbus-1), which is a low-level library and is awkward to use
29   correctly: it is designed to be used via a language binding such as
30   $link[>>http://qt-project.org/doc/qt-4.8/qtdbus.html](QtDBus).
31
32   For documentation on D-Bus itself, see the
33   $link[>>http://dbus.freedesktop.org/doc/dbus-specification.html](D-Bus
34   specification).
35
36 [links section]
37
38 == APIs
39    [id="apis"]
40
41 A D-Bus API is a specification of one or more interfaces, which will be
42 implemented by objects exposed by a service on the bus. Typically an API is
43 designed as a set of $link[>#interface-files](interface files), and the
44 implementation of the service follows those files. Some projects, however,
45 choose to define the API in the code for the service, and to export XML
46 interface files from the running service
47 $link[>>http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-introspectable](using
48 D-Bus introspection). Both are valid approaches.
49
50 For simplicity, this document uses the XML descriptions of D-Bus interfaces as
51 the canonical representation.
52
53 == Interface files
54    [id="interface-files"]
55
56 A D-Bus interface file is an XML file which describes one or more D-Bus
57 interfaces, and is the best way of describing a D-Bus API in a machine
58 readable way. The format is described in the
59 $link[>>http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format](D-Bus
60 specification), and is supported by tools such as $cmd(gdbus-codegen).
61
62 Interface files for public API should be installed to
63 $code($var($$(datadir))/dbus-1/interfaces) so that other services can load
64 them. Private APIs should not be installed. There should be one file installed
65 per D-Bus interface, named after the interface, containing a single top-level
66 $code(<node>) element with a single $code(<interface>) beneath it. For example,
67 interface $code(com.example.MyService1.Manager) would be described by file
68 $file($var($$(datadir))/dbus-1/interfaces/com.example.MyService1.Manager.xml):
69
70 [listing]
71   [title]
72     Example D-Bus Interface XML
73   [desc]
74     A brief example interface XML document.
75   [code mime="application/xml"]
76     <!DOCTYPE node PUBLIC
77         "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
78         "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" >
79     <node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
80       <interface name="com.example.MyService1.InterestingInterface">
81         <method name="AddContact">
82           <arg name="name" direction="in" type="s">
83             <doc:doc><doc:summary>Name of new contact</doc:summary></doc:doc>
84           </arg>
85           <arg name="email" direction="in" type="s">
86             <doc:doc><doc:summary>E-mail address of new contact</doc:summary></doc:doc>
87           </arg>
88           <arg name="id" direction="out" type="u">
89             <doc:doc><doc:summary>ID of newly added contact</doc:summary></doc:doc>
90           </arg>
91           <doc:doc>
92             <doc:description>
93               <doc:para>
94                 Adds a new contact to the address book with their name and
95                 e-mail address.
96               </doc:para>
97             </doc:description>
98           </doc:doc>
99         </method>
100       </interface>
101     </node>
102
103 If an interface defined by service A needs to be used by client B, client B
104 should declare a build time dependency on service A, and use the installed copy
105 of the interface file for any code generation it has to do. It should $em(not)
106 have a local copy of the interface, as that could then go out of sync with the
107 canonical copy in service A’s git repository.
108
109 == API versioning
110    [id="api-versioning"]
111
112 $link[>>http://ometer.com/parallel.html](Just like C APIs), D-Bus interfaces
113 should be designed to be usable in parallel with API-incompatible versions. This
114 is achieved by including a version number in each interface name, service name
115 and object path which is incremented on every backwards-incompatible change.
116
117 Version numbers should be included in all APIs from the first release, as that
118 means moving to a new version is as simple as incrementing the number, rather
119 than inserting a number everywhere, which takes more effort.
120
121 New API can be added to a D-Bus interface without incrementing the version
122 number, as such additions are still backwards-compatible. However, clients
123 should gracefully handle the $code(org.freedesktop.DBus.Error.UnknownMethod)
124 error reply from all D-Bus method calls if they want to run against older
125 versions of the service which don’t implement new methods. (This also prevents
126 use of generated bindings; any method which a client wants to gracefully fall
127 back from should be called using a generic D-Bus method invocation rather than
128 a specific generated binding.)
129
130 When API is broken, changed or removed, the service’s version number must be
131 bumped; for example, from $code(com.example.MyService1)
132 to $code(com.example.MyService2). If backwards compatibility is maintained in
133 the service by implementing both the old and new interfaces, the service can
134 own $em(both) well-known names and clients can use whichever they support.
135
136 As discussed in $link[>#annotations], new or deprecated APIs should be marked in
137 the interface XML using annotations.
138
139 Note, however, that supporting multiple interface versions simultaneously
140 requires that $em(object paths) are versioned as well, so objects $em(must not)
141 be put on the bus at the root path (‘/’). This is for technical reasons: signals
142 sent from a D-Bus service have the originating service name overwritten by its
143 unique name (e.g. $code(com.example.MyService2) is overwritten by $code(:1:15)).
144 If object paths are shared between objects implementing two versions of the
145 service’s interface, client programs cannot tell which object a signal has come
146 from. The solution is to include the version number in all object paths, for
147 example $code(/com/example/MyService1/Manager) instead of $code(/) or
148 $code(/com/example/MyService/Manager).
149
150 In summary, version numbers should be included in all service names, interface
151 names and object paths:
152 [list]
153 * $code(com.example.MyService1)
154 * $code(com.example.MyService1.InterestingInterface)
155 * $code(com.example.MyService1.OtherInterface)
156 * $code(/com/example/MyService1/Manager)
157 * $code(/com/example/MyService1/OtherObject)
158
159 == API design
160    [id="api-design"]
161
162 D-Bus API design is broadly the same as C API design, but there are a few
163 additional points to bear in mind which arise both from D-Bus’ features
164 (explicit errors, signals and properties), and from its implementation as an IPC
165 system.
166
167 D-Bus method calls are much more expensive than C function calls, typically
168 taking on the order of milliseconds to complete a round trip. Therefore, the
169 design should minimize the number of method calls needed to perform an
170 operation.
171
172 The type system is very expressive, especially compared to C’s, and APIs should
173 take full advantage of it.
174
175 Similarly, its support for signals and properties differentiates it from normal
176 C APIs, and well written D-Bus APIs make full use of these features where
177 appropriate. They can be coupled with standard interfaces defined in the D-Bus
178 specification to allow for consistent access to properties and objects in a
179 hierarchy.
180
181 === Minimizing Round Trips
182     [id="round-trips"]
183
184 Each D-Bus method call is a round trip from a client program to a service and
185 back again, which is expensive — taking on the order of a millisecond. One of
186 the top priorities in D-Bus API design is to minimize the number of round trips
187 needed by clients. This can be achieved by a combination of providing specific
188 convenience APIs and designing APIs which operate on large data sets in a single
189 call, rather than requiring as many calls as elements in the data set.
190
191 Consider an address book API, $code(com.example.MyService1.AddressBook). It
192 might have an $code(AddContact(ss) → (u)) method to add a contact (taking name
193 and e-mail address parameters and returning a unique contact ID), and a
194 $code(RemoveContact(u)) method to remove one by ID. In the normal case of
195 operating on single contacts in the address book, these calls are optimal.
196 However, if the user wants to import a list of contacts, or delete multiple
197 contacts simultaneously, one call has to be made per contact — this could take
198 a long time for large contact lists.
199
200 Instead of the $code(AddContact) and $code(RemoveContact) methods, the interface
201 could have an $code(UpdateContacts(a(ss)au) → (au)) method, which takes an array
202 of structs containing the new contacts’ details, and an array of IDs of the
203 contacts to delete, and returns an array of IDs for the new contacts. This
204 reduces the number of round trips needed to one.
205
206 Adding convenience APIs to replace a series of common method calls with a single
207 method call specifically for that task is best done after the API has been
208 profiled and bottlenecks identified, otherwise it could lead to premature
209 optimization. One area where convenience methods can typically be added
210 is during initialization of a client, where multiple method calls are needed to
211 establish its state with the service.
212
213 === Taking Advantage of the Type System
214     [id="type-system"]
215
216 D-Bus’ type system is similar to Python’s, but with a terser syntax which may be
217 unfamiliar to C developers. The key to using the type system effectively is
218 to expose as much structure in types as possible. In particular, sending
219 structured strings over D-Bus should be avoided, as they need to be built and
220 parsed; both are complex operations which are prone to bugs.
221
222 For APIs being used in constrained situations, enumerated values should be
223 transmitted as unsigned integers. For APIs which need to be extended by third
224 parties or which are used in more loosely coupled systems, enumerated values
225 should be strings in some defined format.
226
227 Transmitting values as integers means string parsing and matching can be
228 avoided, the messages are more compact, and typos can be more easily avoided by
229 developers (if, for example, C enums are used in the implementation).
230
231 Transmitting values as strings means additional values can be defined by third
232 parties without fear of conflicting over integer values; for instance by using
233 the same reverse-domain-name namespacing as D-Bus interfaces.
234
235 In both cases, the interface documentation should describe the meaning of each
236 value. It should state whether the type can be extended in future and, if so,
237 how the service and client should handle unrecognized values — typically by
238 considering them equal to an ‘unknown’ or ‘failure’ value. Conventionally, zero
239 is used as the ‘unknown’ value.
240
241 [example]
242   For example, instead of:
243   [code style="invalid" mime="application/xml"]
244     <!--
245         Status:
246
247         Status of the object.
248         Valid statuses: ‘unknown’, ‘ready’, ‘complete’.
249     -->
250     <property name="Status" type="s" access="read" />
251
252   Use:
253   [code style="valid" mime="application/xml"]
254     <!--
255         Status:
256
257         Status of the object.
258         Valid statuses: 0 = Unknown, 1 = Ready, 2 = Complete.
259         Unrecognized statuses should be considered equal to Unknown.
260     -->
261     <property name="Status" type="u" access="read" />
262
263 Similarly, enumerated values should be used instead of booleans, as they allow
264 extra values to be added in future, and there is no ambiguity about the sense of
265 the boolean value.
266
267 [example]
268   For example, instead of:
269   [code style="invalid" mime="application/xml"]
270     <!--
271        MoveAddressBook:
272        @direction: %TRUE to move it up in the list, %FALSE to move it down
273
274        Move this address book up or down in the user’s list of address books.
275        Higher address books have their contacts displayed first in search
276        results.
277     -->
278     <method name="MoveAddressBook">
279       <arg name="direction" type="b" direction="in" />
280     </method>
281
282   Be more explicit than a boolean:
283   [code style="valid" mime="application/xml"]
284     <!--
285        MoveAddressBook:
286        @direction: 0 = Move it up in the list, 1 = Move it down
287
288        Move this address book up or down in the user’s list of address books.
289        Higher address books have their contacts displayed first in search
290        results.
291
292        Unrecognized enum values for @direction will result in the address book
293        not moving.
294     -->
295     <method name="MoveAddressBook">
296       <arg name="direction" type="u" direction="in" />
297     </method>
298
299 Enumerated values should also be used instead of $em(human readable) strings,
300 which should not be sent over the bus if possible. The service and client could
301 be running in different locales, and hence interpret any human readable strings
302 differently, or present them to the user in the wrong language. Transmit an
303 enumerated value and convert it to a human readable string in the client.
304
305 In situations where a service has received a human readable string from
306 somewhere else, it should pass it on unmodified to the client, ideally with its
307 locale alongside. Passing human readable information to a client is better than
308 passing nothing.
309
310 [example]
311   For example, instead of:
312   [code style="invalid" mime="application/xml"]
313     <!--
314        ProgressNotification:
315        @progress_message: Human readable progress message string.
316
317        Emitted whenever significant progress is made with some example
318        operation. The @progress_message can be displayed in a UI dialogue to
319        please the user.
320     -->
321     <signal name="ProgressNotification">
322       <arg name="progress_message" type="s" />
323     </method>
324
325   The progress should be reported as an enumerated value:
326   [code style="valid" mime="application/xml"]
327     <!--
328        ProgressNotification:
329        @progress_state: 0 = Preparing, 1 = In progress, 2 = Finished
330
331        Emitted whenever significant progress is made with some example
332        operation. The @progress_state is typically converted to a human readable
333        string and presented to the user. Unrecognized @progress_state values
334        should be treated as state 1, in progress.
335     -->
336     <signal name="ProgressNotification">
337       <arg name="progress_state" type="u" />
338     </method>
339
340 D-Bus has none of the problems of signed versus unsigned integers which C has
341 (specifically, it does not do implicit sign conversion), so integer types should
342 always be chosen to be an appropriate size and signedness for the data they
343 could possibly contain. Typically, unsigned values are more frequently needed
344 than signed values.
345
346 Structures can be used almost anywhere in a D-Bus type, and arrays of structures
347 are particularly useful. Structures should be used wherever data fields are
348 related. Note, however, that structures are not extensible in future, so always
349 consider $link[>#extensibility].
350
351 [example]
352   For example, instead of several identically-indexed arrays containing
353   different properties of the same set of items:
354   [code style="invalid" mime="application/xml"]
355     <!--
356        AddContacts:
357        @names: Array of contact names to add.
358        @emails: Corresponding array of contact e-mail addresses.
359        @ids: Returned array of the IDs of the new contacts. This will be the
360          same length as @names.
361
362        Add zero or more contacts to the address book, using their names and
363        e-mail addresses. @names and @emails must be the same length.
364     -->
365     <method name="AddContacts">
366       <arg name="names" type="as" direction="in" />
367       <arg name="emails" type="as" direction="in" />
368       <arg name="ids" type="au" direction="out" />
369     </method>
370
371   The arrays can be combined into a single array of structures:
372   [code style="invalid" mime="application/xml"]
373     <!--
374        AddContacts:
375        @details: Array of (contact name, contact e-mail address) to add.
376        @ids: Returned array of the IDs of the new contacts. This will be the
377          same length as @details.
378
379        Add zero or more contacts to the address book, using their names and
380        e-mail addresses.
381     -->
382     <method name="AddContacts">
383       <arg name="details" type="a(ss)" direction="in" />
384       <arg name="ids" type="au" direction="out" />
385     </method>
386
387 Note that D-Bus arrays are automatically transmitted with their length, so there
388 is no need to null-terminate them or encode their length separately.
389
390 [comment]
391   FIXME: Mention maybe types and the extended kdbus/GVariant type system once
392   that’s stable and round-trip-ability is no longer a concern.
393
394 === Extensibility
395     [id="extensibility"]
396
397 Some D-Bus APIs have very well-defined use cases, and will never need extension.
398 Others are used in more loosely coupled systems which may change over time, and
399 hence should be designed to be extensible from the beginning without the need
400 to break API in future. This is a trade off between having a more complex API,
401 and being able to easily extend it in future.
402
403 The key tool for extensibility in D-Bus is $code(a{sv}), the dictionary mapping
404 strings to variants. If well-defined namespaced strings are used as the
405 dictionary keys, arbitrary D-Bus peers can add whatever information they need
406 into the dictionary. Any other peer which understands it can query and retrieve
407 the information; other peers will ignore it.
408
409 The canonical example of an extensible API using $code(a{sv}) is
410 $link[>>http://telepathy.freedesktop.org/spec/](Telepathy). It uses $code(a{sv})
411 values as the final element in structures to allow them to be extended in
412 future.
413
414 A secondary tool is the use of flag fields in method calls. The set of accepted
415 flags is entirely under the control of the interface designer and, as with
416 enumerated types, can be extended in future without breaking API. Adding more
417 flags allows the functionality of the method call to be tweaked.
418
419 === Using Signals, Properties and Errors
420     [id="using-the-features"]
421
422 D-Bus method calls are explicitly asynchronous due to the latency inherent in
423 IPC. This means that peers should not block on receiving a reply from a method
424 call; they should schedule other work (in a main loop) and handle the reply when
425 it is received. Even though method replies may take a while, the caller is
426 $em(guaranteed) to receive exactly one reply eventually. This reply could be the
427 return value from the method, an error from the method, or an error from the
428 D-Bus daemon indicating the service failed in some way (e.g. due to crashing).
429
430 Because of this, service implementations should be careful to always reply
431 exactly once to each method call. Replying at the end of a long-running
432 operation is correct — the client will patiently wait until the operation has
433 finished and the reply is received.
434
435 Note that D-Bus client bindings may implement synthetic timeouts of several
436 tens of seconds, unless explicitly disabled for a call. For very long-running
437 operations, you should disable the client bindings’ timeout and make it clear
438 in the client’s UI that the application has not frozen and is simply running a
439 long operation.
440
441 An anti-pattern to avoid in this situation is to start a long-running operation
442 when a method call is received, then to never reply to the method call and
443 instead notify the client of completion of the operation via a signal. This
444 approach is incorrect as signal emissions do not have a one-to-one relationship
445 with method calls — the signal could theoretically be emitted multiple times, or
446 never, which the client would not be able to handle.
447
448 Similarly, use a D-Bus error reply to signify failure of an operation triggered
449 by a method call, rather than using a custom error code in the method’s
450 reply. This means that a reply always indicates success, and an error always
451 indicates failure — rather than a reply indicating either depending on its
452 parameters, and having to return dummy values in the other parameters. Using
453 D-Bus error replies also means such failures can be highlighted in debugging
454 tools, simplifying debugging.
455
456 Clients should handle all possible standard and documented D-Bus errors for each
457 method call. IPC inherently has more potential failures than normal C function
458 calls, and clients should be prepared to handle all of them gracefully.
459
460 === Using Standard Interfaces
461     [id="standard-interfaces"]
462
463 Use standard D-Bus interfaces where possible.
464
465 ==== Properties
466      [id="interface-properties"]
467
468 The D-Bus specification defines the
469 $link[>>http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties]($code(org.freedesktop.DBus.Properties))
470 interface, which should be used by all objects to notify clients of changes
471 to their property values, with the $code(PropertiesChanged) signal. This signal
472 eliminates the need for individual $code($var(PropertyName)Changed) signals, and
473 allows multiple properties to be notified in a single signal emission, reducing
474 IPC round trips. Similarly, the $code(Get) and $code(Set) methods can be used to
475 manipulate properties on an object, eliminating redundant
476 $code(Get$var(PropertyName)) and $code(Set$var(PropertyName)) methods.
477
478 [example]
479   For example, consider an object implementing an interface
480   $code(com.example.MyService1.SomeInterface) with methods:
481   [list]
482   * $code(GetName() → (s))
483   * $code(SetName(s) → ())
484   * $code(GetStatus() → (u))
485   * $code(RunOperation(ss) → (u))
486   and signals:
487   [list]
488   * $code(NameChanged(u))
489   * $code(StatusChanged(u))
490
491   The interface could be cut down to a single method:
492   [list]
493   * $code(RunOperation(ss) → (u))
494   The object could then implement the $code(org.freedesktop.DBus.Properties)
495   interface and define properties:
496   [list]
497   * $code(Name) of type $code(s), read–write
498   * $code(Status) of type $code(u), read-only
499
500   The $code(NameChanged) and $code(StatusChanged) signals would be replaced by
501   $code(org.freedesktop.DBus.Properties.PropertiesChanged).
502
503 ==== Object Manager
504      [id="interface-object-manager"]
505
506 The specification also defines the
507 $link[>>http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager]($code(org.freedesktop.DBus.ObjectManager))
508 interface, which should be used whenever a service needs to expose a variable
509 number of objects of the same class in a flat or tree-like structure, and
510 clients are expected to be interested in most or all of the objects. For
511 example, this could be used by an address book service which exposes multiple
512 address books, each as a separate object. The $code(GetManagedObjects) method
513 allows the full object tree to be queried, returning all the objects’ properties
514 too, eliminating the need for further IPC round trips to query the properties.
515
516 If clients are not expected to be interested in most of the exposed objects,
517 $code(ObjectManager) should $em(not) be used, as it will send all of the objects
518 to each client anyway, wasting bus bandwidth. A file manager, therefore, should
519 not expose the entire file system hierarchy using $code(ObjectManager).
520
521 [example]
522   For example, consider an object implementing an interface
523   $code(com.example.MyService1.AddressBookManager) with methods:
524   [list]
525   * $code(GetAddressBooks() → (ao))
526   and signals:
527   [list]
528   * $code(AddressBookAdded(o))
529   * $code(AddressBookRemoved(o))
530
531   If the manager object is at path
532   $code(/com/example/MyService1/AddressBookManager), each address book is a
533   child object, e.g.
534   $code(/com/example/MyService1/AddressBookManager/SomeAddressBook).
535
536   The interface could be eliminated, and the
537   $code(org.freedesktop.DBus.ObjectManager) interface implemented on the manager
538   object instead.
539
540   Calls to $code(GetAddressBooks) would become calls to $code(GetManagedObjects)
541   and emissions of the $code(AddressBookAdded) and $code(AddressBookRemoved)
542   signals would become emissions of $code(InterfacesAdded) and
543   $code(InterfacesRemoved).
544
545 === Naming Conventions
546     [id="naming-conventions"]
547
548 All D-Bus names, from service names through to method parameters, follow a set
549 of conventions. Following these conventions makes APIs more natural to use and
550 consistent with all other services on the system.
551
552 Services use reverse-domain-name notation, based on the domain name of the
553 project providing the service (all in lower case), plus a unique name for the
554 service (in camel case).
555
556 [example]
557   For example, version 2 of an address book application called $code(ContactDex)
558   provided by a software vendor whose website is $code(chocolateteapot.com)
559   would use service name $code(com.chocolateteapot.ContactDex2).
560
561 Almost all names use camel case with no underscores, as in the examples below.
562 Method and signal parameters are an exception, using
563 $code(lowercase_with_underscores). Type information is never encoded in the
564 parameter name (i.e. $em(not)
565 $link[>>http://en.wikipedia.org/wiki/Hungarian_notation](Hungarian notation)).
566
567 [example]
568   [terms]
569   - Service Name
570   * $code(com.example.MyService1)
571   - Interface Name
572   * $code(com.example.MyService1.SomeInterface)
573   - Object Path (Root Object)
574   * $code(/com/example/MyService1)
575   - Object Path (Child Object)
576   * $code(/com/example/MyService1/SomeChild)
577   - Object Path (Grandchild Object)
578   * $code(/com/example/MyService1/AnotherChild/Grandchild1)
579   - Method Name
580   * $code(com.example.MyService1.SomeInterface.MethodName)
581   - Signal Name
582   * $code(com.example.MyService1.SomeInterface.SignalName)
583   - Property Name
584   * $code(com.example.MyService1.SomeInterface.PropertyName)
585
586 See also: $link[>#api-versioning].
587
588 == Code generation
589    [id="code-generation"]
590
591 Rather than manually implementing both the server and client sides of a D-Bus
592 interface, it is often easier to write the interface XML description and use a
593 tool such as
594 $link[>>https://developer.gnome.org/gio/stable/gdbus-codegen.html]($cmd(gdbus-codegen))
595 to generate type-safe C APIs, then build the implementation using those. This
596 avoids the tedious and error-prone process of writing code to build and read
597 D-Bus parameter variants for each method call.
598
599 Use of code generators is beyond the scope of this guide; for more information,
600 see the
601 $link[>>https://developer.gnome.org/gio/stable/gdbus-codegen.html]($cmd(gdbus-codegen)
602 manual).
603
604 == Annotations
605    [id="annotations"]
606
607 Annotations may be added to the interface XML to expose metadata on the API
608 which can be used by documentation or code generation tools to modify their
609 output. Some standard annotations are given in the
610 $link[>>http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format](D-Bus
611 specification), but further annotations may be defined by specific tools.
612
613 For example, $cmd(gdbus-codegen) defines several useful annotations, listed on
614 its man page.
615
616 The following annotations are the most useful:
617
618 [terms]
619 - $code(org.freedesktop.DBus.Deprecated)
620 * Mark a symbol as deprecated. This should be used whenever the API is changed,
621   specifying the version introducing the deprecation, the reason for
622   deprecation, and a replacement symbol to use.
623 - $code(org.gtk.GDBus.Since)
624 * Mark a symbol as having been added to the API after the initial release. This
625   should include the version the symbol was first added in.
626 - $code(org.gtk.GDBus.C.Name) and $code(org.freedesktop.DBus.GLib.CSymbol)
627 * Both used interchangeably to hint at a C function name to use when generating
628   code for a symbol. Use of this annotation can make generated bindings a lot
629   more pleasant to use.
630 - $code(org.freedesktop.DBus.Property.EmitsChangedSignal)
631 * Indicate whether a property is expected to emit change signals. This can
632   affect code generation, but is also useful documentation, as client programs
633   then know when to expect property change notifications and when they have to
634   requery.
635
636 == Documentation
637    [id="documentation"]
638
639 Also just like C APIs, D-Bus APIs must be documented. There are several methods
640 for documenting the interfaces, methods, properties and signals in a D-Bus
641 interface XML file, each unfortunately with their own downsides. You should
642 choose the method which best matches the tooling and workflow you are using.
643
644 === XML Comments
645
646 XML comments containing documentation in the
647 $link[>>https://developer.gnome.org/gtk-doc-manual/stable/documenting_syntax.html.en](gtk-doc
648 format) is the recommended format for use with
649 $link[>>https://developer.gnome.org/gio/stable/gdbus-codegen.html]($cmd(gdbus-codegen)).
650 Using $cmd(gdbus-codegen), these comments can be extracted, converted to DocBook
651 format and included in the project’s API manual. For example:
652
653 [listing]
654   [title]
655     Documentation Comments in D-Bus Interface XML
656   [desc]
657     Example gtk-doc–style documentation comments in the introspection XML for
658     the $code(org.freedesktop.DBus.Properties) interface.
659   [code mime="application/xml"]
660     <!--
661         org.freedesktop.DBus.Properties:
662         @short_description: Standard property getter/setter interface
663
664         Interface for all objects which expose properties on the bus, allowing
665         those properties to be got, set, and signals emitted to notify of changes
666         to the property values.
667     -->
668     <interface name="org.freedesktop.DBus.Properties">
669       <!--
670           Get:
671           @interface_name: Name of the interface the property is defined on.
672           @property_name: Name of the property to get.
673           @value: Property value, wrapped in a variant.
674
675           Retrieves the value of the property at @property_name on
676           @interface_name on this object. If @interface_name is an empty string,
677           all interfaces will be searched for @property_name; if multiple
678           properties match, the result is undefined.
679
680           If @interface_name or @property_name do not exist, a
681           #org.freedesktop.DBus.Error.InvalidArgs error is returned.
682       -->
683       <method name="Get">
684         <arg type="s" name="interface_name" direction="in"/>
685         <arg type="s" name="property_name" direction="in"/>
686         <arg type="v" name="value" direction="out"/>
687       </method>
688
689       <!--
690           PropertiesChanged:
691           @interface_name: Name of the interface the properties changed on.
692           @changed_properties: Map of property name to updated value for the
693             changed properties.
694           @invalidated_properties: List of names of other properties which have
695             changed, but whose updated values are not notified.
696
697           Emitted when one or more properties change values on @interface_name.
698           A property may be listed in @changed_properties or
699           @invalidated_properties depending on whether the service wants to
700           broadcast the property’s new value. If a value is large or infrequently
701           used, the service might not want to broadcast it, and will wait for
702           clients to request it instead.
703       -->
704       <signal name="PropertiesChanged">
705         <arg type="s" name="interface_name"/>
706         <arg type="a{sv}" name="changed_properties"/>
707         <arg type="as" name="invalidated_properties"/>
708       </signal>
709     </interface>
710
711 [comment]
712   FIXME: This is only present to fix
713   $link[>>https://github.com/projectmallard/mallard-ducktype/issues/2].
714
715 === XML Annotations
716
717 Documentation can also be added as annotation elements in the XML. This format
718 is also supported by $cmd(gdbus-codegen), but gtk-doc comments are preferred.
719 For example:
720
721 [listing]
722   [title]
723     Documentation Annotations in D-Bus Interface XML
724   [desc]
725     Example GDBus documentation annotations in the introspection XML for
726     the $code(org.freedesktop.DBus.Properties) interface.
727   [code mime="application/xml"]
728     <interface name="org.freedesktop.DBus.Properties">
729       <annotation name="org.gtk.GDBus.DocString" value="Interface for all
730         objects which expose properties on the bus, allowing those properties to
731         be got, set, and signals emitted to notify of changes to the property
732         values."/>
733       <annotation name="org.gtk.GDBus.DocString.Short"
734         value="Standard property getter/setter interface"/>
735
736       <method name="Get">
737         <annotation name="org.gtk.GDBus.DocString" value="Retrieves the value of
738           the property at @property_name on @interface_name on this object. If
739           @interface_name is an empty string, all interfaces will be searched
740           for @property_name; if multiple properties match, the result is
741           undefined.
742
743           If @interface_name or @property_name do not exist, a
744           #org.freedesktop.DBus.Error.InvalidArgs error is returned."/>
745
746         <arg type="s" name="interface_name" direction="in">
747           <annotation name="org.gtk.GDBus.DocString"
748             value="Name of the interface the property is defined on."/>
749         </arg>
750
751         <arg type="s" name="property_name" direction="in">
752           <annotation name="org.gtk.GDBus.DocString"
753             value="Name of the property to get."/>
754         </arg>
755
756         <arg type="v" name="value" direction="out">
757           <annotation name="org.gtk.GDBus.DocString"
758             value="Property value, wrapped in a variant."/>
759         </arg>
760       </method>
761
762       <signal name="PropertiesChanged">
763         <annotation name="org.gtk.GDBus.DocString" value="Emitted when one or
764           more properties change values on @interface_name. A property may be
765           listed in @changed_properties or @invalidated_properties depending on
766           whether the service wants to broadcast the property’s new value. If a
767           value is large or infrequently used, the service might not want to
768           broadcast it, and will wait for clients to request it instead."/>
769
770         <arg type="s" name="interface_name">
771           <annotation name="org.gtk.GDBus.DocString"
772             value="Name of the interface the properties changed on."/>
773         </arg>
774
775         <arg type="a{sv}" name="changed_properties">
776           <annotation name="org.gtk.GDBus.DocString"
777             value="Map of property name to updated value for the changed
778               properties."/>
779         </arg>
780
781         <arg type="as" name="invalidated_properties">
782           <annotation name="org.gtk.GDBus.DocString"
783             value="List of names of other properties which have changed, but
784               whose updated values are not notified."/>
785         </arg>
786       </signal>
787     </interface>
788
789 [comment]
790   FIXME: This is only present to fix
791   $link[>>https://github.com/projectmallard/mallard-ducktype/issues/2].
792
793 == Service files
794    [id="service-files"]
795
796 Each D-Bus service must install a $file(.service) file describing its service
797 name and the command to run to start the service. This allows for service
798 activation (see the
799 $link[>>http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-starting-services](D-Bus
800 specification)).
801
802 Service files must be named after the service’s well-known name, for example
803 file $file(com.example.MyService1.service) for well-known name
804 $code(com.example.MyService1). Files must be installed in
805 $file($var($$(datadir))/dbus-1/services) for the session bus and
806 $file($var($$(datadir))/dbus-1/system-services) for the system bus. Note, however,
807 that services on the system bus almost always need a
808 $link[>#security-policies](security policy) as well.
809
810 == Security Policies
811    [id="security-policies"]
812
813 At a high level, the D-Bus security model is:
814 [list]
815 * There is a system bus, and zero or more session buses.
816 * Any process may connect to the system bus. The system bus limits which can own
817   names or send method calls, and only processes running as privileged users can
818   receive unicast messages not addressed to them. Every process may receive
819   broadcasts.
820 * Each session bus has an owner (a user). Only its owner may connect; on
821   general-purpose Linux, a session bus is not treated as a privilege boundary,
822   so there is no further privilege separation between processes on it.
823
824 Full coverage of securing D-Bus services is beyond the scope of this guide,
825 however there are some steps which you can take when designing an API to ease
826 security policy implementation.
827
828 D-Bus security policies are written as XML files in
829 $file($var($$(datadir)/dbus-1/system.d)),
830 $file($var($$(datadir)/dbus-1/session.d)),
831 $file($var($$(sysconfdir)/dbus-1/system.d)) and
832 $file($var($$(sysconfdir)/dbus-1/session.d)) and use an allow/deny model, where
833 each message (method call, signal emission, etc.) can be allowed or denied
834 according to the sum of all policy rules which match it. Each $code(<allow>) or
835 $code(<deny>) rule in the policy should have the $code(own),
836 $code(send_destination) or $code(receive_sender) attribute set.
837
838 When designing an API, bear in mind the need to write and install such a
839 security policy, and consider splitting up methods or providing more restricted
840 versions which accept constrained parameters, so that they can be exposed with
841 less restrictive security policies if needed by less trusted clients. Since
842 dbus-daemon 1.10, security policies should be installed to
843 $file($var($$(datadir))) rather than $(file($var($$(sysconfdir))); the latter
844 is intended for system administators.
845
846 Secondly, the default D-Bus security policy for the system bus is restrictive
847 enough to allow sensitive data, such as passwords, to be safely sent over the
848 bus in unicast messages (including unicast signals); so there is no need to
849 complicate APIs by implementing extra security. Note, however, that sensitive
850 data must $em(not) be sent in broadcast signals, as they can be seen by all
851 peers on the bus. The default policy for the session bus is not restrictive, but
852 it is typically not a security boundary.
853
854 == Debugging
855    [id="debugging"]
856
857 Debugging services running on D-Bus can be tricky, especially if they are
858 launched via service activation and hence in an environment out of your control.
859
860 Three main tools are available: D-Bus Monitor, Bustle and D-Feet.
861
862 === D-Bus Monitor
863     [id="dbus-monitor"]
864
865 $link[>>http://dbus.freedesktop.org/doc/dbus-monitor.1.html]($cmd(dbus-monitor))
866 is a core D-Bus tool, and allows eavesdropping on the session or system bus,
867 printing all messages it sees. The messages may be filtered using a standard
868 $link[>>http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules](D-Bus
869 match rule) to make the stream more manageable.
870
871 Previous versions of D-Bus have required the security policy for the system bus
872 to be manually relaxed to allow eavesdropping on all messages. This meant that
873 debugging it was difficult and insecure. The latest versions of D-Bus add
874 support for monitor-only connections for the root user, which means that
875 $cmd(dbus-monitor) can be run as root to painlessly monitor all messages on the
876 system bus without modifying its security policy.
877
878 === Bustle
879     [id="bustle"]
880
881 $link[>>http://willthompson.co.uk/bustle/](Bustle) is a graphical version of
882 $cmd(dbus-monitor), with a UI focused on profiling D-Bus performance by plotting
883 messages on a timeline. It is ideal for finding bottlenecks in IPC performance
884 between a service and client.
885
886 === D-Feet
887     [id="d-feet"]
888
889 $link[>>https://wiki.gnome.org/Apps/DFeet](D-Feet) is an introspection tool for
890 D-Bus, which displays all peers on the bus graphically, with their objects,
891 interfaces, methods, signals and properties listed for examination. It is useful
892 for debugging all kinds of issues related to presence of services on the bus
893 and the objects they expose.