Commit 14402695 authored by Alex Merry's avatar Alex Merry Committed by Rémi Denis-Courmont

Fix Metadata marshalling when sending the PropertiesChanged signal

VLC was getting kicked from the D-Bus when a track was stopped, because
it was generating invalid data on the wire when sending the
PropertiesChanged signal for the Metadata property.

The issue was that if there was now no current track, GetInputMeta would
never be called and the the variant would never be populated with the
"a{sv}" structure that the call to dbus_message_iter_open_container
claimed it would be.

We now share the code that GetProperties used, which dealt with this
correctly, although now both use CurrentInput (which is what the signal
previously used) instead of CurrentPlayingItem (which is what
GetProperties previously used).
Signed-off-by: default avatarMirsal Ennaime <mirsal@videolan.org>
(cherry picked from commit 5460e18e20719255d4ed1461594fe72530a19f85)
Signed-off-by: default avatarRémi Denis-Courmont <remi@remlab.net>
parent 34cc9763
...@@ -4,10 +4,12 @@ ...@@ -4,10 +4,12 @@
* Copyright © 2006-2011 Rafaël Carré * Copyright © 2006-2011 Rafaël Carré
* Copyright © 2007-2011 Mirsal Ennaime * Copyright © 2007-2011 Mirsal Ennaime
* Copyright © 2009-2011 The VideoLAN team * Copyright © 2009-2011 The VideoLAN team
* Copyright © 2013 Alex Merry
* $Id$ * $Id$
* *
* Authors: Mirsal Ennaime <mirsal at mirsal fr> * Authors: Mirsal Ennaime <mirsal at mirsal fr>
* Rafaël Carré <funman at videolanorg> * Rafaël Carré <funman at videolanorg>
* Alex Merry <dev at randomguy3 me uk>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -676,30 +678,45 @@ DBUS_METHOD( LoopStatusSet ) ...@@ -676,30 +678,45 @@ DBUS_METHOD( LoopStatusSet )
REPLY_SEND; REPLY_SEND;
} }
static int
MarshalMetadata( intf_thread_t *p_intf, DBusMessageIter *container )
{
DBusMessageIter a;
input_item_t *p_item = 0;
input_thread_t *p_input;
if( ( p_input = playlist_CurrentInput( p_intf->p_sys->p_playlist ) ) ) {
p_item = input_GetItem( p_input );
if( p_item ) {
int result = GetInputMeta( p_item, container );
if (result != VLC_SUCCESS)
return result;
}
vlc_object_release( (vlc_object_t*) p_input );
}
if (!p_item) {
// avoid breaking the type marshalling
if( !dbus_message_iter_open_container( container, DBUS_TYPE_ARRAY, "{sv}", &a ) ||
!dbus_message_iter_close_container( container, &a ) ) {
return VLC_ENOMEM;
}
}
return VLC_SUCCESS;
}
DBUS_METHOD( Metadata ) DBUS_METHOD( Metadata )
{ {
REPLY_INIT; REPLY_INIT;
OUT_ARGUMENTS; OUT_ARGUMENTS;
DBusMessageIter v, a; DBusMessageIter v;
playlist_t *p_playlist = PL;
if( !dbus_message_iter_open_container( &args, DBUS_TYPE_VARIANT, if( !dbus_message_iter_open_container( &args, DBUS_TYPE_VARIANT,
"a{sv}", &v ) ) "a{sv}", &v ) )
return DBUS_HANDLER_RESULT_NEED_MEMORY; return DBUS_HANDLER_RESULT_NEED_MEMORY;
PL_LOCK; if( MarshalMetadata( p_this, &v ) != VLC_SUCCESS ||
playlist_item_t* p_item = playlist_CurrentPlayingItem( p_playlist );
if( p_item )
GetInputMeta( p_item->p_input, &v );
PL_UNLOCK;
if( ( !p_item &&
( !dbus_message_iter_open_container( &v, DBUS_TYPE_ARRAY, "{sv}", &a ) ||
!dbus_message_iter_close_container( &v, &a ) ) ) ||
!dbus_message_iter_close_container( &args, &v ) ) { !dbus_message_iter_close_container( &args, &v ) ) {
return DBUS_HANDLER_RESULT_NEED_MEMORY; return DBUS_HANDLER_RESULT_NEED_MEMORY;
} }
...@@ -891,20 +908,10 @@ PropertiesChangedSignal( intf_thread_t *p_intf, ...@@ -891,20 +908,10 @@ PropertiesChangedSignal( intf_thread_t *p_intf,
if( !strcmp( ppsz_properties[i], "Metadata" ) ) if( !strcmp( ppsz_properties[i], "Metadata" ) )
{ {
input_thread_t *p_input;
p_input = playlist_CurrentInput( p_intf->p_sys->p_playlist );
dbus_message_iter_open_container( &entry, dbus_message_iter_open_container( &entry,
DBUS_TYPE_VARIANT, "a{sv}", DBUS_TYPE_VARIANT, "a{sv}",
&variant ); &variant );
MarshalMetadata( p_intf, &variant );
if( p_input )
{
input_item_t *p_item = input_GetItem( p_input );
GetInputMeta( p_item, &variant );
vlc_object_release( p_input );
}
dbus_message_iter_close_container( &entry, &variant ); dbus_message_iter_close_container( &entry, &variant );
} }
else if( !strcmp( ppsz_properties[i], "PlaybackStatus" ) ) else if( !strcmp( ppsz_properties[i], "PlaybackStatus" ) )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment