[rygel-grilo] Update properties handling



commit 1235a0ffd67fca7383638bcdcc86d55c95ab3cdf
Author: Juan A. Suarez Romero <jasuarez igalia com>
Date:   Tue May 11 13:50:43 2010 +0200

    Update properties handling
    
    Changing properties to definitely version.
    
    Update Get/GetAll functions so it can handle all properties in the spec.

 lib/media-server1-client.c       |   54 +-------
 lib/media-server1-client.h       |    6 +-
 lib/media-server1-common.h       |   61 ++++----
 lib/media-server1-server-table.c |  223 ++++++++++++++++++++++++------
 lib/media-server1-server.c       |  220 ++++++++++++++++++++++++++----
 lib/media-server1-server.h       |   36 ++++-
 src/rygel-grilo.c                |  280 +++++++++++++++++++++++++++++++-------
 7 files changed, 665 insertions(+), 215 deletions(-)
---
diff --git a/lib/media-server1-client.c b/lib/media-server1-client.c
index 51a0fdd..6482c45 100644
--- a/lib/media-server1-client.c
+++ b/lib/media-server1-client.c
@@ -627,7 +627,7 @@ ms1_client_get_item_type (GHashTable *properties)
 
   g_return_val_if_fail (properties, MS1_ITEM_TYPE_UNKNOWN);
 
-  val = g_hash_table_lookup (properties, MS1_PROP_DISPLAY_NAME);
+  val = g_hash_table_lookup (properties, MS1_PROP_TYPE);
   if (!val || !G_VALUE_HOLDS_STRING (val)) {
     return MS1_ITEM_TYPE_UNKNOWN;
   }
@@ -636,8 +636,10 @@ ms1_client_get_item_type (GHashTable *properties)
 
   if (g_strcmp0 (type, MS1_TYPE_CONTAINER) == 0) {
     return MS1_ITEM_TYPE_CONTAINER;
-  } else if (g_strcmp0 (type, MS1_TYPE_VIDEO) == 0) {
-    return MS1_ITEM_TYPE_VIDEO;
+  }   if (g_strcmp0 (type, MS1_TYPE_CONTAINER) == 0) {
+    return MS1_ITEM_TYPE_CONTAINER;
+  } else if (g_strcmp0 (type, MS1_TYPE_ITEM) == 0) {
+    return MS1_ITEM_TYPE_ITEM;
   } else if (g_strcmp0 (type, MS1_TYPE_MOVIE) == 0) {
     return MS1_ITEM_TYPE_MOVIE;
   } else if (g_strcmp0 (type, MS1_TYPE_AUDIO) == 0) {
@@ -654,29 +656,6 @@ ms1_client_get_item_type (GHashTable *properties)
 }
 
 /**
- * ms1_client_get_icon:
- * @properties: a #GHashTable
- *
- * Returns "icon" property value.
- *
- * Returns: property value or @NULL if it is not available
- **/
-const gchar *
-ms1_client_get_icon (GHashTable *properties)
-{
-  GValue *val;
-
-  g_return_val_if_fail (properties, NULL);
-
-  val = g_hash_table_lookup (properties, MS1_PROP_ICON);
-  if (!val || !G_VALUE_HOLDS_STRING (val)) {
-    return NULL;
-  }
-
-  return g_value_get_string (val);
-}
-
-/**
  * ms1_client_get_mime_type:
  * @properties: a #GHashTable
  *
@@ -838,29 +817,6 @@ ms1_client_get_genre (GHashTable *properties)
 }
 
 /**
- * ms1_client_get_child_count:
- * @properties: a #GHashTable
- *
- * Returns "child-count" property value.
- *
- * Returns: property value or -1 if it is not available
- **/
-gint
-ms1_client_get_child_count (GHashTable *properties)
-{
-  GValue *val;
-
-  g_return_val_if_fail (properties, -1);
-
-  val = g_hash_table_lookup (properties, MS1_PROP_CHILD_COUNT);
-  if (!val || !G_VALUE_HOLDS_INT (val)) {
-    return -1;
-  }
-
-  return g_value_get_int (val);
-}
-
-/**
  * ms1_client_get_size:
  * @properties: a #GHashTable
  *
diff --git a/lib/media-server1-client.h b/lib/media-server1-client.h
index 01fd56c..ffab42e 100644
--- a/lib/media-server1-client.h
+++ b/lib/media-server1-client.h
@@ -108,8 +108,6 @@ const gchar *ms1_client_get_display_name (GHashTable *properties);
 
 MS1ItemType ms1_client_get_item_type (GHashTable *properties);
 
-const gchar *ms1_client_get_icon (GHashTable *properties);
-
 const gchar *ms1_client_get_mime_type (GHashTable *properties);
 
 const gchar *ms1_client_get_artist (GHashTable *properties);
@@ -122,9 +120,9 @@ const gchar *ms1_client_get_dlna_profile (GHashTable *properties);
 
 const gchar *ms1_client_get_thumbnail (GHashTable *properties);
 
-const gchar *ms1_client_get_genre (GHashTable *properties);
+const gchar *ms1_client_get_album_art (GHashTable *properties);
 
-gint ms1_client_get_child_count (GHashTable *properties);
+const gchar *ms1_client_get_genre (GHashTable *properties);
 
 gint  ms1_client_get_size (GHashTable *properties);
 
diff --git a/lib/media-server1-common.h b/lib/media-server1-common.h
index 873368b..f00020b 100644
--- a/lib/media-server1-common.h
+++ b/lib/media-server1-common.h
@@ -23,41 +23,43 @@
 #ifndef _MEDIA_SERVER1_COMMON_H_
 #define _MEDIA_SERVER1_COMMON_H_
 
-#define MS1_ERROR                                       \
-  g_quark_from_static_string("media_server1_error")
-
 /* MediaObject1 properties */
-#define MS1_PROP_DISPLAY_NAME "DisplayName"
 #define MS1_PROP_PARENT       "Parent"
+#define MS1_PROP_TYPE         "Type"
 #define MS1_PROP_PATH         "Path"
+#define MS1_PROP_DISPLAY_NAME "DisplayName"
 
 /* MediaItem1 properties */
