[rygel-grilo] Handle introspection message



commit 25d8b1d29b38eb10ca984a11194cb70f3e489825
Author: Juan A. Suarez Romero <jasuarez igalia com>
Date:   Mon Apr 26 18:45:19 2010 +0200

    Handle introspection message
    
    From now on I'm starting a re-work to cope with new and big changes in V2 spec.
    
    Roughly speaking, it is a mix between V1 and old V2.
    
    As I need more powerful than glib-bindings is able to provide, I'm dealing with
    low-level dbus.
    
    In this first commit, I'm handling the Introspectable interface.

 data/media-server2.xml          |   72 +++++++++++++----
 lib/Makefile.am                 |   17 ----
 lib/media-server2-client-glue.h |  102 -----------------------
 lib/media-server2-client.c      |   61 +++++++-------
 lib/media-server2-server-glue.h |  170 ---------------------------------------
 lib/media-server2-server.c      |  109 ++++++++++++++++++-------
 6 files changed, 168 insertions(+), 363 deletions(-)
---
diff --git a/data/media-server2.xml b/data/media-server2.xml
index c056bf9..0074529 100644
--- a/data/media-server2.xml
+++ b/data/media-server2.xml
@@ -4,26 +4,66 @@
 
   <!-- http://live.gnome.org/Rygel/MediaServer2Spec -->
 
-  <interface name="org.gnome.UPnP.MediaServer2">
-    <method name="GetChildren">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
-      <arg name="id"        direction="in" type="s"/>
-      <arg name="offset"    direction="in" type="u"/>
-      <arg name="max_count" direction="in" type="i"/>
-      <arg name="filter"    direction="in" type="as"/>
-      <arg name="children"  direction="out" type="aav"/>
+  <interface name="org.gnome.UPnP.MediaObject2">
+    <property name="DisplayName" type="s" access="read"/>
+    <property name="IsContainer" type="b" access="read"/>
+    <property name="IsItem"      type="b" access="read"/>
+    <property name="Parent"      type="s" access="read"/>
+    <property name="Path"        type="o" access="read"/>
+  </interface>
+
+  <interface name="org.gnome.UPnP.MediaItem2">
+    <property name="URLs"     type="as" access="read"/>
+    <property name="MIMEType" type="s"  access="read"/>
+    <property name="Type"     type="s"  access="read"/>
+    <property name="Artist"   type="s"  access="read"/>
+    <property name="Album"    type="s"  access="read"/>
+    <property name="Genre"    type="s"  access="read"/>
+    <property name="Duration" type="i"  access="read"/>
+    <property name="Bitrate"  type="i"  access="read"/>
+    <property name="Width"    type="i"  access="read"/>
+    <property name="Height"   type="i"  access="read"/>
+  </interface>
+
+  <interface name="org.gnome.UPnP.MediaContainer2">
+    <property name="CanSearch"      type="b"  access="read"/>
+    <property name="ContainerCount" type="u"  access="read"/>
+    <property name="Containers"     type="ao" access="read"/>
+    <property name="ItemCount"      type="u"  access="read"/>
+    <property name="Items"          type="ao" access="read"/>
+
+    <method name="ListObjects">
+      <arg name="offset"  direction="in"  type="u"/>
+      <arg name="max"     direction="in"  type="u"/>
+      <arg name="filter"  direction="in"  type="as"/>
+      <arg name="objects" direction="out" type="a(a{sv})"/>
     </method>
 
-    <method name="GetProperties">
-      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
-      <arg name="id"         direction="in"  type="s"/>
-      <arg name="filter"     direction="in"  type="as"/>
-      <arg name="properties" direction="out" type="av"/>
+    <method name="SearchObjects">
+      <arg name="query"   direction="in"  type="s"/>
+      <arg name="offset"  direction="in"  type="u"/>
+      <arg name="max"     direction="in"  type="u"/>
+      <arg name="filter"  direction="in"  type="as"/>
+      <arg name="objects" direction="out" type="a(a{sv})"/>
     </method>
+  </interface>
 
-    <signal name="Updated">
-      <arg name="id" type="s"/>
-    </signal>
+  <interface name="org.freedesktop.DBus.Introspectable">
+    <method name="Introspect">
+      <arg name="xml_data" direction="out" type="s"/>
+    </method>
+  </interface>
 
+  <interface name="org.freedesktop.DBus.Properties">
+    <method name="Get">
+      <arg name="interface" direction="in"  type="s"/>
+      <arg name="property"  direction="in"  type="s"/>
+      <arg name="value"     direction="out" type="v"/>
+    </method>
+
+    <method name="GetAll">
+      <arg name="interface" direction="in"  type="s"/>
+      <arg name="propeties" direction="out" type="a{sv}"/>
+    </method>
   </interface>
 </node>
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 0d7372b..632bfae 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -7,20 +7,6 @@
 
 INCLUDES = @DEPS_CFLAGS@
 
-%-server-glue.h: $(top_srcdir)/data/%.xml
-	$(AM_V_GEN) $(DBUSBINDINGTOOL)	\
-	--mode=glib-server		\
-	--output=$@			\
-	--prefix=ms2_server		\
-	$^
-
-%-client-glue.h: $(top_srcdir)/data/%.xml
-	$(AM_V_GEN) $(DBUSBINDINGTOOL)	\
-	--mode=glib-client		\
-	--output=$@			\
-	--prefix=ms2_client		\
-	$^
-
 lib_LTLIBRARIES = libmediaserver2.la
 
 libmediaserver2_la_CFLAGS =	\
@@ -30,13 +16,10 @@ libmediaserver2_la_LIBADD =	\
 	$(DEPS_LIBS)
 
 libmediaserver2_la_SOURCES =		\
-	media-server2-private.h		\
 	media-server2-common.h		\
-	media-server2-server-glue.h	\
 	media-server2-server.h		\
 	media-server2-server-table.c	\
 	media-server2-server.c		\
-	media-server2-client-glue.h	\
 	media-server2-client.h		\
 	media-server2-client.c		\
 	media-server2-observer.h	\
diff --git a/lib/media-server2-client.c b/lib/media-server2-client.c
index b8e4da0..936bd79 100644
--- a/lib/media-server2-client.c
+++ b/lib/media-server2-client.c
@@ -25,7 +25,6 @@
 #include <string.h>
 
 #include "media-server2-private.h"
-#include "media-server2-client-glue.h"
 #include "media-server2-client.h"
 
 #define DBUS_TYPE_G_ARRAY_OF_STRING                             \
@@ -156,6 +155,7 @@ get_children_list (GPtrArray *result,
   return children;
 }
 
