[rygel-grilo] Fix get_properties() client function



commit c3f2c5ebd4c6f942a794eeae73c3cb3b61fc8d86
Author: Juan A. Suarez Romero <jasuarez igalia com>
Date:   Wed May 5 17:46:01 2010 +0200

    Fix get_properties() client function

 lib/media-server2-client.c |  183 ++++++++++++++++++++++++++++++++------------
 lib/media-server2-client.h |    4 +-
 src/test-client.c          |   21 ++++--
 3 files changed, 152 insertions(+), 56 deletions(-)
---
diff --git a/lib/media-server2-client.c b/lib/media-server2-client.c
index bca872b..facf8d3 100644
--- a/lib/media-server2-client.c
+++ b/lib/media-server2-client.c
@@ -36,6 +36,9 @@
 #define DBUS_TYPE_CHILDREN                                              \
   dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_PROPERTIES)
 
+#define IMEDIAOBJECT2_INDEX 0
+#define IMEDIAITEM2_INDEX   1
+
 #define MS2_CLIENT_GET_PRIVATE(o)                                       \
   G_TYPE_INSTANCE_GET_PRIVATE((o), MS2_TYPE_CLIENT, MS2ClientPrivate)
 
@@ -65,20 +68,28 @@ typedef struct {
 
 /*
  * Private MS2Client structure
- *   proxy_provider: a dbus proxy of content provider
+ *   bus: connection to DBus session
  *   name: name of provider
+ *   fullname: full dbus service name of provider
+ *   root_path: object path to reach root category
  */
 struct _MS2ClientPrivate {
-  DBusGProxy *proxy_provider;
+  DBusGConnection *bus;
   gchar *name;
+  gchar *fullname;
+  gchar *root_path;
 };
 
 static guint32 signals[LAST_SIGNAL] = { 0 };
 
+static gchar *IFACES[] = { "org.gnome.UPnP.MediaObject2",
+                           "org.gnome.UPnP.MediaItem2" };
+
 G_DEFINE_TYPE (MS2Client, ms2_client, G_TYPE_OBJECT);
 
 /******************** PRIVATE API ********************/
 
+#if 0
 /* Callback invoked when "Updated" dbus signal is received */
 static void
 updated (DBusGProxy *proxy,
@@ -87,6 +98,7 @@ updated (DBusGProxy *proxy,
 {
   g_signal_emit (client, signals[UPDATED], 0, id);
 }
+#endif
 
 /* Free gvalue */
 static void
@@ -106,6 +118,41 @@ free_async_data (AsyncData *adata)
   g_slice_free (AsyncData, adata);
 }
 
+static gboolean
+collect_value (gpointer key,
+               gpointer value,
+               GHashTable *collection)
+{
+  g_hash_table_insert (collection, key, value);
+  return TRUE;
+}
+
+static gchar ***
+split_properties_by_interface (gchar **properties)
+{
+  gchar ***split;
+  gint prop_length;
+  gint mo_index = 0;
+  gint mi_index = 0;
+  gchar **property;
+
+  prop_length = g_strv_length (properties) + 1;
+  split = g_new (gchar **, 2);
+  split[IMEDIAOBJECT2_INDEX] = g_new0 (gchar *, prop_length);
+  split[IMEDIAITEM2_INDEX] = g_new0 (gchar *, prop_length);
+  for (property = properties; *property; property++) {
+    if (g_strcmp0 (*property, MS2_PROP_DISPLAY_NAME) == 0 ||
+        g_strcmp0 (*property, MS2_PROP_PARENT) == 0 ||
+        g_strcmp0 (*property, MS2_PROP_PATH) == 0) {
+      split[IMEDIAOBJECT2_INDEX][mo_index++] = *property;
+    } else {
+      split[IMEDIAITEM2_INDEX][mi_index++] = *property;
+    }
+  }
+
+  return split;
+}
+
 /* Given a GPtrArray result (dbus answer of getting properties), returns a
    ghashtable with pairs <keys, values> */
 static GHashTable *
@@ -210,11 +257,6 @@ ms2_client_dispose (GObject *object)
 
   ms2_observer_remove_client (client, client->priv->name);
 
-  if (client->priv->proxy_provider) {
-    g_object_unref (client->priv->proxy_provider);
-    client->priv->proxy_provider = NULL;
-  }
-
   G_OBJECT_CLASS (ms2_client_parent_class)->dispose (object);
 }
 
@@ -224,6 +266,8 @@ ms2_client_finalize (GObject *object)
   MS2Client *client = MS2_CLIENT (object);
 
   g_free (client->priv->name);
+  g_free (client->priv->fullname);
+  g_free (client->priv->root_path);
 
   G_OBJECT_CLASS (ms2_client_parent_class)->finalize (object);
 }