-#define MS1_PROP_ALBUM     "Album"
-#define MS1_PROP_ARTIST    "Artist"
-#define MS1_PROP_BITRATE   "Bitrate"
-#define MS1_PROP_DURATION  "Duration"
-#define MS1_PROP_GENRE     "Genre"
-#define MS1_PROP_HEIGHT    "Height"
-#define MS1_PROP_MIME_TYPE "MIMEType"
-#define MS1_PROP_TYPE      "Type"
-#define MS1_PROP_URLS      "URLs"
-#define MS1_PROP_WIDTH     "Width"
+#define MS1_PROP_URLS            "URLs"
+#define MS1_PROP_MIME_TYPE       "MIMEType"
+#define MS1_PROP_SIZE            "Size"
+#define MS1_PROP_ARTIST          "Artist"
+#define MS1_PROP_ALBUM           "Album"
+#define MS1_PROP_DATE            "Date"
+#define MS1_PROP_GENRE           "Genre"
+#define MS1_PROP_DLNA_PROFILE    "DLNAProfile"
+#define MS1_PROP_DURATION        "Duration"
+#define MS1_PROP_BITRATE         "Bitrate"
+#define MS1_PROP_SAMPLE_RATE     "SampleRate"
+#define MS1_PROP_BITS_PER_SAMPLE "BitsPerSample"
+#define MS1_PROP_WIDTH           "Width"
+#define MS1_PROP_HEIGHT          "Height"
+#define MS1_PROP_COLOR_DEPTH     "ColorDepth"
+#define MS1_PROP_PIXEL_WIDTH     "PixelWidth"
+#define MS1_PROP_PIXEL_HEIGHT    "PixelHeight"
+#define MS1_PROP_THUMBNAIL       "Thumbnail"
+#define MS1_PROP_ALBUM_ART       "AlbumArt"
 
-/* Other undefined properties; pending to add to spec */
-#define MS1_PROP_CHILD_COUNT     "child-count"
-#define MS1_PROP_ICON            "icon"
-#define MS1_PROP_SIZE            "size"
-#define MS1_PROP_DATE            "date"
-#define MS1_PROP_DLNA_PROFILE    "dlna-profile"
-#define MS1_PROP_SAMPLE_RATE     "sample-rate"
-#define MS1_PROP_BITS_PER_SAMPLE "bits-per-sample"
-#define MS1_PROP_COLOR_DEPTH     "color-depth"
-#define MS1_PROP_PIXEL_WIDTH     "pixel-width"
-#define MS1_PROP_PIXEL_HEIGHT    "pixel-height"
-#define MS1_PROP_THUMBNAIL       "thumbnail"
+/* MediaContainer1 properties */
+#define MS1_PROP_ITEMS           "Items"
+#define MS1_PROP_ITEM_COUNT      "ItemCount"
+#define MS1_PROP_CONTAINERS      "Containers"
+#define MS1_PROP_CONTAINER_COUNT "ContainerCount"
+#define MS1_PROP_SEARCHABLE      "Searchable"
 
 /* Type items */
 #define MS1_TYPE_CONTAINER "container"
+#define MS1_TYPE_ITEM      "item"
 #define MS1_TYPE_VIDEO     "video"
 #define MS1_TYPE_MOVIE     "video.movie"
 #define MS1_TYPE_AUDIO     "audio"
@@ -67,18 +69,16 @@
 
 /* Unknown values */
 #define MS1_UNKNOWN_INT -1
+#define MS1_UNKNOWN_UINT 0
 #define MS1_UNKNOWN_STR ""
 
 /* Root category */
 #define MS1_ROOT ""
 
-typedef enum {
-  MS1_ERROR_GENERAL = 1
-} MS1Error;
-
 /* Type items definition */
 typedef enum {
   MS1_ITEM_TYPE_UNKNOWN = 0,
+  MS1_ITEM_TYPE_ITEM,
   MS1_ITEM_TYPE_CONTAINER,
   MS1_ITEM_TYPE_VIDEO,
   MS1_ITEM_TYPE_MOVIE,
@@ -89,4 +89,3 @@ typedef enum {
 } MS1ItemType;
 
 #endif /* _MEDIA_SERVER1_COMMON_H_ */
-
diff --git a/lib/media-server1-server-table.c b/lib/media-server1-server-table.c
index 1fbe0f2..1d5755c 100644
--- a/lib/media-server1-server-table.c
+++ b/lib/media-server1-server-table.c
@@ -66,6 +66,32 @@ int_to_value (gint number)
   return val;
 }
 
+/* Puts an uint in a gvalue */
+static GValue *
+uint_to_value (guint number)
+{
+  GValue *val = NULL;
+
+  val = g_new0 (GValue, 1);
+  g_value_init (val, G_TYPE_UINT);
+  g_value_set_uint (val, number);
+
+  return val;
+}
+
+/* Puts a boolean in a gvalue */
+static GValue *
+bool_to_value (gboolean boolean)
+{
+  GValue *val = NULL;
+
+  val = g_new0 (GValue, 1);
+  g_value_init (val, G_TYPE_BOOLEAN);
+  g_value_set_boolean (val, boolean);
+
+  return val;
+}
+
 /* Puts a gptrarray in a gvalue */
 static GValue *
 ptrarray_to_value (GPtrArray *array)
@@ -107,6 +133,23 @@ id_to_object_path (MS1Server *server,
   return object_path;
 }
 
+static GPtrArray *
+get_object_paths (GList *items)
+{
+  GList *item;
+  GPtrArray *op;
+  gchar *path;
+
+  op = g_ptr_array_sized_new (g_list_length (items));
+  for (item = items; item; item = g_list_next (item)) {
+    path = g_strdup (ms1_client_get_path (item->data));
+    if (path) {
+      g_ptr_array_add (op, path);
+    }
+  }
+
+  return op;
+}
 /********************* PUBLIC API *********************/
 
 /**
@@ -235,6 +278,11 @@ ms1_server_set_item_type (MS1Server *server,
                          MS1_PROP_TYPE,
                          str_to_value (MS1_TYPE_CONTAINER));
     break;
+  case MS1_ITEM_TYPE_ITEM:
+    g_hash_table_insert (properties,
+                         MS1_PROP_TYPE,
+                         str_to_value (MS1_TYPE_ITEM));
+    break;
   case MS1_ITEM_TYPE_VIDEO:
     g_hash_table_insert (properties,
                          MS1_PROP_TYPE,
@@ -269,31 +317,6 @@ ms1_server_set_item_type (MS1Server *server,
 }
 
 /**
- * ms1_server_set_icon:ç
- * @server: a #MS1Server
- * @properties: a #GHashTable
- * @icon: icon identifier value
- *
- * Sets the "icon" property. Recommended property for containers.
- *
- * Use this to provide an icon to be used by consumer UIs to represent the
- * provider. This is only relevant to root container.
- **/
-void
-ms1_server_set_icon (MS1Server *server,
-                     GHashTable *properties,
-                     const gchar *icon)
-{
-  g_return_if_fail (properties);
-
-  if (icon) {
-    g_hash_table_insert (properties,
-                         MS1_PROP_ICON,
-                         str_to_value (icon));
-  }
-}
-
-/**
  * ms1_server_set_mime_type:
  * @server: a #MS1Server
  * @properties: a #GHashTable
@@ -432,47 +455,47 @@ ms1_server_set_thumbnail (MS1Server *server,
 }
 
 /**
- * ms1_server_set_genre:
+ * ms1_server_set_album_art
  * @server: a #MS1Server
  * @properties: a #GHashTable
- * @genre: genre value
+ * @album_art: albumart identifier value
  *
- * Sets the "genre" property. Optional property for audio/music items.
+ * Sets the "AlbumArt" property. Optional property for video/image items.
  **/
 void
