[Telepathy-commits] [telepathy-glib/master] Add "identifier" property on TpChannel.

Xavier Claessens xclaesse at gmail.com
Fri Dec 12 18:00:00 PST 2008


---
 telepathy-glib/channel-internal.h |    1 +
 telepathy-glib/channel.c          |  134 ++++++++++++++++++++++++++++++++++---
 telepathy-glib/channel.h          |    1 +
 tests/dbus/channel-introspect.c   |    8 ++-
 4 files changed, 134 insertions(+), 10 deletions(-)

diff --git a/telepathy-glib/channel-internal.h b/telepathy-glib/channel-internal.h
index eab5d4c..e856d7c 100644
--- a/telepathy-glib/channel-internal.h
+++ b/telepathy-glib/channel-internal.h
@@ -45,6 +45,7 @@ struct _TpChannelPrivate {
     GQuark channel_type;
     TpHandleType handle_type;
     TpHandle handle;
+    gchar *identifier;
     /* owned string (iface + "." + prop) => slice-allocated GValue */
     GHashTable *channel_properties;
 
diff --git a/telepathy-glib/channel.c b/telepathy-glib/channel.c
index ca43b0b..5665aba 100644
--- a/telepathy-glib/channel.c
+++ b/telepathy-glib/channel.c
@@ -84,6 +84,7 @@ enum
   PROP_CHANNEL_TYPE,
   PROP_HANDLE_TYPE,
   PROP_HANDLE,
+  PROP_IDENTIFIER,
   PROP_CHANNEL_READY,
   PROP_CHANNEL_PROPERTIES,
   PROP_GROUP_SELF_HANDLE,
@@ -188,6 +189,25 @@ tp_channel_get_handle (TpChannel *self,
   return self->priv->handle;
 }
 
+/**
+ * tp_channel_get_identifier:
+ * @self: a channel
+ *
+ * This channel's associated identifier, or NULL if no identifier or unknown.
+ *
+ * The identifier is the result of inspecting #TpChannel:handle.
+ * This is the same as the #TpChannel:identifier property.
+ *
+ * Returns: the identifier
+ * Since: 0.7.FUTURE
+ */
+const gchar *
+tp_channel_get_identifier (TpChannel *self)
+{
+  g_return_val_if_fail (TP_IS_CHANNEL (self), NULL);
+
+  return self->priv->identifier;
+}
 
 /**
  * tp_channel_is_ready:
@@ -284,6 +304,9 @@ tp_channel_get_property (GObject *object,
     case PROP_HANDLE:
       g_value_set_uint (value, self->priv->handle);
       break;
+    case PROP_IDENTIFIER:
+      g_value_set_string (value, self->priv->identifier);
+      break;
     case PROP_CHANNEL_PROPERTIES:
       g_value_set_boxed (value, self->priv->channel_properties);
       break;
@@ -360,6 +383,22 @@ _tp_channel_maybe_set_handle_type (TpChannel *self,
 
 
 static void
+_tp_channel_maybe_set_identifier (TpChannel *self,
+                                  const gchar *identifier)
+{
+  if (identifier != NULL && self->priv->identifier == NULL)
+    {
+      GValue *value = tp_g_value_slice_new (G_TYPE_STRING);
+
+      g_value_set_string (value, identifier);
+      self->priv->identifier = g_strdup (identifier);
+      g_hash_table_insert (self->priv->channel_properties,
+          g_strdup (TP_IFACE_CHANNEL ".TargetID"), value);
+    }
+}
+
+
+static void
 _tp_channel_maybe_set_interfaces (TpChannel *self,
                                   const gchar **interfaces)
 {
@@ -442,6 +481,10 @@ tp_channel_set_property (GObject *object,
                   TP_IFACE_CHANNEL ".TargetHandle", &valid);
               _tp_channel_maybe_set_handle (self, u, valid);
 
+              _tp_channel_maybe_set_identifier (self,
+                  tp_asv_get_string (self->priv->channel_properties,
+                      TP_IFACE_CHANNEL ".TargetID"));
+
               _tp_channel_maybe_set_channel_type (self,
                   tp_asv_get_string (self->priv->channel_properties,
                       TP_IFACE_CHANNEL ".ChannelType"));
@@ -661,6 +704,63 @@ _tp_channel_get_handle (TpChannel *self)
 }
 
 
+
+static void
+tp_channel_got_identifier_cb (TpConnection *connection,
+                              const gchar **identifier,
+                              const GError *error,
+                              gpointer user_data,
+                              GObject *unused2)
+{
+  TpChannel *self = user_data;
+
+  if (error == NULL)
+    {
+      GValue *value;
+
+      DEBUG ("%p: Introspected identifier %s", self, *identifier);
+      self->priv->identifier = g_strdup (*identifier);
+
+      value = tp_g_value_slice_new (G_TYPE_STRING);
+      g_value_set_string (value, *identifier);
+      g_hash_table_insert (self->priv->channel_properties,
+          g_strdup (TP_IFACE_CHANNEL ".TargetID"), value);
+
+      g_object_notify ((GObject *) self, "identifier");
+
+      _tp_channel_continue_introspection (self);
+    }
+  else
+    {
+      _tp_channel_abort_introspection (self, "InspectHandles failed", error);
+    }
+
+  g_object_unref (self);
+}
+
+
+static void
+_tp_channel_get_identifier (TpChannel *self)
+{
+  if (self->priv->identifier == NULL && self->priv->handle != 0 &&
+      self->priv->handle_type != TP_HANDLE_TYPE_NONE)
+    {
+      GArray handles = {(gchar *) &self->priv->handle, 1};
+
+      DEBUG ("%p: calling InspectHandles", self);
+      tp_cli_connection_call_inspect_handles (self->priv->connection, -1,
+          self->priv->handle_type, &handles,
+          tp_channel_got_identifier_cb, g_object_ref (self), NULL, NULL);
+    }
+  else
+    {
+      DEBUG ("%p: identifier already known to be %s", self,
+          self->priv->identifier);
+      _tp_channel_continue_introspection (self);
+    }
+}
+
+
 static void
 _tp_channel_got_properties (TpProxy *proxy,
                             GHashTable *asv,
@@ -693,15 +793,8 @@ _tp_channel_got_properties (TpProxy *proxy,
       u = tp_asv_get_uint32 (asv, "TargetHandle", &valid);
       _tp_channel_maybe_set_handle (self, u, valid);
 
-      s = tp_asv_get_string (asv, "TargetID");
-
-      if (s != NULL)
-        {
-          value = tp_g_value_slice_new (G_TYPE_STRING);
-          g_value_set_string (value, s);
-          g_hash_table_insert (self->priv->channel_properties,
-              g_strdup (TP_IFACE_CHANNEL ".TargetID"), value);
-        }
+      _tp_channel_maybe_set_identifier (self,
+          tp_asv_get_string (asv, "TargetID"));
 
       u = tp_asv_get_uint32 (asv, "InitiatorHandle", &valid);
 
@@ -734,8 +827,10 @@ _tp_channel_got_properties (TpProxy *proxy,
         }
 
       g_object_notify ((GObject *) self, "channel-type");
+      g_object_notify ((GObject *) self, "interfaces");
       g_object_notify ((GObject *) self, "handle-type");
       g_object_notify ((GObject *) self, "handle");
+      g_object_notify ((GObject *) self, "identifier");
     }
   else
     {
@@ -876,6 +971,10 @@ tp_channel_constructor (GType type,
   g_queue_push_tail (self->priv->introspect_needed,
       _tp_channel_get_handle);
 
+  /* this does nothing if we already know the identifier */
+  g_queue_push_tail (self->priv->introspect_needed,
+      _tp_channel_get_identifier);
+
   /* this does nothing if we already know the channel type */
   g_queue_push_tail (self->priv->introspect_needed,
       _tp_channel_get_channel_type);
@@ -980,6 +1079,8 @@ tp_channel_finalize (GObject *object)
   g_assert (self->priv->channel_properties != NULL);
   g_hash_table_destroy (self->priv->channel_properties);
 
+  g_free (self->priv->identifier);
+
   ((GObjectClass *) tp_channel_parent_class)->finalize (object);
 }
 
