Create a utility class to bind low-level tp-glib code without really exposing it
authorTravis Reitter <travis.reitter@collabora.co.uk>
Thu, 15 Apr 2010 20:52:17 +0000 (13:52 -0700)
committerTravis Reitter <travis.reitter@collabora.co.uk>
Thu, 15 Apr 2010 20:52:17 +0000 (13:52 -0700)
.gitignore
configure.ac
telepathy-people/Makefile.am
telepathy-people/persona-store.vala
telepathy-people/tp-lowlevel.c [new file with mode: 0644]
telepathy-people/tp-lowlevel.h [new file with mode: 0644]

index 31bfd69..5ca8022 100644 (file)
@@ -55,5 +55,7 @@ Makefile.in
 /telepathy-people/telepathy-people.pc
 /telepathy-people/telepathy-people-uninstalled.pc
 /telepathy-people/telepathy-people.vapi
+/telepathy-people/tp-lowlevel.gi
+/telepathy-people/tp-lowlevel.vapi
 
 /tests/test-*[^ch]
index 19ea193..85ed378 100644 (file)
@@ -60,6 +60,14 @@ PKG_CHECK_MODULES(LIBTPP,
 AC_SUBST(LIBTPP_CFLAGS)
 AC_SUBST(LIBTPP_LIBS)
 
+PKG_CHECK_MODULES(LIBTP_LOWLEVEL,
+                  glib-2.0 >= $GLIB_REQUIRED
+                  gobject-2.0 >= $GLIB_REQUIRED
+                  telepathy-glib
+                  )
+AC_SUBST(LIBTP_LOWLEVEL_CFLAGS)
+AC_SUBST(LIBTP_LOWLEVEL_LIBS)
+
 GTK_DOC_CHECK([1.10])
 
 # -----------------------------------------------------------
index adb3843..d666fe9 100644 (file)
@@ -1,11 +1,54 @@
+GEN_INTROSPECT = $(shell pkg-config vala-1.0 --variable="gen_introspect")
+VAPIGEN = $(shell pkg-config vala-1.0 --variable="vapigen")
+
 AM_CPPFLAGS = \
        $(LIBTPP_CFLAGS) \
        -include $(CONFIG_HEADER) \
        -DPACKAGE_DATADIR=\"$(pkgdatadir)\" \
        $(NULL)
 
+# this seems to work, even if vim's syntax highlighting suggests otherwise
+VALAFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --variable=valaflags telepathy-vala)
+VALAFLAGS += --vapidir=.
+VALAFLAGS += --pkg gobject-2.0 --pkg gio-2.0 --pkg gee-1.0 --pkg dbus-glib-1 --pkg telepathy-glib
+
 libtelepathy_peopledir = $(includedir)/telepathy-people
-lib_LTLIBRARIES = libtelepathy-people.la
+lib_LTLIBRARIES = \
+       libtp-lowlevel.la \
+       libtelepathy-people.la \
+       $(NULL)
+
+# FIXME: cut the redundancy here with tp_lowlevel_sources, etc.
+libtp_lowlevel_la_SOURCES = \
+       tp-lowlevel.c \
+       tp-lowlevel.h \
+       $(NULL)
+
+libtp_lowlevel_la_CPPFLAGS = \
+       $(LIBTP_LOWLEVEL_CFLAGS) \
+       $(NULL)
+
+libtp_lowlevel_la_LDFLAGS = \
+       $(LIBTP_LOWLEVEL_LIBS) \
+       $(NULL)
+
+tp_lowlevel_sources = \
+       tp-lowlevel.c \
+       tp-lowlevel.h \
+       $(NULL)
+
+# FIXME: wrap lines
+# FIXME: use a better path to the .so file
+tp-lowlevel.gi: $(tp_lowlevel_sources) libtp-lowlevel.la
+       $(GEN_INTROSPECT) --namespace=Tp tp-lowlevel.h \
+               $(shell pkg-config telepathy-glib --cflags) .libs/libtp-lowlevel.so > tp-lowlevel.gi
+
+tp-lowlevel.vapi: tp-lowlevel.gi
+       $(VAPIGEN) $(VALAFLAGS) --library tp-lowlevel tp-lowlevel.gi
+
+internal_vapi_files = \
+       tp-lowlevel.vapi \
+       $(NULL)
 
 libtelepathy_people_la_VALASOURCES = \
        individual.vala \
@@ -16,6 +59,7 @@ libtelepathy_people_la_VALASOURCES = \
 libtelepathy_people_la_SOURCES = \
        telepathy-people.vala.stamp \
        $(libtelepathy_people_la_VALASOURCES:.vala=.c) \
+       $(tp_lowlevel_sources) \
        $(NULL)
 
 libtelepathy_people_la_LIBADD = \
@@ -28,13 +72,10 @@ telepathy_people_HEADERS = \
        telepathy-people.h \
        $(NULL)
 
-# this seems to work, even if vim's syntax highlighting suggests otherwise
-VALAFLAGS += $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --variable=valaflags telepathy-vala)
-
 telepathy-people.h $(libtelepathy_people_la_VALASOURCES:.vala=.c) $(libtelepathy_people_la_VALASOURCES:.vala=.h): telepathy-people.vala.stamp
 
-telepathy-people.vapi telepathy-people.vala.stamp: $(libtelepathy_people_la_VALASOURCES)
-       $(VALAC) $(VALAFLAGS) -C --pkg gobject-2.0 --pkg gio-2.0 --pkg gee-1.0 --pkg dbus-glib-1 --pkg telepathy-glib -H telepathy-people.h --library telepathy-people $^
+telepathy-people.vapi telepathy-people.vala.stamp: $(libtelepathy_people_la_VALASOURCES) $(internal_vapi_files)
+       $(VALAC) $(VALAFLAGS) -C --pkg tp-lowlevel -H telepathy-people.h --library telepathy-people $(libtelepathy_people_la_VALASOURCES)
        touch $@
 
 pkgconfig_in = telepathy-people.pc.in
@@ -44,6 +85,8 @@ pkgconfig_DATA = $(pkgconfig_in:.in=)
 BUILT_SOURCES = \
        telepathy-people.vala.stamp \
        telepathy-people.h \
+       tp-lowlevel.gi \
+       tp-lowlevel.vapi \
        $(libtelepathy_people_la_VALASOURCES:.vala=.c) \
        $(pkgconfig_in:.in=) \
        $(NULL)
@@ -54,6 +97,7 @@ EXTRA_DIST = \
        $(pkgconfig_in) \
        telepathy-people.vala.stamp \
        telepathy-people.vapi \
+       tp-lowlevel.vapi \
        $(NULL)
 
 DISTCLEANFILES = \
index 3c40ff3..f5399f5 100644 (file)
@@ -24,6 +24,7 @@ using Tp.Channel;
 using Tp.Handle;
 using Tp.Account;
 using Tp.AccountManager;
+using Tp.Lowlevel;
 
 /* FIXME: split out the TpAccount-specific parts into a new subclass, since
  * PersonaStore should also be used by non-Telepathy sources */
@@ -32,23 +33,6 @@ public class Tp.PersonaStore : Object {
                         blurb = "Telepathy account this store is based upon")]
         public Account account { get; construct; }
 
