Blame src/modules/contact-photos/e-contact-photo-source.c

Packit Service de44cd
/*
Packit Service de44cd
 * e-contact-photo-source.c
Packit Service de44cd
 *
Packit Service de44cd
 * This program is free software; you can redistribute it and/or modify it
Packit Service de44cd
 * under the terms of the GNU Lesser General Public License as published by
Packit Service de44cd
 * the Free Software Foundation.
Packit Service de44cd
 *
Packit Service de44cd
 * This program is distributed in the hope that it will be useful, but
Packit Service de44cd
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit Service de44cd
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
Packit Service de44cd
 * for more details.
Packit Service de44cd
 *
Packit Service de44cd
 * You should have received a copy of the GNU Lesser General Public License
Packit Service de44cd
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit Service de44cd
 *
Packit Service de44cd
 */
Packit Service de44cd
Packit Service de44cd
#include "e-contact-photo-source.h"
Packit Service de44cd
Packit Service de44cd
#define E_CONTACT_PHOTO_SOURCE_GET_PRIVATE(obj) \
Packit Service de44cd
	(G_TYPE_INSTANCE_GET_PRIVATE \
Packit Service de44cd
	((obj), E_TYPE_CONTACT_PHOTO_SOURCE, EContactPhotoSourcePrivate))
Packit Service de44cd
Packit Service de44cd
typedef struct _AsyncContext AsyncContext;
Packit Service de44cd
Packit Service de44cd
struct _EContactPhotoSourcePrivate {
Packit Service de44cd
	EClientCache *client_cache;
Packit Service de44cd
	ESource *source;
Packit Service de44cd
};
Packit Service de44cd
Packit Service de44cd
struct _AsyncContext {
Packit Service de44cd
	EBookClient *client;
Packit Service de44cd
	gchar *query_string;
Packit Service de44cd
	GInputStream *stream;
Packit Service de44cd
	GCancellable *cancellable;
Packit Service de44cd
	gint priority;
Packit Service de44cd
};
Packit Service de44cd
Packit Service de44cd
enum {
Packit Service de44cd
	PROP_0,
Packit Service de44cd
	PROP_CLIENT_CACHE,
Packit Service de44cd
	PROP_SOURCE
Packit Service de44cd
};
Packit Service de44cd
Packit Service de44cd
/* Forward Declarations */
Packit Service de44cd
static void	e_contact_photo_source_interface_init
Packit Service de44cd
					(EPhotoSourceInterface *iface);
Packit Service de44cd
Packit Service de44cd
G_DEFINE_DYNAMIC_TYPE_EXTENDED (
Packit Service de44cd
	EContactPhotoSource,
Packit Service de44cd
	e_contact_photo_source,
Packit Service de44cd
	G_TYPE_OBJECT,
Packit Service de44cd
	0,
Packit Service de44cd
	G_IMPLEMENT_INTERFACE_DYNAMIC (
Packit Service de44cd
		E_TYPE_PHOTO_SOURCE,
Packit Service de44cd
		e_contact_photo_source_interface_init))
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
async_context_free (AsyncContext *async_context)
Packit Service de44cd
{
Packit Service de44cd
	g_clear_object (&async_context->client);
Packit Service de44cd
	g_free (async_context->query_string);
Packit Service de44cd
	g_clear_object (&async_context->stream);
Packit Service de44cd
	g_clear_object (&async_context->cancellable);
Packit Service de44cd
Packit Service de44cd
	g_slice_free (AsyncContext, async_context);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static EContactPhoto *
Packit Service de44cd
contact_photo_source_extract_photo (EContact *contact,
Packit Service de44cd
                                    gint *out_priority)
Packit Service de44cd
{
Packit Service de44cd
	EContactPhoto *photo;
Packit Service de44cd
Packit Service de44cd
	photo = e_contact_get (contact, E_CONTACT_PHOTO);
Packit Service de44cd
	*out_priority = G_PRIORITY_HIGH;
Packit Service de44cd
Packit Service de44cd
	if (photo == NULL) {
Packit Service de44cd
		photo = e_contact_get (contact, E_CONTACT_LOGO);
Packit Service de44cd
		*out_priority = G_PRIORITY_LOW;
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	return photo;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
contact_photo_source_get_photo_thread (GSimpleAsyncResult *simple,
Packit Service de44cd
                                       GObject *source_object,
Packit Service de44cd
                                       GCancellable *cancellable)
Packit Service de44cd
{
Packit Service de44cd
	AsyncContext *async_context;
Packit Service de44cd
	GSList *slist = NULL;
Packit Service de44cd
	GSList *slink;
Packit Service de44cd
	GError *error = NULL;
Packit Service de44cd
Packit Service de44cd
	async_context = g_simple_async_result_get_op_res_gpointer (simple);
Packit Service de44cd
Packit Service de44cd
	e_book_client_get_contacts_sync (
Packit Service de44cd
		async_context->client,
Packit Service de44cd
		async_context->query_string,
Packit Service de44cd
		&slist, cancellable, &error);
Packit Service de44cd
Packit Service de44cd
	if (error != NULL) {
Packit Service de44cd
		g_warn_if_fail (slist == NULL);
Packit Service de44cd
		g_simple_async_result_take_error (simple, error);
Packit Service de44cd
		return;
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	/* See if any of the contacts have a photo. */
Packit Service de44cd
	for (slink = slist; slink != NULL; slink = g_slist_next (slink)) {
Packit Service de44cd
		EContact *contact = E_CONTACT (slink->data);
Packit Service de44cd
		GInputStream *stream = NULL;
Packit Service de44cd
		EContactPhoto *photo;
Packit Service de44cd
Packit Service de44cd
		photo = contact_photo_source_extract_photo (
Packit Service de44cd
			contact, &async_context->priority);
Packit Service de44cd
Packit Service de44cd
		if (photo == NULL)
Packit Service de44cd
			continue;
Packit Service de44cd
Packit Service de44cd
		/* Stream takes ownership of the inlined data. */
Packit Service de44cd
		if (photo->type == E_CONTACT_PHOTO_TYPE_INLINED) {
Packit Service de44cd
			stream = g_memory_input_stream_new_from_data (
Packit Service de44cd
				photo->data.inlined.data,
Packit Service de44cd
				photo->data.inlined.length,
Packit Service de44cd
				(GDestroyNotify) g_free);
Packit Service de44cd
			photo->data.inlined.data = NULL;
Packit Service de44cd
			photo->data.inlined.length = 0;
Packit Service de44cd
Packit Service de44cd
		} else {
Packit Service de44cd
			GFileInputStream *file_stream;
Packit Service de44cd
			GFile *file;
Packit Service de44cd
Packit Service de44cd
			file = g_file_new_for_uri (photo->data.uri);
Packit Service de44cd
Packit Service de44cd
			/* Disregard errors and proceed as
Packit Service de44cd
			 * though the contact has no photo. */
Packit Service de44cd
Packit Service de44cd
			/* XXX Return type should have been GInputStream. */
Packit Service de44cd
			file_stream = g_file_read (file, cancellable, NULL);
Packit Service de44cd
			if (file_stream != NULL)
Packit Service de44cd
				stream = G_INPUT_STREAM (file_stream);
Packit Service de44cd
Packit Service de44cd
			g_object_unref (file);
Packit Service de44cd
		}
Packit Service de44cd
Packit Service de44cd
		e_contact_photo_free (photo);
Packit Service de44cd
Packit Service de44cd
		/* Stop on the first input stream. */
Packit Service de44cd
		if (stream != NULL) {
Packit Service de44cd
			async_context->stream = g_object_ref (stream);
Packit Service de44cd
			g_object_unref (stream);
Packit Service de44cd
			break;
Packit Service de44cd
		}
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	g_slist_free_full (slist, (GDestroyNotify) g_object_unref);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
contact_photo_source_get_client_cb (GObject *source_object,
Packit Service de44cd
                                    GAsyncResult *result,
Packit Service de44cd
                                    gpointer user_data)
Packit Service de44cd
{
Packit Service de44cd
	GSimpleAsyncResult *simple;
Packit Service de44cd
	AsyncContext *async_context;
Packit Service de44cd
	EClient *client;
Packit Service de44cd
	GError *error = NULL;
Packit Service de44cd
Packit Service de44cd
	simple = G_SIMPLE_ASYNC_RESULT (user_data);
Packit Service de44cd
	async_context = g_simple_async_result_get_op_res_gpointer (simple);
Packit Service de44cd
Packit Service de44cd
	client = e_client_cache_get_client_finish (
Packit Service de44cd
		E_CLIENT_CACHE (source_object), result, &error);
Packit Service de44cd
Packit Service de44cd
	/* Sanity check. */
Packit Service de44cd
	g_return_if_fail (
Packit Service de44cd
		((client != NULL) && (error == NULL)) ||
Packit Service de44cd
		((client == NULL) && (error != NULL)));
Packit Service de44cd
Packit Service de44cd
	if (client != NULL) {
Packit Service de44cd
		async_context->client = g_object_ref (client);
Packit Service de44cd
Packit Service de44cd
		/* The rest of the operation we can run from a
Packit Service de44cd
		 * worker thread to keep the logic flow simple. */
Packit Service de44cd
		g_simple_async_result_run_in_thread (
Packit Service de44cd
			simple, contact_photo_source_get_photo_thread,
Packit Service de44cd
			G_PRIORITY_DEFAULT, async_context->cancellable);
Packit Service de44cd
Packit Service de44cd
		g_object_unref (client);
Packit Service de44cd
Packit Service de44cd
	} else {
Packit Service de44cd
		g_simple_async_result_take_error (simple, error);
Packit Service de44cd
		g_simple_async_result_complete_in_idle (simple);
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	g_object_unref (simple);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
contact_photo_source_set_client_cache (EContactPhotoSource *photo_source,
Packit Service de44cd
                                       EClientCache *client_cache)
Packit Service de44cd
{
Packit Service de44cd
	g_return_if_fail (E_IS_CLIENT_CACHE (client_cache));
Packit Service de44cd
	g_return_if_fail (photo_source->priv->client_cache == NULL);
Packit Service de44cd
Packit Service de44cd
	photo_source->priv->client_cache = g_object_ref (client_cache);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
contact_photo_source_set_source (EContactPhotoSource *photo_source,
Packit Service de44cd
                                 ESource *source)
Packit Service de44cd
{
Packit Service de44cd
	g_return_if_fail (E_IS_SOURCE (source));
Packit Service de44cd
	g_return_if_fail (photo_source->priv->source == NULL);
Packit Service de44cd
Packit Service de44cd
	photo_source->priv->source = g_object_ref (source);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
contact_photo_source_set_property (GObject *object,
Packit Service de44cd
                                   guint property_id,
Packit Service de44cd
                                   const GValue *value,
Packit Service de44cd
                                   GParamSpec *pspec)
Packit Service de44cd
{
Packit Service de44cd
	switch (property_id) {
Packit Service de44cd
		case PROP_CLIENT_CACHE:
Packit Service de44cd
			contact_photo_source_set_client_cache (
Packit Service de44cd
				E_CONTACT_PHOTO_SOURCE (object),
Packit Service de44cd
				g_value_get_object (value));
Packit Service de44cd
			return;
Packit Service de44cd
Packit Service de44cd
		case PROP_SOURCE:
Packit Service de44cd
			contact_photo_source_set_source (
Packit Service de44cd
				E_CONTACT_PHOTO_SOURCE (object),
Packit Service de44cd
				g_value_get_object (value));
Packit Service de44cd
			return;
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
contact_photo_source_get_property (GObject *object,
Packit Service de44cd
                                   guint property_id,
Packit Service de44cd
                                   GValue *value,
Packit Service de44cd
                                   GParamSpec *pspec)
Packit Service de44cd
{
Packit Service de44cd
	switch (property_id) {
Packit Service de44cd
		case PROP_CLIENT_CACHE:
Packit Service de44cd
			g_value_take_object (
Packit Service de44cd
				value,
Packit Service de44cd
				e_contact_photo_source_ref_client_cache (
Packit Service de44cd
				E_CONTACT_PHOTO_SOURCE (object)));
Packit Service de44cd
			return;
Packit Service de44cd
Packit Service de44cd
		case PROP_SOURCE:
Packit Service de44cd
			g_value_take_object (
Packit Service de44cd
				value,
Packit Service de44cd
				e_contact_photo_source_ref_source (
Packit Service de44cd
				E_CONTACT_PHOTO_SOURCE (object)));
Packit Service de44cd
			return;
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
contact_photo_source_dispose (GObject *object)
Packit Service de44cd
{
Packit Service de44cd
	EContactPhotoSourcePrivate *priv;
Packit Service de44cd
Packit Service de44cd
	priv = E_CONTACT_PHOTO_SOURCE_GET_PRIVATE (object);
Packit Service de44cd
Packit Service de44cd
	g_clear_object (&priv->client_cache);
Packit Service de44cd
	g_clear_object (&priv->source);
Packit Service de44cd
Packit Service de44cd
	/* Chain up to parent's dispose() method. */
Packit Service de44cd
	G_OBJECT_CLASS (e_contact_photo_source_parent_class)->dispose (object);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
contact_photo_source_get_photo (EPhotoSource *photo_source,
Packit Service de44cd
                                const gchar *email_address,
Packit Service de44cd
                                GCancellable *cancellable,
Packit Service de44cd
                                GAsyncReadyCallback callback,
Packit Service de44cd
                                gpointer user_data)
Packit Service de44cd
{
Packit Service de44cd
	GSimpleAsyncResult *simple;
Packit Service de44cd
	AsyncContext *async_context;
Packit Service de44cd
	EClientCache *client_cache;
Packit Service de44cd
	ESourceRegistry *registry;
Packit Service de44cd
	EBookQuery *book_query;
Packit Service de44cd
	ESource *source;
Packit Service de44cd
Packit Service de44cd
	book_query = e_book_query_field_test (
Packit Service de44cd
		E_CONTACT_EMAIL, E_BOOK_QUERY_IS, email_address);
Packit Service de44cd
Packit Service de44cd
	async_context = g_slice_new0 (AsyncContext);
Packit Service de44cd
	async_context->query_string = e_book_query_to_string (book_query);
Packit Service de44cd
Packit Service de44cd
	if (G_IS_CANCELLABLE (cancellable))
Packit Service de44cd
		async_context->cancellable = g_object_ref (cancellable);
Packit Service de44cd
Packit Service de44cd
	e_book_query_unref (book_query);
Packit Service de44cd
Packit Service de44cd
	simple = g_simple_async_result_new (
Packit Service de44cd
		G_OBJECT (photo_source), callback,
Packit Service de44cd
		user_data, contact_photo_source_get_photo);
Packit Service de44cd
Packit Service de44cd
	g_simple_async_result_set_check_cancellable (simple, cancellable);
Packit Service de44cd
Packit Service de44cd
	g_simple_async_result_set_op_res_gpointer (
Packit Service de44cd
		simple, async_context, (GDestroyNotify) async_context_free);
Packit Service de44cd
Packit Service de44cd
	client_cache = e_contact_photo_source_ref_client_cache (
Packit Service de44cd
		E_CONTACT_PHOTO_SOURCE (photo_source));
Packit Service de44cd
	registry = e_client_cache_ref_registry (client_cache);
Packit Service de44cd
Packit Service de44cd
	source = e_contact_photo_source_ref_source (
Packit Service de44cd
		E_CONTACT_PHOTO_SOURCE (photo_source));
Packit Service de44cd
Packit Service de44cd
	if (e_source_registry_check_enabled (registry, source)) {
Packit Service de44cd
		/* Obtain the EClient asynchronously.  If an instance needs
Packit Service de44cd
		 * to be created, it's more likely created in a thread with
Packit Service de44cd
		 * a main loop so signal emissions can work. */
Packit Service de44cd
		e_client_cache_get_client (
Packit Service de44cd
			client_cache, source,
Packit Service de44cd
			E_SOURCE_EXTENSION_ADDRESS_BOOK, (guint32) -1,
Packit Service de44cd
			cancellable,
Packit Service de44cd
			contact_photo_source_get_client_cb,
Packit Service de44cd
			g_object_ref (simple));
Packit Service de44cd
	} else {
Packit Service de44cd
		/* Return no result if the source is disabled. */
Packit Service de44cd
		g_simple_async_result_complete_in_idle (simple);
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	g_object_unref (client_cache);
Packit Service de44cd
	g_object_unref (registry);
Packit Service de44cd
	g_object_unref (source);
Packit Service de44cd
Packit Service de44cd
	g_object_unref (simple);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static gboolean
Packit Service de44cd
contact_photo_source_get_photo_finish (EPhotoSource *photo_source,
Packit Service de44cd
                                       GAsyncResult *result,
Packit Service de44cd
                                       GInputStream **out_stream,
Packit Service de44cd
                                       gint *out_priority,
Packit Service de44cd
                                       GError **error)
Packit Service de44cd
{
Packit Service de44cd
	GSimpleAsyncResult *simple;
Packit Service de44cd
	AsyncContext *async_context;
Packit Service de44cd
Packit Service de44cd
	g_return_val_if_fail (
Packit Service de44cd
		g_simple_async_result_is_valid (
Packit Service de44cd
		result, G_OBJECT (photo_source),
Packit Service de44cd
		contact_photo_source_get_photo), FALSE);
Packit Service de44cd
Packit Service de44cd
	simple = G_SIMPLE_ASYNC_RESULT (result);
Packit Service de44cd
	async_context = g_simple_async_result_get_op_res_gpointer (simple);
Packit Service de44cd
Packit Service de44cd
	if (g_simple_async_result_propagate_error (simple, error))
Packit Service de44cd
		return FALSE;
Packit Service de44cd
Packit Service de44cd
	if (async_context->stream != NULL) {
Packit Service de44cd
		*out_stream = g_object_ref (async_context->stream);
Packit Service de44cd
		if (out_priority != NULL)
Packit Service de44cd
			*out_priority = async_context->priority;
Packit Service de44cd
	} else {
Packit Service de44cd
		*out_stream = NULL;
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	return TRUE;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
e_contact_photo_source_class_init (EContactPhotoSourceClass *class)
Packit Service de44cd
{
Packit Service de44cd
	GObjectClass *object_class;
Packit Service de44cd
Packit Service de44cd
	g_type_class_add_private (class, sizeof (EContactPhotoSourcePrivate));
Packit Service de44cd
Packit Service de44cd
	object_class = G_OBJECT_CLASS (class);
Packit Service de44cd
	object_class->set_property = contact_photo_source_set_property;
Packit Service de44cd
	object_class->get_property = contact_photo_source_get_property;
Packit Service de44cd
	object_class->dispose = contact_photo_source_dispose;
Packit Service de44cd
Packit Service de44cd
	g_object_class_install_property (
Packit Service de44cd
		object_class,
Packit Service de44cd
		PROP_CLIENT_CACHE,
Packit Service de44cd
		g_param_spec_object (
Packit Service de44cd
			"client-cache",
Packit Service de44cd
			"Client Cache",
Packit Service de44cd
			"Cache of shared EClient instances",
Packit Service de44cd
			E_TYPE_CLIENT_CACHE,
Packit Service de44cd
			G_PARAM_READWRITE |
Packit Service de44cd
			G_PARAM_CONSTRUCT_ONLY));
Packit Service de44cd
Packit Service de44cd
	g_object_class_install_property (
Packit Service de44cd
		object_class,
Packit Service de44cd
		PROP_SOURCE,
Packit Service de44cd
		g_param_spec_object (
Packit Service de44cd
			"source",
Packit Service de44cd
			"Source",
Packit Service de44cd
			"An address book source",
Packit Service de44cd
			E_TYPE_SOURCE,
Packit Service de44cd
			G_PARAM_READWRITE |
Packit Service de44cd
			G_PARAM_CONSTRUCT_ONLY));
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
e_contact_photo_source_class_finalize (EContactPhotoSourceClass *class)
Packit Service de44cd
{
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
e_contact_photo_source_interface_init (EPhotoSourceInterface *iface)
Packit Service de44cd
{
Packit Service de44cd
	iface->get_photo = contact_photo_source_get_photo;
Packit Service de44cd
	iface->get_photo_finish = contact_photo_source_get_photo_finish;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
e_contact_photo_source_init (EContactPhotoSource *photo_source)
Packit Service de44cd
{
Packit Service de44cd
	photo_source->priv = E_CONTACT_PHOTO_SOURCE_GET_PRIVATE (photo_source);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
void
Packit Service de44cd
e_contact_photo_source_type_register (GTypeModule *type_module)
Packit Service de44cd
{
Packit Service de44cd
	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
Packit Service de44cd
	 *     function, so we have to wrap it with a public function in
Packit Service de44cd
	 *     order to register types from a separate compilation unit. */
Packit Service de44cd
	e_contact_photo_source_register_type (type_module);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
EPhotoSource *
Packit Service de44cd
e_contact_photo_source_new (EClientCache *client_cache,
Packit Service de44cd
                            ESource *source)
Packit Service de44cd
{
Packit Service de44cd
	g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL);
Packit Service de44cd
	g_return_val_if_fail (E_IS_SOURCE (source), NULL);
Packit Service de44cd
Packit Service de44cd
	return g_object_new (
Packit Service de44cd
		E_TYPE_CONTACT_PHOTO_SOURCE,
Packit Service de44cd
		"client-cache", client_cache,
Packit Service de44cd
		"source", source,
Packit Service de44cd
		NULL);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
EClientCache *
Packit Service de44cd
e_contact_photo_source_ref_client_cache (EContactPhotoSource *photo_source)
Packit Service de44cd
{
Packit Service de44cd
	g_return_val_if_fail (E_IS_CONTACT_PHOTO_SOURCE (photo_source), NULL);
Packit Service de44cd
Packit Service de44cd
	return g_object_ref (photo_source->priv->client_cache);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
ESource *
Packit Service de44cd
e_contact_photo_source_ref_source (EContactPhotoSource *photo_source)
Packit Service de44cd
{
Packit Service de44cd
	g_return_val_if_fail (E_IS_CONTACT_PHOTO_SOURCE (photo_source), NULL);
Packit Service de44cd
Packit Service de44cd
	return g_object_ref (photo_source->priv->source);
Packit Service de44cd
}
Packit Service de44cd