# chromeos-dbus-bindings

**chromeos-dbus-bindings** was created to supplement [libbrillo] and
simplify the implementation of [D-Bus] daemons and proxies. It generates C++
classes from the XML specifications of the D-Bus interface. Instead of dealing
directly with `MethodCall` objects and unpacking the arguments manually, the
generated bindings take care of marshalling and unmarshalling D-Bus method
call arguments for you.

Additionally, a Rust crate chromeos_dbus_bindings is supplied for generating a
Rust library with D-Bus bindings from the introspection XML data. Most of the
logic is already provided by dbus-codegen-rust, but the source XML is not always
available to the crate file, so this wraps the generated sources.

## Setting up chromeos-dbus-bindings

The XML format defining objects and interfaces is the same format used in
[the introspection API]. Method and signal handlers are generated from this XML
file. If you were using dbus-c++ before, you are probably using `xml2cpp`
to generate C++ bindings from the XML specification. If not, you may need to
write an XML specification.

After that, you will need to set up some actions in the `BUILD.gn` file for your
service and its users. That will look something like this in your service:

```
import("//common-mk/generate-dbus-adaptors.gni")

generate_dbus_adaptors("frobinator-adaptors") {
  sources = [
    "dbus_bindings/service.name.of.Frobinator.xml",
  ]
  dbus_adaptors_out_dir = "include/frobinator/dbus_adaptors"
  dbus_service_config = "dbus_bindings/dbus-service-config.json"
}
```

and this in users of your service (or for a client library target):

```
import("//common-mk/generate-dbus-proxies.gni")

generate_dbus_proxies("frobinator-proxies") {
  sources = [
    "path/to/frobinator/dbus_bindings/service.name.of.Frobinator.xml",
  ]
  proxy_output_file = "include/frobinator/dbus-proxies.h"
  dbus_service_config = "dbus_bindings/dbus-service-config.json"
}
```

The JSON service configuration file will look like this:

```json
{
  "service_name": "service.name.of.Frobinator",
}
```

Then, in your service, you can
`#include "frobinator/dbus_adaptors/service.name.of.Frobinator.h"` to get the
interface and adaptor classes for Frobinator, and users can
`#include <frobinator/dbus-proxies.h>` to get the proxy classes. Try to
follow the [best practices] doc and only export one object for your service.

## D-Bus types vs. C++ types

D-Bus methods, signals and properties have [type signatures]. When generating
bindings, `chromeos-dbus-bindings` will map D-Bus types to C++ types like
so:

| D-Bus type signature | C++ type                    |
| -------------------- | ----------------------------|
| `y`                  | `uint8_t`                   |
| `b`                  | `bool`                      |
| `n`                  | `int16_t`                   |
| `q`                  | `uint16_t`                  |
| `i`                  | `int32_t`                   |
| `u`                  | `uint32_t`                  |
| `x`                  | `int64_t`                   |
| `t`                  | `uint64_t`                  |
| `d`                  | `double`                    |
| `s`                  | `std::string`               |
| `h`                  | [base::ScopedFD]            |
| `o`                  | [dbus::ObjectPath]          |
| `v` (variant)        | [brillo::Any]               |
| `(TU...)`            | `std::tuple<T, U, ...>`     |
| `aT`                 | `std::vector<T>`            |
| `a{TU}`              | `std::map<T, U>`            |
| `a{sv}`              | [brillo::VariantDictionary] |

This type mapping is also recursive, i.e. an argument of
type `a{s(io)}` will be mapped to
`std::map<std::string, std::tuple<int32_t, dbus::ObjectPath>>`.

For protocol buffers, add an annotation `ay` (array of bytes) with
`org.chromium.DBus.Argument.ProtobufClass`, like:

```
  <arg name="response" type="ay">
    <annotation name="org.chromium.DBus.Argument.ProtobufClass"
       value="vm_tools::concierge::DiskImageStatusResponse" />
  </arg>
```

## Method generation

Suppose you have a service with the following XML specification:

```xml
<node name="/org/chromium/Frobinator">
  <interface name="org.chromium.Frobinator">
    <method name="Frobinate">
      <arg name="foo" type="i" direction="in" />
      <arg name="bar" type="a{sv}" direction="in" />
      <arg name="baz" type="s" direction="out" />
    </method>
  </interface>
</node>
```

The generator will generate a class `org::chromium::FrobinatorInterface` with
the following C++ method signature:

```c++
bool Frobinate(brillo::ErrorPtr* error,
               int32_t foo,
               const brillo::VariantDictionary& bar,
               std::string* baz);
```

This method can be implemented by inheriting
`org::chromium::FrobinatorInterface` and can be called on proxy objects of type
`org::chromium::FrobinatorProxy`. If the method fails, it should set the `error`
to something descriptive and return false. If an arg has direction "in" and is
not a simple numeric type, it will be passed in as `const &`.

### Annotations

The bindings generator also supports several method annotations. Marking your
methods with these will change the generated bindings.

`org.chromium.DBus.Method.Kind`:

* `simple`: This method will not fail and no `brillo::ErrorPtr` argument is
  given. If it has only one "out" argument, it is treated as a normal return
  value. Otherwise, the method returns `void` and passes "out" arguments
  back as pointers as usual.
* `normal`: As stated above. Returns false and sets a `brillo::ErrorPtr` on
  failure.
* `async`: Instead of returning "out" arguments directly, the C++ method
  will take a [DBusMethodResponse] argument templated on the types of the
  "out" arguments. You can pass this object around and call its methods to
  reply later.
* `raw`: Takes a `dbus::MethodCall` and
  `dbus::ExportedObject::ResponseSender` object directly. Use this if you
  need to do your own message parsing. Protos are often passed as type `ay`
  but Chrome's D-Bus bindings have special methods to handle them, and it
  might make sense to take the `MethodCall` directly for these.

These would have the following effect on the `Frobinate` method above:

| Kind annotation | C++ method signature |
| --------------- | -------------------- |
| `simple`        | `std::string Frobinate(int32_t foo, const brillo::VariantDictionary& bar);` |
| `normal`        | `bool Frobinate(brillo::ErrorPtr* error, int32_t foo, const brillo::VariantDictionary& bar, std::string* baz);` |
| `async`         | `void Frobinate(std::unique_ptr<DBusMethodResponse<std::string>> response, int32_t foo, const brillo::VariantDictionary& bar);` |
| `raw`           | `void Frobinate(dbus::MethodCall* method_call, ResponseSender sender);` |

`org.chromium.DBus.Method.Const`: "true" adds `const` to the method signature

`org.chromium.DBus.Method.IncludeDBusMessage`: passes the `dbus::Message*` as
an argument to the generated adaptor method following the `brillo::ErrorPtr*`
or `DBusMethodResponse`

`org.freedesktop.DBus.GLib.Async`: same as setting `Kind` to `async`

## Signal generation

Unlike methods which are exported in the `FrobinatorInterface` class, signals
are sent from the `FrobinatorAdaptor` class and received by the
`FrobinatorProxy` class. Thus, they look different to the service and its
users. Suppose our service has the following XML specification:

```xml
<node name="/org/chromium/Frobinator">
  <interface name="org.chromium.Frobinator">
    <signal name="FrobinationCompleted">
      <arg name="foo" type="i" direction="out" />
      <arg name="bar" type="a{sv}" direction="out" />
    </signal>
  </interface>
</node>
```

Our adaptor class will have a method:

```c++
void SendFrobinationCompletedSignal(int32_t foo,
                                    const brillo::VariantDictionary& bar);
```

and our proxy class will have a method:

```c++
void RegisterFrobinationCompletedSignalHandler(
    const base::RepeatingCallback<void(int32_t, const brillo::VariantDictionary&)>& signal_callback,
    dbus::ObjectProxy::OnConnectedCallback on_connected_callback);
```

Calling this function will call `on_connected_callback` with whether or not the
registration succeeded, and if it did, `signal_callback` will be called when
the service emits this signal.

## On properties

As stated the [best practices] doc, avoid using D-Bus properties because they
won't transfer well to other IPC mechanisms if we need to switch in the future.
Instead, get and set attributes on your service by using methods, and if you
want users to be able to listen for changes in attributes, use signals.

## Integrating with `DBusServiceDaemon`

[brillo::DBusServiceDaemon] is a class which abstracts away some initialization
tasks for D-Bus services and also ensures that all methods are exported before
the service takes its proper name on the bus. This helps prevent races where
users fail invoking methods on a service which claimed its name too early.

`DBusServiceDaemon` has a virtual method `RegisterDBusObjectsAsync` which is
where the adaptor can set up its D-Bus object and export it. Your adaptor
implementation can inherit from `DBusServiceDaemon`, but it's clearer just
to use containment instead here. A simple daemon could look like this:

```c++
class DBusAdaptor : public org::chromium::FrobinatorInterface,
                    public org::chromium::FrobinatorAdaptor {
 public:
  explicit DBusAdaptor(scoped_refptr<dbus::Bus> bus)
    : org::chromium::FrobinatorAdaptor(this),
      dbus_object_(nullptr, bus, dbus::ObjectPath(kFrobinatorServicePath)) {}
  DBusAdaptor(const DBusAdaptor&) = delete;
  DBusAdaptor& operator=(const DBusAdaptor&) = delete;

  void RegisterAsync(
      brillo::dbus_utils::AsyncEventSequencer::CompletionAction cb) {
    RegisterWithDBusObject(&dbus_object_);
    dbus_object_.RegisterAsync(std::move(cb));
  }

  // org::chromium::FrobinatorInterface overrides.
  bool Frobinate(brillo::ErrorPtr* error,
                 int32_t foo,
                 const brillo::VariantDictionary& bar,
                 std::string* baz) override;

 private:
  brillo::dbus_utils::DBusObject dbus_object_;
};

class FrobinatorDaemon : public brillo::DBusServiceDaemon {
 public:
  FrobinatorDaemon() : DBusServiceDaemon(kFrobinatorServiceName) {}
  FrobinatorDaemon(const FrobinatorDaemon&) = delete;
  FrobinatorDaemon& operator=(const FrobinatorDaemon&) = delete;

 protected:
  void RegisterDBusObjectsAsync(
      brillo::dbus_utils::AsyncEventSequencer* sequencer) override {
    adaptor_.reset(new DBusAdaptor(bus_));
    adaptor_->RegisterAsync(sequencer->GetHandler("RegisterAsync() failed",
                                                  true));
  }

 private:
  std::unique_ptr<DBusAdaptor> adaptor_;
};

int main(int argc, char** argv) {
  return FrobinatorDaemon().Run();
}
```

