Skip to content

Properties in auto generated introspection data #130

@mk868

Description

@mk868

Hello,
I like to use this library at work, so I'm writing with a proposal to extend the Introspection functionality.
Currently, automatically generated introspection data doesn't provide information about properties in the interfaces.
This is obvious because property names/types/access for interfaces are not declared anywhere.
The property information can be helpful during development, especially when using tools like d-feet.

Current state

Let's suppose that we have two interfaces:

@DBusInterfaceName("com.example.Foo")
public interface Foo extends DBusInterface {
  String method1();
}
@DBusInterfaceName("com.example.Bar")
public interface Bar extends DBusInterface {
  String method2(int arg);
}

And we have one object implementing interfaces:

public class ExampleObject implements Foo, Bar, Properties {
  // ...
}

The introspection data generated for exported ExampleObject object:

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/aa/bb/ccc1">
 <interface name="com.example.Foo">
  <method name="method1" >
   <arg type="s" direction="out"/>
  </method>
 </interface>
 <interface name="com.example.Bar">
  <method name="method2" >
   <arg type="i" direction="in"/>
   <arg type="s" direction="out"/>
  </method>
 </interface>
 <interface name="org.freedesktop.DBus.Properties">
  <method name="Set" >
   <arg type="s" direction="in"/>
   <arg type="s" direction="in"/>
   <arg type="v" direction="in"/>
  </method>
  <method name="Get" >
   <arg type="s" direction="in"/>
   <arg type="s" direction="in"/>
   <arg type="v" direction="out"/>
  </method>
  <method name="GetAll" >
   <arg type="s" direction="in"/>
   <arg type="a{sv}" direction="out"/>
  </method>
  <signal name="PropertiesChanged">
   <arg type="s" direction="out" />
   <arg type="a{sv}" direction="out" />
   <arg type="as" direction="out" />
  </signal>
 </interface>
 <interface name="org.freedesktop.DBus.Introspectable">
  <method name="Introspect">
   <arg type="s" direction="out"/>
  </method>
 </interface>
 <interface name="org.freedesktop.DBus.Peer">
  <method name="Ping">
  </method>
 </interface>
</node>

DBusProperty annotation proposal

My idea is to create annotation which allows to describe properties in the interface:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(DBusProperties.class)
public @interface DBusProperty {
  // Property name
  String name() default "";
  // Java type, use in case of base types
  Class<?> typeClass() default Void.class;
  // DBus type as a string, use in case of complex DBus types
  String type() default "";
  // property access type
  Access access() default Access.READ_WRITE;

  enum Access {
    READ,
    READ_WRITE,
    WRITE
  }
}

With this annotation we could append information about the interface properties:

@DBusInterfaceName("com.example.Foo")
@DBusProperty(name="Id", typeClass=String.class, access=Access.READ)
@DBusProperty(name="Label", typeClass=String.class, access=Access.READ_WRITE)
public interface Foo extends DBusInterface {
  String method1();
}
@DBusInterfaceName("com.example.Bar")
@DBusProperty(name="SomeMap", type="a{sv}", access=Access.READ)
public interface Bar extends DBusInterface {
  String method2(int arg);
}

At this point, the introspection generator can discover the properties used in the interface and add them to the response body.
The data from introspection will look like this:

<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node name="/aa/bb/ccc1">
 <interface name="com.example.Foo">
  <property name="Id" type="s" access="read"/>
  <property name="Label" type="s" access="readwrite"/>
  <method name="method1" >
   <arg type="s" direction="out"/>
  </method>
 </interface>
 <interface name="com.example.Bar">
  <property name="SomeMap" type="a{sv}" access="read"/>
  <method name="method2" >
   <arg type="i" direction="in"/>
   <arg type="s" direction="out"/>
  </method>
 </interface>
 <interface name="org.freedesktop.DBus.Properties">
  <method name="Set" >
   <arg type="s" direction="in"/>
   <arg type="s" direction="in"/>
   <arg type="v" direction="in"/>
  </method>
  <method name="Get" >
   <arg type="s" direction="in"/>
   <arg type="s" direction="in"/>
   <arg type="v" direction="out"/>
  </method>
  <method name="GetAll" >
   <arg type="s" direction="in"/>
   <arg type="a{sv}" direction="out"/>
  </method>
  <signal name="PropertiesChanged">
   <arg type="s" direction="out" />
   <arg type="a{sv}" direction="out" />
   <arg type="as" direction="out" />
  </signal>
 </interface>
 <interface name="org.freedesktop.DBus.Introspectable">
  <method name="Introspect">
   <arg type="s" direction="out"/>
  </method>
 </interface>
 <interface name="org.freedesktop.DBus.Peer">
  <method name="Ping">
  </method>
 </interface>
</node>

With this change, programs like d-feet will be able to fully detect and correctly display properties in interfaces.
I hope for opinions on this solution, if it's acceptable I could prepare a PR with changes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions