Results 1 to 7 of 7

Thread: QDBusConnection error: Invalid object path passed in arguments

  1. #1
    Join Date
    Aug 2007
    Posts
    244
    Thanks
    42
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default QDBusConnection error: Invalid object path passed in arguments

    Hi, I added mpris support to my application. It works well in all tests except one: Now Playing plasmoid of KDE Plasma Workspace. Clicking on the seek widget to change playback position, Plasma Desktop crashes miserably. In console the following message appears:

    process 2395: arguments to dbus_message_iter_append_basic() were incorrect, assertion "_dbus_check_is_valid_path (*string_p)" failed in file dbus-message.c line 2603.
    Not very explicative, unfortunately. Not knowing how debug dbus I tried a different approach: I recompiled dbus commenting out the offensive line and fortunately I got a more friendly error message:

    QDBusConnection: error: could not send message to service "org.mpris.MediaPlayer2.myapp" path "/org/mpris/MediaPlayer2" interface "org.mpris.MediaPlayer2.Player" member "SetPosition": Marshalling failed: Invalid object path passed in arguments
    Then I used qdbusviewer to inspect all mpris methods of my application and all work fine except SetPosition, where it gives the error:

    Unable to find method SetPosition on path /org/mpris/MediaPlayer2 in interface org.mpris.MediaPlayer2.Player
    Here it is an excerpt of the code I'm using:

    Qt Code:
    1. #include "MprisPlugin.h"
    2. #include "MprisPluginRootAdaptor.h"
    3. #include "MprisPluginPlayerAdaptor.h"
    4.  
    5. namespace mpris
    6. {
    7.  
    8. const char* MprisPlugin::mprisObjectPath = "/org/mpris/MediaPlayer2";
    9. const char* MprisPlugin::serviceName = "org.mpris.MediaPlayer2.myapp";
    10. const char* MprisPlugin::freedesktopPath = "org.freedesktop.DBus.Properties";
    11.  
    12. static QString s_mpInfoIdentifier = QString( "MPRISPLUGIN" );
    13.  
    14. MprisPlugin::MprisPlugin(QObject* parent) :
    15. QObject(parent)
    16. {
    17. // DBus connection
    18. new MprisPluginRootAdaptor( this );
    19. new MprisPluginPlayerAdaptor( this );
    20. QDBusConnection dbus = QDBusConnection::sessionBus();
    21. dbus.registerObject( mprisObjectPath, this );
    22. dbus.registerService( serviceName );
    23.  
    24. // Listen to volume changes
    25. connect( The::audioEngine(), SIGNAL( volumeChanged( int ) ),
    26. SLOT( onVolumeChanged( int ) ) );
    27.  
    28. // When a track is added or removed, CanGoNext updated signal is sent
    29. if ( !The::playlist() )
    30. {
    31. connect( The::playlist(), SIGNAL( itemCountChanged( unsigned int ) ),
    32. SLOT( onTrackCountChanged( unsigned int ) ) );
    33. }
    34.  
    35. // Connect to AudioEngine's seeked signal
    36. connect( The::audioEngine(), SIGNAL( seeked( qint64, bool ) ),
    37. SLOT( onSeeked( qint64, bool ) ) );
    38.  
    39. connect( The::audioEngine(), SIGNAL( stateChanged(Phonon::State, Phonon::State ) ),
    40. SLOT( engineStateChanged(Phonon::State, Phonon::State ) ) );
    41.  
    42. connect( The::audioEngine(), SIGNAL( sourceChanged() ),
    43. SLOT( trackChanged() ) );
    44.  
    45. connect( The::audioEngine(), SIGNAL( seekableChanged(bool) ),
    46. SLOT( seekableChanged(bool) ) );
    47.  
    48. connect( The::audioEngine(), SIGNAL( trackLengthChanged(qint64) ),
    49. SLOT( trackLengthChanged(qint64) ) );
    50. }
    51.  
    52. void MprisPlugin::notifyPropertyChanged( const QString& interface, const QString& propertyName )
    53. {
    54. QDBusMessage signal = QDBusMessage::createSignal(
    55. mprisObjectPath,
    56. freedesktopPath,
    57. "PropertiesChanged" );
    58. signal << interface;
    59. QVariantMap changedProps;
    60. changedProps.insert(propertyName, property(propertyName.toLatin1()));
    61. signal << changedProps;
    62. signal << QStringList();
    63. qDebug() << propertyName;
    64. qDebug() << changedProps;
    65. QDBusConnection::sessionBus().send(signal);
    66. }
    67.  
    68. // ...
    69.  
    70. // org.mpris.MediaPlayer2.Player
    71.  
    72. // ...
    73.  
    74. qlonglong MprisPlugin::position() const
    75. {
    76. return (qlonglong) ( The::audioEngine()->currentTime() * 1000 );
    77. }
    78.  
    79. // ...
    80.  
    81. void MprisPlugin::SetPosition( const QDBusObjectPath& TrackId, qlonglong Position )
    82. {
    83. if ( !canSeek() )
    84. return;
    85.  
    86. if ( TrackId.path() != QString( "/track/" ) + QString::number( The::audioEngine()->currentTrackID() ) )
    87. return;
    88.  
    89. if ( ( Position < 0) || ( Position > The::audioEngine()->currentTrackTotalTime() * 1000 ) )
    90. return;
    91.  
    92. The::audioEngine()->seek( (qint64) (Position / 1000 ) );
    93. }
    94.  
    95. // ...
    96.  
    97. void MprisPlugin::Seek( qlonglong Offset )
    98. {
    99. if ( !canSeek() )
    100. return;
    101.  
    102. qlonglong seekTime = position() + Offset;
    103. if ( seekTime < 0 )
    104. The::audioEngine()->seek( 0 );
    105. else if ( seekTime > The::audioEngine()->currentTrackTotalTime() * 1000 )
    106. Next();
    107. else
    108. The::audioEngine()->seek( (qint64) ( seekTime / 1000 ) );
    109.  
    110. }
    111.  
    112. void MprisPlugin::onSeeked( qint64 ms, bool userSeek )
    113. {
    114. if ( userSeek )
    115. emit Seeked( ms * 1000 );
    116. }
    117.  
    118. void MprisPlugin::engineStateChanged(Phonon::State newState, Phonon::State oldState)
    119. {
    120. if(newState != Phonon::PlayingState && newState != Phonon::PausedState) {
    121. m_lastMetadata= QVariantMap();
    122. notifyPropertyChanged("org.mpris.MediaPlayer2.Player", "Metadata");
    123. }
    124.  
    125. notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "PlaybackStatus" );
    126. notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "CanGoNext" );
    127. notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "CanGoPrevious" );
    128. notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "CanPause" );
    129. }
    130.  
    131. // ...
    132.  
    133. void MprisPlugin::trackChanged()
    134. {
    135. PlaylistItemPtr track = The::audioEngine()->currentTrack();
    136. m_lastMetadata = QVariantMap();
    137. m_lastMetadata.insert( "mpris:trackid", QString( "/track/" ) + QString::number( The::audioEngine()->currentTrackID() ) );
    138. m_lastMetadata.insert( "mpris:length", static_cast<qlonglong>( The::audioEngine()->currentTrackTotalTime() ) * 1000 );
    139. m_lastMetadata.insert( "xesam:album", track->albumName() );
    140. m_lastMetadata.insert( "xesam:artist", QStringList( track->artistName() ) );
    141. m_lastMetadata.insert( "xesam:title", track->songName() );
    142.  
    143. m_lastMetadata.insert( "mpris:artUrl", QString( QUrl::fromLocalFile( track->coverArtFilename() ).toEncoded() ) );
    144.  
    145. notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "Metadata" );
    146. }
    147.  
    148. void MprisPlugin::seekableChanged( bool seekable )
    149. {
    150. notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "CanSeek");
    151. }
    152.  
    153. void MprisPlugin::trackLengthChanged( qint64 milliseconds )
    154. {
    155. if ( milliseconds >= 0 )
    156. trackChanged();
    157. }
    158.  
    159. } //mpris
    To copy to clipboard, switch view to plain text mode 

    Can you explain why just SetPosition does not work?

    Very thanks
    Giuseppe CalÃ

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QDBusConnection error: Invalid object path passed in arguments

    Does the adator for that interface have that method?

    Cheers,
    _

  3. #3
    Join Date
    Aug 2007
    Posts
    244
    Thanks
    42
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QDBusConnection error: Invalid object path passed in arguments

    Giuseppe CalÃ

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QDBusConnection error: Invalid object path passed in arguments

    That's the interface description. Have you checked the adaptor MprisPluginPlayerAdaptor?

    Cheers,
    _

  5. #5
    Join Date
    Aug 2007
    Posts
    244
    Thanks
    42
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QDBusConnection error: Invalid object path passed in arguments

    This is a cmake project so MprisPluginPlayerAdaptor is auto-generated. I'm using the following macros:

    Qt Code:
    1. qt4_add_dbus_adaptor(myapp_SRCS
    2. dbus/MprisPluginRootAdaptor.xml
    3. dbus/MprisPlugin.h mpris::MprisPlugin MprisPluginRootAdaptor MprisPluginRootAdaptor)
    4. qt4_add_dbus_adaptor(myapp_SRCS
    5. dbus/MprisPluginPlayerAdaptor.xml
    6. dbus/MprisPlugin.h mpris::MprisPlugin MprisPluginPlayerAdaptor MprisPluginPlayerAdaptor)
    To copy to clipboard, switch view to plain text mode 


    in resulting MprisPluginPlayerAdaptor I've searched for "position" and found this:

    Qt Code:
    1. qlonglong MprisPluginPlayerAdaptor::position() const
    2. {
    3. // get the value of property Position
    4. return qvariant_cast< qlonglong >(parent()->property("Position"));
    5. }
    6.  
    7. // ...
    8.  
    9. void MprisPluginPlayerAdaptor::SetPosition(const QDBusObjectPath &TrackId, qlonglong Position)
    10. {
    11. // handle method call org.mpris.MediaPlayer2.Player.SetPosition
    12. parent()->SetPosition(TrackId, Position);
    13. }
    To copy to clipboard, switch view to plain text mode 

    So it seems that SetPosition is in place.

    Thanks for your time
    Giuseppe CalÃ

  6. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QDBusConnection error: Invalid object path passed in arguments

    Hmm, very strange.

    Can you try to make the call using dbus-send? In contrast to qdbus or qdbusviewer it doesn't use introspection at runtime.
    Alternatively you could try to generate interfaces in a small test program and use it to call your object's methods.

    The thing with the assert is also puzzling.

    Maybe try running the Plasma applet in plasma-windowed and attach a debugger to it and see what the stack looks like when the assert is triggered?

    Cheers,
    _

  7. #7
    Join Date
    Aug 2007
    Posts
    244
    Thanks
    42
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QDBusConnection error: Invalid object path passed in arguments

    Just a quick update: at the end I dropped my implementation and wrote adaptors from scratch (no more qt4_add_dbus_adaptor macro). Now it works.
    Giuseppe CalÃ

Similar Threads

  1. Replies: 1
    Last Post: 9th January 2014, 15:31
  2. Replies: 4
    Last Post: 4th January 2012, 22:43
  3. Replies: 1
    Last Post: 18th February 2011, 11:05
  4. Replies: 0
    Last Post: 24th October 2010, 19:09
  5. Replies: 1
    Last Post: 25th September 2010, 08:20

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.