-        /* FIXME: cut this */
-#if 0
-        private void account_ready_cb () {
-                /* FIXME: cut this */
-                stdout.printf ("account ready\n");
-
-                /* FIXME: uncomment this */
-#if 0
-                /* FIXME: it would be more conventional to use
-                 * this.account.prepare_async.finish(); we'll need to set that
-                 * up somehow */
-
-                this.account.prepare_finish (result);
-#endif
-        }
-#endif
-
         private void connection_ready_cb (Connection conn, GLib.Error error) {
                 if (error != null) {
                         /* FIXME: cut this */
@@ -56,11 +40,27 @@ public class Tp.PersonaStore : Object {
                                         error.message);
 
                 } else {
+                        Lowlevel lowlevel;
+                        Channel channel;
+
                         /* FIXME: cut this */
                         stdout.printf ("connection_ready_cb: success\n");
-                }
 
+                        /* FIXME: set up a handler for the "NewChannels" signal
+                         * */
+                        /* FIXME: request 'stored' */
+                        /* FIXME: request 'publish' */
+
+                        lowlevel = new Lowlevel ();
+                        channel = yield
+                                lowlevel.connection_open_contact_list_channel_async (
+                                                conn, "subscribe");
+
+                        /* FIXME: cut this */
+                        g_debug ("got channel %p", channel);
 
+                        /* FIXME: actually do something with the channel */
+                }
         }
 
         private async void prep_account () {
@@ -69,24 +69,29 @@ public class Tp.PersonaStore : Object {
                 /* FIXME: cut this */
                 stdout.printf ("about to prep the account\n");
 
-                /* FIXME: handle the GLib.Error */
-                success = yield account.prepare_async (null);
-                if (success == true) {
-                        Connection conn = account.get_connection ();
-
-                        /* FIXME: cut this */
-                        stdout.printf ("the account prep for %s succeeded\n",
-                                        this.account.get_display_name ());
+                try {
+                        success = yield account.prepare_async (null);
+                        if (success == true) {
+                                Connection conn = account.get_connection ();
 
-                        if (conn == null) {
                                 /* FIXME: cut this */
-                                stdout.printf ("connection is offline\n");
-                        } else {
-                                /* FIXME: cut this */
-                                stdout.printf ("connection is online\n");
-
-                                conn.call_when_ready (this.connection_ready_cb);
+                                stdout.printf ("account prep for %s succeeded\n",
+                                                this.account.get_display_name ());
+
+                                if (conn == null) {
+                                        /* FIXME: cut this */
+                                        stdout.printf ("connection offline\n");
+                                } else {
+                                        /* FIXME: cut this */
+                                        stdout.printf ("connection online\n");
+
+                                        conn.call_when_ready (this.connection_ready_cb);
+                                }
                         }
+                } catch (GLib.Error e) {
+                        stderr.printf ("failed to prepare the account '%s': %s",
+                                        this.account.get_display_name (),
+                                        e.message);
                 }
         }
 
@@ -100,18 +105,6 @@ public class Tp.PersonaStore : Object {
 
                 Object (account: account);
 
-                /* FIXME: cut this */
-#if 0
-                stdout.printf ("about to prep the account");
-
-                success = yield account.prepare_async.begin (null);
-                if (success == TRUE) {
-                        bool finish_success;
-
-                        /* FIXME: cut this */
-                        stdout.printf ("the account prep succeeded");
-                }
-#endif
                 this.prep_account ();
 
                 /* FIXME: we need to react to the account going on an offline */
diff --git a/telepathy-people/tp-lowlevel.c b/telepathy-people/tp-lowlevel.c
new file mode 100644 (file)
index 0000000..a962370
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2007-2010 Collabora Ltd.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *       Travis Reitter <travis.reitter@collabora.co.uk>
+ *       Xavier Claessens <xavier.claessens@collabora.co.uk>
+ */
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <telepathy-glib/channel.h>
+#include <telepathy-glib/connection.h>
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/interfaces.h>
+
+#include "tp-lowlevel.h"
+
+G_DEFINE_TYPE (TpLowlevel, tp_lowlevel, G_TYPE_OBJECT);
+
+static void
+connection_ensure_channel_cb (TpConnection *conn,
+    gboolean yours,
+    const gchar *path,
+    GHashTable *properties,
+    const GError *error,
+    gpointer user_data,
+    GObject *weak_object)
+{
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+
+  if (error != NULL)
+    {
+      g_debug ("failed: %s\n", error->message);
+      g_simple_async_result_set_from_error (simple, error);
+    }
+  else
+    {
+      TpChannel *channel;
+
+      /* FIXME: pass in an error here and react to it */
+      channel = tp_channel_new_from_properties (conn, path, properties, NULL);
+      g_simple_async_result_set_op_res_gpointer (simple, g_object_ref (channel),
+          g_object_unref);
+
+      g_object_unref (channel);
+    }
+
+  g_simple_async_result_complete (simple);
+  g_object_unref (simple);
+}
+
+void
+tp_lowlevel_connection_open_contact_list_channel_async (TpLowlevel *lowlevel,
+    TpConnection *conn,
+    const char *name,
+    GAsyncReadyCallback callback,
+    gpointer user_data)
+{
+  GSimpleAsyncResult *result;
+  GHashTable *request;
+
+  /* FIXME: cut this */
+  g_print ("opening channel for contact list '%s'\n", name);
+
+  request = tp_asv_new (TP_IFACE_CHANNEL ".ChannelType", G_TYPE_STRING,
+      TP_IFACE_CHANNEL_TYPE_CONTACT_LIST, TP_IFACE_CHANNEL ".TargetHandleType",
+      G_TYPE_UINT, TP_HANDLE_TYPE_LIST, NULL);
+
+  tp_asv_set_static_string (request, TP_IFACE_CHANNEL ".TargetID", name);
+  result = g_simple_async_result_new (G_OBJECT (conn), callback, user_data,
+      tp_lowlevel_connection_open_contact_list_channel_finish);
+  tp_cli_connection_interface_requests_call_ensure_channel (conn, -1, request,
+      connection_ensure_channel_cb, result, NULL, G_OBJECT (conn));
+}
+
+/* FIXME: if possible, make this static, or at least hide it in the .metadata
+ * file */
+const TpChannel *
+tp_lowlevel_connection_open_contact_list_channel_finish (TpLowlevel *lowlevel,
+    TpConnection *conn,
+    GAsyncResult *result,
+    GError **error)
+{
+  GSimpleAsyncResult *simple;
+
+  g_return_val_if_fail (TP_IS_CONNECTION (conn), FALSE);
+  g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
+
+  simple = G_SIMPLE_ASYNC_RESULT (result);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    return NULL;
+
+  g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (conn),
+        tp_lowlevel_connection_open_contact_list_channel_finish), NULL);
+
+  return g_simple_async_result_get_op_res_gpointer (
+      G_SIMPLE_ASYNC_RESULT (result));
+}
+
+static void
+tp_lowlevel_class_init (TpLowlevelClass *klass)
+{
+}
+
+static void
+tp_lowlevel_init (TpLowlevel *self)
+{
+}
+
+TpLowlevel *
+tp_lowlevel_new ()
+{
+  return TP_LOWLEVEL (g_object_new (TP_TYPE_LOWLEVEL, NULL));
+}
diff --git a/telepathy-people/tp-lowlevel.h b/telepathy-people/tp-lowlevel.h
new file mode 100644 (file)
index 0000000..ecedd40
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *       Travis Reitter <travis.reitter@collabora.co.uk>
+ */
+
+#ifndef TP_LOWLEVEL_H
+#define TP_LOWLEVEL_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+#include <telepathy-glib/channel.h>
+#include <telepathy-glib/connection.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpLowlevel TpLowlevel;
+typedef struct _TpLowlevelClass TpLowlevelClass;
+
+struct _TpLowlevel {
+  /*<private>*/
+  GObject parent;
+};
+
+struct _TpLowlevelClass {
+  /*<private>*/
+  GObjectClass parent_class;
+};
+
+GType tp_lowlevel_get_type (void);
+
+#define TP_TYPE_LOWLEVEL (tp_lowlevel_get_type ())
+#define TP_LOWLEVEL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), TP_TYPE_LOWLEVEL, TpLowlevel))
+#define TP_LOWLEVEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TYPE_LOWLEVEL, TpLowlevelClass))
+#define TP_IS_LOWLEVEL(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), TP_TYPE_LOWLEVEL))
+#define TP_IS_LOWLEVEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TYPE_LOWLEVEL))
+#define TP_LOWLEVEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TYPE_LOWLEVEL, TpLowlevelClass))
+
+TpLowlevel *
+tp_lowlevel_new (void) G_GNUC_WARN_UNUSED_RESULT;
+
+void
+tp_lowlevel_connection_open_contact_list_channel_async (TpLowlevel *lowlevel,
+    TpConnection *conn,
+    const char *name,
+    GAsyncReadyCallback callback,
+    gpointer user_data);
+
+const TpChannel *
+tp_lowlevel_connection_open_contact_list_channel_finish (TpLowlevel *lowlevel,
+    TpConnection *conn,
+    GAsyncResult *result,
+    GError **error);
+
+G_END_DECLS
+
+#endif /* TP_LOWLEVEL_H */