Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-20906

In qdbusviewer, you can only call methods with basic and a few select compound signatures

    XMLWordPrintable

Details

    • Bug
    • Resolution: Incomplete
    • Not Evaluated
    • None
    • 4.7.3
    • D-Bus
    • None

    Description

      In qdbusviewer, if you try to call methods with more complex signatures, it either silently fails or you get the error "Unable to find method <method name> on path <path name> in <interface name>" in a popup box.

      Example: On a contemporary linux box with HAL installed, try calling the following methods on the system bus:

      • "GetAllDevices" on org.freedesktop.hal, path org/freedesktop/Hal/Manager, interface org.freedesktop.Hal.Manager
        Signature in: ""
        Signature out: "ao" (Array of object paths)
        Result: A list is returned and displayed in the lower log window.
      • "GetAllDevicesWithProperties", same name, path and interface
        Signature in: ""
        Signature out: "a(oa {sv}

        )" (array of a compound type)
        Result: Dialog box "Unable to find method GetAllDevicesWithProperties on path /org/freedesktop/Hal/Manager in interface org.freedesktop.Hal.Manager"

      In contrast to the second call, executing the low level command line tool

      "dbus-send --system --print-reply --dest=org.freedesktop.Hal /org/freedesktop/Hal/Manager org.freedesktop.Hal.Manager.GetAllDevicesWithProperties"

      works like a charm (proper data structures returned).

      I read the sources and traced this situation back to src/dbus/qdbusmetatype.cpp:301, function QDBusMetaType::signatureToType(const char*). In it, the first character of the argument is parsed and (in a switch construct) checked for basic types. The last type however is DBUS_TYPE_ARRAY (line 438). If it is encountered, the second character is parsed and checked only for a few simple types (DBUS_TYPE_

      {BYTE,STRING,VARIANT,OBJECT_PATH,SIGNATURE}

      ), otherwise QVariant::Invalid is returned, which in the end leads to qdbusviewer not finding the method:

      1. call method in the UI
      2. QDBusViewer::callMethod(const BusSignature&) is executed, which creates a new QDBusInterface based on service, path and interface of the method
      3. To get the available methods, in the end QDBusMetaObjectGenerator::parseMethods() is called by the constructor
      4. This method calls QDBusMetaObjectGenerator::findType() with the signature of each method contained in the introspect XML data
      5. From there, the above mentioned QDBusMetaType::signatureToType() is called and returns the type.
      6. parseMethods() checks the type and discards methods where the in/out type is QVariant::Invalid; other methods (with "valid" signatures) are added to its methods list
      7. QDBusViewer::callMethod(const BusSignature&) retrieves the interface's QMetaObject and iterates over the methods list using QMetaObject::method(int). In there, it only finds the methods which were added in the step before.

      I'd expect a generic D-Bus interface to be able to handle not just a few select compound types. Is this behaviour by design, i.e. is qdbusviewer intended as a quick hack for demonstration purposes, or should this be fixed?

      If you need more info I'd be happy to provide it.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            Unassigned Unassigned
            chronoss Björn Schließmann
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes