[Telepathy-commits] [telepathy-glib/master] TpGroupMixin: allow channels to make the self-handle always removable

Simon McVittie simon.mcvittie at collabora.co.uk
Thu Mar 12 08:47:48 PDT 2009


Removing the self-handle is (meant to be) the documented way to leave a
chatroom or call gracefully, and possibly with a message or reason code,
so we should support it in all cases. Sadly, that risks crashing
connection managers whose remove callback makes assertions about who
can be removed, so it has to be "opt-in".
---
 docs/reference/telepathy-glib-sections.txt |    1 +
 telepathy-glib/group-mixin.c               |   45 +++++++++++++++++++++++++++-
 telepathy-glib/group-mixin.h               |    1 +
 3 files changed, 46 insertions(+), 1 deletions(-)

diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt
index 5ca077f..24b62b6 100644
--- a/docs/reference/telepathy-glib-sections.txt
+++ b/docs/reference/telepathy-glib-sections.txt
@@ -1351,6 +1351,7 @@ TpGroupMixinRemMemberWithReasonFunc
 TpGroupMixin
 TpGroupMixinClass
 tp_group_mixin_class_init
+tp_group_mixin_class_always_allow_removing_self
 tp_group_mixin_class_set_remove_with_reason_func
 tp_group_mixin_init
 tp_group_mixin_finalize
diff --git a/telepathy-glib/group-mixin.c b/telepathy-glib/group-mixin.c
index 3a6f290..f77d02b 100644
--- a/telepathy-glib/group-mixin.c
+++ b/telepathy-glib/group-mixin.c
@@ -146,6 +146,7 @@ local_pending_info_free (LocalPendingInfo *info)
 
 struct _TpGroupMixinClassPrivate {
     TpGroupMixinRemMemberWithReasonFunc remove_with_reason;
+    unsigned always_allow_removing_self : 1;
 };
 
 struct _TpGroupMixinPrivate {
@@ -250,6 +251,39 @@ tp_group_mixin_class_init (GObjectClass *obj_cls,
 }
 
 /**
+ * tp_group_mixin_class_always_allow_removing_self:
+ * @obj_cls: The class of an object implementing the group interface using this
+ *  mixin
+ *
+ * Configure the mixin to allow attempts to remove the SelfHandle from this
+ * Group, even if the group flags would otherwise disallow this. The
+ * channel's #TpGroupMixinRemMemberFunc or
+ * #TpGroupMixinRemMemberWithReasonFunc will be called as usual for such
+ * attempts, and may make them fail with %TP_ERROR_PERMISSION_DENIED if
+ * required.
+ *
+ * This function should be called from the GObject @class_init callback,
+ * after calling tp_group_mixin_class_init().
+ *
+ * (Recent telepathy-spec changes make it valid to try to remove the
+ * self-handle at all times, regardless of group flags. However, if this was
+ * implemented automatically in TpGroupMixin, this would risk crashing
+ * connection manager implementations that assume that TpGroupMixin will
+ * enforce the group flags strictly. As a result, connection managers should
+ * call this function to indicate to the TpGroupMixin that it may call their
+ * removal callback with the self-handle regardless of flag settings.)
+ *
+ * Since: 0.7.UNRELEASED
+ */
+void
+tp_group_mixin_class_always_allow_removing_self (GObjectClass *obj_cls)
+{
+  TpGroupMixinClass *mixin_cls = TP_GROUP_MIXIN_CLASS (obj_cls);
+
+  mixin_cls->priv->always_allow_removing_self = TRUE;
+}
+
+/**
  * tp_group_mixin_init:
  * @obj: An object implementing the group interface using this mixin
  * @offset: The offset of the TpGroupMixin structure within the instance
@@ -644,7 +678,16 @@ tp_group_mixin_remove_members_with_reason (GObject *obj,
     {
       handle = g_array_index (contacts, TpHandle, i);
 
-      if (tp_handle_set_is_member (mixin->members, handle))
+      if (mixin_cls->priv->always_allow_removing_self &&
+          handle == mixin->self_handle &&
+          (tp_handle_set_is_member (mixin->members, handle) ||
+           tp_handle_set_is_member (mixin->remote_pending, handle) ||
+           tp_handle_set_is_member (mixin->local_pending, handle)))
+        {
+          /* don't check the flags - attempting to remove the self-handle
+           * is explicitly always allowed by this channel */
+        }
+      else if (tp_handle_set_is_member (mixin->members, handle))
         {
           if ((mixin->group_flags & TP_CHANNEL_GROUP_FLAG_CAN_REMOVE) == 0)
             {
diff --git a/telepathy-glib/group-mixin.h b/telepathy-glib/group-mixin.h
index 5011e3c..06a0562 100644
--- a/telepathy-glib/group-mixin.h
+++ b/telepathy-glib/group-mixin.h
@@ -165,6 +165,7 @@ GQuark tp_group_mixin_get_offset_quark (void);
 void tp_group_mixin_class_init (GObjectClass *obj_cls,
     glong offset, TpGroupMixinAddMemberFunc add_func,
     TpGroupMixinRemMemberFunc rem_func);
+void tp_group_mixin_class_always_allow_removing_self (GObjectClass *obj_cls);
 
 void tp_group_mixin_init (GObject *obj, glong offset,
     TpHandleRepoIface *handle_repo, TpHandle self_handle);
-- 
1.5.6.5




More information about the telepathy-commits mailing list