From 9f10c1e5b7a7ceac671d23cdfef2176d4ac8e74d Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Sun, 9 Jan 2011 08:14:43 +0000 Subject: interface introspection underway@ --- configure.ac | 3 +- src/Makefile.am | 3 +- src/mpris2-controller.vala | 26 ++++++++-------- src/mpris2-watcher.vala | 70 ++++++++++++++++++++++++++++++++++++++++---- src/music-player-bridge.vala | 6 ++-- src/sound-service.c | 4 +-- 6 files changed, 88 insertions(+), 24 deletions(-) diff --git a/configure.ac b/configure.ac index c9227cd..928ffff 100644 --- a/configure.ac +++ b/configure.ac @@ -55,7 +55,8 @@ PKG_CHECK_MODULES(SOUNDSERVICE, dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSION indicator >= $INDICATOR_REQUIRED_VERSION indicate >= $INDICATE_REQUIRED_VERSION gee-1.0 - gio-unix-2.0) + gio-unix-2.0 + libxml-2.0) AC_SUBST(SOUNDSERVICE_CFLAGS) AC_SUBST(SOUNDERVICE_LIBS) diff --git a/src/Makefile.am b/src/Makefile.am index 82830e1..57f52d4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -81,7 +81,8 @@ music_bridge_VALAFLAGS = \ --pkg common-defs \ --pkg gio-2.0 \ --pkg gio-unix-2.0 \ - --pkg gdk-pixbuf-2.0 + --pkg gdk-pixbuf-2.0 \ + --pkg libxml-2.0 $(MAINTAINER_VALAFLAGS) diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 5f98541..7b512a3 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -53,7 +53,6 @@ public class Mpris2Controller : GLib.Object this.playlists = Bus.get_proxy_sync ( BusType.SESSION, this.owner.dbus_name, "/org/mpris/MediaPlayer2" ); - this.properties_interface = Bus.get_proxy_sync ( BusType.SESSION, "org.freedesktop.Properties.PropertiesChanged", "/org/mpris/MediaPlayer2" ); @@ -95,9 +94,8 @@ public class Mpris2Controller : GLib.Object metadata.populated(MetadataMenuitem.attributes_format())); } Variant? playlist_v = changed_properties.lookup("ActivePlaylist"); - if ( playlist_v != null ){ + if ( playlist_v != null && this.playlists_support_exist() ){ this.fetch_active_playlist(); - //Timeout.add ( 200, fetch_active_playlist ); } } @@ -154,8 +152,12 @@ public class Mpris2Controller : GLib.Object GLib.HashTable? cleaned_metadata = this.clean_metadata(); this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata, MetadataMenuitem.attributes_format()); - this.fetch_playlists(); - this.fetch_active_playlist(); + + /*if ( playlists_support_exist() == true ){ + debug ("it thinks that there is a valid playlist interface"); + this.fetch_playlists(); + this.fetch_active_playlist(); + }*/ } public void transport_update(TransportMenuitem.action command) @@ -174,8 +176,6 @@ public class Mpris2Controller : GLib.Object public void fetch_playlists() { - if (this.playlists == null) return; - PlaylistDetails[] current_playlists = this.playlists.GetPlaylists(0, 10, "Alphabetical", @@ -189,9 +189,9 @@ public class Mpris2Controller : GLib.Object } private void fetch_active_playlist() - { - if (this.playlists == null && this.playlists.ActivePlaylist.valid == false){ - warning("Playlists object is null or we don't have an active playlist"); + { + if (this.playlists.ActivePlaylist.valid == false){ + debug("We don't have an active playlist"); } PlaylistsMenuitem playlists_item = this.owner.custom_items[PlayerController.widget_order.PLAYLISTS] as PlaylistsMenuitem; playlists_item.update_active_playlist ( this.playlists.ActivePlaylist.details ); @@ -212,10 +212,10 @@ public class Mpris2Controller : GLib.Object public void activate_playlist (ObjectPath path) { - if(this.playlists == null){ - warning("playlists mpris instance is null !"); - return; + if ( playlists_support_exist() == false ){ + return; } + try{ this.playlists.ActivatePlaylist.begin(path); } diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala index 7814975..f572ab7 100644 --- a/src/mpris2-watcher.vala +++ b/src/mpris2-watcher.vala @@ -17,6 +17,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +using Xml; + [DBus (name = "org.freedesktop.DBus")] public interface FreeDesktopObject: Object { public abstract async string[] list_names() throws IOError; @@ -25,6 +27,16 @@ public interface FreeDesktopObject: Object { string new_owner ); } +[DBus (name = "org.freedesktop.DBus.Introspectable")] +public interface FreeDesktopIntrospectable: Object { + public abstract string introspect() throws IOError; +} + +public errordomain XmlError { + FILE_NOT_FOUND, + XML_DOCUMENT_EMPTY +} + public class Mpris2Watcher : GLib.Object { private const string FREEDESKTOP_SERVICE = "org.freedesktop.DBus"; @@ -33,14 +45,14 @@ public class Mpris2Watcher : GLib.Object private const string MPRIS_MEDIA_PLAYER_PATH = "/org/mpris/MediaPlayer2"; FreeDesktopObject fdesktop_obj; - + public signal void client_appeared ( string desktop_file_name, string dbus_name ); public signal void client_disappeared ( string dbus_name ); public Mpris2Watcher () { } - + construct { try { @@ -76,21 +88,69 @@ public class Mpris2Watcher : GLib.Object } } - private MprisRoot? create_mpris_root(string name){ + private MprisRoot? create_mpris_root ( string name ){ MprisRoot mpris2_root = null; if ( name.has_prefix (MPRIS_PREFIX) ){ try { mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, - name, - MPRIS_MEDIA_PLAYER_PATH ); + name, + MPRIS_MEDIA_PLAYER_PATH ); } catch (IOError e){ warning( "Mpris2watcher could not create a root interface: %s", e.message ); } } + this.supports_playlists(name); return mpris2_root; } + + private bool supports_playlists ( string name ) + { + FreeDesktopIntrospectable introspectable; + try { + introspectable = Bus.get_proxy_sync ( BusType.SESSION, + name, + MPRIS_MEDIA_PLAYER_PATH ); + var results = introspectable.introspect(); + return this.parse_interfaces (results); + } + catch (IOError e){ + warning( "Could not create an introspectable object: %s", + e.message ); + } + return false; + } + + private bool parse_interfaces( string interface_info ) + { + //parse the document from path + debug ("attempting to parse %s", interface_info); + Xml.Doc* xml_doc = Parser.parse_doc (interface_info); + if (xml_doc == null) { + warning ("Mpris2Watcher - parse-interfaces - failed to instantiate xml doc"); + return false; + } + //get the root node. notice the dereferencing operator -> instead of . + Xml.Node* root_node = xml_doc->get_root_element (); + if (root_node == null) { + //free the document manually before throwing because the garbage collector can't work on pointers + delete xml_doc; + warning ("Mpris2Watcher - the interface info xml is empty"); + return false; + } + + //let's parse those nodes + for (Xml.Node* iter = root_node->children; iter != null; iter = iter->next) { + //spaces btw. tags are also nodes, discard them + if (iter->type != ElementType.ELEMENT_NODE) + continue; + string node_name = iter->name; //get the node's name + debug ( "this dbus object has interface %s ", node_name ); + } + delete xml_doc; + return false; + } // At startup check to see if there are clients up that we are interested in // More relevant for development and daemon's like mpd. diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index c7391cf..10c333a 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -82,8 +82,9 @@ public class MusicPlayerBridge : GLib.Object return; } if (desktop in this.settings_manager.fetch_blacklist()) { - debug ("Client %s attempting to register but it has been blacklisted", + debug ("Client %s attempting to register but I'm afraid it is blacklisted", desktop); + return; } debug ( "client_has_become_available %s", desktop ); @@ -118,7 +119,8 @@ public class MusicPlayerBridge : GLib.Object public void client_has_vanished ( string mpris_root_interface ) { - debug("MusicPlayerBridge -> on_server_removed with value %s", mpris_root_interface); + debug("MusicPlayerBridge -> client with dbus interface %s has vanished", + mpris_root_interface ); if (root_menu != null){ debug("attempt to remove %s", mpris_root_interface); var mpris_key = determine_key ( mpris_root_interface ); diff --git a/src/sound-service.c b/src/sound-service.c index 98f1881..defcb94 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -40,8 +40,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) { if (mainloop != NULL) { g_debug("Service shutdown !"); - close_pulse_activites(); - g_main_loop_quit(mainloop); + //close_pulse_activites(); + //g_main_loop_quit(mainloop); } return; } -- cgit v1.2.3