2 * Copyright (C) 2009 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>.
3 * Copyright (C) 2009,2010 Nokia Corporation.
5 * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
6 * <zeeshan.ali@nokia.com>
8 * This file is part of Rygel.
10 * Rygel is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * Rygel is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
29 private External.PluginFactory plugin_factory;
31 public void module_init (PluginLoader loader) {
33 plugin_factory = new External.PluginFactory (loader);
34 } catch (IOError error) {
35 critical ("Failed to fetch list of external services: %s\n",
40 public class Rygel.External.PluginFactory {
41 private const string SERVICE_PREFIX = "org.gnome.UPnP.MediaServer2.";
42 private const string GRILO_UPNP_PREFIX = SERVICE_PREFIX + "grl_upnp";
46 IconFactory icon_factory;
48 public PluginFactory (PluginLoader loader) throws IOError {
49 this.icon_factory = new IconFactory ();
51 this.dbus_obj = Bus.get_proxy_sync (BusType.SESSION,
56 this.load_plugins.begin ();
59 private async void load_plugins () throws IOError {
60 var services = yield this.dbus_obj.list_names ();
62 foreach (var service in services) {
63 if (service.has_prefix (SERVICE_PREFIX) &&
64 this.loader.get_plugin_by_name (service) == null) {
65 yield this.load_plugin_n_handle_error (service);
69 yield this.load_activatable_plugins ();
72 private async void load_activatable_plugins () throws IOError {
73 var services = yield this.dbus_obj.list_activatable_names ();
75 foreach (var service in services) {
76 if (service.has_prefix (SERVICE_PREFIX) &&
77 this.loader.get_plugin_by_name (service) == null) {
78 yield this.load_plugin_n_handle_error (service);
82 this.dbus_obj.name_owner_changed.connect (this.name_owner_changed);
85 private void name_owner_changed (DBusObject dbus_obj,
89 var plugin = this.loader.get_plugin_by_name (name);
92 if (old_owner != "" && new_owner == "") {
93 debug ("Service '%s' going down, marking it as unavailable",
95 plugin.available = false;
96 } else if (old_owner == "" && new_owner != "") {
97 debug ("Service '%s' up again, marking it as available", name);
98 plugin.available = true;
100 } else if (name.has_prefix (SERVICE_PREFIX)) {
101 // Ah, new plugin available, lets use it
102 this.load_plugin_n_handle_error.begin (name);
106 private async void load_plugin_n_handle_error (string service_name) {
108 yield this.load_plugin (service_name);
109 } catch (IOError error) {
110 warning ("Failed to load external plugin '%s': %s",
116 private async void load_plugin (string service_name) throws IOError {
117 if (service_name.has_prefix (GRILO_UPNP_PREFIX)) {
118 // We don't entertain UPnP sources
122 // org.gnome.UPnP.MediaServer1.NAME => /org/gnome/UPnP/MediaServer1/NAME
123 var root_object = "/" + service_name.replace (".", "/");
125 // Create proxy to MediaObject iface to get the display name through
126 Properties props = Bus.get_proxy_sync (BusType.SESSION,
130 HashTable<string,Variant> object_props;
131 HashTable<string,Variant> container_props;
133 object_props = yield props.get_all (MediaObjectProxy.IFACE);
134 container_props = yield props.get_all (MediaContainerProxy.IFACE);
136 var icon = yield this.icon_factory.create (service_name,
140 var value = object_props.lookup ("DisplayName");
142 title = (string) value;
144 title = service_name;
147 var child_count = (uint) container_props.lookup ("ChildCount");
148 var searchable = (bool) container_props.lookup ("Searchable");
150 var plugin = new External.Plugin (service_name,
157 this.loader.add_plugin (plugin);