@@ -1046,6 +1147,21 @@ tp_channel_class_init (TpChannelClass *klass)
       "handle");
 
   /**
+   * TpChannel:identifier:
+   *
+   * This channel's associated identifier, or NULL if no identifier or unknown.
+   *
+   * The identifier is the result of inspecting #TpChannel:handle.
+   */
+  param_spec = g_param_spec_string ("identifier",
+      "The identifier",
+      "The identifier of the channel",
+      NULL,
+      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (object_class, PROP_IDENTIFIER,
+      param_spec);
+
+  /**
    * TpChannel:channel-properties:
    *
    * The immutable D-Bus properties of this channel, represented by a
diff --git a/telepathy-glib/channel.h b/telepathy-glib/channel.h
index 34dcfc3..e9a1ccb 100644
--- a/telepathy-glib/channel.h
+++ b/telepathy-glib/channel.h
@@ -95,6 +95,7 @@ gboolean tp_channel_is_ready (TpChannel *self);
 const gchar *tp_channel_get_channel_type (TpChannel *self);
 GQuark tp_channel_get_channel_type_id (TpChannel *self);
 TpHandle tp_channel_get_handle (TpChannel *self, TpHandleType *handle_type);
+const gchar *tp_channel_get_identifier (TpChannel *self);
 TpConnection *tp_channel_borrow_connection (TpChannel *self);
 GHashTable *tp_channel_borrow_immutable_properties (TpChannel *self);
 
diff --git a/tests/dbus/channel-introspect.c b/tests/dbus/channel-introspect.c
index 8277021..01ae92c 100644
--- a/tests/dbus/channel-introspect.c
+++ b/tests/dbus/channel-introspect.c
@@ -20,6 +20,8 @@
 #include "tests/lib/textchan-null.h"
 #include "tests/lib/util.h"
 
+#define IDENTIFIER "them at example.org"
+
 static int fail = 0;
 static GError *invalidated = NULL;
 static GMainLoop *mainloop;
@@ -71,6 +73,7 @@ assert_chan_sane (TpChannel *chan,
   MYASSERT (tp_channel_get_channel_type_id (chan) ==
         TP_IFACE_QUARK_CHANNEL_TYPE_TEXT, "");
   MYASSERT (TP_IS_CONNECTION (tp_channel_borrow_connection (chan)), "");
+  MYASSERT_SAME_STRING (tp_channel_get_identifier (chan), IDENTIFIER);
 
   asv = tp_channel_borrow_immutable_properties (chan);
   MYASSERT (asv != NULL, "");
@@ -83,6 +86,9 @@ assert_chan_sane (TpChannel *chan,
   MYASSERT_SAME_UINT (
       tp_asv_get_uint32 (asv, TP_IFACE_CHANNEL ".TargetHandle", NULL),
       handle);
+  MYASSERT_SAME_STRING (
+      tp_asv_get_string (asv, TP_IFACE_CHANNEL ".TargetID"),
+      IDENTIFIER);
 }
 
 int
@@ -138,7 +144,7 @@ main (int argc,
       TP_HANDLE_TYPE_CONTACT);
   MYASSERT (contact_repo != NULL, "");
 
-  handle = tp_handle_ensure (contact_repo, "them at example.org", NULL, &error);
+  handle = tp_handle_ensure (contact_repo, IDENTIFIER, NULL, &error);
   MYASSERT_NO_ERROR (error);
 
   chan_path = g_strdup_printf ("%s/Channel", conn_path);
-- 
1.5.6.5



More information about the Telepathy-commits mailing list