summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2013-01-08 12:51:27 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2013-01-08 15:08:08 +0000
commit29766a5cfc785bc314b40ec87196e6b78bc0b68a (patch)
tree3a2f0e0ef3e4c3365de3965ff84dd01fba2c2f8d
parente31205cc89683f332a1c0fef4edc834d80854d7f (diff)
Names mixin: add a default implementation of each method
This makes them all mandatory, which is a simplification.
-rw-r--r--telepathy-glib/names-mixin.c189
1 files changed, 125 insertions, 64 deletions
diff --git a/telepathy-glib/names-mixin.c b/telepathy-glib/names-mixin.c
index 0179e8e72..80b0f399d 100644
--- a/telepathy-glib/names-mixin.c
+++ b/telepathy-glib/names-mixin.c
@@ -173,23 +173,41 @@
/**
* TpNamesInterface:
* @parent: the parent interface
- * @request_nickname_async: a #TpNamesInterfaceRequestNicknameAsyncFunc
+ * @request_nickname_async: virtual function to re-download a contact's
+ * nickname from the server
* @request_nickname_finish: virtual function to interpret the result
* of @request_nickname_async
- * @set_nickname_async: a #TpNamesInterfaceSetNicknameAsyncFunc
+ * @set_nickname_async: virtual function to set the user's nickname
* @set_nickname_finish: virtual function to interpret the result
* of @set_nickname_async
- * @set_local_alias_async: a #TpNamesInterfaceSetLocalAliasAsyncFunc
+ * @set_local_alias_async: virtual function to set a contact's local alias
* @set_local_alias_finish: virtual function to interpret the result
* of @set_local_alias_async
*
* Interface structure of virtual methods needed by #TpNamesMixin.
*
+ * The default implementation of @request_nickname_async returns whatever
+ * nickname was last stored in the mixin by
+ * tp_names_mixin_nicknames_changed() or tp_names_mixin_one_nickname_changed()
+ * (or "" if no nickname is stored for that contact), indicating that
+ * either nicknames are not supported at all, or all nicknames are known
+ * already. Connection managers for protocols where the user may need to
+ * "refresh" a contact's nickname by re-querying the server, such as XMPP,
+ * should override this method.
+ *
* The @request_nickname_finish function has a default implementation,
* which assumes that @request_nickname_async uses a #GSimpleAsyncResult
* on which it will store the resulting string using
* g_simple_async_result_set_op_res_gpointer() before completion.
*
+ * The default implementation of @set_nickname_async raises
+ * %TP_ERROR_NOT_IMPLEMENTED. Connection managers for protocols where
+ * the user can change their own nickname should override this method.
+ *
+ * The default implementation of @set_local_alias_async raises
+ * %TP_ERROR_NOT_IMPLEMENTED. Connection managers for protocols where
+ * aliases can be stored should override this method.
+ *
* The @set_nickname_finish and @set_local_alias functions have a default
* implementation, which assumes that the corresponding @async function
* uses a #GSimpleAsyncResult.
@@ -223,6 +241,61 @@
G_DEFINE_INTERFACE (TpNames, tp_names_interface, TP_TYPE_BASE_CONNECTION)
+typedef struct
+{
+ /* Immutable properties once CONNECTED */
+ TpContactMetadataStorageType alias_storage;
+
+ /* TpHandle -> owned string */
+ GHashTable *nicknames;
+ GHashTable *local_aliases;
+} TpNamesMixinPrivate;
+
+#define TP_NAMES_MIXIN_GET_PRIVATE(o) \
+ g_object_get_qdata (G_OBJECT (o), tp_names_mixin_get_quark ())
+
+static GQuark
+tp_names_mixin_get_quark (void)
+{
+ static GQuark quark = 0;
+
+ if (G_UNLIKELY (quark == 0))
+ quark = g_quark_from_static_string ("TpNamesMixin");
+
+ return quark;
+}
+
+static void tp_names_mixin_private_free (gpointer);
+
+static void
+default_request_nickname_async (TpBaseConnection *base,
+ TpHandle contact,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ TpNamesMixinPrivate *priv = TP_NAMES_MIXIN_GET_PRIVATE (base);
+ gchar *nickname;
+ GSimpleAsyncResult *simple;
+
+ /* ignore if called for its side-effects: it has none */
+ if (callback == NULL)
+ return;
+
+ nickname = g_strdup (g_hash_table_lookup (priv->nicknames,
+ GUINT_TO_POINTER (contact)));
+
+ /* NULL means error here, so avoid it */
+ if (nickname == NULL)
+ nickname = g_strdup ("");
+
+ simple = g_simple_async_result_new (G_OBJECT (base),
+ callback, user_data, default_request_nickname_async);
+
+ g_simple_async_result_set_op_res_gpointer (simple, nickname, g_free);
+ g_simple_async_result_complete_in_idle (simple);
+ g_object_unref (simple);
+}
+
static gchar *
default_request_nickname_finish (TpBaseConnection *base,
GAsyncResult *result,
@@ -231,6 +304,20 @@ default_request_nickname_finish (TpBaseConnection *base,
_tp_implement_finish_return_copy_pointer (base, NULL, g_strdup);
}
+static void
+default_set_nickname_async (TpBaseConnection *base,
+ const gchar *nickname,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ if (callback == NULL)
+ return;
+
+ g_simple_async_report_error_in_idle (G_OBJECT (base),
+ callback, user_data, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
+ "Setting your nickname is not implemented");
+}
+
static gboolean
default_set_nickname_finish (TpBaseConnection *base,
GAsyncResult *result,
@@ -239,6 +326,21 @@ default_set_nickname_finish (TpBaseConnection *base,
_tp_implement_finish_void (base, NULL);
}
+static void
+default_set_local_alias_async (TpBaseConnection *base,
+ TpHandle contact,
+ const gchar *alias,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ if (callback == NULL)
+ return;
+
+ g_simple_async_report_error_in_idle (G_OBJECT (base),
+ callback, user_data, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
+ "Setting local aliases is not implemented");
+}
+
static gboolean
default_set_local_alias_finish (TpBaseConnection *base,
GAsyncResult *result,
@@ -250,37 +352,14 @@ default_set_local_alias_finish (TpBaseConnection *base,
static void
tp_names_interface_default_init (TpNamesInterface *iface)
{
+ iface->request_nickname_async = default_request_nickname_async;
iface->request_nickname_finish = default_request_nickname_finish;
+ iface->set_nickname_async = default_set_nickname_async;
iface->set_nickname_finish = default_set_nickname_finish;
+ iface->set_local_alias_async = default_set_local_alias_async;
iface->set_local_alias_finish = default_set_local_alias_finish;
}
-typedef struct
-{
- /* Immutable properties once CONNECTED */
- TpContactMetadataStorageType alias_storage;
-
- /* TpHandle -> owned string */
- GHashTable *nicknames;
- GHashTable *local_aliases;
-} TpNamesMixinPrivate;
-
-#define TP_NAMES_MIXIN_GET_PRIVATE(o) \
- g_object_get_qdata (G_OBJECT (o), tp_names_mixin_get_quark ())
-
-static GQuark
-tp_names_mixin_get_quark (void)
-{
- static GQuark quark = 0;
-
- if (G_UNLIKELY (quark == 0))
- quark = g_quark_from_static_string ("TpNamesMixin");
-
- return quark;
-}
-
-static void tp_names_mixin_private_free (gpointer);
-
/**
* tp_names_mixin_init:
* @object: a #TpBaseConnection object that uses this mixin and implements
@@ -296,12 +375,20 @@ void
tp_names_mixin_init (GObject *object)
{
TpNamesMixinPrivate *priv;
+ TpNamesInterface *iface = TP_NAMES_INTERFACE_GET_IFACE (object);
g_return_if_fail (TP_IS_BASE_CONNECTION (object));
g_return_if_fail (TP_IS_NAMES_INTERFACE (object));
g_return_if_fail (TP_IS_SVC_CONNECTION_INTERFACE_ALIASING (object) ||
TP_IS_SVC_CONNECTION_INTERFACE_NAMES (object));
+ g_return_if_fail (iface->request_nickname_async != NULL);
+ g_return_if_fail (iface->request_nickname_finish != NULL);
+ g_return_if_fail (iface->set_nickname_async != NULL);
+ g_return_if_fail (iface->set_nickname_finish != NULL);
+ g_return_if_fail (iface->set_local_alias_async != NULL);
+ g_return_if_fail (iface->set_local_alias_finish != NULL);
+
priv = g_slice_new0 (TpNamesMixinPrivate);
priv->nicknames = g_hash_table_new_full (NULL, NULL,
@@ -393,9 +480,7 @@ tp_names_mixin_set_dbus_property (GObject *object,
tp_base_connection_get_self_handle (base),
nickname);
- if (iface->set_nickname_async != NULL)
- iface->set_nickname_async (base, nickname, NULL, NULL);
-
+ iface->set_nickname_async (base, nickname, NULL, NULL);
return TRUE;
}
@@ -481,11 +566,8 @@ implicit_request_nickname (TpBaseConnection *base,
{
TpNamesInterface *iface = TP_NAMES_INTERFACE_GET_IFACE (base);
- if (iface->request_nickname_async != NULL)
- {
- iface->request_nickname_async (base, contact,
- implicit_request_nickname_cb, GUINT_TO_POINTER (contact));
- }
+ iface->request_nickname_async (base, contact,
+ implicit_request_nickname_cb, GUINT_TO_POINTER (contact));
}
static void
@@ -536,12 +618,6 @@ tp_names_mixin_request_nickname (TpSvcConnectionInterfaceNames *dbus_iface,
return;
}
- if (iface->request_nickname_async == NULL)
- {
- tp_dbus_g_method_return_not_implemented (context);
- return;
- }
-
iface->request_nickname_async (base, contact,
request_nickname_cb,
request_nickname_data_new (contact, context));
@@ -592,16 +668,8 @@ tp_names_mixin_set_local_alias (TpSvcConnectionInterfaceNames *dbus_iface,
* the session */
tp_names_mixin_one_local_alias_changed (base, contact, alias);
- if (iface->set_local_alias_async != NULL)
- {
- iface->set_local_alias_async (base, contact, alias,
- set_local_alias_cb, context);
- }
- else
- {
- /* Let's silently return, we cached the value anyway */
- tp_svc_connection_interface_names_return_from_set_local_alias (context);
- }
+ iface->set_local_alias_async (base, contact, alias,
+ set_local_alias_cb, context);
}
/**
@@ -765,8 +833,7 @@ tp_names_mixin_aliasing_set_aliases (
tp_names_mixin_one_nickname_changed (base, self_handle, alias);
- if (iface->set_nickname_async != NULL)
- iface->set_nickname_async (base, alias, NULL, NULL);
+ iface->set_nickname_async (base, alias, NULL, NULL);
}
else
{
@@ -774,8 +841,7 @@ tp_names_mixin_aliasing_set_aliases (
* least the session */
tp_names_mixin_one_local_alias_changed (base, contact, alias);
- if (iface->set_local_alias_async != NULL)
- iface->set_local_alias_async (base, contact, alias, NULL, NULL);
+ iface->set_local_alias_async (base, contact, alias, NULL, NULL);
}
}
@@ -927,12 +993,6 @@ tp_names_mixin_aliasing_request_aliases (
return;
}
- if (iface->request_nickname_async == NULL)
- {
- tp_dbus_g_method_return_not_implemented (context);
- return;
- }
-
request = request_aliases_data_new (contacts, context);
for (i = 0; i < contacts->len; i++)
{
@@ -1321,7 +1381,8 @@ tp_names_mixin_set_storage_type (TpBaseConnection *base,
g_return_if_fail (tp_base_connection_get_status (base) !=
TP_CONNECTION_STATUS_CONNECTED);
- g_return_if_fail (iface->set_local_alias_async != NULL ||
+ g_return_if_fail (
+ iface->set_local_alias_async != default_set_local_alias_async ||
alias_storage == TP_CONTACT_METADATA_STORAGE_TYPE_NONE);
priv->alias_storage = alias_storage;