-ms1_server_set_genre (MS1Server *server,
-                      GHashTable *properties,
-                      const gchar *genre)
+ms1_server_set_album_art (MS1Server *server,
+                          GHashTable *properties,
+                          const gchar *album_art)
 {
   g_return_if_fail (properties);
 
-  if (genre) {
+  if (album_art) {
     g_hash_table_insert (properties,
-                         MS1_PROP_GENRE,
-                         str_to_value (genre));
+                         MS1_PROP_ALBUM_ART,
+                         str_to_value (album_art));
   }
 }
 
 /**
- * ms1_server_set_child_count:
+ * ms1_server_set_genre:
  * @server: a #MS1Server
  * @properties: a #GHashTable
- * @child_count: childcount value
- *
- * Sets the "child-count" property. Recommended property for containers.
+ * @genre: genre value
  *
- * It is the number of media objects directly under this container.
+ * Sets the "genre" property. Optional property for audio/music items.
  **/
 void
-ms1_server_set_child_count (MS1Server *server,
-                            GHashTable *properties,
-                            gint child_count)
+ms1_server_set_genre (MS1Server *server,
+                      GHashTable *properties,
+                      const gchar *genre)
 {
   g_return_if_fail (properties);
 
-  g_hash_table_insert (properties,
-                       MS1_PROP_CHILD_COUNT,
-                       int_to_value (child_count));
+  if (genre) {
+    g_hash_table_insert (properties,
+                         MS1_PROP_GENRE,
+                         str_to_value (genre));
+  }
 }
 
 /**
@@ -709,3 +732,113 @@ ms1_server_set_urls (MS1Server *server,
                          ptrarray_to_value (url_array));
   }
 }
+
+/**
+ * ms1_server_set_searchable:
+ * @server: a #MS1Server
+ * @properties: a #GHashTable
+ * @searchable: @TRUE if item is searchable
+ *
+ * Sets the "Searchable" property. Optional property for video/image items.
+ **/
+void
+ms1_server_set_searchable (MS1Server *server,
+                           GHashTable *properties,
+                           gint searchable)
+{
+  g_return_if_fail (properties);
+
+  g_hash_table_insert (properties,
+                       MS1_PROP_SEARCHABLE,
+                       bool_to_value (searchable));
+}
+
+/**
+ * ms1_server_set_items:
+ * @server: a #MS1Server
+ * @properties: a #GHashTable
+ * @items: a list of children
+ *
+ * Sets the "Items" property. Mandatory property for items.
+ **/
+void
+ms1_server_set_items (MS1Server *server,
+                      GHashTable *properties,
+                      GList *items)
+{
+  GPtrArray *object_paths;
+
+  g_return_if_fail (properties);
+
+  if (items) {
+    object_paths = get_object_paths (items);
+    g_hash_table_insert (properties,
+                         MS1_PROP_ITEMS,
+                         ptrarray_to_value (object_paths));
+  }
+}
+
+/**
+ * ms1_server_set_item_count:
+ * @server: a #MS1Server
+ * @properties: a #GHashTable
+ * @item_count: how many items have this container
+ *
+ * Sets the "ItemCount" property. Optional property for video/image items.
+ **/
+void
+ms1_server_set_item_count (MS1Server *server,
+                           GHashTable *properties,
+                           guint item_count)
+{
+  g_return_if_fail (properties);
+
+  g_hash_table_insert (properties,
+                       MS1_PROP_ITEM_COUNT,
+                       uint_to_value (item_count));
+}
+
+/**
+ * ms1_server_set_containers:
+ * @server: a #MS1Server
+ * @properties: a #GHashTable
+ * @containers: a list of children
+ *
+ * Sets the "Containers" property. Mandatory property for items.
+ **/
+void
+ms1_server_set_containers (MS1Server *server,
+                           GHashTable *properties,
+                           GList *containers)
+{
+  GPtrArray *object_paths;
+
+  g_return_if_fail (properties);
+
+  if (containers) {
+    object_paths = get_object_paths (containers);
+    g_hash_table_insert (properties,
+                         MS1_PROP_CONTAINERS,
+                         ptrarray_to_value (object_paths));
+  }
+}
+
+/**
+ * ms1_server_set_container_count:
+ * @server: a #MS1Server
+ * @properties: a #GHashTable
+ * @container_count: how many containers have this container
+ *
+ * Sets the "ContainerCount" property. Optional property for video/image items.
+ **/
+void
+ms1_server_set_container_count (MS1Server *server,
+                                GHashTable *properties,
+                                guint container_count)
+{
+  g_return_if_fail (properties);
+
+  g_hash_table_insert (properties,
+                       MS1_PROP_CONTAINER_COUNT,
+                       uint_to_value (container_count));
+}
diff --git a/lib/media-server1-server.c b/lib/media-server1-server.c
index 2388e76..1b30f4a 100644
--- a/lib/media-server1-server.c
+++ b/lib/media-server1-server.c
@@ -65,23 +65,40 @@ static const gchar get_sgn[]  = { DBUS_TYPE_STRING, DBUS_TYPE_STRING, DBUS_TYPE_
 static const gchar getall_sgn[] = { DBUS_TYPE_STRING, DBUS_TYPE_INVALID };
 static const gchar listobjects_sgn[] = { DBUS_TYPE_UINT32, DBUS_TYPE_UINT32, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, DBUS_TYPE_INVALID };
 
-static const gchar *mediaobject1_properties[] = { MS1_PROP_DISPLAY_NAME,
-                                                  MS1_PROP_PARENT,
+static const gchar *mediaobject1_properties[] = { MS1_PROP_PARENT,
+                                                  MS1_PROP_TYPE,
                                                   MS1_PROP_PATH,
+                                                  MS1_PROP_DISPLAY_NAME,
                                                   NULL };
 
-static const gchar *mediaitem1_properties[] = { MS1_PROP_ALBUM,
+static const gchar *mediaitem1_properties[] = { MS1_PROP_URLS,
+                                                MS1_PROP_MIME_TYPE,
+                                                MS1_PROP_SIZE,
                                                 MS1_PROP_ARTIST,
-                                                MS1_PROP_BITRATE,
-                                                MS1_PROP_DURATION,
+                                                MS1_PROP_ALBUM,
+                                                MS1_PROP_DATE,
                                                 MS1_PROP_GENRE,
-                                                MS1_PROP_HEIGHT,
-                                                MS1_PROP_MIME_TYPE,
-                                                MS1_PROP_TYPE,
-                                                MS1_PROP_URLS,
+                                                MS1_PROP_DLNA_PROFILE,
+                                                MS1_PROP_DURATION,
+                                                MS1_PROP_BITRATE,
+                                                MS1_PROP_SAMPLE_RATE,
+                                                MS1_PROP_BITS_PER_SAMPLE,
                                                 MS1_PROP_WIDTH,
+                                                MS1_PROP_HEIGHT,
+                                                MS1_PROP_COLOR_DEPTH,
+                                                MS1_PROP_PIXEL_WIDTH,
+                                                MS1_PROP_PIXEL_HEIGHT,
+                                                MS1_PROP_THUMBNAIL,
+                                                MS1_PROP_ALBUM_ART,
                                                 NULL };
 
+static const gchar *mediacontainer1_properties[] = { MS1_PROP_ITEMS,
+                                                     MS1_PROP_ITEM_COUNT,
+                                                     MS1_PROP_CONTAINERS,
+                                                     MS1_PROP_CONTAINER_COUNT,
+                                                     MS1_PROP_SEARCHABLE,
+                                                     NULL };
+
 static guint32 signals[LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE (MS1Server, ms1_server, G_TYPE_OBJECT);
@@ -124,6 +141,32 @@ int_to_value (gint number)
   return val;
 }
 
+/* Puts an uint in a gvalue */
+static GValue *
+uint_to_value (guint number)
+{
+  GValue *val = NULL;
+
+  val = g_new0 (GValue, 1);
+  g_value_init (val, G_TYPE_UINT);
+  g_value_set_int (val, number);
+
+  return val;
+}
+
+/* Puts an bool in a gvalue */
+static GValue *
+bool_to_value (gboolean b)
+{
+  GValue *val = NULL;
+
+  val = g_new0 (GValue, 1);
+  g_value_init (val, G_TYPE_BOOLEAN);
+  g_value_set_boolean (val, b);
+
+  return val;
+}
+
 /* Puts a gptrarray in a gvalue */
 static GValue *
 ptrarray_to_value (GPtrArray *array)
@@ -159,29 +202,45 @@ properties_lookup_with_default (GHashTable *properties,
   GValue *propvalue;
   const gchar *intern_property;
   static gchar **int_type_properties = NULL;
+  static gchar **uint_type_properties = NULL;
+  static gchar **bool_type_properties = NULL;
   static gchar **gptrarray_type_properties = NULL;
 
   /* Initialize data */
   if (!int_type_properties) {
-    int_type_properties = g_new (gchar *, 12);
-    int_type_properties[0] = (gchar *) g_intern_static_string (MS1_PROP_CHILD_COUNT);
-    int_type_properties[1] = (gchar *) g_intern_static_string (MS1_PROP_SIZE);
-    int_type_properties[2] = (gchar *) g_intern_static_string (MS1_PROP_DURATION);
-    int_type_properties[3] = (gchar *) g_intern_static_string (MS1_PROP_BITRATE);
-    int_type_properties[4] = (gchar *) g_intern_static_string (MS1_PROP_SAMPLE_RATE);
-    int_type_properties[5] = (gchar *) g_intern_static_string (MS1_PROP_BITS_PER_SAMPLE);
-    int_type_properties[6] = (gchar *) g_intern_static_string (MS1_PROP_WIDTH);
-    int_type_properties[7] = (gchar *) g_intern_static_string (MS1_PROP_HEIGHT);
-    int_type_properties[8] = (gchar *) g_intern_static_string (MS1_PROP_COLOR_DEPTH);
-    int_type_properties[9] = (gchar *) g_intern_static_string (MS1_PROP_PIXEL_WIDTH);
-    int_type_properties[10] = (gchar *) g_intern_static_string (MS1_PROP_PIXEL_HEIGHT);
-    int_type_properties[11] = NULL;
+    int_type_properties = g_new (gchar *, 11);
+    int_type_properties[0] = (gchar *) g_intern_static_string (MS1_PROP_SIZE);
+    int_type_properties[1] = (gchar *) g_intern_static_string (MS1_PROP_DURATION);
+    int_type_properties[2] = (gchar *) g_intern_static_string (MS1_PROP_BITRATE);
+    int_type_properties[3] = (gchar *) g_intern_static_string (MS1_PROP_SAMPLE_RATE);
+    int_type_properties[4] = (gchar *) g_intern_static_string (MS1_PROP_BITS_PER_SAMPLE);
+    int_type_properties[5] = (gchar *) g_intern_static_string (MS1_PROP_WIDTH);
+    int_type_properties[6] = (gchar *) g_intern_static_string (MS1_PROP_HEIGHT);
+    int_type_properties[7] = (gchar *) g_intern_static_string (MS1_PROP_COLOR_DEPTH);
+    int_type_properties[8] = (gchar *) g_intern_static_string (MS1_PROP_PIXEL_WIDTH);
+    int_type_properties[9] = (gchar *) g_intern_static_string (MS1_PROP_PIXEL_HEIGHT);
+    int_type_properties[10] = NULL;
+  }
+
+  if (!uint_type_properties) {
+    uint_type_properties = g_new (gchar *, 3);
+    uint_type_properties[0] = (gchar *) g_intern_static_string (MS1_PROP_ITEM_COUNT);
+    uint_type_properties[1] = (gchar *) g_intern_static_string (MS1_PROP_CONTAINER_COUNT);
+    uint_type_properties[2] = NULL;
+  }
+
+  if (!bool_type_properties) {
+    bool_type_properties = g_new (gchar *, 2);
+    bool_type_properties[0] = (gchar *) g_intern_static_string (MS1_PROP_SEARCHABLE);
+    bool_type_properties[1] = NULL;
   }
 
   if (!gptrarray_type_properties) {
-    gptrarray_type_properties = g_new (gchar *, 2);
+    gptrarray_type_properties = g_new (gchar *, 4);
     gptrarray_type_properties[0] = (gchar *) g_intern_static_string (MS1_PROP_URLS);
-    gptrarray_type_properties[1] = NULL;
+    gptrarray_type_properties[1] = (gchar *) g_intern_static_string (MS1_PROP_ITEMS);
+    gptrarray_type_properties[2] = (gchar *) g_intern_static_string (MS1_PROP_CONTAINERS);
+    gptrarray_type_properties[3] = NULL;
   }
 
   propvalue = g_hash_table_lookup (properties, property);
@@ -198,9 +257,12 @@ properties_lookup_with_default (GHashTable *properties,
   intern_property = g_intern_string (property);
   if (lookup_in_strv (int_type_properties, intern_property)) {
     ret_value = int_to_value (MS1_UNKNOWN_INT);
+  } else if (lookup_in_strv (uint_type_properties, intern_property)) {
+    ret_value = uint_to_value (MS1_UNKNOWN_UINT);
+  } else if (lookup_in_strv (bool_type_properties, intern_property)) {
+    ret_value = bool_to_value (FALSE);
   } else if (lookup_in_strv (gptrarray_type_properties, intern_property)) {
-    ptrarray = g_ptr_array_sized_new (1);
-    g_ptr_array_add (ptrarray, g_strdup (MS1_UNKNOWN_STR));
+    ptrarray = g_ptr_array_sized_new (0);
     ret_value = ptrarray_to_value (ptrarray);
   } else {
     ret_value = str_to_value (MS1_UNKNOWN_STR);
@@ -218,6 +280,7 @@ is_property_valid (const gchar *interface,
   int i;
   static gchar **mo1_properties_intern = NULL;
   static gchar **mi1_properties_intern = NULL;
+  static gchar **mc1_properties_intern = NULL;
 
   /* Initialize MediaObject1 properties interns */
   if (!mo1_properties_intern) {
@@ -241,6 +304,17 @@ is_property_valid (const gchar *interface,
     mi1_properties_intern[i] = NULL;
   }
 
+  /* Initialize MediaContainer1 properties interns */
+  if (!mc1_properties_intern) {
+    mc1_properties_intern = g_new (gchar *,
+                                   g_strv_length ((gchar **) mediacontainer1_properties) + 1);
+    for (i = 0; mediacontainer1_properties[i]; i++) {
+      mc1_properties_intern[i] =
+        (gchar *) g_intern_static_string (mediacontainer1_properties[i]);
+    }
+    mc1_properties_intern[i] = NULL;
+  }
+
   prop_intern = g_intern_string (property);
 
   /* Check MediaObject1 interface */
@@ -259,7 +333,21 @@ is_property_valid (const gchar *interface,
 
   /* Check MediaItem1 interface */
   if (!interface || g_strcmp0 (interface, "org.gnome.UPnP.MediaItem1") == 0) {
-    return lookup_in_strv (mi1_properties_intern, prop_intern);
+    found = lookup_in_strv (mi1_properties_intern, prop_intern);
+
+    if (found) {
+      return TRUE;
+    }
+
+    /* If not found, but interface is NULL, maybe property is in next interface */
+    if (!found && interface) {
+      return FALSE;
+    }
+  }
+
+  /* Check MediaContainer1 interface */
+  if (!interface || g_strcmp0 (interface, "org.gnome.UPnP.MediaContainer1") == 0) {
+    return lookup_in_strv (mc1_properties_intern, prop_intern);
   }
 
   return FALSE;
@@ -351,14 +439,67 @@ get_id_from_message (DBusMessage *m)
 }
 
 static void
+add_gptrarray_as_as (DBusMessage *m,
+                     DBusMessageIter *iter,
+                     GPtrArray *a)
+{
+  DBusMessageIter iternew;
+  DBusMessageIter sub_array;
+  gint i;
+
+  if (!iter) {
+    dbus_message_iter_init_append (m, &iternew);
+    iter = &iternew;
+  }
+
+  dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "s", &sub_array);
+  /* Add array */
+  for (i = 0; i < a->len; i++) {
+    dbus_message_iter_append_basic (&sub_array,
+                                    DBUS_TYPE_STRING,
+                                    &(g_ptr_array_index (a, i)));
+  }
+  dbus_message_iter_close_container (iter, &sub_array);
+}
+
+static void
+add_gptrarray_as_os (DBusMessage *m,
+                     DBusMessageIter *iter,
+                     GPtrArray *a)
+{
+  DBusMessageIter iternew;
+  DBusMessageIter sub_array;
+  gint i;
+
+  if (!iter) {
+    dbus_message_iter_init_append (m, &iternew);
+    iter = &iternew;
+  }
+
+  dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "o", &sub_array);
+
+  /* Add array */
+  for (i = 0; i < a->len; i++) {
+    dbus_message_iter_append_basic (&sub_array,
+                                    DBUS_TYPE_OBJECT_PATH,
+                                    &(g_ptr_array_index (a, i)));
+  }
+
+  dbus_message_iter_close_container (iter, &sub_array);
+}
+
+static void
 add_variant (DBusMessage *m,
              DBusMessageIter *iter,
+             const gchar *key,
              const GValue *v)
 {
   DBusMessageIter iternew;
   DBusMessageIter sub;
   const gchar *str_value;
+  gboolean bool_value;
   gint int_value;
+  guint uint_value;
 
   if (!iter) {
     dbus_message_iter_init_append (m, &iternew);
@@ -375,6 +516,25 @@ add_variant (DBusMessage *m,
     dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "i", &sub);
     dbus_message_iter_append_basic (&sub, DBUS_TYPE_INT32, &int_value);
     dbus_message_iter_close_container (iter, &sub);
+  } else if (G_VALUE_HOLDS_UINT (v)) {
+    uint_value = g_value_get_uint (v);
+    dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "u", &sub);
+    dbus_message_iter_append_basic (&sub, DBUS_TYPE_UINT32, &uint_value);
+    dbus_message_iter_close_container (iter, &sub);
+  } else if (G_VALUE_HOLDS_BOOLEAN (v)) {
+    bool_value = g_value_get_boolean (v);
+    dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "b", &sub);
+    dbus_message_iter_append_basic (&sub, DBUS_TYPE_BOOLEAN, &bool_value);
+    dbus_message_iter_close_container (iter, &sub);
+  } else if (G_VALUE_HOLDS_BOXED (v)) {
+    if (g_strcmp0 (key, "URLs") == 0) {
+      dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "as", &sub);
+      add_gptrarray_as_as (m, &sub, g_value_get_boxed (v));
+    } else {
+      dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "ao", &sub);
+      add_gptrarray_as_os (m, &sub, g_value_get_boxed (v));
+    }
+    dbus_message_iter_close_container (iter, &sub);
   }
 }
 
@@ -410,7 +570,7 @@ add_hashtable_as_dict (DBusMessage *m,
       dbus_message_iter_open_container (&sub_array, DBUS_TYPE_DICT_ENTRY, NULL, &sub_dict);
       /* Add key & value */
       dbus_message_iter_append_basic (&sub_dict, DBUS_TYPE_STRING, &key->data);
-      add_variant (m, &sub_dict, v);
+      add_variant (m, &sub_dict, key->data, v);
       dbus_message_iter_close_container (&sub_array, &sub_dict);
     }
     g_list_free (keys);
@@ -488,7 +648,7 @@ handle_get_message (DBusConnection *c,
                   interface);
     } else {
       r = dbus_message_new_method_return (m);
-      add_variant (r, NULL, value);
+      add_variant (r, NULL, property, value);
       dbus_connection_send (c, r, NULL);
       dbus_message_unref (r);
       free_value (value);
@@ -522,7 +682,7 @@ handle_get_all_message (DBusConnection *c,
     } else if (g_strcmp0 (interface, "org.gnome.UPnP.MediaItem1") == 0) {
       prop = mediaitem1_properties;
     } else if (g_strcmp0 (interface, "org.gnome.UPnP.MediaContainer1") == 0) {
-      prop = NULL;
+      prop = mediacontainer1_properties;
     } else {
       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     }
diff --git a/lib/media-server1-server.h b/lib/media-server1-server.h
index d153ff6..0510cba 100644
--- a/lib/media-server1-server.h
+++ b/lib/media-server1-server.h
@@ -84,7 +84,7 @@ typedef GHashTable * (*GetPropertiesFunc) (MS1Server *server,
 typedef GList * (*GetChildrenFunc) (MS1Server *server,
                                     const gchar *id,
                                     guint offset,
-                                    gint max_count,
+                                    guint max_count,
                                     const gchar **properties,
                                     gpointer data,
                                     GError **error);
@@ -148,17 +148,17 @@ void ms1_server_set_dlna_profile (MS1Server *server,
                                   GHashTable *properties,
                                   const gchar *dlna_profile);
 
-void ms1_server_set_thumbnail (MS1Server *server,
-                               GHashTable *properties,
-                               const gchar *thumbnail);
-
 void ms1_server_set_genre (MS1Server *server,
                            GHashTable *properties,
                            const gchar *genre);
 
-void ms1_server_set_child_count (MS1Server *server,
-                                 GHashTable *properties,
-                                 gint child_count);
+void ms1_server_set_thumbnail (MS1Server *server,
+                               GHashTable *properties,
+                               const gchar *genre);
+
+void ms1_server_set_album_art (MS1Server *server,
+                               GHashTable *properties,
+                               const gchar *album_art);
 
 void ms1_server_set_size (MS1Server *server,
                           GHashTable *properties,
@@ -204,4 +204,24 @@ void ms1_server_set_urls (MS1Server *server,
                           GHashTable *properties,
                           gchar **urls);
 
+void ms1_server_set_searchable (MS1Server *server,
+                                GHashTable *properties,
+                                gboolean searchable);
+
+void ms1_server_set_items (MS1Server *server,
+                           GHashTable *properties,
+                           GList *items);
+
+void ms1_server_set_item_count (MS1Server *server,
+                                GHashTable *properties,
+                                guint item_count);
+
+void ms1_server_set_containers (MS1Server *server,
+                                GHashTable *properties,
+                                GList *containers);
+
+void ms1_server_set_container_count (MS1Server *server,
+                                     GHashTable *properties,
+                                     guint container_count);
+
 #endif /* _MEDIA_SERVER1_SERVER_H_ */
diff --git a/src/rygel-grilo.c b/src/rygel-grilo.c
index 331f4a5..db70514 100644
--- a/src/rygel-grilo.c
+++ b/src/rygel-grilo.c
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (C) 2010 Igalia S.L.
  *
@@ -26,6 +27,7 @@
 #include <stdio.h>
 
 #include <media-server1-server.h>
+#include <media-server1-client.h>
 
 #define RYGEL_GRILO_CONFIG_FILE "rygel-grilo.conf"
 
@@ -67,10 +69,26 @@ typedef struct {
   GrlMediaSource *source;
   MS1Server *server;
   gboolean updated;
-  gboolean parent_requested;
+  GList *other_keys;
   gchar *parent_id;
 } RygelGriloData;
 
+static GHashTable *
+get_properties_cb (MS1Server *server,
+                   const gchar *id,
+                   const gchar **properties,
+                   gpointer data,
+                   GError **error);
+
+static GList *
+get_children_cb (MS1Server *server,
+                 const gchar *id,
+                 guint offset,
+                 guint max_count,
+                 const gchar **properties,
+                 gpointer data,
+                 GError **error);
+
 /* Fix invalid characters so string can be used in a dbus name */
 static void
 sanitize (gchar *string)
@@ -207,57 +225,129 @@ unserialize_media (GrlMetadataSource *source, const gchar *id)
   return media;
 }
 
+static void
+get_items_and_containers (MS1Server *server,
+                          GrlMediaSource *source,
+                          const gchar *container_id,
+                          GList **items,
+                          guint *item_count,
+                          GList **containers,
+                          guint *container_count)
+{
+  const gchar *properties[] = { MS1_PROP_PATH, MS1_PROP_TYPE, NULL };
+  GList *children;
+  GList *child;
+  MS1ItemType type;
+
+  /* Initialize values */
+  if (items) {
+    *items = NULL;
+  }
+
+  if (item_count) {
+    *item_count = 0;
+  }
+
+  if (containers) {
+    *containers = NULL;
+  }
+
+  if (container_count) {
+    *container_count = 0;
+  }
+
+  children =
+    get_children_cb (server, container_id, 0, 0, properties, source, NULL);
+
+  /* Separate containers from items */
+  for (child = children; child; child = g_list_next (child)) {
+    type = ms1_client_get_item_type (child->data);
+    if (type == MS1_ITEM_TYPE_CONTAINER) {
+      if (container_count) {
+        (*container_count)++;
+      }
+      if (containers) {
+        *containers = g_list_prepend (*containers, child->data);
+      } else {
+        g_hash_table_unref (child->data);
+      }
+    } else {
+      if (item_count) {
+        (*item_count)++;
+      }
+      if (items) {
+        *items = g_list_prepend (*items, child->data);
+      }
+    }
+  }
+  if (containers) {
+    *containers = g_list_reverse (*containers);
+  }
+  if (items) {
+    *items = g_list_reverse (*items);
+  }
+  g_list_free (children);
+}
+
 /* Given a null-terminated array of MediaServerSpec1 properties, returns a list
    with the corresponding Grilo metadata keys */
 static GList *
-get_grilo_keys (const gchar **ms_keys, gboolean *contains_parent)
+get_grilo_keys (const gchar **ms_keys, GList **other_keys)
 {
   GList *grl_keys = NULL;
   gint i;
 
-  if (contains_parent) {
-    *contains_parent = FALSE;
-  }
-
   for (i = 0; ms_keys[i]; i++) {
     if (g_strcmp0 (ms_keys[i], MS1_PROP_PATH) == 0) {
-      grl_keys = g_list_append (grl_keys,
-                                GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ID));
+      grl_keys = g_list_prepend (grl_keys,
+                                 GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ID));
     } else if (g_strcmp0 (ms_keys[i], MS1_PROP_DISPLAY_NAME) == 0) {
-      grl_keys = g_list_append (grl_keys,
-                                GRLKEYID_TO_POINTER (GRL_METADATA_KEY_TITLE));
+      grl_keys = g_list_prepend (grl_keys,
+                                 GRLKEYID_TO_POINTER (GRL_METADATA_KEY_TITLE));
+    } else if (g_strcmp0 (ms_keys[i], MS1_PROP_DATE) == 0) {
+      grl_keys = g_list_prepend (grl_keys,
+                                 GRLKEYID_TO_POINTER (GRL_METADATA_KEY_DATE));
     } else if (g_strcmp0 (ms_keys[i], MS1_PROP_ALBUM) == 0) {
-      grl_keys = g_list_append (grl_keys,
-                                GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ALBUM));
+      grl_keys = g_list_prepend (grl_keys,
+                                 GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ALBUM));
     } else if (g_strcmp0 (ms_keys[i], MS1_PROP_ARTIST) == 0) {
-      grl_keys = g_list_append (grl_keys,
-                                GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ARTIST));
+      grl_keys = g_list_prepend (grl_keys,
+                                 GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ARTIST));
     } else if (g_strcmp0 (ms_keys[i], MS1_PROP_GENRE) == 0) {
-      grl_keys = g_list_append (grl_keys,
-                                GRLKEYID_TO_POINTER (GRL_METADATA_KEY_GENRE));
+      grl_keys = g_list_prepend (grl_keys,
+                                 GRLKEYID_TO_POINTER (GRL_METADATA_KEY_GENRE));
     } else if (g_strcmp0 (ms_keys[i], MS1_PROP_MIME_TYPE) == 0) {
-      grl_keys = g_list_append (grl_keys,
-                                GRLKEYID_TO_POINTER (GRL_METADATA_KEY_MIME));
-    } else if (g_strcmp0 (ms_keys[i], MS1_PROP_CHILD_COUNT) == 0) {
-      grl_keys = g_list_append (grl_keys,
-                                GRLKEYID_TO_POINTER (GRL_METADATA_KEY_CHILDCOUNT));
+      grl_keys = g_list_prepend (grl_keys,
+                                 GRLKEYID_TO_POINTER (GRL_METADATA_KEY_MIME));
     } else if (g_strcmp0 (ms_keys[i], MS1_PROP_URLS) == 0) {
-      grl_keys = g_list_append (grl_keys,
-                                GRLKEYID_TO_POINTER (GRL_METADATA_KEY_URL));
+      grl_keys = g_list_prepend (grl_keys,
+                                 GRLKEYID_TO_POINTER (GRL_METADATA_KEY_URL));
     } else if (g_strcmp0 (ms_keys[i], MS1_PROP_BITRATE) == 0) {
-      grl_keys = g_list_append (grl_keys,
-                                GRLKEYID_TO_POINTER (GRL_METADATA_KEY_BITRATE));
+      grl_keys = g_list_prepend (grl_keys,
+                                 GRLKEYID_TO_POINTER (GRL_METADATA_KEY_BITRATE));
     } else if (g_strcmp0 (ms_keys[i], MS1_PROP_DURATION) == 0) {
-      grl_keys = g_list_append (grl_keys,
-                                GRLKEYID_TO_POINTER (GRL_METADATA_KEY_DURATION));
+      grl_keys = g_list_prepend (grl_keys,
+                                 GRLKEYID_TO_POINTER (GRL_METADATA_KEY_DURATION));
     } else if (g_strcmp0 (ms_keys[i], MS1_PROP_HEIGHT) == 0) {
-      grl_keys = g_list_append (grl_keys,
-                                GRLKEYID_TO_POINTER (GRL_METADATA_KEY_HEIGHT));
+      grl_keys = g_list_prepend (grl_keys,
+                                 GRLKEYID_TO_POINTER (GRL_METADATA_KEY_HEIGHT));
     } else if (g_strcmp0 (ms_keys[i], MS1_PROP_WIDTH) == 0) {
-      grl_keys = g_list_append (grl_keys,
-                                GRLKEYID_TO_POINTER (GRL_METADATA_KEY_WIDTH));
-    } else if (g_strcmp0 (ms_keys[i], MS1_PROP_PARENT) == 0 && contains_parent) {
-      *contains_parent = TRUE;
+      grl_keys = g_list_prepend (grl_keys,
+                                 GRLKEYID_TO_POINTER (GRL_METADATA_KEY_WIDTH));
+    } else if (g_strcmp0 (ms_keys[i], MS1_PROP_PARENT) == 0 && other_keys) {
+      *other_keys = g_list_prepend (*other_keys, (gchar *) ms_keys[i]);
+    } else if (g_strcmp0 (ms_keys[i], MS1_PROP_TYPE) == 0 && other_keys) {
+      *other_keys = g_list_prepend (*other_keys, (gchar *) ms_keys[i]);
+    } else if (g_strcmp0 (ms_keys[i], MS1_PROP_ITEMS) == 0 && other_keys) {
+      *other_keys = g_list_prepend (*other_keys, (gchar *) ms_keys[i]);
+    } else if (g_strcmp0 (ms_keys[i], MS1_PROP_ITEM_COUNT) == 0 && other_keys) {
+      *other_keys = g_list_prepend (*other_keys, (gchar *) ms_keys[i]);
+    } else if (g_strcmp0 (ms_keys[i], MS1_PROP_CONTAINERS) == 0 && other_keys) {
+      *other_keys = g_list_prepend (*other_keys, (gchar *) ms_keys[i]);
+    } else if (g_strcmp0 (ms_keys[i], MS1_PROP_CONTAINER_COUNT) == 0 && other_keys) {
+      *other_keys = g_list_prepend (*other_keys, (gchar *) ms_keys[i]);
+    } else if (g_strcmp0 (ms_keys[i], MS1_PROP_SEARCHABLE) == 0 && other_keys) {
+      *other_keys = g_list_prepend (*other_keys, (gchar *) ms_keys[i]);
     }
   }
 
@@ -269,7 +359,6 @@ fill_properties_table (MS1Server *server,
                        GHashTable *properties_table,
                        GList *keys,
                        GrlMedia *media,
-                       gboolean parent_requested,
                        const gchar *parent_id)
 {
   GList *prop;
@@ -320,12 +409,6 @@ fill_properties_table (MS1Server *server,
                                   properties_table,
                                   grl_media_get_mime (media));
         break;
-      case GRL_METADATA_KEY_CHILDCOUNT:
-        ms1_server_set_child_count (server,
-                                    properties_table,
-                                    grl_data_get_int (GRL_DATA (media),
-                                                      GRL_METADATA_KEY_CHILDCOUNT));
-        break;
       case GRL_METADATA_KEY_URL:
         urls[0] = (gchar *) grl_media_get_url (media);
         ms1_server_set_urls (server, properties_table, urls);
@@ -356,9 +439,97 @@ fill_properties_table (MS1Server *server,
       }
     }
   }
+}
 
-  if (parent_requested && parent_id) {
-    ms1_server_set_parent (server, properties_table, parent_id);
+static void
+fill_other_properties_table (MS1Server *server,
+                             GrlMediaSource *source,
+                             GHashTable *properties_table,
+                             GList *keys,
+                             GrlMedia *media,
+                             const gchar *parent_id)
+{
+  GList **containers = NULL;
+  GList **items = NULL;
+  GList *_containers;
+  GList *_items;
+  GList *key;
+  gchar *id;
+  guint *container_count = NULL;
+  guint *item_count = NULL;
+  guint _container_count;
+  guint _item_count;
+
+  for (key = keys; key; key = g_list_next (key)) {
+    if (g_strcmp0 (key->data, MS1_PROP_PARENT) == 0 && parent_id) {
+      ms1_server_set_parent (server,
+                             properties_table,
+                             parent_id);
+    } else if (g_strcmp0 (key->data, MS1_PROP_TYPE) == 0) {
+      if (GRL_IS_MEDIA_BOX (media)) {
+        ms1_server_set_item_type (server,
+                                  properties_table,
+                                  MS1_ITEM_TYPE_CONTAINER);
+      } else if (GRL_IS_MEDIA_IMAGE (media)) {
+        ms1_server_set_item_type (server,
+                                  properties_table,
+                                  MS1_ITEM_TYPE_IMAGE);
+      } else if (GRL_IS_MEDIA_AUDIO (media)) {
+        ms1_server_set_item_type (server,
+                                  properties_table,
+                                  MS1_ITEM_TYPE_AUDIO);
+      } else if (GRL_IS_MEDIA_VIDEO (media)) {
+        ms1_server_set_item_type (server,
+                                  properties_table,
+                                  MS1_ITEM_TYPE_VIDEO);
+      } else {
+        ms1_server_set_item_type (server,
+                                  properties_table,
+                                  MS1_ITEM_TYPE_UNKNOWN);
+      }
+    } else if (g_strcmp0 (key->data, MS1_PROP_ITEMS) == 0) {
+      items = &_items;
+    } else if (g_strcmp0 (key->data, MS1_PROP_ITEM_COUNT) == 0) {
+      item_count = &_item_count;
+    } else if (g_strcmp0 (key->data, MS1_PROP_CONTAINERS) == 0) {
+      containers = &_containers;
+    } else if (g_strcmp0 (key->data, MS1_PROP_CONTAINER_COUNT) == 0) {
+      container_count = &_container_count;
+    } else if (g_strcmp0 (key->data, MS1_PROP_SEARCHABLE) == 0) {
+      ms1_server_set_searchable (server,
+                                 properties_table,
+                                 FALSE);
+    }
+  }
+
+  if (items || item_count || containers || container_count) {
+    id = serialize_media (parent_id, media);
+    if (id) {
+      get_items_and_containers (server,
+                                source,
+                                id,
+                                items,
+                                item_count,
+                                containers,
+                                container_count);
+      g_free (id);
+    }
+    if (items) {
+      ms1_server_set_items (server, properties_table, *items);
+      g_list_foreach (*items, (GFunc) g_hash_table_unref, NULL);
+      g_list_free (*items);
+    }
+    if (item_count) {
+      ms1_server_set_item_count (server, properties_table, *item_count);
+    }
+    if (containers) {
+      ms1_server_set_containers (server, properties_table, *containers);
+      g_list_foreach (*containers, (GFunc) g_hash_table_unref, NULL);
+      g_list_free (*containers);
+    }
+    if (container_count) {
+      ms1_server_set_container_count (server, properties_table, *container_count);
+    }
   }
 }
 
@@ -381,9 +552,15 @@ metadata_cb (GrlMediaSource *source,
                          rgdata->properties,
                          rgdata->keys,
                          media,
-                         rgdata->parent_requested,
                          rgdata->parent_id);
 
+  fill_other_properties_table (rgdata->server,
+                               source,
+                               rgdata->properties,
+                               rgdata->other_keys,
+                               media,
+                               rgdata->parent_id);
+
   rgdata->updated = TRUE;
 }
 