@@ -383,11 +427,8 @@ ms2_client_get_providers ()
 MS2Client *ms2_client_new (const gchar *provider)
 {
   DBusGConnection *connection;
-  DBusGProxy *gproxy;
   GError *error = NULL;
   MS2Client *client;
-  gchar *service_provider;
-  gchar *path_provider;
 
   connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
   if (!connection) {
@@ -396,36 +437,14 @@ MS2Client *ms2_client_new (const gchar *provider)
     return NULL;
   }
 
-  service_provider = g_strconcat (MS2_DBUS_SERVICE_PREFIX, provider, NULL);
-  path_provider = g_strconcat (MS2_DBUS_PATH_PREFIX, provider, NULL);
-
-  gproxy = dbus_g_proxy_new_for_name_owner (connection,
-                                            service_provider,
-                                            path_provider,
-                                            MS2_DBUS_IFACE,
-                                            &error);
-
-  g_free (service_provider);
-  g_free (path_provider);
-
-  if (!gproxy) {
-    g_printerr ("Could not connect to %s provider, %s\n",
-                provider,
-                error->message);
-    g_clear_error (&error);
-    return NULL;
-  }
-
   client = g_object_new (MS2_TYPE_CLIENT, NULL);
-  client->priv->proxy_provider = gproxy;
+  client->priv->bus = connection;
   client->priv->name = g_strdup (provider);
+  client->priv->fullname = g_strconcat (MS2_DBUS_SERVICE_PREFIX, provider, NULL);
+  client->priv->root_path = g_strconcat (MS2_DBUS_PATH_PREFIX, provider, NULL);
 
   ms2_observer_add_client (client, provider);
 
-  /* Listen to "updated" signal */
-  dbus_g_proxy_add_signal (gproxy, "Updated", G_TYPE_STRING, G_TYPE_INVALID);
-  dbus_g_proxy_connect_signal (gproxy, "Updated", G_CALLBACK (updated), client, NULL);
-
   return client;
 }
 