When the `DBusServiceDaemon` is ready to register objects, it calls your
`RegisterDBusObjectsAsync` method. Here we use the `RegisterWithDBusObject`
method from the generated adaptor class to export the methods, and then
call `RegisterAsync` on the `DBusObject` to grab the name and interfaces
for the D-Bus service later. The `AsyncEventSequencer` that the base daemon
code passes us ensures that we'll do things in the right order.

Your service should now appear on the bus and you should be able to call
methods using `dbus-send` or create `org::chromium::FrobinatorProxy` objects
to interact with it:

```c++
dbus::Bus::Options options;
options.bus_type = dbus::Bus::SYSTEM;
scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));

auto frobinator = std::make_unique<org::chromium::FrobinatorProxy>(bus);
brillo::ErrorPtr error;
if (!frobinator->Frobinate(42, {{ "qux", brillo::Any("squawk") }}, &error))
  LOG(WARNING) << "Frobinate failed: " << error->GetMessage();
```

All methods on proxies are specified like `normal` kind methods on interfaces,
with the exception that the error argument appears at the end rather than the
beginning. Even if they are marked `simple` in the interface, there are other
possibilities for errors, such as timeouts, which need to be reported to the
client.

## chromeos_dbus_bindings: Rust D-Bus codegen helper

Tools for generating a Rust library with D-Bus bindings from the introspection
XML data. Most of the logic is already provided by dbus-codegen-rust, but the
source XML is not always available to the crate file, so this wraps the
generated sources.

To use this tool:
1) Add the following to `src/lib.rs`:
    ```rust
    include!(concat!(env!("OUT_DIR"), "/include_modules.rs"));
    ```

2) Add the following to `.gitignore`:
    ```.gitignore
    /src/bindings
    ```

3) Create the `Cargo.toml` file (system_api is a good examples). Be sure to
    include:
    ```toml
    [build-dependencies]
    chromeos_dbus_bindings = { path = "../chromeos-dbus-bindings"} # provided by ebuild

    [dependencies]
    dbus = "0.6"
    ```

4) Create the`build.rs` file. Here is a skeleton:
    ```rust
    use std::path::Path;

    use chromeos_dbus_bindings::{self, generate_module};

    const SOURCE_DIR: &str = ".";

    // (<module name>, <relative path to source xml>)
    const BINDINGS_TO_GENERATE: &[(&str, &str)] = &[
        (
            "org_chromium_sessionmanagerinterface",
            "dbus_bindings/org.chromium.SessionManagerInterface.xml",
        ),
    ];

    fn main() {
        generate_module(Path::new(SOURCE_DIR), BINDINGS_TO_GENERATE).unwrap();
    }
    ```


[D-Bus]: https://www.freedesktop.org/wiki/Software/dbus/
[libbrillo]: https://chromium.googlesource.com/aosp/platform/external/libbrillo/+/HEAD/brillo/dbus/
[the introspection API]: https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
[best practices]: https://chromium.googlesource.com/chromiumos/docs/+/HEAD/dbus_best_practices.md
[type signatures]: https://dbus.freedesktop.org/doc/dbus-specification.html#type-system
[base::ScopedFD]: https://chromium.googlesource.com/chromiumos/platform/libchrome/+/HEAD/base/files/scoped_file.h
[dbus::ObjectPath]: https://chromium.googlesource.com/chromiumos/platform/libchrome/+/HEAD/dbus/object_path.h
[brillo::Any]: https://chromium.googlesource.com/aosp/platform/external/libbrillo/+/HEAD/brillo/any.h
[brillo::VariantDictionary]: https://chromium.googlesource.com/aosp/platform/external/libbrillo/+/HEAD/brillo/variant_dictionary.h
[DBusMethodResponse]: https://chromium.googlesource.com/aosp/platform/external/libbrillo/+/HEAD/brillo/dbus/dbus_method_response.h
[brillo::DBusServiceDaemon]: https://chromium.googlesource.com/aosp/platform/external/libbrillo/+/HEAD/brillo/daemons/dbus_daemon.h
