From b28241622081791ec4589d83a53078c768d4dea2 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 2 Dec 2010 19:35:49 +0000 Subject: moving in the right direction, registration happening on dbus watching --- src/Makefile.am | 2 ++ src/mpris2-controller.vala | 54 ++++++++----------------------- src/mpris2-interfaces.vala | 46 +++++++++++++++++++++++++++ src/mpris2-watcher.vala | 76 ++++++++++++++++++++++++++++++++++++++++++++ src/music-player-bridge.vala | 74 +++++++++++++++++------------------------- src/player-controller.vala | 2 +- src/sound-service.c | 4 +-- 7 files changed, 171 insertions(+), 87 deletions(-) create mode 100644 src/mpris2-interfaces.vala create mode 100644 src/mpris2-watcher.vala diff --git a/src/Makefile.am b/src/Makefile.am index 1362187..1c381f5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -60,6 +60,8 @@ music_bridge_VALASOURCES = \ metadata-menu-item.vala \ title-menu-item.vala \ player-controller.vala \ + mpris2-interfaces.vala \ + mpris2-watcher.vala \ mpris2-controller.vala \ player-item.vala \ familiar-players-db.vala \ diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 0be018a..c382e97 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -19,42 +19,15 @@ with this program. If not, see . //using DBus; using Dbusmenu; -[DBus (name = "org.mpris.MediaPlayer2")] -public interface MprisRoot : Object { - // properties - public abstract bool HasTracklist{owned get; set;} - public abstract bool CanQuit{owned get; set;} - public abstract bool CanRaise{owned get; set;} - public abstract string Identity{owned get; set;} - public abstract string DesktopEntry{owned get; set;} - // methods - public abstract async void Quit() throws IOError; - public abstract async void Raise() throws IOError; -} - -/*[DBus (name = "org.mpris.MediaPlayer2.Player")] -public interface MprisPlayer : DBus.Object { - - // properties - public abstract HashTable Metadata{owned get; set;} - public abstract int32 Position{owned get; set;} - public abstract string PlaybackStatus{owned get; set;} - // methods - public abstract async void PlayPause() throws DBus.Error; - public abstract async void Next() throws DBus.Error; - public abstract async void Previous() throws DBus.Error; - // signals - public signal void Seeked(int64 new_position); -} -[DBus (name = "org.freedesktop.DBus.Properties")] -public interface FreeDesktopProperties : DBus.Object{ +/*[DBus (name = "org.freedesktop.DBus.Properties")] + public interface FreeDesktopProperties : DBus.Object{ // signals public signal void PropertiesChanged(string source, HashTable changed_properties, string[] invalid); } -*/ + /* This class will entirely replace mpris-controller.vala hence why there is no point in trying to get encorporate both into the same object model. @@ -63,8 +36,8 @@ public class Mpris2Controller : GLib.Object { public static const string root_interface = "org.mpris.MediaPlayer2" ; public MprisRoot mpris2_root {get; construct;} - /*public MprisPlayer player {get; construct;} - public FreeDesktopProperties properties_interface {get; construct;}*/ + public MprisPlayer player {get; construct;} + //public FreeDesktopProperties properties_interface {get; construct;} public PlayerController owner {get; construct;} @@ -75,12 +48,13 @@ public class Mpris2Controller : GLib.Object construct{ try { - - this.mpris2_root = Bus.get_proxy_sync (BusType.SESSION, root_interface.concat(".").concat(this.owner.mpris_name), - "/org/mpris/MediaPlayer2"); - /*this.player = (MprisPlayer) connection.get_object (root_interface.concat(".").concat(this.owner.mpris_name), - "/org/mpris/MediaPlayer2", - root_interface.concat(".Player")); + this.mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, + root_interface.concat(".").concat(this.owner.mpris_name), + "/org/mpris/MediaPlayer2"); + this.player = Bus.get_proxy_sync ( BusType.SESSION, + root_interface.concat(".").concat(this.owner.mpris_name), + "/org/mpris/MediaPlayer2" ); + /* this.properties_interface = (FreeDesktopProperties) connection.get_object("org.freedesktop.Properties.PropertiesChanged", "/org/mpris/MediaPlayer2"); this.properties_interface.PropertiesChanged += property_changed_cb;*/ @@ -162,7 +136,7 @@ public class Mpris2Controller : GLib.Object public void transport_update(TransportMenuitem.action command) { debug("transport_event input = %i", (int)command); - /*if(command == TransportMenuitem.action.PLAY_PAUSE){ + if(command == TransportMenuitem.action.PLAY_PAUSE){ this.player.PlayPause.begin(); } else if(command == TransportMenuitem.action.PREVIOUS){ @@ -170,7 +144,7 @@ public class Mpris2Controller : GLib.Object } else if(command == TransportMenuitem.action.NEXT){ this.player.Next.begin(); - }*/ + } } public bool connected() diff --git a/src/mpris2-interfaces.vala b/src/mpris2-interfaces.vala new file mode 100644 index 0000000..ef62aba --- /dev/null +++ b/src/mpris2-interfaces.vala @@ -0,0 +1,46 @@ +/* +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + + +[DBus (name = "org.mpris.MediaPlayer2")] +public interface MprisRoot : Object { + // properties + public abstract bool HasTracklist{owned get; set;} + public abstract bool CanQuit{owned get; set;} + public abstract bool CanRaise{owned get; set;} + public abstract string Identity{owned get; set;} + public abstract string DesktopEntry{owned get; set;} + // methods + public abstract async void Quit() throws IOError; + public abstract async void Raise() throws IOError; +} + +[DBus (name = "org.mpris.MediaPlayer2.Player")] +public interface MprisPlayer : Object { + // properties + public abstract HashTable Metadata{owned get; set;} + public abstract int32 Position{owned get; set;} + public abstract string PlaybackStatus{owned get; set;} + // methods + public abstract async void PlayPause() throws IOError; + public abstract async void Next() throws IOError; + public abstract async void Previous() throws IOError; + // signals + public signal void Seeked(int64 new_position); +} diff --git a/src/mpris2-watcher.vala b/src/mpris2-watcher.vala new file mode 100644 index 0000000..55212ec --- /dev/null +++ b/src/mpris2-watcher.vala @@ -0,0 +1,76 @@ +/* +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +// TODO: Until match rules are properly supported in vala we need to explicitly +// watch for each client inorder to facilitate proper registration. + +public class Mpris2Watcher : GLib.Object +{ + public MusicPlayerBridge the_bridge {get; construct;} + const string BANSHEE_BUS_NAME = "org.mpris.MediaPlayer2.banshee"; + private MprisRoot mpris2_root; + private DBusConnection connection; + + public Mpris2Watcher ( MusicPlayerBridge bridge ) + { + GLib.Object(the_bridge: bridge); + } + + construct{ + try { + this.connection = Bus.get_sync ( BusType.SESSION ); + GLib.BusNameAppearedCallback banshee_change_cb = (GLib.BusNameAppearedCallback)banshee_appeared; + GLib.BusNameVanishedCallback banshee_gone_cb = (GLib.BusNameVanishedCallback)banshee_disappeared; + Bus.watch_name_on_connection ( this.connection, + BANSHEE_BUS_NAME, + BusNameWatcherFlags.AUTO_START, + banshee_change_cb, + banshee_gone_cb ); + } + catch ( IOError e ){ + warning( "Mpris2watcher could not set up a watch for mpris clients appearing on the bus: %s", + e.message ); + } + } + + private void banshee_appeared ( GLib.DBusConnection connection, + string name, + string name_owner ) + { + try { + this.mpris2_root = Bus.get_proxy_sync ( BusType.SESSION, + BANSHEE_BUS_NAME, + "/org/mpris/MediaPlayer2" ); + this.the_bridge.client_has_become_available ( this.mpris2_root.DesktopEntry ); + debug ( "On Name Appeared - name %s, name_owner %s", this.mpris2_root.DesktopEntry, name_owner ); + } + catch ( IOError e ){ + warning( "Mpris2watcher could not instantiate an mpris root for banshee: %s", + e.message ); + } + } + + private void banshee_disappeared ( GLib.DBusConnection connection, + string name, + string name_owner ) + { + debug ( "On Name Disappeared - name %s, name_owner %s", name, name_owner ); + } + +} \ No newline at end of file diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index 3fc7efa..8d7998e 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -26,13 +26,14 @@ public class MusicPlayerBridge : GLib.Object private Dbusmenu.Menuitem root_menu; private HashMap registered_clients; private FamiliarPlayersDB playersDB; - + private Mpris2Watcher watcher; + private const string DESKTOP_PREFIX = "/usr/share/applications/"; public MusicPlayerBridge() { playersDB = new FamiliarPlayersDB(); registered_clients = new HashMap (); } - + private void try_to_add_inactive_familiar_clients(){ foreach(string app in this.playersDB.records()){ if(app == null){ @@ -79,41 +80,39 @@ public class MusicPlayerBridge : GLib.Object listener_get_server_property_cb cb = (listener_get_server_property_cb)desktop_info_callback; this.listener.server_get_desktop(object, cb, this); } - } + }*/ - private void desktop_info_callback ( Indicate.ListenerServer server, - owned string path, - void* data ) - { - MusicPlayerBridge bridge = data as MusicPlayerBridge; - AppInfo? app_info = create_app_info(path); + public void client_has_become_available ( string desktop_file_name ) + { + string path = DESKTOP_PREFIX.concat ( desktop_file_name.concat( ".desktop" ) ); + AppInfo? app_info = create_app_info ( path ); if ( app_info == null ){ warning ( "Could not create app_info for path %s \n Getting out of here ", path); return; } - var mpris_key = determine_key(path); + var mpris_key = determine_key ( desktop_file_name ); - if(bridge.playersDB.already_familiar(path) == false){ - debug("New client has registered that we have seen before: %s", path); - bridge.playersDB.insert(path); - PlayerController ctrl = new PlayerController ( bridge.root_menu, + if ( this.playersDB.already_familiar ( path ) == false ){ + debug("New client has registered that we have not seen before: %s", desktop_file_name ); + this.playersDB.insert ( path ); + PlayerController ctrl = new PlayerController ( this.root_menu, app_info, mpris_key, playersDB.fetch_icon_name(path), - bridge.calculate_menu_position(), + this.calculate_menu_position(), PlayerController.state.READY ); - bridge.registered_clients.set(mpris_key, ctrl); - debug("successfully created appinfo and instance from path and set it on the respective instance"); + this.registered_clients.set ( mpris_key, ctrl ); + debug ( "successfully created appinfo and instance from path and set it on the respective instance" ); } else{ - bridge.registered_clients[mpris_key].update_state(PlayerController.state.READY); - bridge.registered_clients[mpris_key].activate(); + this.registered_clients[mpris_key].update_state ( PlayerController.state.READY ); + this.registered_clients[mpris_key].activate ( ); debug("Ignoring desktop file path callback because the db cache file has it already: %s \n", path); } } - public void on_server_removed(Indicate.ListenerServer object, string type) + /*public void on_server_removed(Indicate.ListenerServer object, string type) { debug("MusicPlayerBridge -> on_server_removed with value %s", type); if(server_is_not_of_interest(type)) return; @@ -125,44 +124,31 @@ public class MusicPlayerBridge : GLib.Object debug("Successively offlined client %s", tmp[tmp.length - 1]); } } - } - - private bool server_is_not_of_interest(string type){ - if (type == null) return true; - if (type.contains("music") == false) { - debug("server is of no interest, it is not an music server"); - return true; - } - return false; }*/ + public void set_root_menu_item(Dbusmenu.Menuitem menu) { this.root_menu = menu; - try_to_add_inactive_familiar_clients(); + this.try_to_add_inactive_familiar_clients(); + this.watcher = new Mpris2Watcher (this) ; } - public static AppInfo? create_app_info(string path) + public static AppInfo? create_app_info ( string path ) { - DesktopAppInfo info = new DesktopAppInfo.from_filename(path); - if(path == null){ - warning("Could not create a desktopappinfo instance from app: %s", path); + DesktopAppInfo info = new DesktopAppInfo.from_filename ( path ) ; + if ( path == null || info == null ){ + warning ( "Could not create a desktopappinfo instance from app: %s", path ); return null; } - GLib.AppInfo app_info = info as GLib.AppInfo; + GLib.AppInfo app_info = info as GLib.AppInfo; return app_info; } - /** - TODO: clean up - **/ - private static string? determine_key(owned string path) + private static string? determine_key(owned string name) { - var tokens = path.split("/"); - if ( tokens.length < 2) return null; - var filename = tokens[tokens.length - 1]; - var result = filename.split(".")[0]; - var temp = result.split("-"); + string result = name; + var temp = name.split("-"); if (temp.length > 1){ result = temp[0]; } diff --git a/src/player-controller.vala b/src/player-controller.vala index 46add60..3c9b0ff 100644 --- a/src/player-controller.vala +++ b/src/player-controller.vala @@ -114,7 +114,7 @@ public class PlayerController : GLib.Object public void vanish() { foreach(Dbusmenu.Menuitem item in this.custom_items){ - root_menu.child_delete(item); + root_menu.child_delete(item); } } diff --git a/src/sound-service.c b/src/sound-service.c index f19379d..51f5f37 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -41,8 +41,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) if (mainloop != NULL) { g_debug("Service shutdown !"); //TODO: uncomment for release !! - close_pulse_activites(); - g_main_loop_quit(mainloop); + //close_pulse_activites(); + //g_main_loop_quit(mainloop); } return; } -- cgit v1.2.3