From 5c55ed8a118f025f4a9d12fc090dcf65a97b5ffa Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Fri, 11 Apr 2008 16:51:42 +0000 Subject: [PATCH] * for NB#83601: with this patch, when we're in low-memory state, we disallow: - addressbook - attachments (attaching, opening, saving) - searching (also over dbus ==> it returns an empty list in that case) - viewing messages, replying/forwarding we still do allow: - composing messages (without attachments) - saving to drafts (< 25Kb) - sending (< 25Kb) also, when sending attachements, make sure the sum of their sizes does not exceed, if they do, raise an error. #define MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (25*1024) #define MODEST_MAX_ATTACHMENT_SIZE (12*1024*1024) still TODO is to make sure that the attachment size limitation also applies to weird filesystems, such as obex and upnp pmo-trunk-r4405 --- src/dbus_api/modest-dbus-callbacks.c | 34 +++++++- src/maemo/modest-msg-edit-window.c | 80 ++++++++++++++---- src/maemo/modest-platform.c | 8 +- src/modest-defs.h | 7 ++ src/modest-ui-actions.c | 151 +++++++++++++++++++++++++--------- src/widgets/modest-msg-edit-window.h | 6 +- 6 files changed, 226 insertions(+), 60 deletions(-) diff --git a/src/dbus_api/modest-dbus-callbacks.c b/src/dbus_api/modest-dbus-callbacks.c index b545854..a64c938 100644 --- a/src/dbus_api/modest-dbus-callbacks.c +++ b/src/dbus_api/modest-dbus-callbacks.c @@ -1721,6 +1721,25 @@ on_dbus_method_get_folders (DBusConnection *con, DBusMessage *message) } +static void +reply_empty_results (DBusConnection *con, DBusMessage *msg) +{ + DBusMessage *reply = dbus_message_new_method_return (msg); + if (reply) { + dbus_uint32_t serial = 0; + /* we simply return an empty list, otherwise + global-search gets confused */ + search_result_to_message (reply, NULL); + + dbus_connection_send (con, reply, &serial); + dbus_connection_flush (con); + dbus_message_unref (reply); + } else + g_warning ("%s: failed to send reply", + __FUNCTION__); +} + + /** 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 @@ -1736,8 +1755,19 @@ modest_dbus_req_filter (DBusConnection *con, if (dbus_message_is_method_call (message, MODEST_DBUS_IFACE, MODEST_DBUS_METHOD_SEARCH)) { - on_dbus_method_search (con, message); - handled = TRUE; + + /* don't try to search when there not enough mem */ + if (modest_platform_check_memory_low (NULL)) { + g_warning ("%s: not enough memory for searching", + __FUNCTION__); + reply_empty_results (con, message); + handled = TRUE; + + } else { + on_dbus_method_search (con, message); + handled = TRUE; + } + } else if (dbus_message_is_method_call (message, MODEST_DBUS_IFACE, MODEST_DBUS_METHOD_GET_FOLDERS)) { diff --git a/src/maemo/modest-msg-edit-window.c b/src/maemo/modest-msg-edit-window.c index 6b3d204..8650857 100644 --- a/src/maemo/modest-msg-edit-window.c +++ b/src/maemo/modest-msg-edit-window.c @@ -2146,7 +2146,8 @@ modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window) -static TnyStream* create_stream_for_uri (const gchar* uri) +static TnyStream* +create_stream_for_uri (const gchar* uri) { if (!uri) return NULL; @@ -2292,14 +2293,18 @@ modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window) gint response = 0; GSList *uris = NULL; GSList *uri_node; - + GnomeVFSFileSize total_size, allowed_size; + ModestMsgEditWindowPrivate *priv; + gint att_num; + guint64 att_size; + + g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(window)); + + priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); - /* we check for low-mem; in that case, show a warning, and don't allow - * attachments - */ if (modest_platform_check_memory_low (MODEST_WINDOW(window))) return; - + dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN); gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title")); gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE); @@ -2315,25 +2320,48 @@ modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window) } gtk_widget_destroy (dialog); + /* allowed size is the maximum size - what's already there */ + modest_attachments_view_get_sizes ( + MODEST_ATTACHMENTS_VIEW (priv->attachments_view), + &att_num, &att_size); + allowed_size = MODEST_MAX_ATTACHMENT_SIZE - att_size; + + total_size = 0; for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) { + const gchar *uri = (const gchar *) uri_node->data; - modest_msg_edit_window_attach_file_one (window, uri); + + total_size += modest_msg_edit_window_attach_file_one + (window, uri, allowed_size); + + if (total_size > allowed_size) { + g_warning ("%s: total size: %u", + __FUNCTION__, (unsigned int)total_size); + break; + } + + allowed_size -= total_size; + + } g_slist_foreach (uris, (GFunc) g_free, NULL); g_slist_free (uris); } -void -modest_msg_edit_window_attach_file_one ( - ModestMsgEditWindow *window, - const gchar *uri) + +GnomeVFSFileSize +modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window, + const gchar *uri, + GnomeVFSFileSize allowed_size) + { GnomeVFSHandle *handle = NULL; ModestMsgEditWindowPrivate *priv; GnomeVFSResult result; + GnomeVFSFileSize size = 0; - g_return_if_fail (window); - g_return_if_fail (uri); + g_return_val_if_fail (window, 0); + g_return_val_if_fail (uri, 0); priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); @@ -2367,6 +2395,20 @@ modest_msg_edit_window_attach_file_one ( mime_type = gnome_vfs_file_info_get_mime_type (info); mime_part = tny_platform_factory_new_mime_part (modest_runtime_get_platform_factory ()); + + /* try to get the attachment's size; this may fail for weird + * file systems, like obex, upnp... */ + if (allowed_size != 0 && + info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) { + size = info->size; + if (size > allowed_size) { + g_warning ("%s: attachment too big", __FUNCTION__); + modest_platform_information_banner (NULL, NULL, dgettext("hildon-fm", "sfil_ib_opening_not_allowed")); + return 0; + } + } else + g_warning ("%s: could not get attachment size", __FUNCTION__); + stream = create_stream_for_uri (uri); if (stream == NULL) { @@ -2375,7 +2417,7 @@ modest_msg_edit_window_attach_file_one ( g_object_unref (mime_part); gnome_vfs_file_info_unref (info); - return; + return 0; } tny_mime_part_construct (mime_part, stream, mime_type, "base64"); @@ -2401,6 +2443,8 @@ modest_msg_edit_window_attach_file_one ( g_object_unref (mime_part); gnome_vfs_file_info_unref (info); } + + return size; } void @@ -2655,6 +2699,14 @@ modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window, g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window)); g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor))); + + /* we check for low-mem; in that case, show a warning, and don't allow + * for the addressbook + */ + if (modest_platform_check_memory_low (MODEST_WINDOW(window))) + return; + + priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window); if (editor == NULL) { diff --git a/src/maemo/modest-platform.c b/src/maemo/modest-platform.c index e15d2a4..73a6ed5 100644 --- a/src/maemo/modest-platform.c +++ b/src/maemo/modest-platform.c @@ -2265,7 +2265,7 @@ gboolean modest_platform_check_memory_low (ModestWindow *win) { gboolean lowmem; - + g_return_val_if_fail (win == NULL || MODEST_IS_WINDOW(win), FALSE); /* are we in low memory state? */ @@ -2276,6 +2276,10 @@ modest_platform_check_memory_low (ModestWindow *win) GTK_WINDOW(win), dgettext("ke-recv","memr_ib_operation_disabled"), TRUE); - + + if (lowmem) + g_warning ("%s: low memory reached. disallowing some operations", + __FUNCTION__); + return lowmem; } diff --git a/src/modest-defs.h b/src/modest-defs.h index 009ac99..b7c29ab 100644 --- a/src/modest-defs.h +++ b/src/modest-defs.h @@ -204,4 +204,11 @@ #define MODEST_EXAMPLE_EMAIL_ADDRESS "first.last@example.com" + +/* max size of message we still allow to save/send when we're in low-mem + * condition + */ +#define MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (25*1024) +#define MODEST_MAX_ATTACHMENT_SIZE (12*1024*1024) + #endif /*__MODEST_DEFS_H__*/ diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index 3cef81b..e119a10 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -718,6 +718,13 @@ modest_ui_actions_compose_msg(ModestWindow *win, ModestWindow *msg_win = NULL; ModestAccountMgr *mgr = modest_runtime_get_account_mgr(); ModestTnyAccountStore *store = modest_runtime_get_account_store(); + GnomeVFSFileSize total_size, allowed_size; + + /* we check for low-mem; in that case, show a warning, and don't allow + * composing a message with attachments + */ + if (attachments && modest_platform_check_memory_low (win)) + goto cleanup; account_name = modest_account_mgr_get_default_account(mgr); if (!account_name) { @@ -755,10 +762,22 @@ modest_ui_actions_compose_msg(ModestWindow *win, /* Create and register edit window */ /* This is destroyed by TODO. */ + total_size = 0; + allowed_size = MODEST_MAX_ATTACHMENT_SIZE; msg_win = modest_msg_edit_window_new (msg, account_name, FALSE); while (attachments) { - modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win, - attachments->data); + total_size += + modest_msg_edit_window_attach_file_one( + (ModestMsgEditWindow *)msg_win, + attachments->data, allowed_size); + + if (total_size > allowed_size) { + g_warning ("%s: total size: %u", + __FUNCTION__, (unsigned int)total_size); + break; + } + allowed_size -= total_size; + attachments = g_slist_next(attachments); } modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win); @@ -771,10 +790,14 @@ cleanup: g_free (signature); g_free (body); g_free (account_name); - if (account) g_object_unref (G_OBJECT(account)); - if (folder) g_object_unref (G_OBJECT(folder)); - if (msg_win) g_object_unref (G_OBJECT(msg_win)); - if (msg) g_object_unref (G_OBJECT(msg)); + if (account) + g_object_unref (G_OBJECT(account)); + if (folder) + g_object_unref (G_OBJECT(folder)); + if (msg_win) + g_object_unref (G_OBJECT(msg_win)); + if (msg) + g_object_unref (G_OBJECT(msg)); } void @@ -1381,6 +1404,12 @@ void modest_ui_actions_on_open (GtkAction *action, ModestWindow *win) { TnyList *headers; + + /* we check for low-mem; in that case, show a warning, and don't allow + * opening + */ + if (modest_platform_check_memory_low (MODEST_WINDOW(win))) + return; /* Get headers */ headers = get_selected_headers (win); @@ -1574,6 +1603,13 @@ reply_forward (ReplyForwardAction action, ModestWindow *win) g_return_if_fail (MODEST_IS_WINDOW(win)); + + /* we check for low-mem; in that case, show a warning, and don't allow + * reply/forward (because it could potentially require a lot of memory */ + if (modest_platform_check_memory_low (MODEST_WINDOW(win))) + return; + + /* we need an account when editing */ if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) { if (!modest_ui_actions_run_account_setup_wizard (win)) @@ -2166,6 +2202,12 @@ modest_ui_actions_on_header_activated (ModestHeaderView *header_view, return; } + /* we check for low-mem; in that case, show a warning, and don't allow + * activating headers + */ + if (modest_platform_check_memory_low (MODEST_WINDOW(main_window))) + return; + /* headers = tny_simple_list_new (); */ /* tny_list_prepend (headers, G_OBJECT (header)); */ @@ -2392,7 +2434,13 @@ modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* l void modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part, ModestWindow *win) -{ +{ + /* we check for low-mem; in that case, show a warning, and don't allow + * viewing attachments + */ + if (modest_platform_check_memory_low (MODEST_WINDOW(win))) + return; + modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part); } @@ -2466,6 +2514,21 @@ modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edi return FALSE; } + + /* + * djcb: if we're in low-memory state, we only allow for + * saving messages smaller than + * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this + * should still allow for sending anything critical... + */ + if (expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) { + + if (modest_platform_check_memory_low (MODEST_WINDOW(edit_window))) { + modest_msg_edit_window_free_msg_data (edit_window, data); + return FALSE; + } + } + account_name = g_strdup (data->account_name); account_mgr = modest_runtime_get_account_mgr(); if (!account_name) @@ -2608,6 +2671,20 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window) return FALSE; } + + /* + * djcb: if we're in low-memory state, we only allow for sending messages + * smaller than MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) + * this should still allow for sending anything critical... + */ + if (expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) { + if (modest_platform_check_memory_low (MODEST_WINDOW(edit_window))) { + modest_msg_edit_window_free_msg_data (edit_window, data); + return FALSE; + } + } + + ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr(); gchar *account_name = g_strdup (data->account_name); if (!account_name) @@ -2808,6 +2885,10 @@ modest_ui_actions_on_insert_image (GtkAction *action, g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window)); g_return_if_fail (GTK_IS_ACTION (action)); + + if (modest_platform_check_memory_low (MODEST_WINDOW(window))) + return; + if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT) return; @@ -2821,6 +2902,9 @@ modest_ui_actions_on_attach_file (GtkAction *action, g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window)); g_return_if_fail (GTK_IS_ACTION (action)); + if (modest_platform_check_memory_low (MODEST_WINDOW(window))) + return; + modest_msg_edit_window_offer_attach_file (window); } @@ -4405,40 +4489,6 @@ create_move_to_dialog (GtkWindow *win, return dialog; } -/* - * Returns TRUE if at least one of the headers of the list belongs to - * a message that has been fully retrieved. - */ -#if 0 /* no longer in use. delete in 2007.10 */ -static gboolean -has_retrieved_msgs (TnyList *list) -{ - TnyIterator *iter; - gboolean found = FALSE; - - iter = tny_list_create_iterator (list); - while (!tny_iterator_is_done (iter) && !found) { - TnyHeader *header; - TnyHeaderFlags flags = 0; - - header = TNY_HEADER (tny_iterator_get_current (iter)); - if (header) { - flags = tny_header_get_flags (header); - if (flags & TNY_HEADER_FLAG_CACHED) -/* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */ - found = TRUE; - - g_object_unref (header); - } - - if (!found) - tny_iterator_next (iter); - } - g_object_unref (iter); - - return found; -} -#endif /* 0 */ /* @@ -5279,6 +5329,10 @@ modest_ui_actions_save_attachments (GtkAction *action, ModestWindow *window) { if (MODEST_IS_MSG_VIEW_WINDOW (window)) { + + if (modest_platform_check_memory_low (MODEST_WINDOW(window))) + return; + modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL); } else { /* not supported window for this action */ @@ -5514,6 +5568,12 @@ modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window) { g_return_if_fail (MODEST_IS_WINDOW (window)); + /* we check for low-mem; in that case, show a warning, and don't allow + * searching + */ + if (modest_platform_check_memory_low (window)) + return; + modest_platform_show_search_messages (GTK_WINDOW (window)); } @@ -5521,6 +5581,15 @@ void modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win) { g_return_if_fail (MODEST_IS_WINDOW (win)); + + + /* we check for low-mem; in that case, show a warning, and don't allow + * for the addressbook + */ + if (modest_platform_check_memory_low (win)) + return; + + modest_platform_show_addressbook (GTK_WINDOW (win)); } diff --git a/src/widgets/modest-msg-edit-window.h b/src/widgets/modest-msg-edit-window.h index 21a6f35..c24e30a 100644 --- a/src/widgets/modest-msg-edit-window.h +++ b/src/widgets/modest-msg-edit-window.h @@ -31,6 +31,7 @@ #define __MODEST_MSG_EDIT_WINDOW_H__ #include +#include #include G_BEGIN_DECLS @@ -228,11 +229,14 @@ void modest_msg_edit_window_offer_attach_file (Mode * modest_msg_edit_window_attach_file_one: * @self: a #ModestMsgEditWindow * @file_uri: The URI of a file to attach to the email message. + * @allowed_size: max size allowed for this attachment, 0 for unlimited * * attach a file to a MsgEditWindow non interactively, * without file dialog. This is needed by dbus callbacks. + * + * Returns: the filesize (if available) */ -void modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window, const gchar *file_uri); +GnomeVFSFileSize modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window, const gchar *file_uri, GnomeVFSFileSize allowed_size); /** * modest_msg_edit_window_remove_attachments: -- 1.7.9.5