+#if 0
 /* Callback invoked by dbus as answer to get_properties_async() */
 static void
 get_properties_async_reply (DBusGProxy *proxy,
@@ -176,7 +176,9 @@ get_properties_async_reply (DBusGProxy *proxy,
   g_simple_async_result_complete (res);
   g_object_unref (res);
 }
+#endif
 
+#if 0
 /* Callback invoked by dbus as answer to get_children_async() */
 static void
 get_children_async_reply (DBusGProxy *proxy,
@@ -198,6 +200,7 @@ get_children_async_reply (DBusGProxy *proxy,
   g_simple_async_result_complete (res);
   g_object_unref (res);
 }
+#endif
 
 /* Dispose function */
 static void
@@ -465,13 +468,13 @@ ms2_client_get_properties (MS2Client *client,
 
   g_return_val_if_fail (MS2_IS_CLIENT (client), NULL);
 
-  if (!org_gnome_UPnP_MediaServer2_get_properties (client->priv->proxy_provider,
-                                                   id,
-                                                   properties,
-                                                   &result,
-                                                   error)) {
-    return NULL;
-  }
+  /* if (!org_gnome_UPnP_MediaServer2_get_properties (client->priv->proxy_provider, */
+  /*                                                  id, */
+  /*                                                  properties, */
+  /*                                                  &result, */
+  /*                                                  error)) { */
+  /*   return NULL; */
+  /* } */
 
   prop_result = get_properties_table (result, properties);
   g_boxed_free (DBUS_TYPE_PROPERTIES, result);
@@ -522,11 +525,11 @@ void ms2_client_get_properties_async (MS2Client *client,
                                              adata,
                                              (GDestroyNotify) free_async_data);
 
-  org_gnome_UPnP_MediaServer2_get_properties_async (client->priv->proxy_provider,
-                                                    id,
-                                                    properties,
-                                                    get_properties_async_reply,
-                                                    res);
+  /* org_gnome_UPnP_MediaServer2_get_properties_async (client->priv->proxy_provider, */
+  /*                                                   id, */
+  /*                                                   properties, */
+  /*                                                   get_properties_async_reply, */
+  /*                                                   res); */
 }
 
 /**
@@ -583,15 +586,15 @@ ms2_client_get_children (MS2Client *client,
 
   g_return_val_if_fail (MS2_IS_CLIENT (client), NULL);
 
-  if (!org_gnome_UPnP_MediaServer2_get_children (client->priv->proxy_provider,
-                                                 id,
-                                                 offset,
-                                                 max_count,
-                                                 properties,
-                                                 &result,
-                                                 error)) {
-    return NULL;
-  }
+  /* if (!org_gnome_UPnP_MediaServer2_get_children (client->priv->proxy_provider, */
+  /*                                                id, */
+  /*                                                offset, */
+  /*                                                max_count, */
+  /*                                                properties, */
+  /*                                                &result, */
+  /*                                                error)) { */
+  /*   return NULL; */
+  /* } */
 
 
   children = get_children_list (result, properties);
@@ -648,13 +651,13 @@ void ms2_client_get_children_async (MS2Client *client,
                                              adata,
                                              (GDestroyNotify) free_async_data);
 
-  org_gnome_UPnP_MediaServer2_get_children_async (client->priv->proxy_provider,
-                                                  id,
-                                                  offset,
-                                                  max_count,
-                                                  properties,
-                                                  get_children_async_reply,
-                                                  res);
+  /* org_gnome_UPnP_MediaServer2_get_children_async (client->priv->proxy_provider, */
+  /*                                                 id, */
+  /*                                                 offset, */
+  /*                                                 max_count, */
+  /*                                                 properties, */
+  /*                                                 get_children_async_reply, */
+  /*                                                 res); */
 }
 
 /**
diff --git a/lib/media-server2-server.c b/lib/media-server2-server.c
index fafab9f..9490ff4 100644
--- a/lib/media-server2-server.c
+++ b/lib/media-server2-server.c
@@ -22,12 +22,16 @@
 
 #include <dbus/dbus-glib-bindings.h>
 #include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus.h>
 #include <string.h>
 
 #include "media-server2-private.h"
-#include "media-server2-server-glue.h"
 #include "media-server2-server.h"
 
+#define INTROSPECTION_FILE                                              \
+  "/home/jasuarez/Projects/grilo/rygel-grilo/data/media-server2.xml"
+
 #define DBUS_TYPE_G_ARRAY_OF_STRING                             \
   (dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING))
 
@@ -53,6 +57,8 @@ struct _MS2ServerPrivate {
   GetPropertiesFunc get_properties;
 };
 
+static const gchar introspect_sgn[] = { DBUS_TYPE_INVALID };
+
 static guint32 signals[LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE (MS2Server, ms2_server, G_TYPE_OBJECT);
@@ -224,51 +230,102 @@ check_properties (const gchar **filter)
   return NULL;
 }
 
+static const gchar *
+get_introspection ()
+{
+  GError *error = NULL;
+  GFile *uri;
+  static gchar *introspection = NULL;
+
+  if (!introspection) {
+    uri = g_vfs_get_file_for_path (g_vfs_get_default (), INTROSPECTION_FILE);
+    if (!g_file_load_contents (uri, NULL, &introspection, NULL, NULL, &error)) {
+      g_printerr ("Unable to load introspection data, %s\n", error->message);
+      g_error_free (error);
+    }
+    g_object_unref (uri);
+  }
+
+  return introspection;
+}
+
+static DBusHandlerResult
+handle_introspect_message (DBusConnection *c,
+                           DBusMessage *m,
+                           void *userdata)
+{
+  const gchar *xml;
+  DBusMessage *r;
+
+  /* Check signature */
+  if (dbus_message_has_signature (m, introspect_sgn)) {
+    xml = get_introspection ();
+    r = dbus_message_new_method_return (m);
+    dbus_message_append_args (r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID);
+    dbus_connection_send (c, r, NULL);
+    dbus_message_unref (r);
+    return DBUS_HANDLER_RESULT_HANDLED;
+  } else {
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+  }
+}
+
+static DBusHandlerResult
+root_handler (DBusConnection *c,
+              DBusMessage *m,
+              void *userdata)
+{
+  const gchar *iface;
+
+  iface = dbus_message_get_interface (m);
+
+  if (dbus_message_is_method_call (m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
+    return handle_introspect_message (c, m, userdata);
+  } else {
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+  }
+}
+
 /* Registers the MS2Server object in dbus */
 static gboolean
 ms2_server_dbus_register (MS2Server *server,
                           const gchar *name)
 {
-  DBusGConnection *connection;
-  DBusGProxy *gproxy;
-  GError *error = NULL;
+  DBusConnection *connection;
+  DBusError error;
   gchar *dbus_name;
   gchar *dbus_path;
-  guint request_name_result;
+  static const DBusObjectPathVTable vtable_root = {
+    .message_function = root_handler,
+  };
 
-  connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+  dbus_error_init (&error);
+
+  connection = dbus_bus_get (DBUS_BUS_SESSION, &error);
   if (!connection) {
-    g_printerr ("Could not connect to session bus, %s\n", error->message);
-    g_error_free (error);
+    g_printerr ("Could not connect to session bus, %s\n", error.message);
     return FALSE;
   }
 
-  gproxy = dbus_g_proxy_new_for_name (connection,
-                                      DBUS_SERVICE_DBUS,
-                                      DBUS_PATH_DBUS,
-                                      DBUS_INTERFACE_DBUS);
-
   /* Request name */
   dbus_name = g_strconcat (MS2_DBUS_SERVICE_PREFIX, name, NULL);
-  if (!org_freedesktop_DBus_request_name (gproxy,
-                                          dbus_name,
-                                          DBUS_NAME_FLAG_DO_NOT_QUEUE,
-                                          &request_name_result,
-                                          NULL))  {
+  if (dbus_bus_request_name (connection,
+                             dbus_name,
+                             DBUS_NAME_FLAG_DO_NOT_QUEUE,
+                             &error) != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+    g_printerr ("Failed to request name %s, %s\n", dbus_name, error.message);
     g_free (dbus_name);
     return FALSE;
   }
   g_free (dbus_name);
-  g_object_unref (gproxy);
 
   dbus_path = g_strconcat (MS2_DBUS_PATH_PREFIX, name, NULL);
+  dbus_connection_register_object_path (connection, dbus_path, &vtable_root, server);
 
-  /* Register object */
-  dbus_g_connection_register_g_object (connection,
-                                       dbus_path,
-                                       G_OBJECT (server));
   g_free (dbus_path);
 
+  dbus_connection_setup_with_g_main(connection, NULL);
+
   return TRUE;
 }
 
@@ -335,10 +392,6 @@ ms2_server_class_init (MS2ServerClass *klass)
                                    G_TYPE_NONE,
                                    1,
                                    G_TYPE_STRING);
-
-  /* Register introspection */
-  dbus_g_object_type_install_info (MS2_TYPE_SERVER,
-                                   &dbus_glib_ms2_server_object_info);
 }
 
 /* Object init function */
@@ -517,8 +570,6 @@ ms2_server_get_children (MS2Server *server,
 
 /********************* PUBLIC API *********************/
 
-/********** SERVER API **********/
-
 /**
  * ms2_server_new:
  * @name: the name used when registered in DBus



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