Search code examples
dbusintrospectionqdbusgdbusqdbusxml2cpp

D-Bus method not found at object path despite the fact that method exist


I implement an app with this com.example.appname.desktop file as follows:

$ cat /usr/local/share/applications/com.example.appname.desktop 
[Desktop Entry]
Version=1.0
Terminal=false
Type=Application
Name=appname
Exec=/opt/app/appname %u
DBusActivatable=true
Categories=Network;
MimeType=x-scheme-handler/itmm;
NoDisplay=false

$ cat /usr/share/dbus-1/services/com.example.appname.service 
[D-BUS Service]
Name=com.example.appname
Exec=/opt/app/appname

Introspection XML looks like this:

    $ qdbus com.example.appname /com/example/appname  org.freedesktop.DBus.Introspectable.Introspect
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
  <interface name="org.freedesktop.Application">
    <method name="ActivateAction">
      <arg name="action_name" type="s" direction="in"/>
      <arg name="parameter" type="av" direction="in"/>
      <arg name="platform_data" type="a{sv}" direction="in"/>
      <annotation name="org.qtproject.QtDBus.QtTypeName.In2" value="QVariantMap"/>
    </method>
    <method name="Activate">
      <arg name="platform_data" type="a{sv}" direction="in"/>
      <annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QVariantMap"/>
    </method>
    <method name="Open">
      <arg name="uris" type="as" direction="in"/>
      <arg name="platform_data" type="a{sv}" direction="in"/>
      <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="QVariantMap"/>
    </method>
  </interface>
  <interface name="org.freedesktop.DBus.Properties">
    <method name="Get">
      <arg name="interface_name" type="s" direction="in"/>
      <arg name="property_name" type="s" direction="in"/>
      <arg name="value" type="v" direction="out"/>
    </method>
  ----<snipped>-----

But when i try to launch the method it gives me an error:

$ gapplication launch com.example.appname                                                                                                               
error sending Activate message to application: GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod: No such method 'Activate' in interface 'org.freedesktop.Application' at object path '/com/example/appname' (signature 'a{sv}')

Is "annotation name=.." XML tag (see introspection XML) the reason this method is not found? Browsing to itmm://192.168.1.1/query?version=1.0 via browser launches the application with command line parameter, but it is not launched via D-Bus service and thats what my requirement is. Is there a way to debug this via firefox or google chrome browsers?


Solution

  • I use QT's D-Bus binding to implement D-Bus service. My issue were

    1. My class that implemented D-Bus interface was not inheriting QDBusAbstractAdaptor .
    2. Methods to be exported were not marked as public slots

    My original class looked like this below:

    class DBusService : public Application
    {
        QOBJECT
        Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Application") 
        public:
        void Activate(QMap<QString, QVariant> platform_data)
        {   
           Q_UNUSED(platform_data);
        }    
    
        void Open(QStringList uris, QMap<QString, QVariant> platform_data)
        {   
           Q_UNUSED(platform_data);
           if( ! uris.size() ) {
              return;
           }
           QUrl url(uris[0]);
           //use url
        }
    }
    

    Following one works:

    class DBusService : public QDBusAbstractAdaptor  //<----- Inherit from this class
    {
        QOBJECT
        Q_CLASSINFO("D-Bus Interface", "org.freedesktop.Application") 
    
        public slots:  // <------ mark public slots
        void Activate(QMap<QString, QVariant> platform_data)
        {   
           Q_UNUSED(platform_data);
        }    
    
        void Open(QStringList uris, QMap<QString, QVariant> platform_data)
        {   
           Q_UNUSED(platform_data);
           if( ! uris.size() ) {
              return;
           }
           QUrl url(uris[0]);
           qApp->MyCustomMethod(url);
        }
    }
    

    D-Bus debugging tools


    These tools helped me debugging D-Bus issues.
    dbus-monitor - sniffs traffic on the bus

    gapplication - lets you debug DBusActivatable services.