[rygel-grilo] Handle ListObjects message
- From: Juan A. Suarez Romero <jasuarez src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel-grilo] Handle ListObjects message
- Date: Tue, 4 May 2010 10:29:15 +0000 (UTC)
commit c12e85731e9d127549f4e53ba9d75cbc8e2176c8
Author: Juan A. Suarez Romero <jasuarez igalia com>
Date: Tue May 4 11:47:11 2010 +0200
Handle ListObjects message
lib/media-server2-introspection.h | 1 -
lib/media-server2-server-table.c | 46 ++++++++++-----
lib/media-server2-server.c | 110 +++++++++++++++++++++++++++++++++----
lib/media-server2-server.h | 9 ++-
src/rygel-grilo.c | 78 +++++++++++++++-----------
5 files changed, 179 insertions(+), 65 deletions(-)
---
diff --git a/lib/media-server2-introspection.h b/lib/media-server2-introspection.h
index 5736ddd..1a1d593 100644
--- a/lib/media-server2-introspection.h
+++ b/lib/media-server2-introspection.h
@@ -106,4 +106,3 @@
INTROSPECTION_CLOSE
#endif /* _MEDIA_SERVER2_INTROSPECTION_H_ */
-
diff --git a/lib/media-server2-server-table.c b/lib/media-server2-server-table.c
index 8eb3fc9..28e216d 100644
--- a/lib/media-server2-server-table.c
+++ b/lib/media-server2-server-table.c
@@ -111,40 +111,54 @@ id_to_object_path (MS2Server *server,
/**
* ms2_server_new_properties_hashtable:
- * @server: a #MS2Server
- * @id: identifier of item which properties will be stored in the table
- * @is_container: @TRUE if the item is a container, or @FALSE if it is an item.
*
* Creates a new #GHashTable suitable to store items properties.
*
- * @id will be transformed in an object path.
- *
* Returns: a new #GHashTable
**/
GHashTable *
-ms2_server_new_properties_hashtable (MS2Server *server,
- const gchar *id,
- gboolean is_container)
+ms2_server_new_properties_hashtable ()
{
GHashTable *properties;
- gchar *object_path;
-
- g_return_val_if_fail (MS2_IS_SERVER (server), NULL);
- g_return_val_if_fail (id, NULL);
properties = g_hash_table_new_full (g_str_hash,
g_str_equal,
NULL,
(GDestroyNotify) free_value);
- object_path = id_to_object_path (server, id, is_container);
- g_hash_table_insert (properties, MS2_PROP_ID, str_to_value (object_path));
- g_free (object_path);
-
return properties;
}
/**
+ * ms2_server_set_id:
+ * @server: a #MS2Server
+ * @properties: a #GHashTable
+ * @id: identifier value
+ * @is_container: @TRUE if the @id identifies a a container
+ *
+ * Sets the "id" property. Mandatory property
+ *
+ * @id will be transformed in an object path
+ **/
+void
+ms2_server_set_id (MS2Server *server,
+ GHashTable *properties,
+ const gchar *id,
+ gboolean is_container)
+{
+ gchar *object_path;
+
+ g_return_if_fail (MS2_IS_SERVER (server));
+ g_return_if_fail (properties);
+
+ if (id) {
+ object_path = id_to_object_path (server, id, is_container);
+ g_hash_table_insert (properties, MS2_PROP_ID, str_to_value (object_path));
+ g_free (object_path);
+ }
+}
+
+/**
* ms2_server_set_parent:
* @server: a #MS2Server
* @properties: a #GHashTable
diff --git a/lib/media-server2-server.c b/lib/media-server2-server.c
index c56ec5c..8187640 100644
--- a/lib/media-server2-server.c
+++ b/lib/media-server2-server.c
@@ -63,6 +63,7 @@ struct _MS2ServerPrivate {
static const gchar introspect_sgn[] = { DBUS_TYPE_INVALID };
static const gchar get_sgn[] = { DBUS_TYPE_STRING, DBUS_TYPE_STRING, DBUS_TYPE_INVALID };
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 *mediaobject2_properties[] = { MS2_PROP_DISPLAY_NAME,
MS2_PROP_PARENT,
@@ -466,9 +467,9 @@ get_id_from_message (DBusMessage *m)
}
static void
-append_variant_arg (DBusMessage *m,
- DBusMessageIter *iter,
- const GValue *v)
+add_variant (DBusMessage *m,
+ DBusMessageIter *iter,
+ const GValue *v)
{
DBusMessageIter iternew;
DBusMessageIter sub;
@@ -494,19 +495,24 @@ append_variant_arg (DBusMessage *m,
}
static void
-append_hashtable_arg (DBusMessage *m,
- GHashTable *t)
+add_hashtable_as_dict (DBusMessage *m,
+ DBusMessageIter *iter,
+ GHashTable *t)
{
- DBusMessageIter iter;
+ DBusMessageIter iternew;
DBusMessageIter sub_array;
DBusMessageIter sub_dict;
GList *key;
GList *keys;
GValue *v;
- dbus_message_iter_init_append (m, &iter);
+ if (!iter) {
+ dbus_message_iter_init_append (m, &iternew);
+ iter = &iternew;
+ }
+
/* Add an array of dict */
- dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sv}", &sub_array);
+ dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{sv}", &sub_array);
/* Add hashtable */
if (t) {
keys = g_hash_table_get_keys (t);
@@ -520,12 +526,35 @@ append_hashtable_arg (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);
- append_variant_arg (m, &sub_dict, v);
+ add_variant (m, &sub_dict, v);
dbus_message_iter_close_container (&sub_array, &sub_dict);
}
g_list_free (keys);
}
- dbus_message_iter_close_container (&iter, &sub_array);
+ dbus_message_iter_close_container (iter, &sub_array);
+}
+
+static void
+add_glist_as_array (DBusMessage *m,
+ DBusMessageIter *iter,
+ GList *l)
+{
+ DBusMessageIter iternew;
+ DBusMessageIter sub_array;
+
+ if (!iter) {
+ dbus_message_iter_init_append (m, &iternew);
+ iter = &iternew;
+ }
+
+ /* Add an array */
+ dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "a{sv}", &sub_array);
+ while (l) {
+ add_hashtable_as_dict (m, &sub_array, l->data);
+ l = g_list_next (l);
+ }
+
+ dbus_message_iter_close_container (iter, &sub_array);
}
static DBusHandlerResult
@@ -575,7 +604,7 @@ handle_get_message (DBusConnection *c,
interface);
} else {
r = dbus_message_new_method_return (m);
- append_variant_arg (r, NULL, value);
+ add_variant (r, NULL, value);
dbus_connection_send (c, r, NULL);
dbus_message_unref (r);
free_value (value);
@@ -630,7 +659,7 @@ handle_get_all_message (DBusConnection *c,
propresult = NULL;
}
r = dbus_message_new_method_return (m);
- append_hashtable_arg (r, propresult);
+ add_hashtable_as_dict (r, NULL, propresult);
dbus_connection_send (c, r, NULL);
dbus_message_unref (r);
if (propresult) {
@@ -643,6 +672,59 @@ handle_get_all_message (DBusConnection *c,
}
static DBusHandlerResult
+handle_list_objects_message (DBusConnection *c,
+ DBusMessage *m,
+ void *userdata)
+{
+ DBusMessage *r;
+ GList *children;
+ gchar **filter;
+ gchar *id;
+ guint max_count;
+ guint offset;
+ gint nitems;
+ MS2Server *server = MS2_SERVER (userdata);
+
+ /* Check signature */
+ if (dbus_message_has_signature (m, listobjects_sgn)) {
+ dbus_message_get_args (m, NULL,
+ DBUS_TYPE_UINT32, &offset,
+ DBUS_TYPE_UINT32, &max_count,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &filter, &nitems,
+ DBUS_TYPE_INVALID);
+ if (!server->priv->get_children || nitems == 0) {
+ children = NULL;
+ } else {
+ id = get_id_from_message (m);
+ if (!id) {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ children = server->priv->get_children (server,
+ id,
+ offset,
+ max_count? max_count: G_MAXUINT,
+ (const gchar **) filter,
+ server->priv->data,
+ NULL);
+ g_free (id);
+ dbus_free_string_array (filter);
+ }
+
+ r = dbus_message_new_method_return (m);
+ add_glist_as_array (r, NULL, children);
+ dbus_connection_send (c, r, NULL);
+ dbus_message_unref (r);
+ if (children) {
+ g_list_foreach (children, (GFunc) g_hash_table_unref, NULL);
+ g_list_free (children);
+ }
+ return DBUS_HANDLER_RESULT_HANDLED;
+ } else {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+}
+
+static DBusHandlerResult
items_handler (DBusConnection *c,
DBusMessage *m,
void *userdata)
@@ -683,6 +765,10 @@ containers_handler (DBusConnection *c,
"org.freedesktop.DBus.Properties",
"GetAll")) {
return handle_get_all_message (c, m, userdata);
+ } else if (dbus_message_is_method_call (m,
+ "org.gnome.UPnP.MediaContainer2",
+ "ListObjects")) {
+ return handle_list_objects_message (c, m, userdata);
} else {
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
diff --git a/lib/media-server2-server.h b/lib/media-server2-server.h
index 462ad7a..07323a2 100644
--- a/lib/media-server2-server.h
+++ b/lib/media-server2-server.h
@@ -105,9 +105,12 @@ void ms2_server_updated (MS2Server *server,
const gchar *ms2_server_get_name (MS2Server *server);
-GHashTable *ms2_server_new_properties_hashtable (MS2Server *server,
- const gchar *id,
- gboolean is_container);
+GHashTable *ms2_server_new_properties_hashtable (void);
+
+void ms2_server_set_id (MS2Server *server,
+ GHashTable *properties,
+ const gchar *id,
+ gboolean is_container);
void ms2_server_set_parent (MS2Server *server,
GHashTable *properties,
diff --git a/src/rygel-grilo.c b/src/rygel-grilo.c
index 501ab15..3641bfb 100644
--- a/src/rygel-grilo.c
+++ b/src/rygel-grilo.c
@@ -67,6 +67,7 @@ typedef struct {
GrlMediaSource *source;
MS2Server *server;
gboolean updated;
+ gboolean parent_requested;
gchar *parent_id;
} RygelGriloData;
@@ -209,13 +210,20 @@ unserialize_media (GrlMetadataSource *source, const gchar *id)
/* Given a null-terminated array of MediaServerSpec2 properties, returns a list
with the corresponding Grilo metadata keys */
static GList *
-get_grilo_keys (const gchar **ms_keys)
+get_grilo_keys (const gchar **ms_keys, gboolean *contains_parent)
{
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], MS2_PROP_DISPLAY_NAME) == 0) {
+ if (g_strcmp0 (ms_keys[i], MS2_PROP_ID) == 0) {
+ grl_keys = g_list_append (grl_keys,
+ GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ID));
+ } else if (g_strcmp0 (ms_keys[i], MS2_PROP_DISPLAY_NAME) == 0) {
grl_keys = g_list_append (grl_keys,
GRLKEYID_TO_POINTER (GRL_METADATA_KEY_TITLE));
} else if (g_strcmp0 (ms_keys[i], MS2_PROP_ALBUM) == 0) {
@@ -248,6 +256,8 @@ get_grilo_keys (const gchar **ms_keys)
} else if (g_strcmp0 (ms_keys[i], MS2_PROP_WIDTH) == 0) {
grl_keys = g_list_append (grl_keys,
GRLKEYID_TO_POINTER (GRL_METADATA_KEY_WIDTH));
+ } else if (g_strcmp0 (ms_keys[i], MS2_PROP_PARENT) == 0 && contains_parent) {
+ *contains_parent = TRUE;
}
}
@@ -259,16 +269,29 @@ fill_properties_table (MS2Server *server,
GHashTable *properties_table,
GList *keys,
GrlMedia *media,
+ gboolean parent_requested,
const gchar *parent_id)
{
GList *prop;
GrlKeyID key;
+ gchar *id;
gchar *urls[2] = { 0 };
for (prop = keys; prop; prop = g_list_next (prop)) {
key = POINTER_TO_GRLKEYID (prop->data);
- if (grl_data_key_is_known (GRL_DATA (media), key)) {
+ if (key == GRL_METADATA_KEY_ID ||
+ grl_data_key_is_known (GRL_DATA (media), key)) {
switch (key) {
+ case GRL_METADATA_KEY_ID:
+ id = serialize_media (parent_id, media);
+ if (id) {
+ ms2_server_set_id (server,
+ properties_table,
+ id,
+ GRL_IS_MEDIA_BOX (media));
+ g_free (id);
+ }
+ break;
case GRL_METADATA_KEY_TITLE:
ms2_server_set_display_name (server,
properties_table,
@@ -334,7 +357,7 @@ fill_properties_table (MS2Server *server,
}
}
- if (parent_id) {
+ if (parent_requested && parent_id) {
ms2_server_set_parent (server, properties_table, parent_id);
}
}
@@ -346,25 +369,20 @@ metadata_cb (GrlMediaSource *source,
const GError *error)
{
RygelGriloData *rgdata = (RygelGriloData *) user_data;
- gchar *id;
if (error) {
rgdata->error = g_error_copy (error);
rgdata->updated = TRUE;
return;
}
- id = serialize_media (rgdata->parent_id, media);
- if (id) {
- rgdata->properties = ms2_server_new_properties_hashtable (rgdata->server,
- id,
- GRL_IS_MEDIA_BOX (media));
- fill_properties_table (rgdata->server,
- rgdata->properties,
- rgdata->keys,
- media,
- rgdata->parent_id);
- g_free (id);
- }
+
+ rgdata->properties = ms2_server_new_properties_hashtable ();
+ fill_properties_table (rgdata->server,
+ rgdata->properties,
+ rgdata->keys,
+ media,
+ rgdata->parent_requested,
+ rgdata->parent_id);
rgdata->updated = TRUE;
}
@@ -379,7 +397,6 @@ browse_cb (GrlMediaSource *source,
{
GHashTable *prop_table;
RygelGriloData *rgdata = (RygelGriloData *) user_data;
- gchar *id;
if (error) {
rgdata->error = g_error_copy (error);
@@ -388,19 +405,14 @@ browse_cb (GrlMediaSource *source,
}
if (media) {
- id = serialize_media (rgdata->parent_id, media);
- if (id) {
- prop_table = ms2_server_new_properties_hashtable (rgdata->server,
- id,
- GRL_IS_MEDIA_BOX (media));
- fill_properties_table (rgdata->server,
- prop_table,
- rgdata->keys,
- media,
- rgdata->parent_id);
- rgdata->children = g_list_prepend (rgdata->children, prop_table);
- g_free (id);
- }
+ prop_table = ms2_server_new_properties_hashtable ();
+ fill_properties_table (rgdata->server,
+ prop_table,
+ rgdata->keys,
+ media,
+ rgdata->parent_requested,
+ rgdata->parent_id);
+ rgdata->children = g_list_prepend (rgdata->children, prop_table);
}
if (!remaining) {
@@ -438,7 +450,7 @@ get_properties_cb (MS2Server *server,
rgdata = g_slice_new0 (RygelGriloData);
rgdata->server = g_object_ref (server);
rgdata->source = (GrlMediaSource *) data;
- rgdata->keys = get_grilo_keys (properties);
+ rgdata->keys = get_grilo_keys (properties, &rgdata->parent_requested);
rgdata->parent_id = get_parent_id (id);
media = unserialize_media (GRL_METADATA_SOURCE (rgdata->source), id);
@@ -488,7 +500,7 @@ get_children_cb (MS2Server *server,
rgdata = g_slice_new0 (RygelGriloData);
rgdata->server = g_object_ref (server);
rgdata->source = (GrlMediaSource *) data;
- rgdata->keys = get_grilo_keys (properties);
+ rgdata->keys = get_grilo_keys (properties, &rgdata->parent_requested);
rgdata->parent_id = g_strdup (id);
media = unserialize_media (GRL_METADATA_SOURCE (rgdata->source), id);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]