From 1928e560fa179d8a6427ff3a1300f739b6fb847a Mon Sep 17 00:00:00 2001 From: Murray Cumming Date: Thu, 21 Jun 2007 12:42:31 +0000 Subject: [PATCH 1/1] 2007-06-21 Murray Cumming * libmodest-dbus-client/libmodest-dbus-client.h: * libmodest-dbus-client/libmodest-dbus-client.c: (modest_dbus_message_iter_get_search_hit), (libmodest_dbus_client_search): Reorganised and commented this. Removed modest_search_hit_free() from the public API because it is not needed. Added libmodest_dbus_client_get_folders() and modest_folder_result_list_free(). * src/dbus_api/modest-dbus-api.h: * src/dbus_api/modest-dbus-callbacks.c: (modest_dbus_req_filter): Commented. Moved most code to on_dbus_method_search() and added on_dbus_method_get_folders(). * src/maemo/modest-platform.c: (modest_platform_init): Commented the use of the extra D-Bus handler. * tests/dbus_api/Makefile.am: * tests/dbus_api/test_get_folders.c: New test for libmodest_dbus_client_get_folders(). This seems to return an empty list at the moment. That could be the same error that causes the message list to be empty sometimes. This should help with projects.maemo.org bug NB#57740. pmo-trunk-r2358 --- ChangeLog | 22 ++ ChangeLog2 | 28 ++ libmodest-dbus-client/libmodest-dbus-client.c | 256 +++++++++++++++-- libmodest-dbus-client/libmodest-dbus-client.h | 20 +- src/dbus_api/modest-dbus-api.h | 6 +- src/dbus_api/modest-dbus-callbacks.c | 373 ++++++++++++++++++------- src/maemo/modest-platform.c | 9 +- src/modest-tny-account-store.h | 2 +- tests/dbus_api/Makefile.am | 6 +- tests/dbus_api/test_compose_mail.c | 2 +- tests/dbus_api/test_get_folders.c | 50 ++++ 11 files changed, 643 insertions(+), 131 deletions(-) create mode 100644 tests/dbus_api/test_get_folders.c diff --git a/ChangeLog b/ChangeLog index acb6b92..9d4f329 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1 +1,23 @@ +2007-06-21 Murray Cumming,,, + + reviewed by: + + * libmodest-dbus-client/libmodest-dbus-client.c: + (modest_dbus_message_iter_get_search_hit), + (libmodest_dbus_client_search), (modest_folder_result_free), + (modest_folder_result_list_free), + (modest_dbus_message_iter_get_folder_item), + (libmodest_dbus_client_get_folders): + * libmodest-dbus-client/libmodest-dbus-client.h: + * src/dbus_api/modest-dbus-api.h: + * src/dbus_api/modest-dbus-callbacks.c: (modest_dbus_req_handler), + (on_dbus_method_search), (get_folders_result_to_message), + (add_folders_to_list), (on_dbus_method_get_folders), + (modest_dbus_req_filter): + * src/maemo/modest-platform.c: (modest_platform_init): + * src/modest-tny-account-store.h: + * tests/dbus_api/Makefile.am: + * tests/dbus_api/test_compose_mail.c: (main): + * tests/dbus_api/test_get_folders.c: (main): + * please check the svn log instead diff --git a/ChangeLog2 b/ChangeLog2 index b98779a..7370d64 100644 --- a/ChangeLog2 +++ b/ChangeLog2 @@ -1,3 +1,31 @@ +2007-06-21 Murray Cumming + + * libmodest-dbus-client/libmodest-dbus-client.h: + * libmodest-dbus-client/libmodest-dbus-client.c: + (modest_dbus_message_iter_get_search_hit), + (libmodest_dbus_client_search): + Reorganised and commented this. + Removed modest_search_hit_free() from the public API because it + is not needed. + + Added libmodest_dbus_client_get_folders() and + modest_folder_result_list_free(). + + * src/dbus_api/modest-dbus-api.h: + * src/dbus_api/modest-dbus-callbacks.c: + (modest_dbus_req_filter): Commented. Moved most code to + on_dbus_method_search() and added on_dbus_method_get_folders(). + + * src/maemo/modest-platform.c: (modest_platform_init): Commented the use + of the extra D-Bus handler. + + * tests/dbus_api/Makefile.am: + * tests/dbus_api/test_get_folders.c: New test for + libmodest_dbus_client_get_folders(). This seems to return an empty list + at the moment. That could be the same error that causes the message list + to be empty sometimes. + This should help with projects.maemo.org bug NB#57740. + 2007-06-21 Armin Burgmeier * src/modest-mail-operation.c: Do not call diff --git a/libmodest-dbus-client/libmodest-dbus-client.c b/libmodest-dbus-client/libmodest-dbus-client.c index 68fe837..85d9447 100644 --- a/libmodest-dbus-client/libmodest-dbus-client.c +++ b/libmodest-dbus-client/libmodest-dbus-client.c @@ -298,7 +298,7 @@ libmodest_dbus_client_delete_message (osso_context_t *osso_ctx, return ret == OSSO_OK; } -void +static void modest_search_hit_free (ModestSearchHit *hit) { g_free (hit->msgid); @@ -380,9 +380,10 @@ _dbus_iter_get_boolean (DBusMessageIter *iter) return ret; } - +/** Get the values from the complex type (SEARCH_HIT_DBUS_TYPE) + * in the D-Bus return message. */ static ModestSearchHit * -dbus_message_iter_get_search_hit (DBusMessageIter *parent) +modest_dbus_message_iter_get_search_hit (DBusMessageIter *parent) { ModestSearchHit *hit; DBusMessageIter child; @@ -513,7 +514,7 @@ dbus_message_iter_get_search_hit (DBusMessageIter *parent) goto out; } - /* msize */ + /* timestamp */ arg_type = dbus_message_iter_get_arg_type (&child); if (arg_type != DBUS_TYPE_INT64) { @@ -531,7 +532,7 @@ dbus_message_iter_get_search_hit (DBusMessageIter *parent) out: if (error) { - g_warning ("Error during unmarshaling"); + g_warning ("%s: Error during unmarshalling", __FUNCTION__); modest_search_hit_free (hit); hit = NULL; } @@ -615,14 +616,14 @@ libmodest_dbus_client_search (osso_context_t *osso_ctx, { DBusMessage *msg; - dbus_bool_t res; + dbus_bool_t res; DBusError err; DBusConnection *con; DBusMessageIter iter; DBusMessageIter child; - DBusMessage *reply = NULL; + DBusMessage *reply = NULL; gint timeout; - int arg_type; + int arg_type; dbus_int64_t sd_v; dbus_int64_t ed_v; dbus_int32_t flags_v; @@ -642,14 +643,14 @@ libmodest_dbus_client_search (osso_context_t *osso_ctx, msg = dbus_message_new_method_call (MODEST_DBUS_SERVICE, - MODEST_DBUS_OBJECT, - MODEST_DBUS_IFACE, - MODEST_DBUS_METHOD_SEARCH); + MODEST_DBUS_OBJECT, + MODEST_DBUS_IFACE, + MODEST_DBUS_METHOD_SEARCH); - if (msg == NULL) { - //ULOG_ERR_F("dbus_message_new_method_call failed"); + if (msg == NULL) { + //ULOG_ERR_F("dbus_message_new_method_call failed"); return OSSO_ERROR; - } + } if (folder == NULL) { folder = ""; @@ -712,7 +713,7 @@ libmodest_dbus_client_search (osso_context_t *osso_ctx, return FALSE; } - g_debug ("message return"); + g_debug ("%s: message return", __FUNCTION__); dbus_message_iter_init (reply, &iter); arg_type = dbus_message_iter_get_arg_type (&iter); @@ -723,7 +724,7 @@ libmodest_dbus_client_search (osso_context_t *osso_ctx, do { ModestSearchHit *hit; - hit = dbus_message_iter_get_search_hit (&child); + hit = modest_dbus_message_iter_get_search_hit (&child); if (hit) { *hits = g_list_prepend (*hits, hit); @@ -765,3 +766,226 @@ libmodest_dbus_client_search (osso_context_t *osso_ctx, return TRUE; } + +static void +modest_folder_result_free (ModestFolderResult *item) +{ + g_free (item->folder_name); + g_free (item->folder_uri); + g_slice_free (ModestFolderResult, item); +} + +void +modest_folder_result_list_free (GList *list) +{ + GList *iter; + + if (list == NULL) { + return; + } + + for (iter = list; iter; iter = iter->next) { + modest_folder_result_free ((ModestFolderResult *) iter->data); + } + + g_list_free (list); +} + + +/** Get the values from the complex type (GET_FOLDERS_RESULT_DBUS_TYPE) + * in the D-Bus return message. */ +static ModestFolderResult * +modest_dbus_message_iter_get_folder_item (DBusMessageIter *parent) +{ + gboolean error = FALSE; + ModestFolderResult *item = g_slice_new0 (ModestFolderResult); + + int arg_type = dbus_message_iter_get_arg_type (parent); + + if (arg_type != 'r') { + return NULL; + } + + DBusMessageIter child; + dbus_message_iter_recurse (parent, &child); + + /* folder name: */ + arg_type = dbus_message_iter_get_arg_type (&child); + + if (arg_type != DBUS_TYPE_STRING) { + error = TRUE; + goto out; + } + + item->folder_name = _dbus_iter_get_string_or_null (&child); + + + dbus_bool_t res = dbus_message_iter_next (&child); + if (res == FALSE) { + error = TRUE; + goto out; + } + + /* folder URI: */ + arg_type = dbus_message_iter_get_arg_type (&child); + + if (arg_type != DBUS_TYPE_STRING) { + error = TRUE; + goto out; + } + + item->folder_uri = _dbus_iter_get_string_or_null (&child); + + +out: + if (error) { + g_warning ("%s: Error during unmarshalling", __FUNCTION__); + modest_folder_result_free (item); + item = NULL; + } + + return item; +} + +/** + * libmodest_dbus_client_get_folders: + * @osso_ctx: A valid #osso_context_t object. + * @folders: A pointer to a valid GList pointer that will contain the folder items + * (ModestFolderResult). The list and the items must be freed by the caller + * with modest_folder_result_list_free(). + * + * This method will obtain a list of folders in the default account. + * + * Upon success TRUE is returned and @folders will include the folders or the list + * might be empty if there are no folders. The returned + * list must be freed with modest_folder_result_list_free (). + * + * NOTE: A folder will only be retrieved if it was previously downloaded by + * modest. This function does also not attempt do to remote refreshes (i.e. IMAP). + * + * Return value: TRUE if the request succeded or FALSE for an error. + **/ +gboolean +libmodest_dbus_client_get_folders (osso_context_t *osso_ctx, + GList **folders) +{ + /* Initialize output argument: */ + if (folders) + *folders = NULL; + else + return FALSE; + + DBusConnection *con = osso_get_dbus_connection (osso_ctx); + + if (con == NULL) { + g_warning ("Could not get dbus connection\n"); + return FALSE; + + } + + DBusMessage *msg = dbus_message_new_method_call (MODEST_DBUS_SERVICE, + MODEST_DBUS_OBJECT, + MODEST_DBUS_IFACE, + MODEST_DBUS_METHOD_GET_FOLDERS); + + if (msg == NULL) { + //ULOG_ERR_F("dbus_message_new_method_call failed"); + return OSSO_ERROR; + } + + dbus_message_set_auto_start (msg, TRUE); + + gint timeout = 1000; //XXX + osso_rpc_get_timeout (osso_ctx, &timeout); + + DBusError err; + dbus_error_init (&err); + DBusMessage *reply = dbus_connection_send_with_reply_and_block (con, + msg, + timeout, + &err); + + dbus_message_unref (msg); + msg = NULL; + + if (reply == NULL) { + //ULOG_ERR_F("dbus_connection_send_with_reply_and_block error: %s", err.message); + //XXX to GError?! + return FALSE; + } + + switch (dbus_message_get_type (reply)) { + + case DBUS_MESSAGE_TYPE_ERROR: + dbus_set_error_from_message (&err, reply); + //XXX to GError?! + dbus_error_free (&err); + dbus_message_unref (reply); + return FALSE; + + case DBUS_MESSAGE_TYPE_METHOD_RETURN: + /* ok we are good to go + * lets drop outa here and handle that */ + break; + default: + //ULOG_WARN_F("got unknown message type as reply"); + //retval->type = DBUS_TYPE_STRING; + //retval->value.s = g_strdup("Invalid return value"); + //XXX to GError?! + dbus_message_unref (reply); + return FALSE; + } + + g_debug ("%s: message return", __FUNCTION__); + + DBusMessageIter iter; + dbus_message_iter_init (reply, &iter); + /* int arg_type = dbus_message_iter_get_arg_type (&iter); */ + + DBusMessageIter child; + dbus_message_iter_recurse (&iter, &child); + + do { + ModestFolderResult *item = modest_dbus_message_iter_get_folder_item (&child); + + if (item) { + *folders = g_list_append (*folders, item); + } + + } while (dbus_message_iter_next (&child)); + + dbus_message_unref (reply); + + + /* TODO: This is from osso source, do we need it? */ +#if 0 + /* Tell TaskNavigator to show "launch banner" */ + msg = dbus_message_new_method_call (TASK_NAV_SERVICE, + APP_LAUNCH_BANNER_METHOD_PATH, + APP_LAUNCH_BANNER_METHOD_INTERFACE, + APP_LAUNCH_BANNER_METHOD); + + if (msg == NULL) { + g_warn ("dbus_message_new_method_call failed"); + } + + + + dbus_message_append_args (msg, + DBUS_TYPE_STRING, + &service, + DBUS_TYPE_INVALID); + + b = dbus_connection_send (conn, msg, NULL); + + if (b == NULL) { + ULOG_WARN_F("dbus_connection_send failed"); + } + + dbus_message_unref (msg); +#endif + + return TRUE; +} + + diff --git a/libmodest-dbus-client/libmodest-dbus-client.h b/libmodest-dbus-client/libmodest-dbus-client.h index 7b7bdc6..7ec38dd 100644 --- a/libmodest-dbus-client/libmodest-dbus-client.h +++ b/libmodest-dbus-client/libmodest-dbus-client.h @@ -69,7 +69,6 @@ typedef enum { } ModestDBusSearchFlags; typedef struct { - gchar *msgid; /* E.g. the URI of the message. */ gchar *subject; gchar *folder; /* The name, not the URI. */ @@ -78,15 +77,13 @@ typedef struct { gboolean has_attachment; gboolean is_unread; gint64 timestamp; - } ModestSearchHit; -void modest_search_hit_free (ModestSearchHit *hit); void modest_search_hit_list_free (GList *hits); -gboolean libmodest_dbus_client_search (osso_context_t *osso_ctx, +gboolean libmodest_dbus_client_search (osso_context_t *osso_ctx, const gchar *query, const gchar *folder, time_t start_date, @@ -95,6 +92,19 @@ gboolean libmodest_dbus_client_search (osso_context_t ModestDBusSearchFlags flags, GList **hits); -gboolean libmodest_dbus_client_delete_message (osso_context_t *osso_ctx, +gboolean libmodest_dbus_client_delete_message (osso_context_t *osso_ctx, const char *msg_uri); + + +typedef struct { + gchar *folder_uri; + gchar *folder_name; +} ModestFolderResult; + +gboolean libmodest_dbus_client_get_folders (osso_context_t *osso_ctx, GList **folders); + +void modest_folder_result_list_free (GList *folders); + + + #endif /* __LIBMODEST_DBUS_CLIENT_H__ */ diff --git a/src/dbus_api/modest-dbus-api.h b/src/dbus_api/modest-dbus-api.h index c43cf50..364de16 100644 --- a/src/dbus_api/modest-dbus-api.h +++ b/src/dbus_api/modest-dbus-api.h @@ -80,8 +80,6 @@ enum ModestDbusComposeMailArguments MODEST_DEBUS_COMPOSE_MAIL_ARGS_COUNT }; -#define MODEST_DBUS_METHOD_SEARCH "Search" - #define MODEST_DBUS_METHOD_DELETE_MESSAGE "DeleteMessage" enum ModestDbusDeleteMessageArguments { @@ -91,7 +89,9 @@ enum ModestDbusDeleteMessageArguments #define MODEST_DBUS_METHOD_OPEN_DEFAULT_INBOX "OpenDefaultInbox" - +/* These are handle via normal D-Bus instead of osso-rpc: */ +#define MODEST_DBUS_METHOD_SEARCH "Search" +#define MODEST_DBUS_METHOD_GET_FOLDERS "GetFolders" #endif /* __MODEST_DBUS_API__ */ diff --git a/src/dbus_api/modest-dbus-callbacks.c b/src/dbus_api/modest-dbus-callbacks.c index da56d4d..b7a0437 100644 --- a/src/dbus_api/modest-dbus-callbacks.c +++ b/src/dbus_api/modest-dbus-callbacks.c @@ -838,23 +838,26 @@ gint modest_dbus_req_handler(const gchar * interface, const gchar * method, } else { /* We need to return INVALID here so - * osso is returning DBUS_HANDLER_RESULT_NOT_YET_HANDLED - * so our modest_dbus_req_filter can kick in! + * libosso will return DBUS_HANDLER_RESULT_NOT_YET_HANDLED, + * so that our modest_dbus_req_filter will then be tried instead. * */ return OSSO_INVALID; } } - + +/* A complex D-Bus type (like a struct), + * used to return various information about a search hit. + */ #define SEARCH_HIT_DBUS_TYPE \ DBUS_STRUCT_BEGIN_CHAR_AS_STRING \ - DBUS_TYPE_STRING_AS_STRING \ - DBUS_TYPE_STRING_AS_STRING \ - DBUS_TYPE_STRING_AS_STRING \ - DBUS_TYPE_STRING_AS_STRING \ - DBUS_TYPE_UINT64_AS_STRING \ - DBUS_TYPE_BOOLEAN_AS_STRING \ - DBUS_TYPE_BOOLEAN_AS_STRING \ - DBUS_TYPE_INT64_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING /* msgid */ \ + DBUS_TYPE_STRING_AS_STRING /* subject */ \ + DBUS_TYPE_STRING_AS_STRING /* folder */ \ + DBUS_TYPE_STRING_AS_STRING /* sender */ \ + DBUS_TYPE_UINT64_AS_STRING /* msize */ \ + DBUS_TYPE_BOOLEAN_AS_STRING /* has_attachment */ \ + DBUS_TYPE_BOOLEAN_AS_STRING /* is_unread */ \ + DBUS_TYPE_INT64_AS_STRING /* timestamp */ \ DBUS_STRUCT_END_CHAR_AS_STRING static DBusMessage * @@ -949,121 +952,287 @@ search_result_to_message (DBusMessage *reply, return reply; } -DBusHandlerResult -modest_dbus_req_filter (DBusConnection *con, - DBusMessage *message, - void *user_data) -{ - gboolean handled = FALSE; - DBusError error; - if (dbus_message_is_method_call (message, - MODEST_DBUS_IFACE, - MODEST_DBUS_METHOD_SEARCH)) { - ModestDBusSearchFlags dbus_flags; - ModestSearch search; - DBusMessage *reply = NULL; - dbus_bool_t res; - dbus_int64_t sd_v; - dbus_int64_t ed_v; - dbus_int32_t flags_v; - dbus_uint32_t serial; - dbus_uint32_t size_v; - char *folder; - char *query; - time_t start_date; - time_t end_date; - GList *hits; - - handled = TRUE; - - dbus_error_init (&error); - - sd_v = ed_v = 0; - flags_v = 0; - - res = dbus_message_get_args (message, - &error, - DBUS_TYPE_STRING, &query, - DBUS_TYPE_STRING, &folder, - DBUS_TYPE_INT64, &sd_v, - DBUS_TYPE_INT64, &ed_v, - DBUS_TYPE_INT32, &flags_v, - DBUS_TYPE_UINT32, &size_v, - DBUS_TYPE_INVALID); - - dbus_flags = (ModestDBusSearchFlags) flags_v; - start_date = (time_t) sd_v; - end_date = (time_t) ed_v; +static void +on_dbus_method_search (DBusConnection *con, DBusMessage *message) +{ + ModestDBusSearchFlags dbus_flags; + ModestSearch search; + DBusMessage *reply = NULL; + dbus_bool_t res; + dbus_int64_t sd_v; + dbus_int64_t ed_v; + dbus_int32_t flags_v; + dbus_uint32_t size_v; + char *folder; + char *query; + time_t start_date; + time_t end_date; + GList *hits; + + DBusError error; + dbus_error_init (&error); + + sd_v = ed_v = 0; + flags_v = 0; + + res = dbus_message_get_args (message, + &error, + DBUS_TYPE_STRING, &query, + DBUS_TYPE_STRING, &folder, + DBUS_TYPE_INT64, &sd_v, + DBUS_TYPE_INT64, &ed_v, + DBUS_TYPE_INT32, &flags_v, + DBUS_TYPE_UINT32, &size_v, + DBUS_TYPE_INVALID); + + dbus_flags = (ModestDBusSearchFlags) flags_v; + start_date = (time_t) sd_v; + end_date = (time_t) ed_v; - memset (&search, 0, sizeof (search)); + memset (&search, 0, sizeof (search)); #ifdef MODEST_HAVE_OGS - search.query = query; + search.query = query; #endif - search.before = start_date; - search.after = end_date; - search.flags = 0; + search.before = start_date; + search.after = end_date; + search.flags = 0; - if (dbus_flags & MODEST_DBUS_SEARCH_SUBJECT) { - search.flags |= MODEST_SEARCH_SUBJECT; - search.subject = query; - } + if (dbus_flags & MODEST_DBUS_SEARCH_SUBJECT) { + search.flags |= MODEST_SEARCH_SUBJECT; + search.subject = query; + } - if (dbus_flags & MODEST_DBUS_SEARCH_SENDER) { - search.flags |= MODEST_SEARCH_SENDER; - search.from = query; - } + if (dbus_flags & MODEST_DBUS_SEARCH_SENDER) { + search.flags |= MODEST_SEARCH_SENDER; + search.from = query; + } - if (dbus_flags & MODEST_DBUS_SEARCH_RECIPIENT) { - search.flags |= MODEST_SEARCH_RECIPIENT; - search.recipient = query; - } + if (dbus_flags & MODEST_DBUS_SEARCH_RECIPIENT) { + search.flags |= MODEST_SEARCH_RECIPIENT; + search.recipient = query; + } - if (dbus_flags & MODEST_DBUS_SEARCH_BODY) { - search.flags |= MODEST_SEARCH_BODY; - search.body = query; - } + if (dbus_flags & MODEST_DBUS_SEARCH_BODY) { + search.flags |= MODEST_SEARCH_BODY; + search.body = query; + } - if (sd_v > 0) { - search.flags |= MODEST_SEARCH_BEFORE; - search.before = start_date; - } + if (sd_v > 0) { + search.flags |= MODEST_SEARCH_BEFORE; + search.before = start_date; + } - if (ed_v > 0) { - search.flags |= MODEST_SEARCH_AFTER; - search.after = end_date; - } + if (ed_v > 0) { + search.flags |= MODEST_SEARCH_AFTER; + search.after = end_date; + } - if (size_v > 0) { - search.flags |= MODEST_SEARCH_SIZE; - search.minsize = size_v; - } + if (size_v > 0) { + search.flags |= MODEST_SEARCH_SIZE; + search.minsize = size_v; + } #ifdef MODEST_HAVE_OGS - search.flags |= MODEST_SEARCH_USE_OGS; - g_debug ("%s: Starting search for %s", __FUNCTION__, search.query); + search.flags |= MODEST_SEARCH_USE_OGS; + g_debug ("%s: Starting search for %s", __FUNCTION__, search.query); #endif - hits = modest_search_all_accounts (&search); + hits = modest_search_all_accounts (&search); - reply = dbus_message_new_method_return (message); + reply = dbus_message_new_method_return (message); - search_result_to_message (reply, hits); + search_result_to_message (reply, hits); - if (reply == NULL) { - g_warning ("Could not create reply"); - } + if (reply == NULL) { + g_warning ("%s: Could not create reply.", __FUNCTION__); + } + + if (reply) { + dbus_uint32_t serial = 0; + dbus_connection_send (con, reply, &serial); + dbus_connection_flush (con); + dbus_message_unref (reply); + } + + g_list_free (hits); +} + + +/* A complex D-Bus type (like a struct), + * used to return various information about a folder. + */ +#define GET_FOLDERS_RESULT_DBUS_TYPE \ + DBUS_STRUCT_BEGIN_CHAR_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING /* Folder Name */ \ + DBUS_TYPE_STRING_AS_STRING /* Folder URI */ \ + DBUS_STRUCT_END_CHAR_AS_STRING + +static DBusMessage * +get_folders_result_to_message (DBusMessage *reply, + GList *folder_ids) +{ + DBusMessageIter iter; + dbus_message_iter_init_append (reply, &iter); + + DBusMessageIter array_iter; + dbus_message_iter_open_container (&iter, + DBUS_TYPE_ARRAY, + GET_FOLDERS_RESULT_DBUS_TYPE, + &array_iter); - if (reply) { - dbus_connection_send (con, reply, &serial); - dbus_connection_flush (con); - dbus_message_unref (reply); + GList *list_iter = folder_ids; + for (list_iter = folder_ids; list_iter; list_iter = list_iter->next) { + + const gchar *folder_id = (const gchar*)list_iter->data; + if (folder_id) { + g_debug ("DEBUG: %s: Adding folder: %s", __FUNCTION__, folder_id); + + DBusMessageIter struct_iter; + dbus_message_iter_open_container (&array_iter, + DBUS_TYPE_STRUCT, + NULL, + &struct_iter); + + dbus_message_iter_append_basic (&struct_iter, + DBUS_TYPE_STRING, + &folder_id); + + /* name: */ + const gchar *folder_name = (const gchar*)list_iter->data; + dbus_message_iter_append_basic (&struct_iter, + DBUS_TYPE_STRING, + &folder_name); /* The string will be copied. */ + + /* URI: This is maybe not needed by osso-global-search: */ + const gchar *folder_uri = "TODO:unimplemented"; + dbus_message_iter_append_basic (&struct_iter, + DBUS_TYPE_STRING, + &folder_uri); /* The string will be copied. */ + + dbus_message_iter_close_container (&array_iter, + &struct_iter); } + } + + dbus_message_iter_close_container (&iter, &array_iter); + + return reply; +} + +void add_folders_to_list (TnyFolderStore *folder_store, GList** list) +{ + if (!folder_store) + return; + + /* Add this folder to the list: */ + if (TNY_IS_FOLDER (folder_store)) { + const gchar * folder_name = tny_folder_get_name (TNY_FOLDER (folder_store)); + if (folder_name) + *list = g_list_append(*list, g_strdup (folder_name)); + } + + /* Recurse into child folders: */ + + /* Get the folders list: */ + TnyFolderStoreQuery *query = tny_folder_store_query_new (); + tny_folder_store_query_add_item (query, NULL, + TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED); + TnyList *all_folders = tny_simple_list_new (); + tny_folder_store_get_folders (folder_store, + all_folders, + query, + NULL /* error */); + + TnyIterator *iter = tny_list_create_iterator (all_folders); + while (!tny_iterator_is_done (iter)) { + TnyFolderStore *folder = TNY_FOLDER_STORE (tny_iterator_get_current (iter)); + + add_folders_to_list (folder, list); + + tny_iterator_next (iter); + } + g_object_unref (G_OBJECT (iter)); +} - g_list_free (hits); +static void +on_dbus_method_get_folders (DBusConnection *con, DBusMessage *message) +{ + DBusMessage *reply = NULL; + + /* Get the TnyStoreAccount so we can get the folders: */ + ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr(); + gchar *account_name = modest_account_mgr_get_default_account (account_mgr); + if (!account_name) { + g_printerr ("modest: no account found\n"); } + TnyAccount *account = NULL; + if (account_mgr) { + account = modest_tny_account_store_get_server_account ( + modest_runtime_get_account_store(), account_name, + TNY_ACCOUNT_TYPE_STORE); + } + + if (!account) { + g_printerr ("modest: failed to get tny account folder'%s'\n", account_name); + } + + g_free (account_name); + account_name = NULL; + + GList *folder_names = NULL; + add_folders_to_list (TNY_FOLDER_STORE (account), &folder_names); + + + g_object_unref (account); + account = NULL; + + /* Put the result in a DBus reply: */ + reply = dbus_message_new_method_return (message); + + get_folders_result_to_message (reply, folder_names); + + if (reply == NULL) { + g_warning ("%s: Could not create reply.", __FUNCTION__); + } + + if (reply) { + dbus_uint32_t serial = 0; + dbus_connection_send (con, reply, &serial); + dbus_connection_flush (con); + dbus_message_unref (reply); + } + + g_list_foreach (folder_names, (GFunc)g_free, NULL); + g_list_free (folder_names); +} + +/** This D-Bus handler is used when the main osso-rpc + * D-Bus handler has not handled something. + * We use this for D-Bus methods that need to use more complex types + * than osso-rpc supports. + */ +DBusHandlerResult +modest_dbus_req_filter (DBusConnection *con, + DBusMessage *message, + void *user_data) +{ + gboolean handled = FALSE; + + if (dbus_message_is_method_call (message, + MODEST_DBUS_IFACE, + MODEST_DBUS_METHOD_SEARCH)) { + on_dbus_method_search (con, message); + handled = TRUE; + } else if (dbus_message_is_method_call (message, + MODEST_DBUS_IFACE, + MODEST_DBUS_METHOD_GET_FOLDERS)) { + on_dbus_method_get_folders (con, message); + handled = TRUE; + } + return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED); diff --git a/src/maemo/modest-platform.c b/src/maemo/modest-platform.c index 1dab457..db49d84 100644 --- a/src/maemo/modest-platform.c +++ b/src/maemo/modest-platform.c @@ -83,16 +83,21 @@ modest_platform_init (void) } + /* Add a D-Bus handler to be used when the main osso-rpc + * D-Bus handler has not handled something. + * We use this for D-Bus methods that need to use more complex types + * than osso-rpc supports. + */ if (!dbus_connection_add_filter (con, modest_dbus_req_filter, NULL, NULL)) { - g_printerr ("Could not add dbus filter\n"); + g_printerr ("Could not add D-Bus filter\n"); return FALSE; } - /* Register our D-Bus callbacks, via the osso API: */ + /* Register our simple D-Bus callbacks, via the osso API: */ osso_return_t result = osso_rpc_set_cb_f(osso_context, MODEST_DBUS_SERVICE, MODEST_DBUS_OBJECT, diff --git a/src/modest-tny-account-store.h b/src/modest-tny-account-store.h index 9081753..1c73c27 100644 --- a/src/modest-tny-account-store.h +++ b/src/modest-tny-account-store.h @@ -126,7 +126,7 @@ TnyAccount* modest_tny_account_store_get_tny_account_by (ModestTnyAccountStore * Get the tny account corresponding to one of the server_accounts for account with @account_name * * Returns: the tnyaccount for the server account or NULL in case it's not found or error, - * g_object_unref when it's no longer needed + * g_object_unref when it's no longer needed. TODO: Check that callers are unreffing. */ TnyAccount* modest_tny_account_store_get_server_account (ModestTnyAccountStore *self, const gchar *account_name, diff --git a/tests/dbus_api/Makefile.am b/tests/dbus_api/Makefile.am index 27805a7..696683b 100644 --- a/tests/dbus_api/Makefile.am +++ b/tests/dbus_api/Makefile.am @@ -22,7 +22,8 @@ noinst_PROGRAMS = test_send_mail \ test_search \ test_delete_message \ test_compose_mail \ - test_open_default_inbox + test_open_default_inbox \ + test_get_folders test_send_mail_SOURCES = test_send_mail.c test_send_mail_LDADD = $(objects) @@ -44,3 +45,6 @@ test_delete_message_LDADD = $(objects) test_open_default_inbox_SOURCES = test_open_default_inbox.c test_open_default_inbox_LDADD = $(objects) + +test_get_folders_SOURCES = test_get_folders.c +test_get_folders_LDADD = $(objects) diff --git a/tests/dbus_api/test_compose_mail.c b/tests/dbus_api/test_compose_mail.c index afc3f34..6751aa1 100644 --- a/tests/dbus_api/test_compose_mail.c +++ b/tests/dbus_api/test_compose_mail.c @@ -31,7 +31,7 @@ int main(int argc, char *argv[]) if (!ret) { - printf("libmodest_dbus_client_compose_mai() failed.\n"); + printf("libmodest_dbus_client_compose_mail() failed.\n"); return OSSO_ERROR; } else { printf("libmodest_dbus_client_compose_mail() succeeded\n"); diff --git a/tests/dbus_api/test_get_folders.c b/tests/dbus_api/test_get_folders.c new file mode 100644 index 0000000..9aef59c --- /dev/null +++ b/tests/dbus_api/test_get_folders.c @@ -0,0 +1,50 @@ +#include +#include + + +int main(int argc, char *argv[]) +{ + GSList *attachments = NULL; + /* Initialize maemo application */ + osso_context_t * osso_context = osso_initialize( + "test_hello", "0.0.1", TRUE, NULL); + + /* Check that initialization was ok */ + if (osso_context == NULL) + { + printf("osso_initialize() failed.\n"); + return OSSO_ERROR; + } + + /* Call the function in libmodest-dbus-client: */ + + attachments = g_slist_append(attachments, "/usr/include/math.h,/usr/include/malloc.h"); + + GList *list = NULL; + const gboolean ret = libmodest_dbus_client_get_folders ( + osso_context, &list); + + if (!ret) { + printf("libmodest_dbus_client_get_folders() failed.\n"); + return OSSO_ERROR; + } else { + printf("libmodest_dbus_client_get_folders() succeeded\n"); + } + + if (list) { + GList *iter = NULL; + for (iter = list; iter; iter = iter->next) { + ModestFolderResult *item = (ModestFolderResult*)iter->data; + if (item) { + printf(" Folder name=%s\n", item->folder_name); + } + } + + modest_folder_result_list_free (list); + } else { + printf(" The list of folders was empty.\n"); + } + + /* Exit */ + return 0; +} -- 1.7.9.5