summaryrefslogtreecommitdiff
path: root/src/plugins/mpris/rygel-mpris-plugin-factory.vala
blob: 91c47140f5d40c934070e8700f278beea08cb10e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * Copyright (C) 2009 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>.
 * Copyright (C) 2009,2010 Nokia Corporation.
 *
 * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
 *                               <zeeshan.ali@nokia.com>
 *
 * This file is part of Rygel.
 *
 * Rygel is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Rygel is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

using Rygel;
using Gee;
using FreeDesktop;

private MPRIS.PluginFactory plugin_factory;

public void module_init (PluginLoader loader) {
    try {
        plugin_factory = new MPRIS.PluginFactory (loader);
    } catch (IOError error) {
        message (_("Module '%s' could not connect to D-Bus session bus. "+
                   "Ignoring…"), MPRIS.Plugin.MODULE_NAME);
    }
}

public class Rygel.MPRIS.PluginFactory {
    private const string DBUS_SERVICE = "org.freedesktop.DBus";
    private const string DBUS_OBJECT = "/org/freedesktop/DBus";

    private const string SERVICE_PREFIX = "org.mpris.MediaPlayer2.";
    private const string MEDIA_PLAYER_PATH = "/org/mpris/MediaPlayer2";

    FreeDesktop.DBusObject dbus_obj;
    PluginLoader           loader;

    public PluginFactory (PluginLoader loader) throws IOError {
        this.dbus_obj = Bus.get_proxy_sync
                                        (BusType.SESSION,
                                         DBUS_SERVICE,
                                         DBUS_OBJECT,
                                         DBusProxyFlags.DO_NOT_LOAD_PROPERTIES);
        this.loader = loader;

        this.load_plugins.begin ();
    }

    private async void load_plugins () throws DBusError {
        var services = yield this.dbus_obj.list_names ();

        foreach (var service in services) {
            if (service.has_prefix (SERVICE_PREFIX) &&
                this.loader.get_plugin_by_name (service) == null) {
                yield this.load_plugin_n_handle_error (service);
            }
        }

        yield this.load_activatable_plugins ();
    }

    private async void load_activatable_plugins () throws DBusError {
        var services = yield this.dbus_obj.list_activatable_names ();

        foreach (var service in services) {
            if (service.has_prefix (SERVICE_PREFIX) &&
                this.loader.get_plugin_by_name (service) == null) {
                yield this.load_plugin_n_handle_error (service);
            }
        }

        this.dbus_obj.name_owner_changed.connect (this.name_owner_changed);
    }

    private void name_owner_changed (FreeDesktop.DBusObject dbus_obj,
                                     string                 name,
                                     string                 old_owner,
                                     string                 new_owner) {
        var plugin = this.loader.get_plugin_by_name (name);

        if (plugin != null) {
            if (old_owner != "" && new_owner == "") {
                debug ("Service '%s' going down, Deactivating it",
                       name);
                plugin.active = false;
            } else if (old_owner == "" && new_owner != "") {
                debug ("Service '%s' up again, activating it", name);
                plugin.active = true;
            }
        } else if (name.has_prefix (SERVICE_PREFIX)) {
            // Ah, new plugin available, lets use it
            this.load_plugin_n_handle_error.begin (name);
        }
    }

    private async void load_plugin_n_handle_error (string service_name) {
        if (loader.plugin_disabled (service_name)) {
            message ("Plugin '%s' disabled by user, ignoring..", service_name);

            return;
        }

        try {
            yield this.load_plugin (service_name);
        } catch (IOError error) {
            warning ("Failed to load MPRIS2 plugin '%s': %s",
                     service_name,
                     error.message);
        }
    }

    private async void load_plugin (string service_name) throws IOError {
        MediaPlayer.PlayerProxy player =
                                        yield Bus.get_proxy (BusType.SESSION,
                                                             service_name,
                                                             MEDIA_PLAYER_PATH);

        var plugin = new MPRIS.Plugin (service_name, player);

        this.loader.add_plugin (plugin);
    }
}