[rygel] Load the external services dynamically



commit 80a8d40fce03d9622e9abab94979885a1dbb63e0
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Thu May 7 19:42:20 2009 +0300

    Load the external services dynamically
    
    We now talk to all the services on the bus that has the prefix
    "org.Rygel.MediaServer1." in their names. This currently doesn't work
    since Rygel is incapable of handling spaces in names. Should be easy to
    fix.
---
 .../external/rygel-external-content-dir.vala       |    9 +--
 src/plugins/external/rygel-external-plugin.vala    |   64 +++++++++++++++++---
 2 files changed, 58 insertions(+), 15 deletions(-)

diff --git a/src/plugins/external/rygel-external-content-dir.vala b/src/plugins/external/rygel-external-content-dir.vala
index 73d4fef..595e252 100644
--- a/src/plugins/external/rygel-external-content-dir.vala
+++ b/src/plugins/external/rygel-external-content-dir.vala
@@ -31,16 +31,13 @@ using Gee;
  * Implementation of External ContentDirectory service.
  */
 public class Rygel.ExternalContentDir : ContentDirectory {
-    private const string EXTERNAL_SERVICE = "org.Rygel.MediaServer1.PulseAudio";
-    private const string EXTERNAL_PATH = "/org/Rygel/MediaServer1/PulseAudio";
-
     // Pubic methods
     public override MediaContainer? create_root_container () {
-        //string friendly_name = this.root_device.get_friendly_name ();
+        var plugin = (ExternalPlugin) this.root_device.resource_factory;
 
         return new ExternalContainer ("0",
-                                      EXTERNAL_SERVICE,
-                                      EXTERNAL_PATH,
+                                      plugin.service_name,
+                                      plugin.root_object,
                                       null);
     }
 }
diff --git a/src/plugins/external/rygel-external-plugin.vala b/src/plugins/external/rygel-external-plugin.vala
index 10850f9..b88e83e 100644
--- a/src/plugins/external/rygel-external-plugin.vala
+++ b/src/plugins/external/rygel-external-plugin.vala
@@ -26,18 +26,64 @@ using Rygel;
 using Gee;
 using CStuff;
 
+private const string DBUS_SERVICE = "org.freedesktop.DBus";
+private const string DBUS_OBJECT = "/org/freedesktop/DBus";
+private const string DBUS_IFACE = "org.freedesktop.DBus";
+private const string PROPS_IFACE = "org.freedesktop.DBus.Properties";
+
+private const string OBJECT_IFACE = "org.Rygel.MediaObject1";
+private const string SERVICE_PREFIX = "org.Rygel.MediaServer1.";
+
 [ModuleInit]
 public void load_plugin (PluginLoader loader) {
-    Plugin plugin = new Plugin ("PulseAudio");
-
-    // We only implement a ContentDirectory service
-    var resource_info = new ResourceInfo (ContentDirectory.UPNP_ID,
-                                          ContentDirectory.UPNP_TYPE,
-                                          ContentDirectory.DESCRIPTION_PATH,
-                                          typeof (ExternalContentDir));
+    try {
+        DBus.Connection connection = DBus.Bus.get (DBus.BusType.SESSION);
 
-    plugin.add_resource (resource_info);
+        dynamic DBus.Object dbus_obj = connection.get_object (DBUS_SERVICE,
+                                                              DBUS_OBJECT,
+                                                              DBUS_IFACE);
 
-    loader.add_plugin (plugin);
+        string[] services = dbus_obj.ListNames ();
+        foreach (var service in services) {
+            if (service.has_prefix (SERVICE_PREFIX)) {
+                loader.add_plugin (new ExternalPlugin (connection, service));
+            }
+        }
+    } catch (DBus.Error error) {
+        critical ("Failed to fetch list of external services: %s\n",
+                error.message);
+    }
 }
 
+public class ExternalPlugin : Plugin {
+    // class-wide constants
+    public string service_name;
+    public string root_object;
+
+    public ExternalPlugin (DBus.Connection connection,
+                           string          service_name) {
+        // org.Rygel.MediaServer1.NAME => /org/Rygel/MediaServer1/NAME
+        var root_object = "/" + service_name.replace (".", "/");
+
+        // Create proxy to MediaObject iface to get the display name through
+        dynamic DBus.Object props = connection.get_object (service_name,
+                                                           root_object,
+                                                           PROPS_IFACE);
+        Value value;
+        props.Get (OBJECT_IFACE, "display-name", out value);
+        var title = value.get_string ();
+
+        base (title);
+
+        this.service_name = service_name;
+        this.root_object = root_object;
+
+        // We only implement a ContentDirectory service
+        var resource_info = new ResourceInfo (ContentDirectory.UPNP_ID,
+                                              ContentDirectory.UPNP_TYPE,
+                                              ContentDirectory.DESCRIPTION_PATH,
+                                              typeof (ExternalContentDir));
+
+        this.add_resource (resource_info);
+    }
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]