aboutsummaryrefslogtreecommitdiff
path: root/src/music-player-bridge.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/music-player-bridge.vala')
-rw-r--r--src/music-player-bridge.vala256
1 files changed, 141 insertions, 115 deletions
diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala
index f13c2f4..327a775 100644
--- a/src/music-player-bridge.vala
+++ b/src/music-player-bridge.vala
@@ -17,151 +17,177 @@ You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-using Indicate;
using Dbusmenu;
using Gee;
using GLib;
public class MusicPlayerBridge : GLib.Object
{
- private Listener listener;
+ private SettingsManager settings_manager;
private Dbusmenu.Menuitem root_menu;
- private HashMap<string, PlayerController> registered_clients;
- private FamiliarPlayersDB playersDB;
-
+ private HashMap<string, PlayerController> registered_clients;
+ private Mpris2Watcher watcher;
+ private const string DESKTOP_PREFIX = "/usr/share/applications/";
+ private Settings settings;
+
public MusicPlayerBridge()
{
- playersDB = new FamiliarPlayersDB();
- registered_clients = new HashMap<string, PlayerController> ();
- listener = Listener.ref_default();
- listener.server_added.connect(on_server_added);
- listener.server_removed.connect(on_server_removed);
+ }
+
+ construct{
+ this.registered_clients = new HashMap<string, PlayerController> ();
+ this.settings_manager = new SettingsManager();
+ this.settings_manager.blacklist_updates.connect ( this.on_blacklist_update );
+ }
+
+ private void on_blacklist_update ( string[] blacklist )
+ {
+ debug("some blacklist update");
}
- private void try_to_add_inactive_familiar_clients(){
- foreach(string app in this.playersDB.records()){
- if(app == null){
- warning("App string in keyfile is null therefore moving on to next player");
- continue;
- }
-
- debug("attempting to make an app info from %s", app);
-
- DesktopAppInfo info = new DesktopAppInfo.from_filename(app);
+ private void try_to_add_inactive_familiar_clients()
+ {
+ foreach ( string desktop in this.settings_manager.fetch_interested()){
+ debug ( "interested client found : %s", desktop );
+ string path = DESKTOP_PREFIX.concat ( desktop.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);
+ continue;
+ }
+ var mpris_key = determine_key ( path );
+ PlayerController ctrl = new PlayerController ( this.root_menu,
+ app_info,
+ null,
+ this.fetch_icon_name(path),
+ calculate_menu_position(),
+ PlayerController.state.OFFLINE );
+ this.registered_clients.set(mpris_key, ctrl);
+ }
+ }
- if(info == null){
- warning("Could not create a desktopappinfo instance from app,: %s , moving on to the next client", app);
- continue;
- }
-
- GLib.AppInfo app_info = info as GLib.AppInfo;
- var mpris_key = determine_key(app);
- PlayerController ctrl = new PlayerController(this.root_menu,
- app_info,
- mpris_key,
- playersDB.fetch_icon_name(app),
- calculate_menu_position(),
- PlayerController.state.OFFLINE);
- this.registered_clients.set(mpris_key, ctrl);
- }
- }
-
- private int calculate_menu_position()
- {
- if(this.registered_clients.size == 0){
- return 2;
- }
- else{
- return (2 + (this.registered_clients.size * PlayerController.WIDGET_QUANTITY));
- }
- }
-
- public void on_server_added(Indicate.ListenerServer object, string type)
+ private int calculate_menu_position()
{
- debug("MusicPlayerBridge -> on_server_added with value %s", type);
- if(server_is_not_of_interest(type)) return;
- if ( this.root_menu != null ){
- listener_get_server_property_cb cb = (listener_get_server_property_cb)desktop_info_callback;
- this.listener.server_get_desktop(object, cb, this);
- }
+ if(this.registered_clients.size == 0){
+ return 2;
+ }
+ else{
+ return (2 + (this.registered_clients.size * PlayerController.WIDGET_QUANTITY));
+ }
}
- 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, string dbus_name )
+ {
+ if (desktop == null || desktop == ""){
+ warning("Client %s attempting to register without desktop entry being set on the mpris root",
+ dbus_name);
+ return;
+ }
+ debug ( "client_has_become_available %s", desktop );
+ string path = DESKTOP_PREFIX.concat ( desktop.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);
-
- 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,
- app_info,
- mpris_key,
- playersDB.fetch_icon_name(path),
- bridge.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");
- }
- else{
- bridge.registered_clients[mpris_key].update_state(PlayerController.state.READY);
- bridge.registered_clients[mpris_key].activate();
- debug("Ignoring desktop file path callback because the db cache file has it already: %s \n", path);
- }
- }
+ var mpris_key = determine_key ( path );
+ // Are we sure clients will appear like this with the new registration method in place.
+ if ( this.registered_clients.has_key (mpris_key) == false ){
+ debug("New client has registered that we have not seen before: %s", dbus_name );
+ PlayerController ctrl = new PlayerController ( this.root_menu,
+ app_info,
+ dbus_name,
+ this.fetch_icon_name(path),
+ this.calculate_menu_position(),
+ PlayerController.state.READY );
+ this.registered_clients.set ( mpris_key, ctrl );
+ debug ( "Have not seen this %s before, new controller created.", desktop );
+ this.settings_manager.add_interested ( desktop );
+ debug ( "application added to the interested list" );
+ }
+ else{
+ this.registered_clients[mpris_key].update_state ( PlayerController.state.READY );
+ this.registered_clients[mpris_key].activate ( dbus_name );
+ debug("Application has already registered - awaken the hibernation: %s \n", dbus_name );
+ }
+ }
- public void on_server_removed(Indicate.ListenerServer object, string type)
+ public void client_has_vanished ( string mpris_root_interface )
{
- debug("MusicPlayerBridge -> on_server_removed with value %s", type);
- if(server_is_not_of_interest(type)) return;
- if (root_menu != null){
- var tmp = type.split(".");
- debug("attempt to remove %s", tmp[tmp.length-1]);
- if(tmp.length > 0){
- registered_clients[tmp[tmp.length - 1]].hibernate();
- debug("Successively offlined client %s", tmp[tmp.length - 1]);
+ debug("MusicPlayerBridge -> on_server_removed with value %s", mpris_root_interface);
+ if (root_menu != null){
+ debug("attempt to remove %s", mpris_root_interface);
+ var mpris_key = determine_key ( mpris_root_interface );
+ if ( mpris_key != null ){
+ registered_clients[mpris_key].hibernate();
+ debug("Successively offlined client %s", mpris_key);
}
- }
- }
-
- 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)
+ }
+
+ public void set_root_menu_item ( Dbusmenu.Menuitem menu )
{
- this.root_menu = menu;
- try_to_add_inactive_familiar_clients();
+ this.root_menu = menu;
+ this.watcher = new Mpris2Watcher ();
+ this.watcher.client_appeared += this.client_has_become_available;
+ this.watcher.client_disappeared += this.client_has_vanished;
+ this.try_to_add_inactive_familiar_clients();
}
- 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);
- return null;
- }
- GLib.AppInfo app_info = info as GLib.AppInfo;
- return app_info;
- }
+ private static AppInfo? create_app_info ( string 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;
+ return app_info;
+ }
+
+ private static string? fetch_icon_name(string desktop_path)
+ {
+ KeyFile desktop_keyfile = new KeyFile ();
+ try{
+ desktop_keyfile.load_from_file (desktop_path, KeyFileFlags.NONE);
+ }
+ catch(GLib.FileError error){
+ warning("Error loading keyfile - FileError");
+ return null;
+ }
+ catch(GLib.KeyFileError error){
+ warning("Error loading keyfile - KeyFileError");
+ return null;
+ }
+
+ try{
+ return desktop_keyfile.get_string (KeyFileDesktop.GROUP,
+ KeyFileDesktop.KEY_ICON);
+ }
+ catch(GLib.KeyFileError error){
+ warning("Error trying to fetch the icon name from the keyfile");
+ return null;
+ }
+ }
+ /*
+ Messy but necessary method to consolidate desktop filesnames and mpris dbus names
+ into the one single word string (used as the key in the players hash).
+ So this means that we can determine the key for the players_hash from the
+ dbus interface name or the desktop file name.
+ */
private static string? determine_key(owned string path)
{
- var tokens = path.split("/");
- if ( tokens.length < 2) return null;
+ var tokens = path.split( "/" );
+ if ( tokens.length < 2 ){
+ // try to split on "."
+ tokens = path.split(".");
+ if ( tokens.length < 2 ){
+ // don't know what this is
+ return null;
+ }
+ }
var filename = tokens[tokens.length - 1];
var result = filename.split(".")[0];
var temp = result.split("-");