@@ -410,8 +587,13 @@ browse_cb (GrlMediaSource *source,
                            prop_table,
                            rgdata->keys,
                            media,
-                           rgdata->parent_requested,
                            rgdata->parent_id);
+    fill_other_properties_table (rgdata->server,
+                                 source,
+                                 prop_table,
+                                 rgdata->other_keys,
+                                 media,
+                                 rgdata->parent_id);
     rgdata->children = g_list_prepend (rgdata->children, prop_table);
   }
 
@@ -450,7 +632,7 @@ get_properties_cb (MS1Server *server,
   rgdata = g_slice_new0 (RygelGriloData);
   rgdata->server = g_object_ref (server);
   rgdata->source = (GrlMediaSource *) data;
-  rgdata->keys = get_grilo_keys (properties, &rgdata->parent_requested);
+  rgdata->keys = get_grilo_keys (properties, &rgdata->other_keys);
   rgdata->parent_id = get_parent_id (id);
   media = unserialize_media (GRL_METADATA_SOURCE (rgdata->source), id);
 
@@ -477,6 +659,7 @@ get_properties_cb (MS1Server *server,
 
   g_object_unref (media);
   g_list_free (rgdata->keys);
+  g_list_free (rgdata->other_keys);
   g_free (rgdata->parent_id);
   g_object_unref (rgdata->server);
   g_slice_free (RygelGriloData, rgdata);
@@ -488,7 +671,7 @@ static GList *
 get_children_cb (MS1Server *server,
                  const gchar *id,
                  guint offset,
-                 gint max_count,
+                 guint max_count,
                  const gchar **properties,
                  gpointer data,
                  GError **error)
@@ -500,7 +683,7 @@ get_children_cb (MS1Server *server,
   rgdata = g_slice_new0 (RygelGriloData);
   rgdata->server = g_object_ref (server);
   rgdata->source = (GrlMediaSource *) data;
-  rgdata->keys = get_grilo_keys (properties, &rgdata->parent_requested);
+  rgdata->keys = get_grilo_keys (properties, &rgdata->other_keys);
   rgdata->parent_id = g_strdup (id);
   media = unserialize_media (GRL_METADATA_SOURCE (rgdata->source), id);
 
@@ -508,7 +691,7 @@ get_children_cb (MS1Server *server,
                            media,
                            rgdata->keys,
                            offset,
-                           max_count < 0? G_MAXINT: max_count,
+                           max_count == 0? G_MAXINT: max_count,
                            GRL_RESOLVE_FULL | GRL_RESOLVE_IDLE_RELAY,
                            browse_cb,
                            rgdata);
@@ -528,6 +711,7 @@ get_children_cb (MS1Server *server,
 
   g_object_unref (media);
   g_list_free (rgdata->keys);
+  g_list_free (rgdata->other_keys);
   g_free (rgdata->parent_id);
   g_object_unref (rgdata->server);
   g_slice_free (RygelGriloData, rgdata);



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