From: Zeeshan Ali (Khattak) Date: Mon, 14 Sep 2009 15:34:29 +0000 (+0300) Subject: external: Fetch items on demand X-Git-Tag: RYGEL_0_4~92 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=22d1b33c61a51d1d87c917c6b9dc927a310fd45d;p=profile%2Fivi%2Frygel.git external: Fetch items on demand --- diff --git a/src/plugins/external/rygel-external-container.vala b/src/plugins/external/rygel-external-container.vala index b1e4dd9..9946eb5 100644 --- a/src/plugins/external/rygel-external-container.vala +++ b/src/plugins/external/rygel-external-container.vala @@ -44,7 +44,7 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer { public string service_name; private string object_path; - private ArrayList media_objects; + private ArrayList containers; public ExternalContainer (string id, string service_name, @@ -57,7 +57,7 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer { this.object_path = object_path; this.host_ip = host_ip; - this.media_objects = new ArrayList (); + this.containers = new ArrayList (); try { DBus.Connection connection = DBus.Bus.get (DBus.BusType.SESSION); @@ -75,12 +75,13 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer { object_path, CONTAINER_IFACE); - this.fetch_media_objects (); + this.update_container (); this.actual_container.Updated += this.on_container_updated; - } catch (DBus.Error error) { - critical ("Failed to fetch root media objects: %s\n", - error.message); + } catch (GLib.Error err) { + critical ("Failed to fetch information about container '%s': %s\n", + this.id, + err.message); } } @@ -88,14 +89,40 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer { uint max_count, Cancellable? cancellable, AsyncReadyCallback callback) { - uint stop = offset + max_count; + var media_objects = new ArrayList (); + + // First add the child containers + media_objects.add_all (this.containers); + + // Then get and add the child items + Value value; + this.props.Get (CONTAINER_IFACE, "Items", out value); + unowned PtrArray obj_paths = (PtrArray) value.get_boxed (); + if (obj_paths.len > 0) { + for (var i = 0; i < obj_paths.len; i++) { + var obj_path = (ObjectPath) obj_paths.pdata[i]; + + try { + var item = new ExternalItem.for_path (obj_path, this); + + media_objects.add (item); + } catch (GLib.Error err) { + warning ("Error initializable item at '%s': %s. Ignoring..", + obj_path, + err.message); + } + } + } + + uint stop = offset + max_count; stop = stop.clamp (0, this.child_count); - var containers = this.media_objects.slice ((int) offset, (int) stop); + + var children = media_objects.slice ((int) offset, (int) stop); var res = new Rygel.SimpleAsyncResult> (this, callback); - res.data = containers; + res.data = children; res.complete_in_idle (); } @@ -109,10 +136,17 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer { public override void find_object (string id, Cancellable? cancellable, AsyncReadyCallback callback) { - MediaObject media_object = find_object_sync (id); - var res = new Rygel.SimpleAsyncResult (this, callback); + MediaObject media_object = find_container (id); + if (media_object == null && ExternalItem.id_valid (id)) { + try { + media_object = new ExternalItem.for_id (id, this); + } catch (GLib.Error err) { + res.error = err; + } + } + res.data = media_object; res.complete_in_idle (); } @@ -120,7 +154,12 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer { public override MediaObject? find_object_finish (AsyncResult res) throws GLib.Error { var simple_res = (Rygel.SimpleAsyncResult) res; - return simple_res.data; + + if (simple_res.error != null) { + throw simple_res.error; + } else { + return simple_res.data; + } } public string substitute_keywords (string title) { @@ -135,32 +174,31 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer { } // Private methods - private MediaObject? find_object_sync (string id) { - MediaObject obj = null; + private MediaContainer? find_container (string id) { + MediaContainer container = null; - foreach (var tmp in this.media_objects) { + foreach (var tmp in this.containers) { if (id == tmp.id) { - obj = tmp; - } else if (tmp is ExternalContainer) { + container = tmp; + } else { // Check it's children - var container = (ExternalContainer) tmp; - - obj = container.find_object_sync (id); + container = tmp.find_container (id); } - if (obj != null) { + if (container != null) { break; } } - return obj; + return container; } - private void fetch_media_objects () throws GLib.Error { - HashTable all_props = - this.props.GetAll (CONTAINER_IFACE); + private void update_container () throws GLib.Error { + this.containers.clear (); + + Value value; + this.props.Get (CONTAINER_IFACE, "Containers", out value); - var value = all_props.lookup ("Containers"); unowned PtrArray obj_paths = (PtrArray) value.get_boxed (); if (obj_paths.len > 0) { for (var i = 0; i < obj_paths.len; i++) { @@ -171,30 +209,23 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer { obj_path, this.host_ip, this); - this.media_objects.add (container); - } - } - - value = all_props.lookup ("Items"); - obj_paths = (PtrArray) value.get_boxed (); - if (obj_paths.len > 0) { - for (var i = 0; i < obj_paths.len; i++) { - var obj_path = (ObjectPath) obj_paths.pdata[i]; - this.media_objects.add (new ExternalItem (obj_path, - this)); + this.containers.add (container); } } - this.child_count = this.media_objects.size; + this.child_count = this.containers.size; + this.props.Get (CONTAINER_IFACE, "ItemCount", out value); + this.child_count = value.get_int (); } private void on_container_updated (dynamic DBus.Object actual_container) { - // Re-fetch the objects - this.media_objects.clear (); try { - this.fetch_media_objects (); + // Update our information about the container + this.update_container (); } catch (GLib.Error err) { - warning ("Failed to re-fetch media objects: %s\n", err.message); + warning ("Failed to update information about container '%s': %s\n", + this.id, + err.message); } // and signal the clients diff --git a/src/plugins/external/rygel-external-item.vala b/src/plugins/external/rygel-external-item.vala index fe5131e..9f078e3 100644 --- a/src/plugins/external/rygel-external-item.vala +++ b/src/plugins/external/rygel-external-item.vala @@ -33,10 +33,26 @@ public class Rygel.ExternalItem : Rygel.MediaItem { private static string OBJECT_IFACE = "org.gnome.UPnP.MediaObject1"; private static string ITEM_IFACE = "org.gnome.UPnP.MediaItem1"; - public ExternalItem (string object_path, - ExternalContainer parent) - throws GLib.Error { - base ("item:" + object_path, + public ExternalItem.for_path (string object_path, + ExternalContainer parent) throws GLib.Error { + this ("item:" + object_path, object_path, parent); + } + + public ExternalItem.for_id (string id, + ExternalContainer parent) throws GLib.Error { + var object_path = id.str ("/"); + if (object_path == null) { + throw new ContentDirectoryError.NO_SUCH_OBJECT ("No such object"); + } + + this (id, object_path, parent); + } + + private ExternalItem (string id, + string object_path, + ExternalContainer parent) + throws GLib.Error { + base (id, parent, "Unknown", /* Title Unknown at this point */ "Unknown"); /* UPnP Class Unknown at this point */ @@ -152,5 +168,9 @@ public class Rygel.ExternalItem : Rygel.MediaItem { this.color_depth = value.get_int (); } } + + public static bool id_valid (string id) { + return id.has_prefix ("item:/"); + } }