diff options
author | Travis Reitter <treitter@gmail.com> | 2010-02-25 14:36:08 -0800 |
---|---|---|
committer | Travis Reitter <treitter@gmail.com> | 2010-02-25 14:36:09 -0800 |
commit | 6f5caa40473feea9c9c7526affab43d173b34636 (patch) | |
tree | 05ea18a2154d7482547031a8c1357e5f08a9a9db | |
parent | 9c5151d2622f1ef04ce0d7a59c70cc355df3af28 (diff) | |
download | telepathy-logger-6f5caa40473feea9c9c7526affab43d173b34636.tar.gz |
Add favourite contacts support.
This adds a simple D-Bus API and implementation for storing and manipulating a set of favourite Telepathy contacts.
-rw-r--r-- | extensions/Logger.xml | 83 | ||||
-rw-r--r-- | telepathy-logger/Makefile.am | 2 | ||||
-rw-r--r-- | telepathy-logger/dbus-service.c | 660 | ||||
-rw-r--r-- | telepathy-logger/dbus-service.h | 6 |
4 files changed, 749 insertions, 2 deletions
diff --git a/extensions/Logger.xml b/extensions/Logger.xml index 1695690..a377829 100644 --- a/extensions/Logger.xml +++ b/extensions/Logger.xml @@ -91,6 +91,89 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</ </tp:docstring> </method> + <method name="GetFavouriteContacts" + tp:name-for-bindings="Get_Favourite_Contacts"> + <arg direction="out" name="Favourite_Contacts" type="a(oas)"> + <tp:docstring> + The favourite contacts, as an array of TpAccounts and their contact + identifiers. + </tp:docstring> + </arg> + + <tp:docstring> + Returns the favourite contacts. + </tp:docstring> + </method> + + <method name="AddFavouriteContact" + tp:name-for-bindings="Add_Favourite_Contact"> + <arg direction="in" name="Account" type="o" tp:type="Account"> + <tp:docstring> + The object path for the TpAccount to which the contact belongs + </tp:docstring> + </arg> + + <arg direction="in" name="Identifier" type="s"> + <tp:docstring> + The favourite contact's identifier + </tp:docstring> + </arg> + + <tp:docstring> + Add a contact's designation as a favourite. This method may not be + called until the service is ready. See the <tp:dbus-ref + namespace="org.freedesktop.Telepathy.Logger.DRAFT">FavouriteContactsReady</tp:dbus-ref> signal and <tp:dbus-ref + namespace="org.freedesktop.Telepathy.Logger.DRAFT">FavouriteContactsIsReady</tp:dbus-ref> property. + </tp:docstring> + </method> + + <method name="RemoveFavouriteContact" + tp:name-for-bindings="Remove_Favourite_Contact"> + <arg direction="in" name="Account" type="o" tp:type="Account"> + <tp:docstring> + The object path for the TpAccount to which the contact belongs + </tp:docstring> + </arg> + + <arg direction="in" name="Identifier" type="s"> + <tp:docstring> + The favourite contact's identifier + </tp:docstring> + </arg> + + <tp:docstring> + Remove a contact's designation as a favourite. This method may not be + called until the service is ready. See the <tp:dbus-ref + namespace="org.freedesktop.Telepathy.Logger.DRAFT">FavouriteContactsReady</tp:dbus-ref> signal and <tp:dbus-ref + namespace="org.freedesktop.Telepathy.Logger.DRAFT">FavouriteContactsIsReady</tp:dbus-ref> property. + </tp:docstring> + </method> + + <signal name="FavouriteContactsChanged" + tp:name-for-bindings="Favourite_Contacts_Changed"> + <tp:docstring> + The set of favourite contacts has changed. + </tp:docstring> + + <arg name="Account" type="o" tp:type="Account"> + <tp:docstring> + An account associated with the contact. + </tp:docstring> + </arg> + + <arg name="Added" type="as"> + <tp:docstring> + List of contact identifiers of contacts which are now favourites. + </tp:docstring> + </arg> + + <arg name="Removed" type="as"> + <tp:docstring> + List of contact identifiers of contacts which are no longer favourites. + </tp:docstring> + </arg> + </signal> + </interface> </node> <!-- vim:set sw=2 sts=2 et ft=xml: --> diff --git a/telepathy-logger/Makefile.am b/telepathy-logger/Makefile.am index 3f2021c..3892482 100644 --- a/telepathy-logger/Makefile.am +++ b/telepathy-logger/Makefile.am @@ -6,6 +6,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir) \ $(ERROR_CFLAGS) \ -DG_LOG_DOMAIN=\"tp-logger\" \ + -DTPL_DATA_DIR=\"$(PACKAGE_NAME)\" \ $(LIBTPL_CFLAGS) \ $(DISABLE_DEPRECATED) \ $(WARN_CFLAGS) @@ -38,7 +39,6 @@ LIBTPL_HEADERS = \ observer.h \ util.h - libtelepathy_logger_la_SOURCES = \ action-chain.c \ channel.c \ diff --git a/telepathy-logger/dbus-service.c b/telepathy-logger/dbus-service.c index 6f00c44..26a358b 100644 --- a/telepathy-logger/dbus-service.c +++ b/telepathy-logger/dbus-service.c @@ -22,11 +22,16 @@ #include "config.h" #include "dbus-service.h" +#include <string.h> +#include <sys/stat.h> + #include <glib.h> #include <telepathy-glib/dbus.h> #include <telepathy-glib/account.h> #include <telepathy-glib/util.h> +#include <telepathy-glib/svc-generic.h> +#include <telepathy-logger/action-chain.h> #include <telepathy-logger/log-entry-text.h> #include <telepathy-logger/log-manager.h> #include <telepathy-logger/util.h> @@ -36,22 +41,306 @@ #define DEBUG_FLAG TPL_DEBUG_DBUS_SERVICE #include <telepathy-logger/debug.h> +#define FAVOURITE_CONTACTS_FILENAME "favourite-contacts.txt" + static void tpl_logger_iface_init (gpointer iface, gpointer iface_data); #define GET_PRIV(obj) TPL_GET_PRIV (obj, TplDBusService) struct _TplDBusServicePriv { TplLogManager *manager; + /* map of (string) account name -> (string set) contact ID */ + /* (the set is implemented as a hash table) */ + GHashTable *accounts_contacts_map; + TplActionChain *favourite_contacts_actions; }; G_DEFINE_TYPE_WITH_CODE (TplDBusService, tpl_dbus_service, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (TPL_TYPE_SVC_LOGGER, tpl_logger_iface_init)); +typedef struct _FavouriteContactClosure FavouriteContactClosure; +typedef void (*FavouriteContactCallback) (gboolean success, + FavouriteContactClosure *closure); + + +struct _FavouriteContactClosure { + TplDBusService *service; + gchar *account; + gchar *contact_id; + gchar *file_contents; + DBusGMethodInvocation *context; + FavouriteContactCallback cb; +}; + + +static void +favourite_contact_closure_free (FavouriteContactClosure *closure) +{ + if (closure == NULL) + return; + + if (closure->service != NULL) + g_object_unref (closure->service); + + g_free (closure->account); + g_free (closure->contact_id); + g_free (closure->file_contents); + g_slice_free (FavouriteContactClosure, closure); +} + + +static FavouriteContactClosure * +favourite_contact_closure_new (TplDBusService *self, + const gchar *account, + const gchar *contact_id, + DBusGMethodInvocation *context) +{ + FavouriteContactClosure *closure; + + closure = g_slice_new0 (FavouriteContactClosure); + closure->service = g_object_ref (G_OBJECT (self)); + closure->account = g_strdup (account); + closure->contact_id = g_strdup (contact_id); + /* XXX: ideally we'd up the ref count or duplicate this */ + closure->context = context; + + return closure; +} + + +static gboolean +favourite_contacts_add_entry (TplDBusService *self, + const gchar *account, + const gchar *contact_id) +{ + GHashTable *contacts; + gboolean new_entry = FALSE; + TplDBusServicePriv *priv; + + g_return_val_if_fail (TPL_IS_DBUS_SERVICE (self), FALSE); + g_return_val_if_fail (account != NULL, FALSE); + g_return_val_if_fail (contact_id != NULL, FALSE); + + priv = GET_PRIV (self); + + DEBUG ("adding favourite contact: account '%s', ID '%s'", + account, contact_id); + + contacts = g_hash_table_lookup (priv->accounts_contacts_map, account); + if (contacts == NULL) + { + contacts = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, NULL); + g_hash_table_insert (priv->accounts_contacts_map, g_strdup (account), + contacts); + new_entry = TRUE; + } + else if (g_hash_table_lookup (contacts, contact_id) == NULL) + { + new_entry = TRUE; + } + + if (new_entry) + { + /* add dummy string for the value just for the convenience of looking up + * whether the key already exists */ + g_hash_table_insert (contacts, g_strdup (contact_id), + GINT_TO_POINTER (TRUE)); + } + + return new_entry; +} + + +static const gchar * +favourite_contacts_get_filename (void) +{ + static gchar *filename = NULL; + + if (filename == NULL) + { + filename = g_build_filename (g_get_user_data_dir (), TPL_DATA_DIR, + FAVOURITE_CONTACTS_FILENAME, NULL); + } + + return filename; +} + + +static gboolean +favourite_contacts_parse_line (TplDBusService *self, + const gchar *line) +{ + gboolean success = TRUE; + gchar **elements; + + if (line == NULL || line[0] == '\0') + return TRUE; + + /* this works on the assumption that account names can't have spaces in them + */ + elements = g_strsplit (line, " ", 2); + if (g_strv_length (elements) < 2) + { + DEBUG ("invalid number of elements on favourite contacts file line:\n" + "%s\n", line); + success = FALSE; + } + else + favourite_contacts_add_entry (self, elements[0], elements[1]); + + g_strfreev (elements); + + return success; +} + + +static void +favourite_contacts_file_read_line_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GDataInputStream *data_stream = G_DATA_INPUT_STREAM (object); + TplActionChain *action_chain = (TplActionChain *) (user_data); + TplDBusService *self = tpl_actionchain_get_object (action_chain); + TplDBusServicePriv *priv; + gchar *line; + GError *error = NULL; + + priv = GET_PRIV (self); + + line = g_data_input_stream_read_line_finish (data_stream, result, NULL, &error); + + if (error != NULL) + { + DEBUG ("failed to open favourite contacts file: %s", error->message); + g_clear_error (&error); + tpl_actionchain_terminate (action_chain); + } + else if (line != NULL) + { + favourite_contacts_parse_line (self, line); + + g_data_input_stream_read_line_async (data_stream, G_PRIORITY_DEFAULT, + NULL, favourite_contacts_file_read_line_cb, action_chain); + } + else + tpl_actionchain_continue (action_chain); +} + + +static void +favourite_contacts_file_open_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GFile *file = G_FILE (object); + TplActionChain *action_chain = (TplActionChain *) user_data; + GFileInputStream *stream; + GError *error = NULL; + + if ((stream = g_file_read_finish (file, result, &error))) + { + GDataInputStream *data_stream = g_data_input_stream_new ( + G_INPUT_STREAM (stream)); + + g_data_input_stream_read_line_async (data_stream, G_PRIORITY_DEFAULT, + NULL, favourite_contacts_file_read_line_cb, action_chain); + + g_object_unref (stream); + } + else if (error->code == G_IO_ERROR_NOT_FOUND) + { + DEBUG ("Favourite contacts file doesn't exist yet. Will create as " + "necessary."); + + g_clear_error (&error); + tpl_actionchain_continue (action_chain); + } + else + { + DEBUG ("Failed to open the favourite contacts file: %s", error->message); + g_clear_error (&error); + tpl_actionchain_terminate (action_chain); + } +} + + +static void +pendingproc_favourite_contacts_file_open (TplActionChain *action_chain, + gpointer user_data) +{ + const gchar *filename; + GFile *file; + + filename = favourite_contacts_get_filename (); + file = g_file_new_for_path (filename); + + g_file_read_async (file, G_PRIORITY_DEFAULT, NULL, + favourite_contacts_file_open_cb, action_chain); + + g_object_unref (G_OBJECT (file)); +} + + +static void +tpl_dbus_service_dispose (GObject *obj) +{ + TplDBusServicePriv *priv = GET_PRIV (obj); + + if (priv->accounts_contacts_map != NULL) + { + g_hash_table_destroy (priv->accounts_contacts_map); + priv->accounts_contacts_map = NULL; + } + + if (priv->favourite_contacts_actions != NULL) + priv->favourite_contacts_actions = NULL; + + G_OBJECT_CLASS (tpl_dbus_service_parent_class)->dispose (obj); +} + + +static void +favourite_contacts_file_parsed_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + TplDBusService *self = TPL_DBUS_SERVICE (object); + TplDBusServicePriv *priv = GET_PRIV (self); + + if (!tpl_actionchain_finish (result)) + { + DEBUG ("Failed to parse the favourite contacts file and/or execute " + "subsequent queued method calls"); + } + + priv->favourite_contacts_actions = NULL; +} + + +static void +tpl_dbus_service_constructed (GObject *object) +{ + TplDBusServicePriv *priv = GET_PRIV (object); + + priv->favourite_contacts_actions = tpl_actionchain_new (object, + favourite_contacts_file_parsed_cb, object); + + tpl_actionchain_append (priv->favourite_contacts_actions, + pendingproc_favourite_contacts_file_open, NULL); + tpl_actionchain_continue (priv->favourite_contacts_actions); +} + + static void tpl_dbus_service_class_init (TplDBusServiceClass *klass) { GObjectClass* object_class = G_OBJECT_CLASS (klass); + object_class->constructed = tpl_dbus_service_constructed; + object_class->dispose = tpl_dbus_service_dispose; + g_type_class_add_private (object_class, sizeof (TplDBusServicePriv)); } @@ -66,6 +355,9 @@ tpl_dbus_service_init (TplDBusService *self) self->priv = priv; priv->manager = tpl_log_manager_dup_singleton (); + priv->accounts_contacts_map = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, (GDestroyNotify) g_hash_table_destroy); + priv->favourite_contacts_actions = NULL; } @@ -209,6 +501,371 @@ out: static void +append_favourite_contacts_account_and_contacts (const gchar *account, + GHashTable *contacts, + GPtrArray *packed) +{ + GList *l; + gchar **contact_ids; + gint i; + + /* this case shouldn't happen, but this is just some basic sanity checking */ + if (g_hash_table_size (contacts) < 1) + return; + + /* includes room for the terminal NULL */ + contact_ids = g_new0 (gchar *, g_hash_table_size (contacts)+1); + + for (i = 0, l = g_hash_table_get_keys (contacts); + l; + i++, l = g_list_delete_link (l, l)) + { + contact_ids[i] = l->data; + } + + g_ptr_array_add (packed, tp_value_array_build (2, + DBUS_TYPE_G_OBJECT_PATH, account, + G_TYPE_STRV, contact_ids, + G_TYPE_INVALID)); + + g_free (contact_ids); +} + + +static void +pendingproc_get_favourite_contacts (TplActionChain *action_chain, + gpointer user_data) +{ + FavouriteContactClosure *closure = user_data; + TplDBusServicePriv *priv; + GPtrArray *packed; + + g_return_if_fail (closure); + g_return_if_fail (TPL_IS_DBUS_SERVICE (closure->service)); + g_return_if_fail (closure->context != NULL); + + priv = GET_PRIV (closure->service); + + packed = g_ptr_array_new_with_free_func ((GDestroyNotify) g_value_array_free); + + g_hash_table_foreach (priv->accounts_contacts_map, + (GHFunc) append_favourite_contacts_account_and_contacts, packed); + + tpl_svc_logger_return_from_get_favourite_contacts (closure->context, packed); + + g_ptr_array_free (packed, TRUE); + favourite_contact_closure_free (closure); + + if (action_chain != NULL) + tpl_actionchain_continue (action_chain); +} + + +static void +tpl_dbus_service_get_favourite_contacts (TplSvcLogger *self, + DBusGMethodInvocation *context) +{ + TplDBusServicePriv *priv; + FavouriteContactClosure *closure; + + g_return_if_fail (TPL_IS_DBUS_SERVICE (self)); + g_return_if_fail (context != NULL); + + priv = GET_PRIV (self); + + closure = favourite_contact_closure_new (TPL_DBUS_SERVICE (self), NULL, NULL, + context); + + /* If we're still waiting on the contacts to finish being parsed from disk, + * queue this action */ + if (priv->favourite_contacts_actions != NULL) + { + tpl_actionchain_append (priv->favourite_contacts_actions, + pendingproc_get_favourite_contacts, closure); + } + else + pendingproc_get_favourite_contacts (NULL, closure); +} + + +static void +append_favourite_contacts_file_entries (const gchar *account, + GHashTable *contacts, + GString *string) +{ + GList *l; + + for (l = g_hash_table_get_keys (contacts); l; l = g_list_delete_link (l, l)) + g_string_append_printf (string, "%s %s\n", account, (const gchar*) l->data); +} + + +static gchar * +favourite_contacts_to_string (TplDBusService *self) +{ + TplDBusServicePriv *priv = GET_PRIV (self); + GString *string; + + string = g_string_new (""); + + g_hash_table_foreach (priv->accounts_contacts_map, + (GHFunc) append_favourite_contacts_file_entries, string); + + return g_string_free (string, FALSE); +} + + +static void +favourite_contacts_file_replace_contents_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GFile *file = G_FILE (object); + GError *error = NULL; + FavouriteContactClosure *closure = user_data; + gboolean success; + + if (g_file_replace_contents_finish (file, result, NULL, &error)) + { + success = TRUE; + } + else + { + DEBUG ("Failed to save favourite contacts file: %s", error->message); + success = FALSE; + g_clear_error (&error); + } + + ((FavouriteContactCallback) closure->cb) (success, closure); +} + + +static void +favourite_contacts_file_save_async (TplDBusService *self, + FavouriteContactClosure *closure) +{ + gchar *dir; + const gchar *filename; + GFile *file; + gchar *file_contents; + + g_return_if_fail (closure != NULL); + + filename = favourite_contacts_get_filename (); + dir = g_path_get_dirname (filename); + g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR); + g_free (dir); + + file = g_file_new_for_path (filename); + + file_contents = favourite_contacts_to_string (self); + + closure->file_contents = file_contents; + + g_file_replace_contents_async (file, + file_contents, strlen (file_contents), NULL, FALSE, + G_FILE_CREATE_REPLACE_DESTINATION, NULL, + favourite_contacts_file_replace_contents_cb, closure); + + g_object_unref (file); +} + + +static void +add_favourite_contact_file_save_cb (gboolean added_favourite, + FavouriteContactClosure *closure) +{ + TplDBusServicePriv *priv = GET_PRIV (closure->service); + TplActionChain *action_chain = priv->favourite_contacts_actions; + + if (added_favourite) + { + const gchar *added[] = { NULL, NULL }; + const gchar *removed[] = { NULL }; + + added[0] = closure->contact_id; + + tpl_svc_logger_emit_favourite_contacts_changed (closure->service, + closure->account, added, removed); + } + + tpl_svc_logger_return_from_add_favourite_contact (closure->context); + + favourite_contact_closure_free (closure); + if (action_chain != NULL) + tpl_actionchain_continue (action_chain); +} + + +static void +pendingproc_add_favourite_contact (TplActionChain *action_chain, + gpointer user_data) +{ + FavouriteContactClosure *closure = user_data; + gboolean should_add = FALSE; + TplDBusServicePriv *priv; + GError *error = NULL; + + g_return_if_fail (closure); + g_return_if_fail (TPL_IS_DBUS_SERVICE (closure->service)); + g_return_if_fail (closure->context != NULL); + + priv = GET_PRIV (closure->service); + + if (!tp_dbus_check_valid_object_path (closure->account, &error)) + { + dbus_g_method_return_error (closure->context, error); + + goto pendingproc_add_favourite_contact_ERROR; + } + + should_add = favourite_contacts_add_entry (closure->service, closure->account, + closure->contact_id); + + closure->cb = add_favourite_contact_file_save_cb; + + if (should_add) + favourite_contacts_file_save_async (closure->service, closure); + else + add_favourite_contact_file_save_cb (FALSE, closure); + + return; + +pendingproc_add_favourite_contact_ERROR: + g_clear_error (&error); + if (action_chain != NULL) + tpl_actionchain_terminate (action_chain); +} + + +static void +tpl_dbus_service_add_favourite_contact (TplSvcLogger *self, + const gchar *account, + const gchar *contact_id, + DBusGMethodInvocation *context) +{ + TplDBusServicePriv *priv; + FavouriteContactClosure *closure; + + g_return_if_fail (TPL_IS_DBUS_SERVICE (self)); + g_return_if_fail (context != NULL); + + priv = GET_PRIV (self); + + closure = favourite_contact_closure_new (TPL_DBUS_SERVICE (self), account, + contact_id, context); + + /* If we're still waiting on the contacts to finish being parsed from disk, + * queue this action */ + if (priv->favourite_contacts_actions != NULL) + { + tpl_actionchain_append (priv->favourite_contacts_actions, + pendingproc_add_favourite_contact, closure); + } + else + pendingproc_add_favourite_contact (NULL, closure); +} + +static void +remove_favourite_contact_file_save_cb (gboolean removed_favourite, + FavouriteContactClosure *closure) +{ + TplDBusServicePriv *priv = GET_PRIV (closure->service); + TplActionChain *action_chain = priv->favourite_contacts_actions; + + if (removed_favourite) + { + const gchar *added[] = { NULL }; + const gchar *removed[] = { NULL, NULL }; + + removed[0] = closure->contact_id; + + tpl_svc_logger_emit_favourite_contacts_changed (closure->service, + closure->account, added, removed); + } + + tpl_svc_logger_return_from_remove_favourite_contact (closure->context); + + favourite_contact_closure_free (closure); + if (action_chain != NULL) + tpl_actionchain_continue (action_chain); +} + + +static void +pendingproc_remove_favourite_contact (TplActionChain *action_chain, + gpointer user_data) +{ + FavouriteContactClosure *closure = user_data; + GHashTable *contacts; + gboolean removed = FALSE; + GError *error = NULL; + + g_return_if_fail (closure != NULL); + g_return_if_fail (TPL_IS_DBUS_SERVICE (closure->service)); + g_return_if_fail (closure->context != NULL); + + TplDBusServicePriv *priv = GET_PRIV (closure->service); + + if (!tp_dbus_check_valid_object_path (closure->account, &error)) + { + dbus_g_method_return_error (closure->context, error); + + goto pendingproc_remove_favourite_contact_ERROR; + } + + DEBUG ("removing favourite contact: account '%s', ID '%s'", + closure->account, closure->contact_id); + + contacts = g_hash_table_lookup (priv->accounts_contacts_map, + closure->account); + if (contacts != NULL && g_hash_table_remove (contacts, closure->contact_id)) + removed = TRUE; + + closure->cb = remove_favourite_contact_file_save_cb; + + if (removed) + favourite_contacts_file_save_async (closure->service, closure); + else + remove_favourite_contact_file_save_cb (FALSE, closure); + + return; + +pendingproc_remove_favourite_contact_ERROR: + g_clear_error (&error); + if (action_chain != NULL) + tpl_actionchain_terminate (action_chain); +} + +static void +tpl_dbus_service_remove_favourite_contact (TplSvcLogger *self, + const gchar *account, + const gchar *contact_id, + DBusGMethodInvocation *context) +{ + TplDBusServicePriv *priv; + FavouriteContactClosure *closure; + + g_return_if_fail (TPL_IS_DBUS_SERVICE (self)); + g_return_if_fail (context != NULL); + + priv = GET_PRIV (self); + + closure = favourite_contact_closure_new (TPL_DBUS_SERVICE (self), account, + contact_id, context); + + /* If we're still waiting on the contacts to finish being parsed from disk, + * queue this action */ + if (priv->favourite_contacts_actions != NULL) + { + tpl_actionchain_append (priv->favourite_contacts_actions, + pendingproc_remove_favourite_contact, closure); + } + else + pendingproc_remove_favourite_contact (NULL, closure); +} + +static void tpl_logger_iface_init (gpointer iface, gpointer iface_data) { @@ -216,5 +873,8 @@ tpl_logger_iface_init (gpointer iface, #define IMPLEMENT(x) tpl_svc_logger_implement_##x (klass, tpl_dbus_service_##x) IMPLEMENT (get_recent_messages); + IMPLEMENT (get_favourite_contacts); + IMPLEMENT (add_favourite_contact); + IMPLEMENT (remove_favourite_contact); #undef IMPLEMENT } diff --git a/telepathy-logger/dbus-service.h b/telepathy-logger/dbus-service.h index d0424a2..600c826 100644 --- a/telepathy-logger/dbus-service.h +++ b/telepathy-logger/dbus-service.h @@ -23,6 +23,7 @@ #define __TPL_DBUS_SERVICE_H__ #include <glib-object.h> +#include <telepathy-glib/dbus-properties-mixin.h> #include <telepathy-logger/log-manager.h> @@ -44,7 +45,10 @@ G_BEGIN_DECLS "tpl-dbus-service-error-quark") typedef enum { - TPL_DBUS_SERVICE_ERROR_FAILED + TPL_DBUS_SERVICE_ERROR_FAILED, + /* >= 1 argument(s) is/are invalid */ + TPL_DBUS_SERVICE_ERROR_INVALID_ARGS, + TPL_DBUS_SERVICE_ERROR_NOT_READY, } TplDBusServiceError; typedef struct _TplDBusServicePriv TplDBusServicePriv; |