@@ -459,27 +478,87 @@ ms2_client_get_provider_name (MS2Client *client)
  **/
 GHashTable *
 ms2_client_get_properties (MS2Client *client,
-                           const gchar *id,
-                           const gchar **properties,
+                           const gchar *object_path,
+                           gchar **properties,
                            GError **error)
 {
+  DBusGProxy *gproxy;
+  GHashTable *collected_properties;
   GHashTable *prop_result;
-  GPtrArray *result = NULL;
+  GValue *v;
+  gboolean error_happened = FALSE;
+  gchar ***prop_by_iface;
+  gint i;
+  gint num_props;
 
   g_return_val_if_fail (MS2_IS_CLIENT (client), NULL);
+  g_return_val_if_fail (properties, NULL);
 
-  /* if (!org_gnome_UPnP_MediaServer2_get_properties (client->priv->proxy_provider, */
-  /*                                                  id, */
-  /*                                                  properties, */
-  /*                                                  &result, */
-  /*                                                  error)) { */
-  /*   return NULL; */
-  /* } */
+  gproxy = dbus_g_proxy_new_for_name (client->priv->bus,
+                                      client->priv->fullname,
+                                      object_path,
+                                      "org.freedesktop.DBus.Properties");
+
+  collected_properties = g_hash_table_new_full (g_str_hash,
+                                                g_str_equal,
+                                                (GDestroyNotify) g_free,
+                                                (GDestroyNotify) free_gvalue);
+
+  prop_by_iface = split_properties_by_interface (properties);
+  for (i = 0; i < 2; i++) {
+    num_props = g_strv_length (prop_by_iface[i]);
+    /* If only one property is required, then invoke "Get" method */
+    if (num_props == 1) {
+      v = g_new0 (GValue, 1);
+      if (dbus_g_proxy_call (gproxy,
+                             "Get", error,
+                             G_TYPE_STRING, IFACES[i],
+                             G_TYPE_STRING, prop_by_iface[i][0],
+                             G_TYPE_INVALID,
+                             G_TYPE_VALUE, &v,
+                             G_TYPE_INVALID)) {
+        g_hash_table_insert (collected_properties,
+                             g_strdup (prop_by_iface[i][0]),
+                             v);
+      } else {
+        error_happened = TRUE;
+        break;
+      }
+    } else if (num_props > 1) {
+      /* If several properties are required, use "GetAll" method */
+      if (dbus_g_proxy_call (gproxy,
+                             "GetAll", error,
+                             G_TYPE_STRING, IFACES[i],
+                             G_TYPE_INVALID,
+                             dbus_g_type_get_map ("GHashTable",
+                                                  G_TYPE_STRING,
+                                                  G_TYPE_VALUE), &prop_result,
+                            G_TYPE_INVALID)) {
+        g_hash_table_foreach_steal (prop_result,
+                                    (GHRFunc) collect_value,
+                                    collected_properties);
+        g_hash_table_unref (prop_result);
+      } else {
+        error_happened = TRUE;
+        break;
+      }
+    }
+  }
 
-  prop_result = get_properties_table (result, properties);
-  g_boxed_free (DBUS_TYPE_PROPERTIES, result);
+  g_object_unref (gproxy);
 
-  return prop_result;
+  g_free (prop_by_iface[0]);
+  g_free (prop_by_iface[1]);
+  g_free (prop_by_iface);
+
+  if (error_happened) {
+    if (collected_properties) {
+      g_hash_table_unref (collected_properties);
+    }
+    return NULL;
+  } else {
+    return collected_properties;
+  }
 }
 
 /**
@@ -686,6 +765,14 @@ ms2_client_get_children_finish (MS2Client *client,
   return adata->children_result;
 }
 
+const gchar *
+ms2_client_get_root_path (MS2Client *client)
+{
+  g_return_val_if_fail (MS2_IS_CLIENT (client), NULL);
+
+  return client->priv->root_path;
+}
+
 /******************** PROPERTIES TABLE API ********************/
 
 /**
diff --git a/lib/media-server2-client.h b/lib/media-server2-client.h
index 2e5a302..b7f9baa 100644
--- a/lib/media-server2-client.h
+++ b/lib/media-server2-client.h
@@ -88,7 +88,7 @@ const gchar *ms2_client_get_provider_name (MS2Client *client);
 
 GHashTable *ms2_client_get_properties (MS2Client *client,
                                        const gchar *id,
-                                       const gchar **properties,
+                                       gchar **properties,
                                        GError **error);
 
 void ms2_client_get_properties_async (MS2Client *client,
@@ -120,6 +120,8 @@ GList *ms2_client_get_children_finish (MS2Client *client,
                                        GAsyncResult *res,
                                        GError **error);
 
+const gchar *ms2_client_get_root_path (MS2Client *client);
+
 const gchar *ms2_client_get_path (GHashTable *properties);
 
 const gchar *ms2_client_get_parent (GHashTable *properties);
diff --git a/src/test-client.c b/src/test-client.c
index fb20e7e..24d9db9 100644
--- a/src/test-client.c
+++ b/src/test-client.c
@@ -6,7 +6,6 @@
 static const gchar *properties[] = { MS2_PROP_PATH,
 				     MS2_PROP_DISPLAY_NAME,
                                      MS2_PROP_PARENT,
-                                     MS2_PROP_CHILD_COUNT,
                                      NULL };
 
 static void
@@ -63,7 +62,7 @@ test_children_async ()
     }
 
     ms2_client_get_children_async (client,
-                                   MS2_ROOT,
+                                   ms2_client_get_root_path (client),
                                    0,
                                    -1,
                                    properties,
@@ -132,7 +131,7 @@ test_properties_async ()
     }
 
     ms2_client_get_properties_async (client,
-                                     MS2_ROOT,
+                                     ms2_client_get_root_path (client),
                                      properties,
                                      properties_reply,
                                      g_strdup (*provider));
@@ -167,7 +166,10 @@ test_properties_sync ()
       return;
     }
 
-    result = ms2_client_get_properties (client, MS2_ROOT, properties, &error);
+    result = ms2_client_get_properties (client,
+                                        ms2_client_get_root_path (client),
+                                        (gchar **) properties,
+                                        &error);
 
     g_print ("\n* Provider '%s'\n", *provider);
     if (!result) {
@@ -217,7 +219,12 @@ test_children_sync ()
       return;
     }
 
-    children  = ms2_client_get_children (client, MS2_ROOT, 0, -1, properties, &error);
+    children  = ms2_client_get_children (client,
+                                         ms2_client_get_root_path (client),
+                                         0,
+                                         -1,
+                                         properties,
+                                         &error);
 
     g_print ("\n* Provider '%s'\n", *provider);
     if (!children) {
@@ -329,12 +336,12 @@ int main (int argc, char **argv)
 
   g_type_init ();
 
-  if (0) test_properties_sync ();
+  if (1) test_properties_sync ();
   if (0) test_children_sync ();
   if (0) test_properties_async ();
   if (0) test_children_async ();
   if (0) test_provider_free ();
-  if (1) test_dynamic_providers ();
+  if (0) test_dynamic_providers ();
 
   mainloop = g_main_loop_new (NULL, FALSE);
   g_main_loop_run (mainloop);



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