From d538278be62687758c956af62ee47c53637d67d8 Mon Sep 17 00:00:00 2001 From: cketti Date: Tue, 28 Apr 2015 05:41:35 +0200 Subject: [PATCH 01/44] Don't write HtmlConverterTest results to a file Fixes issue #618 --- .../com/fsck/k9/helper/HtmlConverterTest.java | 35 +++---------------- 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/k9mail/src/androidTest/java/com/fsck/k9/helper/HtmlConverterTest.java b/k9mail/src/androidTest/java/com/fsck/k9/helper/HtmlConverterTest.java index 701a9ec83..e61b6e84b 100644 --- a/k9mail/src/androidTest/java/com/fsck/k9/helper/HtmlConverterTest.java +++ b/k9mail/src/androidTest/java/com/fsck/k9/helper/HtmlConverterTest.java @@ -1,8 +1,5 @@ package com.fsck.k9.helper; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; import android.support.test.runner.AndroidJUnit4; @@ -14,9 +11,6 @@ import static junit.framework.Assert.assertEquals; @RunWith(AndroidJUnit4.class) public class HtmlConverterTest { - // Useful if you want to write stuff to a file for debugging in a browser. - private static final boolean WRITE_TO_FILE = Boolean.parseBoolean(System.getProperty("k9.htmlConverterTest.writeToFile", "false")); - private static final String OUTPUT_FILE = "C:/temp/parse.html"; @Test public void testTextQuoteToHtmlBlockquote() { @@ -32,7 +26,7 @@ public class HtmlConverterTest { "Nice job :)\r\n" + ">> Guess!"; String result = HtmlConverter.textToHtml(message); - writeToFile(result); + assertEquals("
"
                 + "Panama!
" + "
" @@ -71,7 +65,7 @@ public class HtmlConverterTest { ">\r\n" + "> :)"; String result = HtmlConverter.textToHtml(message); - writeToFile(result); + assertEquals("
"
                 + "*facepalm*
" + "
" @@ -106,7 +100,7 @@ public class HtmlConverterTest { ">>>>> five\r\n" + ">>>>>> six"; String result = HtmlConverter.textToHtml(message); - writeToFile(result); + assertEquals("
"
                 + "zero
" + "
" @@ -130,32 +124,13 @@ public class HtmlConverterTest { + "
", result); } - private void writeToFile(final String content) { - if (!WRITE_TO_FILE) { - return; - } - try { - System.err.println(content); - - File f = new File(OUTPUT_FILE); - f.delete(); - - FileWriter fstream = new FileWriter(OUTPUT_FILE); - BufferedWriter out = new BufferedWriter(fstream); - out.write(content); - out.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - @Test public void testPreserveSpacesAtFirst() { String message = "foo\r\n" + " bar\r\n" + " baz\r\n"; String result = HtmlConverter.textToHtml(message); - writeToFile(result); + assertEquals("
"
                 + "foo
" + " bar
" @@ -172,7 +147,7 @@ public class HtmlConverterTest { + " <\r\n" + " > \r\n"; String result = HtmlConverter.textToHtml(message); - writeToFile(result); + assertEquals("
"
                 + " 
" + " &
" From c37934ea16f5b852d18db4913806a60375d8ab9a Mon Sep 17 00:00:00 2001 From: Marcus Wolschon Date: Tue, 28 Apr 2015 22:04:22 +0200 Subject: [PATCH 02/44] Fixed wrong parameter order leading to broken MessageReferences. --- .../src/main/java/com/fsck/k9/activity/MessageReference.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/activity/MessageReference.java b/k9mail/src/main/java/com/fsck/k9/activity/MessageReference.java index e21e10112..107fae67b 100644 --- a/k9mail/src/main/java/com/fsck/k9/activity/MessageReference.java +++ b/k9mail/src/main/java/com/fsck/k9/activity/MessageReference.java @@ -176,9 +176,9 @@ public class MessageReference implements Parcelable { String folderName = source.readString(); String flag = source.readString(); if (flag != null) { - ref = new MessageReference(uid, accountUuid, folderName, Flag.valueOf(flag)); + ref = new MessageReference(accountUuid, folderName, uid, Flag.valueOf(flag)); } else { - ref = new MessageReference(uid, accountUuid, folderName, null); + ref = new MessageReference(accountUuid, folderName, uid, null); } return ref; } From 0f848ee51fb15e6268ca65e19ff1b4cc74724e55 Mon Sep 17 00:00:00 2001 From: Marcus Wolschon Date: Tue, 28 Apr 2015 22:17:02 +0200 Subject: [PATCH 03/44] reverting accidental commit 1dfc2a5490e89e793471c29ae05db192ae12d002 --- .../com/fsck/k9/helper/HtmlConverterTest.java | 91 ++++++++++++------- 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/k9mail/src/androidTest/java/com/fsck/k9/helper/HtmlConverterTest.java b/k9mail/src/androidTest/java/com/fsck/k9/helper/HtmlConverterTest.java index e61b6e84b..c09244164 100644 --- a/k9mail/src/androidTest/java/com/fsck/k9/helper/HtmlConverterTest.java +++ b/k9mail/src/androidTest/java/com/fsck/k9/helper/HtmlConverterTest.java @@ -1,5 +1,8 @@ package com.fsck.k9.helper; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; import android.support.test.runner.AndroidJUnit4; @@ -11,22 +14,25 @@ import static junit.framework.Assert.assertEquals; @RunWith(AndroidJUnit4.class) public class HtmlConverterTest { + // Useful if you want to write stuff to a file for debugging in a browser. + private static final boolean WRITE_TO_FILE = Boolean.parseBoolean(System.getProperty("k9.htmlConverterTest.writeToFile", "false")); + private static final String OUTPUT_FILE = "C:/temp/parse.html"; @Test public void testTextQuoteToHtmlBlockquote() { String message = "Panama!\r\n" + - "\r\n" + - "Bob Barker wrote:\r\n" + - "> a canal\r\n" + - ">\r\n" + - "> Dorothy Jo Gideon espoused:\r\n" + - "> >A man, a plan...\r\n" + - "> Too easy!\r\n" + - "\r\n" + - "Nice job :)\r\n" + - ">> Guess!"; + "\r\n" + + "Bob Barker wrote:\r\n" + + "> a canal\r\n" + + ">\r\n" + + "> Dorothy Jo Gideon espoused:\r\n" + + "> >A man, a plan...\r\n" + + "> Too easy!\r\n" + + "\r\n" + + "Nice job :)\r\n" + + ">> Guess!"; String result = HtmlConverter.textToHtml(message); - + writeToFile(result); assertEquals("
"
                 + "Panama!
" + "
" @@ -57,15 +63,15 @@ public class HtmlConverterTest { @Test public void testTextQuoteToHtmlBlockquoteIndented() { String message = "*facepalm*\r\n" + - "\r\n" + - "Bob Barker wrote:\r\n" + - "> A wise man once said...\r\n" + - ">\r\n" + - "> LOL F1RST!!!!!\r\n" + - ">\r\n" + - "> :)"; + "\r\n" + + "Bob Barker wrote:\r\n" + + "> A wise man once said...\r\n" + + ">\r\n" + + "> LOL F1RST!!!!!\r\n" + + ">\r\n" + + "> :)"; String result = HtmlConverter.textToHtml(message); - + writeToFile(result); assertEquals("
"
                 + "*facepalm*
" + "
" @@ -93,14 +99,14 @@ public class HtmlConverterTest { assertEquals(HtmlConverter.getQuoteColor(6), HtmlConverter.QUOTE_COLOR_DEFAULT); String message = "zero\r\n" + - "> one\r\n" + - ">> two\r\n" + - ">>> three\r\n" + - ">>>> four\r\n" + - ">>>>> five\r\n" + - ">>>>>> six"; + "> one\r\n" + + ">> two\r\n" + + ">>> three\r\n" + + ">>>> four\r\n" + + ">>>>> five\r\n" + + ">>>>>> six"; String result = HtmlConverter.textToHtml(message); - + writeToFile(result); assertEquals("
"
                 + "zero
" + "
" @@ -124,13 +130,32 @@ public class HtmlConverterTest { + "
", result); } + private void writeToFile(final String content) { + if (!WRITE_TO_FILE) { + return; + } + try { + System.err.println(content); + + File f = new File(OUTPUT_FILE); + f.delete(); + + FileWriter fstream = new FileWriter(OUTPUT_FILE); + BufferedWriter out = new BufferedWriter(fstream); + out.write(content); + out.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + @Test public void testPreserveSpacesAtFirst() { String message = "foo\r\n" + " bar\r\n" + " baz\r\n"; String result = HtmlConverter.textToHtml(message); - + writeToFile(result); assertEquals("
"
                 + "foo
" + " bar
" @@ -141,13 +166,13 @@ public class HtmlConverterTest { @Test public void testPreserveSpacesAtFirstForSpecialCharacters() { String message = - " \r\n" - + " &\r\n" - + " \n" - + " <\r\n" - + " > \r\n"; + " \r\n" + + " &\r\n" + + " \n" + + " <\r\n" + + " > \r\n"; String result = HtmlConverter.textToHtml(message); - + writeToFile(result); assertEquals("
"
                 + " 
" + " &
" From 64e22a72ed711b84cf88ffa7d50f2a3666d6d020 Mon Sep 17 00:00:00 2001 From: Marcus Wolschon Date: Tue, 28 Apr 2015 22:26:17 +0200 Subject: [PATCH 04/44] Some first android wear support for enhancement #619 "Add android wear support" No reply with voice yet (as requested in the ticket). No user-configurable actions yet, just delete+archive+spam No stacked notification for multiple messages yet. --- .../k9/controller/MessagingController.java | 41 +++++- .../k9/service/NotificationActionService.java | 123 ++++++++++++++++++ k9mail/src/main/res/values-de/strings.xml | 2 + k9mail/src/main/res/values/strings.xml | 3 + 4 files changed, 167 insertions(+), 2 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java index 3eff01fe5..93687f60d 100644 --- a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java +++ b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java @@ -211,8 +211,8 @@ public class MessagingController implements Runnable { /** * List of messages that should be used for the inbox-style overview. * It's sorted from newest to oldest message. - * Don't modify this list directly, but use {@link addMessage} and - * {@link removeMatchingMessage} instead. + * Don't modify this list directly, but use {@link #addMessage(com.fsck.k9.mailstore.LocalMessage)} and + * {@link #removeMatchingMessage(android.content.Context, com.fsck.k9.activity.MessageReference)} instead. */ LinkedList messages; /** @@ -4853,6 +4853,7 @@ public class MessagingController implements Runnable { NotificationActionService.getReplyIntent(context, account, message.makeMessageReference())); } + // Mark Read on phone builder.addAction( platformSupportsLockScreenNotifications() ? R.drawable.ic_action_mark_as_read_dark_vector @@ -4864,15 +4865,51 @@ public class MessagingController implements Runnable { boolean showDeleteAction = deleteOption == NotificationQuickDelete.ALWAYS || (deleteOption == NotificationQuickDelete.FOR_SINGLE_MSG && newMessages == 1); + NotificationCompat.WearableExtender wearableExtender = new NotificationCompat.WearableExtender(); if (showDeleteAction) { // we need to pass the action directly to the activity, otherwise the // status bar won't be pulled up and we won't see the confirmation (if used) + + // Delete on phone builder.addAction( platformSupportsLockScreenNotifications() ? R.drawable.ic_action_delete_dark_vector : R.drawable.ic_action_delete_dark, context.getString(R.string.notification_action_delete), NotificationDeleteConfirmation.getIntent(context, account, allRefs)); + + // Delete on wear only if no confirmation is required + if (!K9.confirmDeleteFromNotification()) { + NotificationCompat.Action wearActionDelete = + new NotificationCompat.Action.Builder( + R.drawable.ic_action_delete_dark, + context.getString(R.string.notification_action_delete), + NotificationDeleteConfirmation.getIntent(context, account, allRefs)) + .build(); + builder.extend(wearableExtender.addAction(wearActionDelete)); + } + } + if (NotificationActionService.isArchiveAllMessagesWearAvaliable(context, account, data.messages)) { + + // Archive on wear + NotificationCompat.Action wearActionArchive = + new NotificationCompat.Action.Builder( + R.drawable.ic_action_delete_dark, + context.getString(R.string.notification_action_archive), + NotificationActionService.getArchiveAllMessagesIntent(context, account, allRefs)) + .build(); + builder.extend(wearableExtender.addAction(wearActionArchive)); + } + if (NotificationActionService.isSpamAllMessagesWearAvaliable(context, account, data.messages)) { + + // Archive on wear + NotificationCompat.Action wearActionSpam = + new NotificationCompat.Action.Builder( + R.drawable.ic_action_delete_dark, + context.getString(R.string.notification_action_spam), + NotificationActionService.getSpamAllMessagesIntent(context, account, allRefs)) + .build(); + builder.extend(wearableExtender.addAction(wearActionSpam)); } } else { String accountNotice = context.getString(R.string.notification_new_one_account_fmt, diff --git a/k9mail/src/main/java/com/fsck/k9/service/NotificationActionService.java b/k9mail/src/main/java/com/fsck/k9/service/NotificationActionService.java index 8b4e59440..3dd050884 100644 --- a/k9mail/src/main/java/com/fsck/k9/service/NotificationActionService.java +++ b/k9mail/src/main/java/com/fsck/k9/service/NotificationActionService.java @@ -2,6 +2,7 @@ package com.fsck.k9.service; import java.io.Serializable; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import com.fsck.k9.Account; @@ -18,10 +19,16 @@ import android.content.Context; import android.content.Intent; import android.util.Log; +/** + * Service called by actions in notifications. + * Provides a number of default actions to trigger. + */ public class NotificationActionService extends CoreService { private final static String REPLY_ACTION = "com.fsck.k9.service.NotificationActionService.REPLY_ACTION"; private final static String READ_ALL_ACTION = "com.fsck.k9.service.NotificationActionService.READ_ALL_ACTION"; private final static String DELETE_ALL_ACTION = "com.fsck.k9.service.NotificationActionService.DELETE_ALL_ACTION"; + private final static String ARCHIVE_ALL_ACTION = "com.fsck.k9.service.NotificationActionService.ARCHIVE_ALL_ACTION"; + private final static String SPAM_ALL_ACTION = "com.fsck.k9.service.NotificationActionService.SPAM_ALL_ACTION"; private final static String ACKNOWLEDGE_ACTION = "com.fsck.k9.service.NotificationActionService.ACKNOWLEDGE_ACTION"; private final static String EXTRA_ACCOUNT = "account"; @@ -63,6 +70,69 @@ public class NotificationActionService extends CoreService { return i; } + /** + * Check if for the given parameters the ArchiveAllMessages intent is possible for Android Wear. + * (No confirmation on the phone required and moving these messages to the spam-folder possible)
+ * Since we can not show a toast like on the phone screen, we must not offer actions that can not be performed. + * @see #getArchiveAllMessagesIntent(android.content.Context, com.fsck.k9.Account, java.io.Serializable) + * @param context the context to get a {@link MessagingController} + * @param account the account (must allow moving messages to allow true as a result) + * @param messages the messages to move to the spam folder (must be synchronized to allow true as a result) + * @return true if the ArchiveAllMessages intent is available for the given messages + */ + public static boolean isArchiveAllMessagesWearAvaliable(Context context, final Account account, final LinkedList messages) { + final MessagingController controller = MessagingController.getInstance(context); + return (account.getArchiveFolderName() != null && !(account.getArchiveFolderName().equals(account.getSpamFolderName()) && K9.confirmSpam()) && isMovePossible(controller, account, account.getSentFolderName(), messages)); + } + + public static PendingIntent getArchiveAllMessagesIntent(Context context, final Account account, final Serializable refs) { + Intent i = new Intent(context, NotificationActionService.class); + i.putExtra(EXTRA_ACCOUNT, account.getUuid()); + i.putExtra(EXTRA_MESSAGE_LIST, refs); + i.setAction(ARCHIVE_ALL_ACTION); + + return PendingIntent.getService(context, account.getAccountNumber(), i, PendingIntent.FLAG_UPDATE_CURRENT); + + } + + /** + * Check if for the given parameters the SpamAllMessages intent is possible for Android Wear. + * (No confirmation on the phone required and moving these messages to the spam-folder possible)
+ * Since we can not show a toast like on the phone screen, we must not offer actions that can not be performed. + * @see #getSpamAllMessagesIntent(android.content.Context, com.fsck.k9.Account, java.io.Serializable) + * @param context the context to get a {@link MessagingController} + * @param account the account (must allow moving messages to allow true as a result) + * @param messages the messages to move to the spam folder (must be synchronized to allow true as a result) + * @return true if the SpamAllMessages intent is available for the given messages + */ + public static boolean isSpamAllMessagesWearAvaliable(Context context, final Account account, final LinkedList messages) { + final MessagingController controller = MessagingController.getInstance(context); + return (account.getSpamFolderName() != null && !K9.confirmSpam() && isMovePossible(controller, account, account.getSentFolderName(), messages)); + } + + public static PendingIntent getSpamAllMessagesIntent(Context context, final Account account, final Serializable refs) { + Intent i = new Intent(context, NotificationActionService.class); + i.putExtra(EXTRA_ACCOUNT, account.getUuid()); + i.putExtra(EXTRA_MESSAGE_LIST, refs); + i.setAction(SPAM_ALL_ACTION); + + return PendingIntent.getService(context, account.getAccountNumber(), i, PendingIntent.FLAG_UPDATE_CURRENT); + } + + private static boolean isMovePossible(MessagingController controller, Account account, String dstFolder, List messages) { + if (!controller.isMoveCapable(account)) { + return false; + } + if (K9.FOLDER_NONE.equalsIgnoreCase(dstFolder)) { + return false; + } + for(LocalMessage messageToMove : messages) { + if (!controller.isMoveCapable(messageToMove)) { + return false; + } + } + return true; + } @Override public int startService(Intent intent, int startId) { if (K9.DEBUG) @@ -98,6 +168,59 @@ public class NotificationActionService extends CoreService { } controller.deleteMessages(messages, null); + } else if (ARCHIVE_ALL_ACTION.equals(action)) { + if (K9.DEBUG) + Log.i(K9.LOG_TAG, "NotificationActionService archiving messages"); + + List refs = + intent.getParcelableArrayListExtra(EXTRA_MESSAGE_LIST); + List messages = new ArrayList(); + + for (MessageReference ref : refs) { + LocalMessage m = ref.restoreToLocalMessage(this.getApplicationContext()); + if (m != null) { + messages.add(m); + } + } + + String dstFolder = account.getArchiveFolderName(); + if (dstFolder != null + && !(dstFolder.equals(account.getSpamFolderName()) && K9.confirmSpam()) + && isMovePossible(controller, account, dstFolder, messages)) { + for(LocalMessage messageToMove : messages) { + if (!controller.isMoveCapable(messageToMove)) { + //Toast toast = Toast.makeText(getActivity(), R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG); + //toast.show(); + continue; + } + String srcFolder = messageToMove.getFolder().getName(); + controller.moveMessage(account, srcFolder, messageToMove, dstFolder, null); + } + } + } else if (SPAM_ALL_ACTION.equals(action)) { + if (K9.DEBUG) + Log.i(K9.LOG_TAG, "NotificationActionService moving messages to spam"); + + List refs = + intent.getParcelableArrayListExtra(EXTRA_MESSAGE_LIST); + List messages = new ArrayList(); + + for (MessageReference ref : refs) { + LocalMessage m = ref.restoreToLocalMessage(this); + if (m != null) { + messages.add(m); + } + } + + String dstFolder = account.getSpamFolderName(); + if (dstFolder != null + && !K9.confirmSpam() + && isMovePossible(controller, account, dstFolder, messages)) { + for(LocalMessage messageToMove : messages) { + String srcFolder = messageToMove.getFolder().getName(); + controller.moveMessage(account, srcFolder, messageToMove, dstFolder, null); + } + } } else if (REPLY_ACTION.equals(action)) { if (K9.DEBUG) Log.i(K9.LOG_TAG, "NotificationActionService initiating reply"); diff --git a/k9mail/src/main/res/values-de/strings.xml b/k9mail/src/main/res/values-de/strings.xml index d006470e8..ed79da500 100644 --- a/k9mail/src/main/res/values-de/strings.xml +++ b/k9mail/src/main/res/values-de/strings.xml @@ -167,6 +167,8 @@ Um Fehler zu melden, neue Funktionen vorzuschlagen oder Fragen zu stellen, besuc Antworten Gelesen Löschen + Spam + Archivieren Zertifikatsproblem (%s) Überprüfen Sie Ihre Servereinstellungen Neue E-Mails in %s:%s werden abgerufen diff --git a/k9mail/src/main/res/values/strings.xml b/k9mail/src/main/res/values/strings.xml index 5d977423d..ad916134b 100644 --- a/k9mail/src/main/res/values/strings.xml +++ b/k9mail/src/main/res/values/strings.xml @@ -210,6 +210,8 @@ Please submit bug reports, contribute new features and ask questions at Reply Mark Read Delete + Archive + Spam Certificate error for %s Check your server settings @@ -1147,4 +1149,5 @@ Please submit bug reports, contribute new features and ask questions at Incomplete message Click \'Download complete message\' to allow decryption. + From 05934d75d84f9b80ebfc716ca3b7275ff8dac5c3 Mon Sep 17 00:00:00 2001 From: Marcus Wolschon Date: Tue, 28 Apr 2015 23:08:17 +0200 Subject: [PATCH 05/44] wrong parameter order in format string. (Found via Android Studio Lint tool) --- k9mail/src/main/res/values-zh-rTW/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k9mail/src/main/res/values-zh-rTW/strings.xml b/k9mail/src/main/res/values-zh-rTW/strings.xml index 3cf136a1f..7283a5ed9 100644 --- a/k9mail/src/main/res/values-zh-rTW/strings.xml +++ b/k9mail/src/main/res/values-zh-rTW/strings.xml @@ -129,7 +129,7 @@ 正在重建帳戶「%s 您有新郵件 您有%d封未讀郵件(%s - + 來自%s已超過%d則訊息 + + 來自%2$s已超過%1$d則訊息 回覆 開啟 刪除 From 3e833580ac965f1ff10104d5cfefbab1b3d410a6 Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 30 Apr 2015 09:58:31 +0200 Subject: [PATCH 06/44] Use numbered parameters in format string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … because Transifex is stupid and complains when a parameter doesn't show up in a translation exactly like it's defined in the source language. --- k9mail/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/k9mail/src/main/res/values/strings.xml b/k9mail/src/main/res/values/strings.xml index ad916134b..988750b5f 100644 --- a/k9mail/src/main/res/values/strings.xml +++ b/k9mail/src/main/res/values/strings.xml @@ -205,7 +205,7 @@ Please submit bug reports, contribute new features and ask questions at %d new messages %d Unread (%s) - + %d more on %s + + %1$d more on %2$s Reply Mark Read From ce86e773e0745a0a34ae6f4ee4c87a42755f3cdd Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 30 Apr 2015 10:10:54 +0200 Subject: [PATCH 07/44] Use Greenmail 1.4.1 release instead of (now removed) snapshot --- k9mail/build.gradle | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/k9mail/build.gradle b/k9mail/build.gradle index 39d36a55c..a9efee7da 100644 --- a/k9mail/build.gradle +++ b/k9mail/build.gradle @@ -5,9 +5,6 @@ apply from: '../gradle/plugins/findbugs-android.gradle' repositories { jcenter() - maven { - url "https://oss.sonatype.org/content/repositories/snapshots/" - } } dependencies { @@ -24,7 +21,7 @@ dependencies { androidTestCompile 'com.android.support.test:testing-support-lib:0.1' androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0' - androidTestCompile('com.icegreen:greenmail:1.4.1-SNAPSHOT') { + androidTestCompile('com.icegreen:greenmail:1.4.1') { exclude group: 'junit' } androidTestCompile 'com.madgag.spongycastle:pg:1.51.0.0' From c4723cba4a72afc4f51ae9908c2288ea57693be7 Mon Sep 17 00:00:00 2001 From: Samuel Sieb Date: Tue, 28 Apr 2015 20:57:30 -0700 Subject: [PATCH 08/44] Disable RigidWebView resize throttling on Android Lollipop or higher. This fixes the problem with blank messages. --- src/com/fsck/k9/view/RigidWebView.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/com/fsck/k9/view/RigidWebView.java b/src/com/fsck/k9/view/RigidWebView.java index 2031648b7..796ab5674 100644 --- a/src/com/fsck/k9/view/RigidWebView.java +++ b/src/com/fsck/k9/view/RigidWebView.java @@ -18,6 +18,7 @@ package com.fsck.k9.view; import android.content.Context; +import android.os.Build; import android.util.AttributeSet; import android.util.Log; import android.webkit.WebView; @@ -45,6 +46,7 @@ public class RigidWebView extends WebView { super(context, attrs, defStyle); } + private boolean noThrottle = Build.VERSION.SDK_INT >= 21; //Build.VERSION_CODES.LOLLIPOP private static final int MIN_RESIZE_INTERVAL = 200; private static final int MAX_RESIZE_INTERVAL = 300; private final Clock mClock = Clock.INSTANCE; @@ -66,6 +68,13 @@ public class RigidWebView extends WebView { protected void onSizeChanged(int w, int h, int ow, int oh) { mRealWidth = w; mRealHeight = h; + + // Don't throttle resizes on Android 5 or higher. + if (noThrottle) { + performSizeChange(ow, oh); + return; + } + long now = mClock.getTime(); boolean recentlySized = (now - mLastSizeChangeTime < MIN_RESIZE_INTERVAL); From 4784a3f6fff346eb7c36697d1efe84180b59b044 Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 30 Apr 2015 04:41:50 +0200 Subject: [PATCH 09/44] Do less work in RigidWebView in 'no throttle' case --- src/com/fsck/k9/view/RigidWebView.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/com/fsck/k9/view/RigidWebView.java b/src/com/fsck/k9/view/RigidWebView.java index 796ab5674..43e344ba5 100644 --- a/src/com/fsck/k9/view/RigidWebView.java +++ b/src/com/fsck/k9/view/RigidWebView.java @@ -35,6 +35,7 @@ import com.fsck.k9.helper.Utility; * contents with percent-based height will force the WebView to infinitely expand (or shrink). */ public class RigidWebView extends WebView { + private static final boolean NO_THROTTLE = Build.VERSION.SDK_INT >= 21; //Build.VERSION_CODES.LOLLIPOP public RigidWebView(Context context) { super(context); @@ -46,7 +47,6 @@ public class RigidWebView extends WebView { super(context, attrs, defStyle); } - private boolean noThrottle = Build.VERSION.SDK_INT >= 21; //Build.VERSION_CODES.LOLLIPOP private static final int MIN_RESIZE_INTERVAL = 200; private static final int MAX_RESIZE_INTERVAL = 300; private final Clock mClock = Clock.INSTANCE; @@ -66,15 +66,14 @@ public class RigidWebView extends WebView { @Override protected void onSizeChanged(int w, int h, int ow, int oh) { - mRealWidth = w; - mRealHeight = h; - - // Don't throttle resizes on Android 5 or higher. - if (noThrottle) { - performSizeChange(ow, oh); + if (NO_THROTTLE) { + super.onSizeChanged(w, h, ow, oh); return; } + mRealWidth = w; + mRealHeight = h; + long now = mClock.getTime(); boolean recentlySized = (now - mLastSizeChangeTime < MIN_RESIZE_INTERVAL); From 0b49c85c93d03cb9720d70b0108d1bec2afc99c7 Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 2 May 2015 17:56:36 +0200 Subject: [PATCH 10/44] Prepare changelog for 5.106 --- res/xml/changelog_master.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/res/xml/changelog_master.xml b/res/xml/changelog_master.xml index 1b3e0f69c..cc6946a6e 100644 --- a/res/xml/changelog_master.xml +++ b/res/xml/changelog_master.xml @@ -8,6 +8,9 @@ They are automatically updated with "ant bump-version". --> + + Fixed a bug where messages where not always displayed on Android 5.x + Reverted all changes introduced with v5.104 except for the bugfixes related to Android 5.1 From 9d225dc84c1c8f64ec07048492b0c8ba7e8e5cf0 Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 2 May 2015 17:57:09 +0200 Subject: [PATCH 11/44] Bump version to 5.106 --- AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index a8db319bb..affd2f232 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="23060" + android:versionName="5.106"> Date: Wed, 20 May 2015 18:04:20 +0200 Subject: [PATCH 12/44] Update Gradle Android plugin to 1.2.3 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6f91a86ec..16a8c0754 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:1.0.0' + classpath 'com.android.tools.build:gradle:1.2.3' classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0' } } From b45065a5b2cee4e5d917c8bba41cf8f27eceb471 Mon Sep 17 00:00:00 2001 From: cketti Date: Wed, 20 May 2015 20:55:24 +0200 Subject: [PATCH 13/44] Improve FindBugs Gradle task Based on https://github.com/square/sqlbrite/blob/master/gradle/android-findbugs.gradle --- gradle/plugins/findbugs-android.gradle | 37 ++++++++++++++++++-------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/gradle/plugins/findbugs-android.gradle b/gradle/plugins/findbugs-android.gradle index ee83f1808..7a22caf72 100644 --- a/gradle/plugins/findbugs-android.gradle +++ b/gradle/plugins/findbugs-android.gradle @@ -1,14 +1,29 @@ apply plugin: 'findbugs' -check.dependsOn 'findbugs' -task findbugs(type: FindBugs, dependsOn: ['compileDebugJava', 'compileDebugTestJava']) { - ignoreFailures = true - classes = fileTree('build/intermediates/classes/debug/') + - fileTree('build/intermediates/classes/test/debug/') - source = project.android.sourceSets.main.java.getSrcDirs() + - project.android.sourceSets.androidTest.java.getSrcDirs() - classpath = files() - effort = 'max' - includeFilter = file("$rootProject.projectDir/config/findbugs/include_filter.xml") - excludeFilter = file("$rootProject.projectDir/config/findbugs/exclude_filter.xml") +afterEvaluate { + def variants = plugins.hasPlugin('com.android.application') ? + android.applicationVariants : android.libraryVariants + + variants.each { variant -> + def task = project.task("findBugs${variant.name.capitalize()}", type: FindBugs) { + group = 'verification' + description = "Run FindBugs for the ${variant.description}." + + effort = 'max' + ignoreFailures = true + + includeFilter = file("$rootProject.projectDir/config/findbugs/include_filter.xml") + excludeFilter = file("$rootProject.projectDir/config/findbugs/exclude_filter.xml") + + def variantCompile = variant.javaCompile + + classes = fileTree(variantCompile.destinationDir) + source = variantCompile.source + classpath = variantCompile.classpath.plus(project.files(android.bootClasspath)) + + dependsOn(variantCompile) + } + + tasks.getByName('check').dependsOn(task) + } } From 0f66cacf1025ea6ced103d7806ad52466e596523 Mon Sep 17 00:00:00 2001 From: cketti Date: Wed, 20 May 2015 19:21:33 +0200 Subject: [PATCH 14/44] Move JVM tests into main k9mail module Use Robolectric for the tests that use framework classes. --- k9mail/build.gradle | 8 ++++++++ .../test/java/com/fsck/k9/helper/HtmlSanitizerTest.java | 0 .../src/test/java/com/fsck/k9/mail/AddressTest.java | 5 +++++ .../test/java/com/fsck/k9/mail/Address_quoteAtoms.java | 5 +++++ .../k9/mail/filter/EOLConvertingOutputStreamTest.java | 0 .../com/fsck/k9/mail/internet/CharsetSupportTest.java | 5 +++++ .../java/com/fsck/k9/mail/internet/DecoderUtilTest.java | 5 +++++ .../com/fsck/k9/mail/internet/MimeMessageParseTest.java | 5 +++++ .../java/com/fsck/k9/mail/internet/MimeUtilityTest.java | 0 .../java/com/fsck/k9/mail/store/imap/ImapListTest.java | 0 .../fsck/k9/mail/store/imap/ImapResponseParserTest.java | 5 +++++ .../com/fsck/k9/mail/store/imap/ImapStoreUriTest.java | 0 .../java/com/fsck/k9/mail/store/imap/ImapUtilityTest.java | 5 +++++ .../java/com/fsck/k9/message/TextBodyBuilderTest.java | 3 +++ settings.gradle | 1 - 15 files changed, 46 insertions(+), 1 deletion(-) rename {tests-on-jvm => k9mail}/src/test/java/com/fsck/k9/helper/HtmlSanitizerTest.java (100%) rename {tests-on-jvm => k9mail}/src/test/java/com/fsck/k9/mail/AddressTest.java (88%) rename {tests-on-jvm => k9mail}/src/test/java/com/fsck/k9/mail/Address_quoteAtoms.java (87%) rename {tests-on-jvm => k9mail}/src/test/java/com/fsck/k9/mail/filter/EOLConvertingOutputStreamTest.java (100%) rename {tests-on-jvm => k9mail}/src/test/java/com/fsck/k9/mail/internet/CharsetSupportTest.java (95%) rename {tests-on-jvm => k9mail}/src/test/java/com/fsck/k9/mail/internet/DecoderUtilTest.java (94%) rename {tests-on-jvm => k9mail}/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java (98%) rename {tests-on-jvm => k9mail}/src/test/java/com/fsck/k9/mail/internet/MimeUtilityTest.java (100%) rename {tests-on-jvm => k9mail}/src/test/java/com/fsck/k9/mail/store/imap/ImapListTest.java (100%) rename {tests-on-jvm => k9mail}/src/test/java/com/fsck/k9/mail/store/imap/ImapResponseParserTest.java (95%) rename {tests-on-jvm => k9mail}/src/test/java/com/fsck/k9/mail/store/imap/ImapStoreUriTest.java (100%) rename {tests-on-jvm => k9mail}/src/test/java/com/fsck/k9/mail/store/imap/ImapUtilityTest.java (96%) rename {tests-on-jvm => k9mail}/src/test/java/com/fsck/k9/message/TextBodyBuilderTest.java (99%) diff --git a/k9mail/build.gradle b/k9mail/build.gradle index a9efee7da..ff71994bd 100644 --- a/k9mail/build.gradle +++ b/k9mail/build.gradle @@ -25,6 +25,14 @@ dependencies { exclude group: 'junit' } androidTestCompile 'com.madgag.spongycastle:pg:1.51.0.0' + + testCompile('org.robolectric:robolectric:3.0-rc3') { + exclude group: 'org.hamcrest', module: 'hamcrest-core' + } + testCompile 'org.hamcrest:hamcrest-core:1.3' + testCompile('junit:junit:4.10') { + exclude group: 'org.hamcrest', module: 'hamcrest-core' + } } android { diff --git a/tests-on-jvm/src/test/java/com/fsck/k9/helper/HtmlSanitizerTest.java b/k9mail/src/test/java/com/fsck/k9/helper/HtmlSanitizerTest.java similarity index 100% rename from tests-on-jvm/src/test/java/com/fsck/k9/helper/HtmlSanitizerTest.java rename to k9mail/src/test/java/com/fsck/k9/helper/HtmlSanitizerTest.java diff --git a/tests-on-jvm/src/test/java/com/fsck/k9/mail/AddressTest.java b/k9mail/src/test/java/com/fsck/k9/mail/AddressTest.java similarity index 88% rename from tests-on-jvm/src/test/java/com/fsck/k9/mail/AddressTest.java rename to k9mail/src/test/java/com/fsck/k9/mail/AddressTest.java index 7b9c2b891..d8080f063 100644 --- a/tests-on-jvm/src/test/java/com/fsck/k9/mail/AddressTest.java +++ b/k9mail/src/test/java/com/fsck/k9/mail/AddressTest.java @@ -2,10 +2,15 @@ package com.fsck.k9.mail; import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import static org.junit.Assert.assertEquals; +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) public class AddressTest { /** * test the possibility to parse "From:" fields with no email. diff --git a/tests-on-jvm/src/test/java/com/fsck/k9/mail/Address_quoteAtoms.java b/k9mail/src/test/java/com/fsck/k9/mail/Address_quoteAtoms.java similarity index 87% rename from tests-on-jvm/src/test/java/com/fsck/k9/mail/Address_quoteAtoms.java rename to k9mail/src/test/java/com/fsck/k9/mail/Address_quoteAtoms.java index 6de516565..5a2fa88cb 100644 --- a/tests-on-jvm/src/test/java/com/fsck/k9/mail/Address_quoteAtoms.java +++ b/k9mail/src/test/java/com/fsck/k9/mail/Address_quoteAtoms.java @@ -2,10 +2,15 @@ package com.fsck.k9.mail; import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import static org.junit.Assert.assertEquals; +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) public class Address_quoteAtoms { @Test public void testNoQuote() { diff --git a/tests-on-jvm/src/test/java/com/fsck/k9/mail/filter/EOLConvertingOutputStreamTest.java b/k9mail/src/test/java/com/fsck/k9/mail/filter/EOLConvertingOutputStreamTest.java similarity index 100% rename from tests-on-jvm/src/test/java/com/fsck/k9/mail/filter/EOLConvertingOutputStreamTest.java rename to k9mail/src/test/java/com/fsck/k9/mail/filter/EOLConvertingOutputStreamTest.java diff --git a/tests-on-jvm/src/test/java/com/fsck/k9/mail/internet/CharsetSupportTest.java b/k9mail/src/test/java/com/fsck/k9/mail/internet/CharsetSupportTest.java similarity index 95% rename from tests-on-jvm/src/test/java/com/fsck/k9/mail/internet/CharsetSupportTest.java rename to k9mail/src/test/java/com/fsck/k9/mail/internet/CharsetSupportTest.java index d1918be58..3d5141884 100644 --- a/tests-on-jvm/src/test/java/com/fsck/k9/mail/internet/CharsetSupportTest.java +++ b/k9mail/src/test/java/com/fsck/k9/mail/internet/CharsetSupportTest.java @@ -2,10 +2,15 @@ package com.fsck.k9.mail.internet; import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import static org.junit.Assert.assertEquals; +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) public class CharsetSupportTest { @Test diff --git a/tests-on-jvm/src/test/java/com/fsck/k9/mail/internet/DecoderUtilTest.java b/k9mail/src/test/java/com/fsck/k9/mail/internet/DecoderUtilTest.java similarity index 94% rename from tests-on-jvm/src/test/java/com/fsck/k9/mail/internet/DecoderUtilTest.java rename to k9mail/src/test/java/com/fsck/k9/mail/internet/DecoderUtilTest.java index 0f58ddf70..5a24544c5 100644 --- a/tests-on-jvm/src/test/java/com/fsck/k9/mail/internet/DecoderUtilTest.java +++ b/k9mail/src/test/java/com/fsck/k9/mail/internet/DecoderUtilTest.java @@ -2,10 +2,15 @@ package com.fsck.k9.mail.internet; import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import static org.junit.Assert.assertEquals; +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) public class DecoderUtilTest { @Test diff --git a/tests-on-jvm/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java b/k9mail/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java similarity index 98% rename from tests-on-jvm/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java rename to k9mail/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java index 3fc7e4b4a..1dcc88f91 100644 --- a/tests-on-jvm/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java +++ b/k9mail/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java @@ -18,10 +18,15 @@ import com.fsck.k9.mail.Body; import com.fsck.k9.mail.BodyPart; import com.fsck.k9.mail.Message.RecipientType; import com.fsck.k9.mail.Multipart; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import static org.junit.Assert.assertEquals; +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) public class MimeMessageParseTest { @Before public void setup() { diff --git a/tests-on-jvm/src/test/java/com/fsck/k9/mail/internet/MimeUtilityTest.java b/k9mail/src/test/java/com/fsck/k9/mail/internet/MimeUtilityTest.java similarity index 100% rename from tests-on-jvm/src/test/java/com/fsck/k9/mail/internet/MimeUtilityTest.java rename to k9mail/src/test/java/com/fsck/k9/mail/internet/MimeUtilityTest.java diff --git a/tests-on-jvm/src/test/java/com/fsck/k9/mail/store/imap/ImapListTest.java b/k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapListTest.java similarity index 100% rename from tests-on-jvm/src/test/java/com/fsck/k9/mail/store/imap/ImapListTest.java rename to k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapListTest.java diff --git a/tests-on-jvm/src/test/java/com/fsck/k9/mail/store/imap/ImapResponseParserTest.java b/k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapResponseParserTest.java similarity index 95% rename from tests-on-jvm/src/test/java/com/fsck/k9/mail/store/imap/ImapResponseParserTest.java rename to k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapResponseParserTest.java index d9ce8b445..31e867cc5 100644 --- a/tests-on-jvm/src/test/java/com/fsck/k9/mail/store/imap/ImapResponseParserTest.java +++ b/k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapResponseParserTest.java @@ -3,6 +3,9 @@ package com.fsck.k9.mail.store.imap; import com.fsck.k9.mail.filter.PeekableInputStream; import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -16,6 +19,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) public class ImapResponseParserTest { @Test public void testSimpleOkResponse() throws IOException { diff --git a/tests-on-jvm/src/test/java/com/fsck/k9/mail/store/imap/ImapStoreUriTest.java b/k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapStoreUriTest.java similarity index 100% rename from tests-on-jvm/src/test/java/com/fsck/k9/mail/store/imap/ImapStoreUriTest.java rename to k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapStoreUriTest.java diff --git a/tests-on-jvm/src/test/java/com/fsck/k9/mail/store/imap/ImapUtilityTest.java b/k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapUtilityTest.java similarity index 96% rename from tests-on-jvm/src/test/java/com/fsck/k9/mail/store/imap/ImapUtilityTest.java rename to k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapUtilityTest.java index 283660fbb..f91ec80b1 100644 --- a/tests-on-jvm/src/test/java/com/fsck/k9/mail/store/imap/ImapUtilityTest.java +++ b/k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapUtilityTest.java @@ -18,12 +18,17 @@ package com.fsck.k9.mail.store.imap; import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import java.util.List; import static org.junit.Assert.assertArrayEquals; +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) public class ImapUtilityTest { @Test public void testGetImapSequenceValues() { diff --git a/tests-on-jvm/src/test/java/com/fsck/k9/message/TextBodyBuilderTest.java b/k9mail/src/test/java/com/fsck/k9/message/TextBodyBuilderTest.java similarity index 99% rename from tests-on-jvm/src/test/java/com/fsck/k9/message/TextBodyBuilderTest.java rename to k9mail/src/test/java/com/fsck/k9/message/TextBodyBuilderTest.java index afb95eb2f..cf6b03fcb 100644 --- a/tests-on-jvm/src/test/java/com/fsck/k9/message/TextBodyBuilderTest.java +++ b/k9mail/src/test/java/com/fsck/k9/message/TextBodyBuilderTest.java @@ -3,6 +3,7 @@ package com.fsck.k9.message; import com.fsck.k9.Account.QuoteStyle; import com.fsck.k9.mail.internet.TextBody; +import org.junit.Ignore; import org.junit.experimental.theories.DataPoints; import org.junit.experimental.theories.Theories; import org.junit.experimental.theories.Theory; @@ -12,6 +13,8 @@ import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; +//TODO: Get rid of 'Theories' and write simple tests +@Ignore @RunWith(Theories.class) public class TextBodyBuilderTest { diff --git a/settings.gradle b/settings.gradle index a39b9d813..febff8e7f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,4 +3,3 @@ include ':k9mail-library' include ':plugins:Android-PullToRefresh:library' include ':plugins:HoloColorPicker' include ':plugins:openpgp-api-library' -include ':tests-on-jvm' From 4b273c1749e4761a86b045a2b40e93d267e878cb Mon Sep 17 00:00:00 2001 From: cketti Date: Wed, 20 May 2015 20:57:21 +0200 Subject: [PATCH 15/44] Move some tests from 'androidTest' to 'test' folder --- .../com/fsck/k9/activity/MessageReferenceTest.java | 7 ++++--- .../com/fsck/k9/crypto/MessageDecryptVerifierTest.java | 7 ++++--- .../java/com/fsck/k9/helper/HtmlConverterTest.java | 8 +++++--- .../java/com/fsck/k9/helper/MessageHelperTest.java | 10 ++++++---- 4 files changed, 19 insertions(+), 13 deletions(-) rename k9mail/src/{androidTest => test}/java/com/fsck/k9/activity/MessageReferenceTest.java (97%) rename k9mail/src/{androidTest => test}/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java (94%) rename k9mail/src/{androidTest => test}/java/com/fsck/k9/helper/HtmlConverterTest.java (98%) rename k9mail/src/{androidTest => test}/java/com/fsck/k9/helper/MessageHelperTest.java (91%) diff --git a/k9mail/src/androidTest/java/com/fsck/k9/activity/MessageReferenceTest.java b/k9mail/src/test/java/com/fsck/k9/activity/MessageReferenceTest.java similarity index 97% rename from k9mail/src/androidTest/java/com/fsck/k9/activity/MessageReferenceTest.java rename to k9mail/src/test/java/com/fsck/k9/activity/MessageReferenceTest.java index 3ad1ba75b..85acf6b27 100644 --- a/k9mail/src/androidTest/java/com/fsck/k9/activity/MessageReferenceTest.java +++ b/k9mail/src/test/java/com/fsck/k9/activity/MessageReferenceTest.java @@ -1,12 +1,12 @@ package com.fsck.k9.activity; -import android.support.test.runner.AndroidJUnit4; - import com.fsck.k9.mail.Flag; import com.fsck.k9.mail.MessagingException; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; @@ -14,7 +14,8 @@ import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; -@RunWith(AndroidJUnit4.class) +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) public class MessageReferenceTest { @Test diff --git a/k9mail/src/androidTest/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java b/k9mail/src/test/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java similarity index 94% rename from k9mail/src/androidTest/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java rename to k9mail/src/test/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java index e06bd7971..3764cd6d5 100644 --- a/k9mail/src/androidTest/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java +++ b/k9mail/src/test/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java @@ -3,8 +3,6 @@ package com.fsck.k9.crypto; import java.util.List; -import android.support.test.runner.AndroidJUnit4; - import com.fsck.k9.mail.Part; import com.fsck.k9.mail.internet.MimeBodyPart; import com.fsck.k9.mail.internet.MimeMessage; @@ -13,12 +11,15 @@ import com.fsck.k9.mail.internet.MimeMultipart; import com.fsck.k9.mail.internet.TextBody; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertSame; -@RunWith(AndroidJUnit4.class) +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) public class MessageDecryptVerifierTest { @Test diff --git a/k9mail/src/androidTest/java/com/fsck/k9/helper/HtmlConverterTest.java b/k9mail/src/test/java/com/fsck/k9/helper/HtmlConverterTest.java similarity index 98% rename from k9mail/src/androidTest/java/com/fsck/k9/helper/HtmlConverterTest.java rename to k9mail/src/test/java/com/fsck/k9/helper/HtmlConverterTest.java index c09244164..9292991b5 100644 --- a/k9mail/src/androidTest/java/com/fsck/k9/helper/HtmlConverterTest.java +++ b/k9mail/src/test/java/com/fsck/k9/helper/HtmlConverterTest.java @@ -1,18 +1,20 @@ package com.fsck.k9.helper; + import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; -import android.support.test.runner.AndroidJUnit4; - import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import static junit.framework.Assert.assertEquals; -@RunWith(AndroidJUnit4.class) +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) public class HtmlConverterTest { // Useful if you want to write stuff to a file for debugging in a browser. private static final boolean WRITE_TO_FILE = Boolean.parseBoolean(System.getProperty("k9.htmlConverterTest.writeToFile", "false")); diff --git a/k9mail/src/androidTest/java/com/fsck/k9/helper/MessageHelperTest.java b/k9mail/src/test/java/com/fsck/k9/helper/MessageHelperTest.java similarity index 91% rename from k9mail/src/androidTest/java/com/fsck/k9/helper/MessageHelperTest.java rename to k9mail/src/test/java/com/fsck/k9/helper/MessageHelperTest.java index 485f11520..a2292a61c 100644 --- a/k9mail/src/androidTest/java/com/fsck/k9/helper/MessageHelperTest.java +++ b/k9mail/src/test/java/com/fsck/k9/helper/MessageHelperTest.java @@ -3,27 +3,29 @@ package com.fsck.k9.helper; import android.content.Context; import android.graphics.Color; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; import android.text.SpannableString; import com.fsck.k9.mail.Address; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; -@RunWith(AndroidJUnit4.class) +@RunWith(RobolectricTestRunner.class) +@Config(manifest = Config.NONE) public class MessageHelperTest { private Contacts contacts; private Contacts mockContacts; @Before public void setUp() throws Exception { - Context context = InstrumentationRegistry.getTargetContext(); + Context context = RuntimeEnvironment.application; contacts = new Contacts(context); mockContacts = new Contacts(context) { @Override public String getNameForAddress(String address) { From a24d85d754dcdcd4499c67abc4ebeb5e335d14fe Mon Sep 17 00:00:00 2001 From: cketti Date: Wed, 20 May 2015 23:48:30 +0200 Subject: [PATCH 16/44] Move library tests to k9mail-library module --- k9mail-library/build.gradle | 14 ++++++++++++++ .../java/com/fsck/k9/mail/MessageTest.java | 0 .../java/com/fsck/k9/mail/PgpMimeMessageTest.java | 0 .../com/fsck/k9/mail/ReconstructMessageTest.java | 0 .../fsck/k9/mail/ssl/TrustManagerFactoryTest.java | 0 .../test/java/com/fsck/k9/mail/AddressTest.java | 0 .../java/com/fsck/k9/mail/Address_quoteAtoms.java | 0 .../mail/filter/EOLConvertingOutputStreamTest.java | 0 .../fsck/k9/mail/internet/CharsetSupportTest.java | 0 .../com/fsck/k9/mail/internet/DecoderUtilTest.java | 0 .../k9/mail/internet/MimeMessageParseTest.java | 0 .../com/fsck/k9/mail/internet/MimeUtilityTest.java | 0 .../com/fsck/k9/mail/store/imap/ImapListTest.java | 0 .../k9/mail/store/imap/ImapResponseParserTest.java | 0 .../fsck/k9/mail/store/imap/ImapStoreUriTest.java | 0 .../fsck/k9/mail/store/imap/ImapUtilityTest.java | 0 k9mail/build.gradle | 1 - 17 files changed, 14 insertions(+), 1 deletion(-) rename {k9mail => k9mail-library}/src/androidTest/java/com/fsck/k9/mail/MessageTest.java (100%) rename {k9mail => k9mail-library}/src/androidTest/java/com/fsck/k9/mail/PgpMimeMessageTest.java (100%) rename {k9mail => k9mail-library}/src/androidTest/java/com/fsck/k9/mail/ReconstructMessageTest.java (100%) rename {k9mail => k9mail-library}/src/androidTest/java/com/fsck/k9/mail/ssl/TrustManagerFactoryTest.java (100%) rename {k9mail => k9mail-library}/src/test/java/com/fsck/k9/mail/AddressTest.java (100%) rename {k9mail => k9mail-library}/src/test/java/com/fsck/k9/mail/Address_quoteAtoms.java (100%) rename {k9mail => k9mail-library}/src/test/java/com/fsck/k9/mail/filter/EOLConvertingOutputStreamTest.java (100%) rename {k9mail => k9mail-library}/src/test/java/com/fsck/k9/mail/internet/CharsetSupportTest.java (100%) rename {k9mail => k9mail-library}/src/test/java/com/fsck/k9/mail/internet/DecoderUtilTest.java (100%) rename {k9mail => k9mail-library}/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java (100%) rename {k9mail => k9mail-library}/src/test/java/com/fsck/k9/mail/internet/MimeUtilityTest.java (100%) rename {k9mail => k9mail-library}/src/test/java/com/fsck/k9/mail/store/imap/ImapListTest.java (100%) rename {k9mail => k9mail-library}/src/test/java/com/fsck/k9/mail/store/imap/ImapResponseParserTest.java (100%) rename {k9mail => k9mail-library}/src/test/java/com/fsck/k9/mail/store/imap/ImapStoreUriTest.java (100%) rename {k9mail => k9mail-library}/src/test/java/com/fsck/k9/mail/store/imap/ImapUtilityTest.java (100%) diff --git a/k9mail-library/build.gradle b/k9mail-library/build.gradle index b32294f08..f95a158f6 100644 --- a/k9mail-library/build.gradle +++ b/k9mail-library/build.gradle @@ -12,6 +12,17 @@ dependencies { compile 'commons-io:commons-io:2.4' compile 'com.jcraft:jzlib:1.0.7' compile 'com.beetstra.jutf7:jutf7:1.0.0' + + androidTestCompile 'com.android.support.test:testing-support-lib:0.1' + androidTestCompile 'com.madgag.spongycastle:pg:1.51.0.0' + + testCompile('org.robolectric:robolectric:3.0-rc3') { + exclude group: 'org.hamcrest', module: 'hamcrest-core' + } + testCompile 'org.hamcrest:hamcrest-core:1.3' + testCompile('junit:junit:4.10') { + exclude group: 'org.hamcrest', module: 'hamcrest-core' + } } android { @@ -21,6 +32,8 @@ android { defaultConfig { minSdkVersion 15 targetSdkVersion 21 + + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } lintOptions { @@ -40,5 +53,6 @@ android { exclude 'META-INF/LICENSE.txt' exclude 'META-INF/NOTICE' exclude 'META-INF/NOTICE.txt' + exclude 'LICENSE.txt' } } diff --git a/k9mail/src/androidTest/java/com/fsck/k9/mail/MessageTest.java b/k9mail-library/src/androidTest/java/com/fsck/k9/mail/MessageTest.java similarity index 100% rename from k9mail/src/androidTest/java/com/fsck/k9/mail/MessageTest.java rename to k9mail-library/src/androidTest/java/com/fsck/k9/mail/MessageTest.java diff --git a/k9mail/src/androidTest/java/com/fsck/k9/mail/PgpMimeMessageTest.java b/k9mail-library/src/androidTest/java/com/fsck/k9/mail/PgpMimeMessageTest.java similarity index 100% rename from k9mail/src/androidTest/java/com/fsck/k9/mail/PgpMimeMessageTest.java rename to k9mail-library/src/androidTest/java/com/fsck/k9/mail/PgpMimeMessageTest.java diff --git a/k9mail/src/androidTest/java/com/fsck/k9/mail/ReconstructMessageTest.java b/k9mail-library/src/androidTest/java/com/fsck/k9/mail/ReconstructMessageTest.java similarity index 100% rename from k9mail/src/androidTest/java/com/fsck/k9/mail/ReconstructMessageTest.java rename to k9mail-library/src/androidTest/java/com/fsck/k9/mail/ReconstructMessageTest.java diff --git a/k9mail/src/androidTest/java/com/fsck/k9/mail/ssl/TrustManagerFactoryTest.java b/k9mail-library/src/androidTest/java/com/fsck/k9/mail/ssl/TrustManagerFactoryTest.java similarity index 100% rename from k9mail/src/androidTest/java/com/fsck/k9/mail/ssl/TrustManagerFactoryTest.java rename to k9mail-library/src/androidTest/java/com/fsck/k9/mail/ssl/TrustManagerFactoryTest.java diff --git a/k9mail/src/test/java/com/fsck/k9/mail/AddressTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/AddressTest.java similarity index 100% rename from k9mail/src/test/java/com/fsck/k9/mail/AddressTest.java rename to k9mail-library/src/test/java/com/fsck/k9/mail/AddressTest.java diff --git a/k9mail/src/test/java/com/fsck/k9/mail/Address_quoteAtoms.java b/k9mail-library/src/test/java/com/fsck/k9/mail/Address_quoteAtoms.java similarity index 100% rename from k9mail/src/test/java/com/fsck/k9/mail/Address_quoteAtoms.java rename to k9mail-library/src/test/java/com/fsck/k9/mail/Address_quoteAtoms.java diff --git a/k9mail/src/test/java/com/fsck/k9/mail/filter/EOLConvertingOutputStreamTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/filter/EOLConvertingOutputStreamTest.java similarity index 100% rename from k9mail/src/test/java/com/fsck/k9/mail/filter/EOLConvertingOutputStreamTest.java rename to k9mail-library/src/test/java/com/fsck/k9/mail/filter/EOLConvertingOutputStreamTest.java diff --git a/k9mail/src/test/java/com/fsck/k9/mail/internet/CharsetSupportTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/internet/CharsetSupportTest.java similarity index 100% rename from k9mail/src/test/java/com/fsck/k9/mail/internet/CharsetSupportTest.java rename to k9mail-library/src/test/java/com/fsck/k9/mail/internet/CharsetSupportTest.java diff --git a/k9mail/src/test/java/com/fsck/k9/mail/internet/DecoderUtilTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/internet/DecoderUtilTest.java similarity index 100% rename from k9mail/src/test/java/com/fsck/k9/mail/internet/DecoderUtilTest.java rename to k9mail-library/src/test/java/com/fsck/k9/mail/internet/DecoderUtilTest.java diff --git a/k9mail/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java similarity index 100% rename from k9mail/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java rename to k9mail-library/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java diff --git a/k9mail/src/test/java/com/fsck/k9/mail/internet/MimeUtilityTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/internet/MimeUtilityTest.java similarity index 100% rename from k9mail/src/test/java/com/fsck/k9/mail/internet/MimeUtilityTest.java rename to k9mail-library/src/test/java/com/fsck/k9/mail/internet/MimeUtilityTest.java diff --git a/k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapListTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/ImapListTest.java similarity index 100% rename from k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapListTest.java rename to k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/ImapListTest.java diff --git a/k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapResponseParserTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/ImapResponseParserTest.java similarity index 100% rename from k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapResponseParserTest.java rename to k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/ImapResponseParserTest.java diff --git a/k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapStoreUriTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/ImapStoreUriTest.java similarity index 100% rename from k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapStoreUriTest.java rename to k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/ImapStoreUriTest.java diff --git a/k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapUtilityTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/ImapUtilityTest.java similarity index 100% rename from k9mail/src/test/java/com/fsck/k9/mail/store/imap/ImapUtilityTest.java rename to k9mail-library/src/test/java/com/fsck/k9/mail/store/imap/ImapUtilityTest.java diff --git a/k9mail/build.gradle b/k9mail/build.gradle index ff71994bd..c667e60a4 100644 --- a/k9mail/build.gradle +++ b/k9mail/build.gradle @@ -24,7 +24,6 @@ dependencies { androidTestCompile('com.icegreen:greenmail:1.4.1') { exclude group: 'junit' } - androidTestCompile 'com.madgag.spongycastle:pg:1.51.0.0' testCompile('org.robolectric:robolectric:3.0-rc3') { exclude group: 'org.hamcrest', module: 'hamcrest-core' From 9c258ee60ca38b48e62057ad3911c552dd2a53d4 Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 21 May 2015 00:15:53 +0200 Subject: [PATCH 17/44] Ignore Lint warning for OldTargetApi --- config/lint/lint.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/lint/lint.xml b/config/lint/lint.xml index ad613c633..c38682ef5 100644 --- a/config/lint/lint.xml +++ b/config/lint/lint.xml @@ -1,6 +1,7 @@ + From 916929e5073398b343fb6d1435c66f44d260aad7 Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 21 May 2015 14:52:50 +0200 Subject: [PATCH 18/44] Fix getting code coverage on CI builds --- k9mail-library/build.gradle | 7 +++++++ k9mail/build.gradle | 1 + 2 files changed, 8 insertions(+) diff --git a/k9mail-library/build.gradle b/k9mail-library/build.gradle index f95a158f6..317862f87 100644 --- a/k9mail-library/build.gradle +++ b/k9mail-library/build.gradle @@ -1,6 +1,7 @@ apply plugin: 'com.android.library' apply from: '../gradle/plugins/checkstyle-android.gradle' apply from: '../gradle/plugins/findbugs-android.gradle' +apply plugin: 'jacoco' repositories { jcenter() @@ -36,6 +37,12 @@ android { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } + buildTypes { + debug { + testCoverageEnabled rootProject.testCoverage + } + } + lintOptions { abortOnError true warningsAsErrors true diff --git a/k9mail/build.gradle b/k9mail/build.gradle index c667e60a4..e14789301 100644 --- a/k9mail/build.gradle +++ b/k9mail/build.gradle @@ -2,6 +2,7 @@ apply plugin: 'android-sdk-manager' apply plugin: 'com.android.application' apply from: '../gradle/plugins/checkstyle-android.gradle' apply from: '../gradle/plugins/findbugs-android.gradle' +apply plugin: 'jacoco' repositories { jcenter() From 706fd85a0479666d7a01adcb10734634ec72eaaf Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 21 May 2015 14:53:34 +0200 Subject: [PATCH 19/44] Remove tests-on-jvm module --- tests-on-jvm/build.gradle | 39 ------------------- .../src/test/java/android/text/TextUtils.java | 7 ---- .../src/test/java/android/util/Log.java | 11 ------ .../src/test/java/com/fsck/k9/K9.java | 5 --- 4 files changed, 62 deletions(-) delete mode 100644 tests-on-jvm/build.gradle delete mode 100644 tests-on-jvm/src/test/java/android/text/TextUtils.java delete mode 100644 tests-on-jvm/src/test/java/android/util/Log.java delete mode 100644 tests-on-jvm/src/test/java/com/fsck/k9/K9.java diff --git a/tests-on-jvm/build.gradle b/tests-on-jvm/build.gradle deleted file mode 100644 index 831e87a39..000000000 --- a/tests-on-jvm/build.gradle +++ /dev/null @@ -1,39 +0,0 @@ -repositories { - mavenCentral() -} - -apply plugin: 'java' -apply plugin: 'findbugs' -apply plugin: 'checkstyle' -apply plugin: 'jacoco' - -dependencies { - testCompile project(':k9mail') - testCompile 'junit:junit:4.12' -} - -sourceSets { - test { - compileClasspath += files(project(':k9mail').compileDebugJava.destinationDir) - compileClasspath += project(':k9mail').compileDebugJava.classpath - runtimeClasspath += files(project(':k9mail').compileDebugJava.destinationDir) - runtimeClasspath += project(':k9mail').compileDebugJava.classpath - } -} - -checkstyle { - ignoreFailures = true - configFile file("$rootProject.projectDir/config/checkstyle/checkstyle.xml") -} - -findbugs { - ignoreFailures = true - effort = 'max' - includeFilter = file("$rootProject.projectDir/config/findbugs/include_filter.xml") - excludeFilter = file("$rootProject.projectDir/config/findbugs/exclude_filter.xml") -} - -check.dependsOn 'checkstyleTest' -check.dependsOn 'findbugsTest' - -compileTestJava.dependsOn ':k9mail:compileDebugJava' diff --git a/tests-on-jvm/src/test/java/android/text/TextUtils.java b/tests-on-jvm/src/test/java/android/text/TextUtils.java deleted file mode 100644 index cdc2ddc19..000000000 --- a/tests-on-jvm/src/test/java/android/text/TextUtils.java +++ /dev/null @@ -1,7 +0,0 @@ -package android.text; - -public class TextUtils { - public static boolean isEmpty(CharSequence str) { - return (str == null || str.length() == 0); - } -} diff --git a/tests-on-jvm/src/test/java/android/util/Log.java b/tests-on-jvm/src/test/java/android/util/Log.java deleted file mode 100644 index 4d952eb26..000000000 --- a/tests-on-jvm/src/test/java/android/util/Log.java +++ /dev/null @@ -1,11 +0,0 @@ -package android.util; - -public class Log { - public static int v(String tag, String message) { return 0; } - public static int d(String tag, String message) { return 0; } - public static int d(String tag, String message, Throwable throwable) { return 0; } - public static int i(String tag, String message) { return 0; } - public static int w(String tag, String message) { return 0; } - public static int e(String tag, String message) { return 0; } - public static int e(String tag, String message, Throwable th) { return 0; } -} diff --git a/tests-on-jvm/src/test/java/com/fsck/k9/K9.java b/tests-on-jvm/src/test/java/com/fsck/k9/K9.java deleted file mode 100644 index 64c6b7c47..000000000 --- a/tests-on-jvm/src/test/java/com/fsck/k9/K9.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.fsck.k9; - -public class K9 { - public static boolean DEBUG = false; -} From 1cd7df136953d1c278ae238e8039f5b8da979620 Mon Sep 17 00:00:00 2001 From: cketti Date: Fri, 22 May 2015 03:41:24 +0200 Subject: [PATCH 20/44] Don't write the new push state to the database for every message --- .../com/fsck/k9/controller/MessagingController.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java index 93687f60d..c7f26ae73 100644 --- a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java +++ b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java @@ -1296,14 +1296,15 @@ public class MessagingController implements Runnable { fetchUnsyncedMessages(account, remoteFolder, localFolder, unsyncedMessages, smallMessages, largeMessages, progress, todo, fp); - // If a message didn't exist, messageFinished won't be called, but we shouldn't try again - // If we got here, nothing failed + String updatedPushState = localFolder.getPushState(); for (Message message : unsyncedMessages) { - String newPushState = remoteFolder.getNewPushState(localFolder.getPushState(), message); + String newPushState = remoteFolder.getNewPushState(updatedPushState, message); if (newPushState != null) { - localFolder.setPushState(newPushState); + updatedPushState = newPushState; } } + localFolder.setPushState(updatedPushState); + if (K9.DEBUG) { Log.d(K9.LOG_TAG, "SYNC: Synced unsynced messages for folder " + folder); } @@ -1462,10 +1463,6 @@ public class MessagingController implements Runnable { @Override public void messageFinished(T message, int number, int ofTotal) { try { - String newPushState = remoteFolder.getNewPushState(localFolder.getPushState(), message); - if (newPushState != null) { - localFolder.setPushState(newPushState); - } if (message.isSet(Flag.DELETED) || message.olderThan(earliestDate)) { if (K9.DEBUG) { From 6138afb579fb4367c0a9e653c420e21fbe630c77 Mon Sep 17 00:00:00 2001 From: cketti Date: Fri, 22 May 2015 07:16:35 +0200 Subject: [PATCH 21/44] Don't write messages without (partial) body to database Opening such messages during download will display "No text" and (probably due to a bug) might lead to the synchronization process being aborted. Instead of fixing the UI issue we now don't write these incomplete messages to the database. This has the potential to massively speed up the sync process. But it will take longer for messages to show up in the message list, especially with slow connections. --- .../k9/controller/MessagingController.java | 67 +------------------ 1 file changed, 1 insertion(+), 66 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java index c7f26ae73..bc2f79108 100644 --- a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java +++ b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java @@ -1294,7 +1294,7 @@ public class MessagingController implements Runnable { Log.d(K9.LOG_TAG, "SYNC: About to fetch " + unsyncedMessages.size() + " unsynced messages for folder " + folder); - fetchUnsyncedMessages(account, remoteFolder, localFolder, unsyncedMessages, smallMessages, largeMessages, progress, todo, fp); + fetchUnsyncedMessages(account, remoteFolder, unsyncedMessages, smallMessages, largeMessages, progress, todo, fp); String updatedPushState = localFolder.getPushState(); for (Message message : unsyncedMessages) { @@ -1442,7 +1442,6 @@ public class MessagingController implements Runnable { } private void fetchUnsyncedMessages(final Account account, final Folder remoteFolder, - final LocalFolder localFolder, List unsyncedMessages, final List smallMessages, final List largeMessages, @@ -1453,18 +1452,12 @@ public class MessagingController implements Runnable { final Date earliestDate = account.getEarliestPollDate(); - /* - * Messages to be batch written - */ - final List chunk = new ArrayList(UNSYNC_CHUNK_SIZE); - remoteFolder.fetch(unsyncedMessages, fp, new MessageRetrievalListener() { @Override public void messageFinished(T message, int number, int ofTotal) { try { if (message.isSet(Flag.DELETED) || message.olderThan(earliestDate)) { - if (K9.DEBUG) { if (message.isSet(Flag.DELETED)) { Log.v(K9.LOG_TAG, "Newly downloaded message " + account + ":" + folder + ":" + message.getUid() @@ -1487,24 +1480,6 @@ public class MessagingController implements Runnable { } else { smallMessages.add(message); } - - // And include it in the view - if (message.getSubject() != null && message.getFrom() != null) { - /* - * We check to make sure that we got something worth - * showing (subject and from) because some protocols - * (POP) may not be able to give us headers for - * ENVELOPE, only size. - */ - - // keep message for delayed storing - chunk.add(message); - - if (chunk.size() >= UNSYNC_CHUNK_SIZE) { - writeUnsyncedMessages(chunk, localFolder, account, folder); - chunk.clear(); - } - } } catch (Exception e) { Log.e(K9.LOG_TAG, "Error while storing downloaded message.", e); addErrorMessage(account, null, e); @@ -1520,48 +1495,8 @@ public class MessagingController implements Runnable { } }); - if (!chunk.isEmpty()) { - writeUnsyncedMessages(chunk, localFolder, account, folder); - chunk.clear(); - } } - /** - * Actual storing of messages - * - *
- * FIXME: This method should really be moved in the above MessageRetrievalListener once {@link MessageRetrievalListener#messagesFinished(int)} is properly invoked by various stores - * - * @param messages Never null. - * @param localFolder - * @param account - * @param folder - */ - private void writeUnsyncedMessages(final List messages, final LocalFolder localFolder, final Account account, final String folder) { - if (K9.DEBUG) { - Log.v(K9.LOG_TAG, "Batch writing " + Integer.toString(messages.size()) + " messages"); - } - try { - // Store the new message locally - localFolder.appendMessages(messages); - - for (final Message message : messages) { - final LocalMessage localMessage = localFolder.getMessage(message.getUid()); - syncFlags(localMessage, message); - if (K9.DEBUG) - Log.v(K9.LOG_TAG, "About to notify listeners that we got a new unsynced message " - + account + ":" + folder + ":" + message.getUid()); - for (final MessagingListener l : getListeners()) { - l.synchronizeMailboxAddOrUpdateMessage(account, folder, localMessage); - } - } - } catch (final Exception e) { - Log.e(K9.LOG_TAG, "Error while storing downloaded message.", e); - addErrorMessage(account, null, e); - } - } - - private boolean shouldImportMessage(final Account account, final String folder, final Message message, final AtomicInteger progress, final Date earliestDate) { if (account.isSearchByDateCapable() && message.olderThan(earliestDate)) { From a63a91fa542f145d7e66df3712d95d5161997240 Mon Sep 17 00:00:00 2001 From: "brian m. carlson" Date: Sat, 23 May 2015 21:32:22 +0000 Subject: [PATCH 22/44] Support GCM cipher suites. --- .../com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java b/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java index 3c9fe800f..06a37f325 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java @@ -32,6 +32,12 @@ public class DefaultTrustedSocketFactory implements TrustedSocketFactory { // Order taken from OpenSSL 1.0.1c protected static final String ORDERED_KNOWN_CIPHERS[] = { + "TLS_ECDHE_RSA_AES_256_GCM_SHA384", + "TLS_ECDHE_ECDSA_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_AES_128_GCM_SHA256", + "TLS_ECDHE_ECDSA_AES_128_GCM_SHA256", + "TLS_DHE_RSA_AES_256_GCM_SHA384", + "TLS_DHE_RSA_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", From 4fb12ff12b4514cb11a975f7b495b7bbc1284c3d Mon Sep 17 00:00:00 2001 From: cketti Date: Mon, 25 May 2015 18:12:18 +0200 Subject: [PATCH 23/44] Fix cipher suite names --- .../k9/mail/ssl/DefaultTrustedSocketFactory.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java b/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java index 06a37f325..62ae2ed70 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java @@ -30,14 +30,13 @@ public class DefaultTrustedSocketFactory implements TrustedSocketFactory { protected static final String ENABLED_CIPHERS[]; protected static final String ENABLED_PROTOCOLS[]; - // Order taken from OpenSSL 1.0.1c protected static final String ORDERED_KNOWN_CIPHERS[] = { - "TLS_ECDHE_RSA_AES_256_GCM_SHA384", - "TLS_ECDHE_ECDSA_AES_256_GCM_SHA384", - "TLS_ECDHE_RSA_AES_128_GCM_SHA256", - "TLS_ECDHE_ECDSA_AES_128_GCM_SHA256", - "TLS_DHE_RSA_AES_256_GCM_SHA384", - "TLS_DHE_RSA_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", From 37a313efb502a4cff87cae1dffd63ede98c9d69f Mon Sep 17 00:00:00 2001 From: Salvatore LaMendola Date: Fri, 29 May 2015 12:57:23 -0400 Subject: [PATCH 24/44] Disabling support for SSLv3 protocol/ciphers and all RC4 ciphers. --- .../mail/ssl/DefaultTrustedSocketFactory.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java b/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java index 62ae2ed70..cc631eac0 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java @@ -48,7 +48,6 @@ public class DefaultTrustedSocketFactory implements TrustedSocketFactory { "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", - "SSL_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", @@ -56,14 +55,6 @@ public class DefaultTrustedSocketFactory implements TrustedSocketFactory { "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", - "TLS_ECDHE_RSA_WITH_RC4_128_SHA", - "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", - "TLS_ECDH_RSA_WITH_RC4_128_SHA", - "TLS_ECDH_ECDSA_WITH_RC4_128_SHA", - "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", - "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", - "SSL_RSA_WITH_RC4_128_SHA", - "SSL_RSA_WITH_RC4_128_MD5", }; protected static final String[] BLACKLISTED_CIPHERS = { @@ -74,10 +65,19 @@ public class DefaultTrustedSocketFactory implements TrustedSocketFactory { "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", + "SSL_RSA_WITH_3DES_EDE_CBC_SHA", + "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", + "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", + "TLS_ECDHE_RSA_WITH_RC4_128_SHA", + "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", + "TLS_ECDH_RSA_WITH_RC4_128_SHA", + "TLS_ECDH_ECDSA_WITH_RC4_128_SHA", + "SSL_RSA_WITH_RC4_128_SHA", + "SSL_RSA_WITH_RC4_128_MD5", }; protected static final String ORDERED_KNOWN_PROTOCOLS[] = { - "TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3" + "TLSv1.2", "TLSv1.1", "TLSv1" }; static { From f0962fdb6a12da0582565efd50b0e9d24bb92a0c Mon Sep 17 00:00:00 2001 From: Salvatore LaMendola Date: Mon, 1 Jun 2015 17:55:59 -0400 Subject: [PATCH 25/44] Create a protocols blacklist that should work in the same way as the ciphers one does. --- .../com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java b/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java index cc631eac0..7967d0dd3 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java @@ -80,6 +80,10 @@ public class DefaultTrustedSocketFactory implements TrustedSocketFactory { "TLSv1.2", "TLSv1.1", "TLSv1" }; + protected static final String[] BLACKLISTED_PROTOCOLS = { + "SSLv3" + }; + static { String[] enabledCiphers = null; String[] supportedProtocols = null; @@ -106,7 +110,7 @@ public class DefaultTrustedSocketFactory implements TrustedSocketFactory { reorder(enabledCiphers, ORDERED_KNOWN_CIPHERS, BLACKLISTED_CIPHERS); ENABLED_PROTOCOLS = (supportedProtocols == null) ? null : - reorder(supportedProtocols, ORDERED_KNOWN_PROTOCOLS, null); + reorder(supportedProtocols, ORDERED_KNOWN_PROTOCOLS, BLACKLISTED_PROTOCOLS); } public DefaultTrustedSocketFactory(Context context) { From 3c1c1e4e5821434375c781503cb64044fef65791 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Sat, 6 Jun 2015 12:11:20 +0100 Subject: [PATCH 26/44] Remove unneeded static modifier --- k9mail-library/src/main/java/com/fsck/k9/mail/K9MailLib.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/K9MailLib.java b/k9mail-library/src/main/java/com/fsck/k9/mail/K9MailLib.java index 38c4b10dd..393622edf 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/K9MailLib.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/K9MailLib.java @@ -55,7 +55,7 @@ public class K9MailLib { } } - public static interface DebugStatus { + public interface DebugStatus { boolean enabled(); boolean debugSensitive(); @@ -68,7 +68,7 @@ public class K9MailLib { debugStatus = status; } - private static interface WritableDebugStatus extends DebugStatus { + private interface WritableDebugStatus extends DebugStatus { void setEnabled(boolean enabled); void setSensitive(boolean sensitive); From 2d45e537394daef4a68a0c94a0287887619ba701 Mon Sep 17 00:00:00 2001 From: Art O Cathain Date: Sat, 13 Jun 2015 15:29:58 +0100 Subject: [PATCH 27/44] fix potential NPE --- .../java/com/fsck/k9/activity/Accounts.java | 67 +++++++++---------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/activity/Accounts.java b/k9mail/src/main/java/com/fsck/k9/activity/Accounts.java index ff5028a83..840689146 100644 --- a/k9mail/src/main/java/com/fsck/k9/activity/Accounts.java +++ b/k9mail/src/main/java/com/fsck/k9/activity/Accounts.java @@ -1183,41 +1183,40 @@ public class Accounts extends K9ListActivity implements OnItemClickListener { if (menuInfo != null) { mSelectedContextAccount = (BaseAccount)getListView().getItemAtPosition(menuInfo.position); } - Account realAccount = null; if (mSelectedContextAccount instanceof Account) { - realAccount = (Account)mSelectedContextAccount; - } - switch (item.getItemId()) { - case R.id.delete_account: - onDeleteAccount(realAccount); - break; - case R.id.account_settings: - onEditAccount(realAccount); - break; - case R.id.activate: - onActivateAccount(realAccount); - break; - case R.id.clear_pending: - onClearCommands(realAccount); - break; - case R.id.empty_trash: - onEmptyTrash(realAccount); - break; - case R.id.clear: - onClear(realAccount); - break; - case R.id.recreate: - onRecreate(realAccount); - break; - case R.id.export: - onExport(false, realAccount); - break; - case R.id.move_up: - onMove(realAccount, true); - break; - case R.id.move_down: - onMove(realAccount, false); - break; + Account realAccount = (Account)mSelectedContextAccount; + switch (item.getItemId()) { + case R.id.delete_account: + onDeleteAccount(realAccount); + break; + case R.id.account_settings: + onEditAccount(realAccount); + break; + case R.id.activate: + onActivateAccount(realAccount); + break; + case R.id.clear_pending: + onClearCommands(realAccount); + break; + case R.id.empty_trash: + onEmptyTrash(realAccount); + break; + case R.id.clear: + onClear(realAccount); + break; + case R.id.recreate: + onRecreate(realAccount); + break; + case R.id.export: + onExport(false, realAccount); + break; + case R.id.move_up: + onMove(realAccount, true); + break; + case R.id.move_down: + onMove(realAccount, false); + break; + } } return true; } From 591785a3aba6c22b500cca2a26267868aabe0e86 Mon Sep 17 00:00:00 2001 From: Art O Cathain Date: Sat, 13 Jun 2015 16:09:24 +0100 Subject: [PATCH 28/44] fix up some dodgy nulls --- .../k9/mail/internet/BinaryTempFileBody.java | 16 ++++++++------- .../internet/BinaryTempFileMessageBody.java | 2 +- k9mail/src/main/java/com/fsck/k9/Account.java | 2 +- .../fsck/k9/fragment/MessageListFragment.java | 20 ++++++------------- .../com/fsck/k9/helper/HtmlConverterTest.java | 13 +++++++++--- 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/BinaryTempFileBody.java b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/BinaryTempFileBody.java index 157b4046c..c14df1c5a 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/BinaryTempFileBody.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/BinaryTempFileBody.java @@ -46,24 +46,26 @@ public class BinaryTempFileBody implements RawDataBody, SizeAware { try { File newFile = File.createTempFile("body", null, mTempDirectory); - OutputStream out = new FileOutputStream(newFile); + final OutputStream out = new FileOutputStream(newFile); try { + OutputStream wrappedOut = null; if (MimeUtil.ENC_QUOTED_PRINTABLE.equals(encoding)) { - out = new QuotedPrintableOutputStream(out, false); + wrappedOut = new QuotedPrintableOutputStream(out, false); } else if (MimeUtil.ENC_BASE64.equals(encoding)) { - out = new Base64OutputStream(out); + wrappedOut = new Base64OutputStream(out); } else { throw new RuntimeException("Target encoding not supported: " + encoding); } InputStream in = getInputStream(); try { - IOUtils.copy(in, out); + IOUtils.copy(in, wrappedOut); } finally { - in.close(); + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(wrappedOut); } } finally { - out.close(); + IOUtils.closeQuietly(out); } mFile = newFile; @@ -100,7 +102,7 @@ public class BinaryTempFileBody implements RawDataBody, SizeAware { try { IOUtils.copy(in, out); } finally { - in.close(); + IOUtils.closeQuietly(in); } } diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/BinaryTempFileMessageBody.java b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/BinaryTempFileMessageBody.java index a47f2dffd..d4eb0435d 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/BinaryTempFileMessageBody.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/BinaryTempFileMessageBody.java @@ -46,7 +46,7 @@ public class BinaryTempFileMessageBody extends BinaryTempFileBody implements Com IOUtils.copy(in, out); } } finally { - in.close(); + IOUtils.closeQuietly(in); } } diff --git a/k9mail/src/main/java/com/fsck/k9/Account.java b/k9mail/src/main/java/com/fsck/k9/Account.java index 13c47c9ed..82029468b 100644 --- a/k9mail/src/main/java/com/fsck/k9/Account.java +++ b/k9mail/src/main/java/com/fsck/k9/Account.java @@ -1404,7 +1404,7 @@ public class Account implements BaseAccount, StoreConfig { if (i < identities.size()) { return identities.get(i); } - return null; + throw new IllegalArgumentException("Identity with index " + i + " not found"); } public boolean isAnIdentity(Address[] addrs) { diff --git a/k9mail/src/main/java/com/fsck/k9/fragment/MessageListFragment.java b/k9mail/src/main/java/com/fsck/k9/fragment/MessageListFragment.java index 4a5bf8f07..78c14f8db 100644 --- a/k9mail/src/main/java/com/fsck/k9/fragment/MessageListFragment.java +++ b/k9mail/src/main/java/com/fsck/k9/fragment/MessageListFragment.java @@ -1024,15 +1024,10 @@ public class MessageListFragment extends Fragment implements OnItemClickListener } private String getFolderNameById(Account account, long folderId) { - try { - Folder folder = getFolderById(account, folderId); - if (folder != null) { - return folder.getName(); - } - } catch (Exception e) { - Log.e(K9.LOG_TAG, "getFolderNameById() failed.", e); + Folder folder = getFolderById(account, folderId); + if (folder != null) { + return folder.getName(); } - return null; } @@ -1042,9 +1037,8 @@ public class MessageListFragment extends Fragment implements OnItemClickListener LocalFolder localFolder = localStore.getFolderById(folderId); localFolder.open(Folder.OPEN_MODE_RO); return localFolder; - } catch (Exception e) { - Log.e(K9.LOG_TAG, "getFolderNameById() failed.", e); - return null; + } catch (MessagingException e) { + throw new RuntimeException(e); } } @@ -3162,10 +3156,8 @@ public class MessageListFragment extends Fragment implements OnItemClickListener try { return folder.getMessage(uid); } catch (MessagingException e) { - Log.e(K9.LOG_TAG, "Something went wrong while fetching a message", e); + throw new RuntimeException(e); } - - return null; } private List getCheckedMessages() { diff --git a/k9mail/src/test/java/com/fsck/k9/helper/HtmlConverterTest.java b/k9mail/src/test/java/com/fsck/k9/helper/HtmlConverterTest.java index 9292991b5..3ea67e03d 100644 --- a/k9mail/src/test/java/com/fsck/k9/helper/HtmlConverterTest.java +++ b/k9mail/src/test/java/com/fsck/k9/helper/HtmlConverterTest.java @@ -4,7 +4,9 @@ package com.fsck.k9.helper; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; +import java.io.IOException; +import org.apache.commons.io.IOUtils; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; @@ -136,18 +138,23 @@ public class HtmlConverterTest { if (!WRITE_TO_FILE) { return; } + + FileWriter fstream = null; + try { System.err.println(content); File f = new File(OUTPUT_FILE); f.delete(); - FileWriter fstream = new FileWriter(OUTPUT_FILE); + fstream = new FileWriter(OUTPUT_FILE); BufferedWriter out = new BufferedWriter(fstream); out.write(content); out.close(); - } catch (Exception e) { - e.printStackTrace(); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + IOUtils.closeQuietly(fstream); } } From 7fc8767a5c68ee64946dba35a7db5b247c7f46e8 Mon Sep 17 00:00:00 2001 From: Art O Cathain Date: Sat, 13 Jun 2015 16:47:35 +0100 Subject: [PATCH 29/44] fix static analysis warnings and stop using nulls everywhere --- .../src/main/java/com/fsck/k9/mail/Part.java | 3 ++ .../com/fsck/k9/mail/internet/JisSupport.java | 8 ++--- .../com/fsck/k9/mail/internet/MimeHeader.java | 5 +--- .../fsck/k9/mail/store/imap/ImapStore.java | 2 +- .../com/fsck/k9/activity/MessageCompose.java | 6 ++-- .../k9/controller/MessagingController.java | 2 +- .../com/fsck/k9/mailstore/LocalFolder.java | 6 ++-- .../k9/mailstore/LocalMessageExtractor.java | 2 +- .../com/fsck/k9/provider/MessageProvider.java | 29 ++++++++++--------- 9 files changed, 32 insertions(+), 31 deletions(-) diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/Part.java b/k9mail-library/src/main/java/com/fsck/k9/mail/Part.java index d78132f21..937c3ee1e 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/Part.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/Part.java @@ -22,6 +22,9 @@ public interface Part { String getContentId(); + /** + * Returns an array of headers of the given name. The array may be empty. + */ String[] getHeader(String name) throws MessagingException; boolean isMimeType(String mimeType) throws MessagingException; diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/JisSupport.java b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/JisSupport.java index a6a30329a..fcc4086f0 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/JisSupport.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/JisSupport.java @@ -49,8 +49,8 @@ class JisSupport { private static String getJisVariantFromMailerHeaders(Message message) throws MessagingException { - String mailerHeaders[] = message.getHeader("X-Mailer"); - if (mailerHeaders == null || mailerHeaders.length == 0) + String[] mailerHeaders = message.getHeader("X-Mailer"); + if (mailerHeaders.length == 0) return null; if (mailerHeaders[0].startsWith("iPhone Mail ") || mailerHeaders[0].startsWith("iPad Mail ")) @@ -61,8 +61,8 @@ class JisSupport { private static String getJisVariantFromReceivedHeaders(Part message) throws MessagingException { - String receivedHeaders[] = message.getHeader("Received"); - if (receivedHeaders == null) + String[] receivedHeaders = message.getHeader("Received"); + if (receivedHeaders.length == 0) return null; for (String receivedHeader : receivedHeaders) { diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeHeader.java b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeHeader.java index 318ea6da0..aafd72d5d 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeHeader.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeHeader.java @@ -26,7 +26,7 @@ public class MimeHeader { public String getFirstHeader(String name) { String[] header = getHeader(name); - if (header == null) { + if (header.length == 0) { return null; } return header[0]; @@ -65,9 +65,6 @@ public class MimeHeader { values.add(field.getValue()); } } - if (values.isEmpty()) { - return null; - } return values.toArray(EMPTY_STRING_ARRAY); } diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapStore.java b/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapStore.java index e02d84d84..95137802a 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapStore.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapStore.java @@ -1937,7 +1937,7 @@ public class ImapStore extends RemoteStore { */ String[] messageIdHeader = message.getHeader("Message-ID"); - if (messageIdHeader == null || messageIdHeader.length == 0) { + if (messageIdHeader.length == 0) { if (K9MailLib.isDebug()) Log.d(LOG_TAG, "Did not get a message-id in order to search for UID for " + getLogId()); return null; diff --git a/k9mail/src/main/java/com/fsck/k9/activity/MessageCompose.java b/k9mail/src/main/java/com/fsck/k9/activity/MessageCompose.java index f541260d5..57e2fe666 100644 --- a/k9mail/src/main/java/com/fsck/k9/activity/MessageCompose.java +++ b/k9mail/src/main/java/com/fsck/k9/activity/MessageCompose.java @@ -2362,13 +2362,13 @@ public class MessageCompose extends K9Activity implements OnClickListener, // Read In-Reply-To header from draft final String[] inReplyTo = message.getHeader("In-Reply-To"); - if ((inReplyTo != null) && (inReplyTo.length >= 1)) { + if (inReplyTo.length >= 1) { mInReplyTo = inReplyTo[0]; } // Read References header from draft final String[] references = message.getHeader("References"); - if ((references != null) && (references.length >= 1)) { + if (references.length >= 1) { mReferences = references[0]; } @@ -2379,7 +2379,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, // Decode the identity header when loading a draft. // See buildIdentityHeader(TextBody) for a detailed description of the composition of this blob. Map k9identity = new HashMap(); - if (message.getHeader(K9.IDENTITY_HEADER) != null && message.getHeader(K9.IDENTITY_HEADER).length > 0 && message.getHeader(K9.IDENTITY_HEADER)[0] != null) { + if (message.getHeader(K9.IDENTITY_HEADER).length > 0 && message.getHeader(K9.IDENTITY_HEADER)[0] != null) { k9identity = IdentityHeaderParser.parse(message.getHeader(K9.IDENTITY_HEADER)[0]); } diff --git a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java index bc2f79108..952b405c0 100644 --- a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java +++ b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java @@ -3424,7 +3424,7 @@ public class MessagingController implements Runnable { try { - if (message.getHeader(K9.IDENTITY_HEADER) != null) { + if (message.getHeader(K9.IDENTITY_HEADER).length > 0) { Log.v(K9.LOG_TAG, "The user has set the Outbox and Drafts folder to the same thing. " + "This message appears to be a draft, so K-9 will not send it"); continue; diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalFolder.java b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalFolder.java index 7f8fa7bef..63172d205 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalFolder.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalFolder.java @@ -1451,7 +1451,7 @@ public class LocalFolder extends Folder implements Serializable { private String getTransferEncoding(Part part) throws MessagingException { String[] contentTransferEncoding = part.getHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING); - if (contentTransferEncoding != null && contentTransferEncoding.length > 0) { + if (contentTransferEncoding.length > 0) { return contentTransferEncoding[0].toLowerCase(Locale.US); } @@ -1812,14 +1812,14 @@ public class LocalFolder extends Folder implements Serializable { // Get the message IDs from the "References" header line String[] referencesArray = message.getHeader("References"); List messageIds = null; - if (referencesArray != null && referencesArray.length > 0) { + if (referencesArray.length > 0) { messageIds = Utility.extractMessageIds(referencesArray[0]); } // Append the first message ID from the "In-Reply-To" header line String[] inReplyToArray = message.getHeader("In-Reply-To"); String inReplyTo; - if (inReplyToArray != null && inReplyToArray.length > 0) { + if (inReplyToArray.length > 0) { inReplyTo = Utility.extractMessageId(inReplyToArray[0]); if (inReplyTo != null) { if (messageIds == null) { diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java index 2835046a4..06d64bc1f 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java @@ -560,7 +560,7 @@ public class LocalMessageExtractor { // attachments. if (contentDisposition != null && MimeUtility.getHeaderParameter(contentDisposition, null).matches("^(?i:inline)") && - part.getHeader(MimeHeader.HEADER_CONTENT_ID) != null) { + part.getHeader(MimeHeader.HEADER_CONTENT_ID).length > 0) { firstClassAttachment = false; } diff --git a/k9mail/src/main/java/com/fsck/k9/provider/MessageProvider.java b/k9mail/src/main/java/com/fsck/k9/provider/MessageProvider.java index f6fb010e8..2bb404afa 100644 --- a/k9mail/src/main/java/com/fsck/k9/provider/MessageProvider.java +++ b/k9mail/src/main/java/com/fsck/k9/provider/MessageProvider.java @@ -1017,15 +1017,10 @@ public class MessageProvider extends ContentProvider { // Note: can only delete a message - List segments = null; - int accountId = -1; - String folderName = null; - String msgUid = null; - - segments = uri.getPathSegments(); - accountId = Integer.parseInt(segments.get(1)); - folderName = segments.get(2); - msgUid = segments.get(3); + List segments = uri.getPathSegments(); + int accountId = Integer.parseInt(segments.get(1)); + String folderName = segments.get(2); + String msgUid = segments.get(3); // get account Account myAccount = null; @@ -1039,6 +1034,10 @@ public class MessageProvider extends ContentProvider { } } + if (myAccount == null) { + throw new IllegalArgumentException("Could not find account with id " + accountId); + } + // get localstore parameter LocalMessage msg = null; try { @@ -1049,14 +1048,16 @@ public class MessageProvider extends ContentProvider { } msg = lf.getMessage(msgUid); } catch (MessagingException e) { - Log.e(K9.LOG_TAG, "Unable to retrieve message", e); + throw new RuntimeException(e); + } + + if (msg == null) { + throw new IllegalArgumentException("Could not find message with id " + msgUid); } // launch command to delete the message - if ((myAccount != null) && (msg != null)) { - MessagingController controller = MessagingController.getInstance(getContext()); - controller.deleteMessages(Collections.singletonList(msg), null); - } + MessagingController controller = MessagingController.getInstance(getContext()); + controller.deleteMessages(Collections.singletonList(msg), null); // FIXME return the actual number of deleted messages return 0; From 366531bdf74e85df72ba434098a24e4e48504484 Mon Sep 17 00:00:00 2001 From: cketti Date: Wed, 17 Jun 2015 21:11:24 +0200 Subject: [PATCH 30/44] Fix code style --- .../mail/ssl/DefaultTrustedSocketFactory.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java b/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java index 7967d0dd3..c2a509dbe 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java @@ -1,16 +1,5 @@ package com.fsck.k9.mail.ssl; -import android.content.Context; -import android.text.TextUtils; -import android.util.Log; - -import com.fsck.k9.mail.MessagingException; - -import javax.net.ssl.KeyManager; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; import java.io.IOException; import java.net.Socket; @@ -20,6 +9,17 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import android.content.Context; +import android.text.TextUtils; +import android.util.Log; + +import com.fsck.k9.mail.MessagingException; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; + import static com.fsck.k9.mail.K9MailLib.LOG_TAG; @@ -27,10 +27,10 @@ import static com.fsck.k9.mail.K9MailLib.LOG_TAG; * Filter and reorder list of cipher suites and TLS versions. */ public class DefaultTrustedSocketFactory implements TrustedSocketFactory { - protected static final String ENABLED_CIPHERS[]; - protected static final String ENABLED_PROTOCOLS[]; + protected static final String[] ENABLED_CIPHERS; + protected static final String[] ENABLED_PROTOCOLS; - protected static final String ORDERED_KNOWN_CIPHERS[] = { + protected static final String[] ORDERED_KNOWN_CIPHERS = { "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", @@ -76,7 +76,7 @@ public class DefaultTrustedSocketFactory implements TrustedSocketFactory { "SSL_RSA_WITH_RC4_128_MD5", }; - protected static final String ORDERED_KNOWN_PROTOCOLS[] = { + protected static final String[] ORDERED_KNOWN_PROTOCOLS = { "TLSv1.2", "TLSv1.1", "TLSv1" }; @@ -110,7 +110,7 @@ public class DefaultTrustedSocketFactory implements TrustedSocketFactory { reorder(enabledCiphers, ORDERED_KNOWN_CIPHERS, BLACKLISTED_CIPHERS); ENABLED_PROTOCOLS = (supportedProtocols == null) ? null : - reorder(supportedProtocols, ORDERED_KNOWN_PROTOCOLS, BLACKLISTED_PROTOCOLS); + reorder(supportedProtocols, ORDERED_KNOWN_PROTOCOLS, BLACKLISTED_PROTOCOLS); } public DefaultTrustedSocketFactory(Context context) { From 05f4002a2a3a2f93e1e8542f33d2cde94a448560 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 19 Jun 2015 12:13:55 +0100 Subject: [PATCH 31/44] Build script for Debian Add a script which builds the project on Debian and produces an apk. This makes creating test builds a little easier --- tools/debian_build.sh | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100755 tools/debian_build.sh diff --git a/tools/debian_build.sh b/tools/debian_build.sh new file mode 100755 index 000000000..51b8d4457 --- /dev/null +++ b/tools/debian_build.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +# This script is intended to be used on Debian systems for building +# the project. It has been tested with Debian 8 + +USERNAME=$USER +SIGNING_NAME='k-9' + +cd .. + +PROJECT_HOME=$(pwd) + +sudo apt-get install build-essential default-jdk android-tools-adb \ + lib32stdc++6 lib32z1 lib32z1-dev gradle + +if [ ! -d ~/Android ]; then + echo -n 'Download android studio from http://developer.android.com/sdk/' + echo -n 'index.html and extract it to the the home folder, install, open' + echo -n 'the Sdk Manager and install Android 17 and Sdk tools for 19.1, ' + echo 'then press any key...' + read -n 1 -s + cd ~/Android/Sdk/tools + echo '' + echo '' + echo -n 'You need to have pretty much everything installed. ' + echo 'It will take some time.' + ./android sdk + cd $PROJECT_HOME +fi + +echo "sdk.dir=/home/$USERNAME/Android/Sdk" > local.properties + +# install Gradle (if is not installed yet) and then execute Gradle +./gradlew build + +#cd ~/develop/$PROJECT_NAME/build/outputs/apk +#keytool -genkey -v -keystore example.keystore -alias \ +# "$SIGNING_NAME" -keyalg RSA -keysize 4096 +#jarsigner -verbose -keystore example.keystore \ +# k9mail-release-unsigned.apk "$SIGNING_NAME" + +# cleaning up +cd $PROJECT_HOME/k9mail/build/outputs/apk +if [ ! -f k9mail-release-unsigned.apk ]; then + echo 'k9mail-release-unsigned.apk was not found' + exit 648 +fi +echo 'Build script ended successfully' +echo -n 'apk is available at: ' +echo "$PROJECT_HOME/k9mail/build/outputs/apk/k9mail-release-unsigned.apk" +exit 0 From 777ace34203df2dffa9572195840ff012ca4dad8 Mon Sep 17 00:00:00 2001 From: Chris Rhodes Date: Fri, 19 Jun 2015 23:02:56 +1000 Subject: [PATCH 32/44] Created README Copied from the google code page. --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..1ce8851d5 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# k-9 +K-9 is an opensource email client based on the Email application shipped with the initial release of Android. + +K-9 is focused on making it easy to chew through large volumes of email. + +You can find out more on the [wiki](https://github.com/k9mail/k-9/wiki). + +If you're interested in contributing to K-9. please drop us a line. + +[ReleaseNotes](https://github.com/k9mail/k-9/wiki/ReleaseNotes) describes changes in each version of K-9 + +[BuildingK9](https://github.com/k9mail/k-9/wiki/BuildingK9) describes how to build the project + +Developers: Join us on IRC on #k-9 on irc.freenode.net + +We're on [Google+](https://plus.google.com/114221735215588688400) + +Download K-9 from [Google Play](https://play.google.com/store/apps/details?id=com.fsck.k9): + +![QR Code](http://chart.apis.google.com/chart?cht=qr&chs=100x100&chl=market%3A//details%3Fid%3Dcom.fsck.k9&force-image.png) From d16d95d8401ecda49f91e1e978cf77bd52aedfa1 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 21 Jun 2015 18:21:48 +0100 Subject: [PATCH 33/44] Use standalone sdk This makes the build script a bit more independent from Debian specifically --- tools/debian_build.sh | 61 +++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/tools/debian_build.sh b/tools/debian_build.sh index 51b8d4457..1dd565785 100755 --- a/tools/debian_build.sh +++ b/tools/debian_build.sh @@ -5,33 +5,50 @@ USERNAME=$USER SIGNING_NAME='k-9' +SDK_VERSION='r24.3.3' +SDK_DIR=$HOME/android-sdk cd .. PROJECT_HOME=$(pwd) -sudo apt-get install build-essential default-jdk android-tools-adb \ - lib32stdc++6 lib32z1 lib32z1-dev gradle +sudo apt-get install build-essential default-jdk \ + lib32stdc++6 lib32z1 lib32z1-dev -if [ ! -d ~/Android ]; then - echo -n 'Download android studio from http://developer.android.com/sdk/' - echo -n 'index.html and extract it to the the home folder, install, open' - echo -n 'the Sdk Manager and install Android 17 and Sdk tools for 19.1, ' - echo 'then press any key...' - read -n 1 -s - cd ~/Android/Sdk/tools - echo '' - echo '' - echo -n 'You need to have pretty much everything installed. ' - echo 'It will take some time.' - ./android sdk - cd $PROJECT_HOME +if [ ! -d $SDK_DIR ]; then + mkdir -p $SDK_DIR fi +cd $SDK_DIR -echo "sdk.dir=/home/$USERNAME/Android/Sdk" > local.properties +# download the SDK +if [ ! -f $SDK_DIR/android-sdk_$SDK_VERSION-linux.tgz ]; then + wget http://dl.google.com/android/android-sdk_$SDK_VERSION-linux.tgz + tar -xzvf android-sdk_$SDK_VERSION-linux.tgz +fi +SDK_DIR=$SDK_DIR/android-sdk-linux -# install Gradle (if is not installed yet) and then execute Gradle -./gradlew build +echo 'Check that you have the SDK tools installed for Android 17, SDK 19.1' +if [ ! -f $SDK_DIR/tools/android ]; then + echo "$SDK_DIR/tools/android not found" + exit -1 +fi +cd $SDK_DIR +chmod -R 0755 $SDK_DIR +chmod a+rx $SDK_DIR/tools + +ANDROID_HOME=$SDK_DIR +echo "sdk.dir=$SDK_DIR" > $ANDROID_HOME/local.properties +PATH=${PATH}:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools + +android sdk +cd $PROJECT_HOME + + +if [ ! -f $SDK_DIR/tools/templates/gradle/wrapper/gradlew ]; then + echo "$SDK_DIR/tools/templates/gradle/wrapper/gradlew not found" + exit -2 +fi +. $SDK_DIR/tools/templates/gradle/wrapper/gradlew build #cd ~/develop/$PROJECT_NAME/build/outputs/apk #keytool -genkey -v -keystore example.keystore -alias \ @@ -41,11 +58,11 @@ echo "sdk.dir=/home/$USERNAME/Android/Sdk" > local.properties # cleaning up cd $PROJECT_HOME/k9mail/build/outputs/apk -if [ ! -f k9mail-release-unsigned.apk ]; then - echo 'k9mail-release-unsigned.apk was not found' - exit 648 +if [ ! -f k9mail-debug.apk ]; then + echo 'k9mail-debug.apk was not found' + exit -3 fi echo 'Build script ended successfully' echo -n 'apk is available at: ' -echo "$PROJECT_HOME/k9mail/build/outputs/apk/k9mail-release-unsigned.apk" +echo "$PROJECT_HOME/k9mail/build/outputs/apk/k9mail-debug.apk" exit 0 From 9d44f0e06232661259681d64002dd53c7c43099d Mon Sep 17 00:00:00 2001 From: cketti Date: Mon, 22 Jun 2015 00:37:48 +0200 Subject: [PATCH 34/44] Improve send failure handling We now no longer parse the exception message in MessagingController to find out if it was a permanent SMTP failure. Overall the code is still a mess, but the error handling should be a little bit better and more readable now. --- .../fsck/k9/mail/transport/SmtpTransport.java | 27 +++---- .../k9/controller/MessagingController.java | 72 +++++++++++++------ 2 files changed, 63 insertions(+), 36 deletions(-) diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/transport/SmtpTransport.java b/k9mail-library/src/main/java/com/fsck/k9/mail/transport/SmtpTransport.java index c6292a569..1e2ccec6a 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/transport/SmtpTransport.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/transport/SmtpTransport.java @@ -491,7 +491,6 @@ public class SmtpTransport extends Transport { private void sendMessageTo(List addresses, Message message) throws MessagingException { - boolean possibleSend = false; close(); open(); @@ -503,13 +502,11 @@ public class SmtpTransport extends Transport { // the size of messages, count the message's size before sending it if (mLargestAcceptableMessage > 0 && message.hasAttachments()) { if (message.calculateSize() > mLargestAcceptableMessage) { - MessagingException me = new MessagingException("Message too large for server"); - //TODO this looks rather suspicious... shouldn't it be true? - me.setPermanentFailure(possibleSend); - throw me; + throw new MessagingException("Message too large for server", true); } } + boolean entireMessageSent = false; Address[] from = message.getFrom(); try { executeSimpleCommand("MAIL FROM:" + "<" + from[0].getAddress() + ">" @@ -527,20 +524,14 @@ public class SmtpTransport extends Transport { // We use BufferedOutputStream. So make sure to call flush() ! msgOut.flush(); - possibleSend = true; // After the "\r\n." is attempted, we may have sent the message + entireMessageSent = true; // After the "\r\n." is attempted, we may have sent the message executeSimpleCommand("\r\n."); + } catch (NegativeSmtpReplyException e) { + throw e; } catch (Exception e) { MessagingException me = new MessagingException("Unable to send message", e); + me.setPermanentFailure(entireMessageSent); - // "5xx text" -responses are permanent failures - String msg = e.getMessage(); - if (msg != null && msg.startsWith("5")) { - Log.w(LOG_TAG, "handling 5xx SMTP error code as a permanent failure"); - possibleSend = false; - } - - //TODO this looks rather suspicious... why is possibleSend used, and why are 5xx NOT permanent (in contrast to the log text) - me.setPermanentFailure(possibleSend); throw me; } finally { close(); @@ -775,11 +766,15 @@ public class SmtpTransport extends Transport { private final String mReplyText; public NegativeSmtpReplyException(int replyCode, String replyText) { - super("Negative SMTP reply: " + replyCode + " " + replyText); + super("Negative SMTP reply: " + replyCode + " " + replyText, isPermanentSmtpError(replyCode)); mReplyCode = replyCode; mReplyText = replyText; } + private static boolean isPermanentSmtpError(int replyCode) { + return replyCode >= 500 && replyCode <= 599; + } + public int getReplyCode() { return mReplyCode; } diff --git a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java index bc2f79108..8aa648861 100644 --- a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java +++ b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java @@ -3367,6 +3367,7 @@ public class MessagingController implements Runnable { public void sendPendingMessagesSynchronous(final Account account) { Folder localFolder = null; Exception lastFailure = null; + boolean wasPermanentFailure = false; try { Store localStore = account.getLocalStore(); localFolder = localStore.getFolder( @@ -3463,38 +3464,40 @@ public class MessagingController implements Runnable { processPendingCommands(account); } - } catch (Exception e) { - // 5.x.x errors from the SMTP server are "PERMFAIL" - // move the message over to drafts rather than leaving it in the outbox - // This is a complete hack, but is worlds better than the previous - // "don't even bother" functionality - if (getRootCauseMessage(e).startsWith("5")) { - localFolder.moveMessages(Collections.singletonList(message), (LocalFolder) localStore.getFolder(account.getDraftsFolderName())); - } + } catch (CertificateValidationException e) { + lastFailure = e; + wasPermanentFailure = false; notifyUserIfCertificateProblem(context, e, account, false); - addErrorMessage(account, "Failed to send message", e); - message.setFlag(Flag.X_SEND_FAILED, true); - Log.e(K9.LOG_TAG, "Failed to send message", e); - for (MessagingListener l : getListeners()) { - l.synchronizeMailboxFailed(account, localFolder.getName(), getRootCauseMessage(e)); - } + handleSendFailure(account, localStore, localFolder, message, e, wasPermanentFailure); + } catch (MessagingException e) { lastFailure = e; + wasPermanentFailure = e.isPermanentFailure(); + + handleSendFailure(account, localStore, localFolder, message, e, wasPermanentFailure); + } catch (Exception e) { + lastFailure = e; + wasPermanentFailure = true; + + handleSendFailure(account, localStore, localFolder, message, e, wasPermanentFailure); } } catch (Exception e) { - Log.e(K9.LOG_TAG, "Failed to fetch message for sending", e); - for (MessagingListener l : getListeners()) { - l.synchronizeMailboxFailed(account, localFolder.getName(), getRootCauseMessage(e)); - } - addErrorMessage(account, "Failed to fetch message for sending", e); lastFailure = e; + wasPermanentFailure = false; + + Log.e(K9.LOG_TAG, "Failed to fetch message for sending", e); + + addErrorMessage(account, "Failed to fetch message for sending", e); + notifySynchronizeMailboxFailed(account, localFolder, e); } } + for (MessagingListener l : getListeners()) { l.sendPendingMessagesCompleted(account); } + if (lastFailure != null) { - if (getRootCauseMessage(lastFailure).startsWith("5")) { + if (wasPermanentFailure) { notifySendPermFailed(account, lastFailure); } else { notifySendTempFailed(account, lastFailure); @@ -3517,6 +3520,35 @@ public class MessagingController implements Runnable { } } + private void handleSendFailure(Account account, Store localStore, Folder localFolder, Message message, + Exception exception, boolean permanentFailure) throws MessagingException { + + Log.e(K9.LOG_TAG, "Failed to send message", exception); + + if (permanentFailure) { + moveMessageToDraftsFolder(account, localFolder, localStore, message); + } + + addErrorMessage(account, "Failed to send message", exception); + message.setFlag(Flag.X_SEND_FAILED, true); + + notifySynchronizeMailboxFailed(account, localFolder, exception); + } + + private void moveMessageToDraftsFolder(Account account, Folder localFolder, Store localStore, Message message) + throws MessagingException { + LocalFolder draftsFolder = (LocalFolder) localStore.getFolder(account.getDraftsFolderName()); + localFolder.moveMessages(Collections.singletonList(message), draftsFolder); + } + + private void notifySynchronizeMailboxFailed(Account account, Folder localFolder, Exception exception) { + String folderName = localFolder.getName(); + String errorMessage = getRootCauseMessage(exception); + for (MessagingListener listener : getListeners()) { + listener.synchronizeMailboxFailed(account, folderName, errorMessage); + } + } + public void getAccountStats(final Context context, final Account account, final MessagingListener listener) { From 17a2309bb99843cbf08f95780061a06acf11b379 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 24 Jun 2015 09:08:40 +0100 Subject: [PATCH 35/44] Use https to download SDK --- tools/debian_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/debian_build.sh b/tools/debian_build.sh index 1dd565785..65dbd0dbc 100755 --- a/tools/debian_build.sh +++ b/tools/debian_build.sh @@ -22,7 +22,7 @@ cd $SDK_DIR # download the SDK if [ ! -f $SDK_DIR/android-sdk_$SDK_VERSION-linux.tgz ]; then - wget http://dl.google.com/android/android-sdk_$SDK_VERSION-linux.tgz + wget https://dl.google.com/android/android-sdk_$SDK_VERSION-linux.tgz tar -xzvf android-sdk_$SDK_VERSION-linux.tgz fi SDK_DIR=$SDK_DIR/android-sdk-linux From d301d632745065760037c79d8d131ac13cd44768 Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 25 Jun 2015 22:47:17 +0200 Subject: [PATCH 36/44] Add support for saving message/rfc822 parts Fixes #603 --- .../main/java/com/fsck/k9/mailstore/LocalFolder.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalFolder.java b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalFolder.java index 7f8fa7bef..e01c4d93c 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalFolder.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalFolder.java @@ -1311,6 +1311,8 @@ public class LocalFolder extends Folder implements Serializable { multipartToContentValues(cv, (Multipart) body); } else if (body == null) { missingPartToContentValues(cv, part); + } else if (body instanceof Message) { + messageMarkerToContentValues(cv); } else { file = leafPartToContentValues(cv, part, body); } @@ -1344,6 +1346,10 @@ public class LocalFolder extends Folder implements Serializable { cv.put("decoded_body_size", attachment.size); } + private void messageMarkerToContentValues(ContentValues cv) throws MessagingException { + cv.put("data_location", DataLocation.CHILD_PART_CONTAINS_DATA); + } + private File leafPartToContentValues(ContentValues cv, Part part, Body body) throws MessagingException, IOException { AttachmentViewInfo attachment = LocalMessageExtractor.extractAttachmentInfo(part); @@ -1466,6 +1472,9 @@ public class LocalFolder extends Folder implements Serializable { BodyPart childPart = multipart.getBodyPart(i); stack.push(new PartContainer(parentMessageId, childPart)); } + } else if (body instanceof Message) { + Message innerMessage = (Message) body; + stack.push(new PartContainer(parentMessageId, innerMessage)); } } @@ -1994,5 +2003,6 @@ public class LocalFolder extends Folder implements Serializable { static final int MISSING = 0; static final int IN_DATABASE = 1; static final int ON_DISK = 2; + static final int CHILD_PART_CONTAINS_DATA = 3; } } From 07c12e83d0dd7b1d8d9d84273878adf66d366383 Mon Sep 17 00:00:00 2001 From: Sander Baas Date: Wed, 27 May 2015 16:18:27 +0200 Subject: [PATCH 37/44] Add option to disable notifications in quiet time Fixes #661 --- k9mail/src/main/java/com/fsck/k9/K9.java | 11 +++++++++++ .../main/java/com/fsck/k9/activity/setup/Prefs.java | 5 +++++ .../com/fsck/k9/controller/MessagingController.java | 5 +++++ k9mail/src/main/res/values/strings.xml | 2 ++ k9mail/src/main/res/xml/global_preferences.xml | 7 +++++++ 5 files changed, 30 insertions(+) diff --git a/k9mail/src/main/java/com/fsck/k9/K9.java b/k9mail/src/main/java/com/fsck/k9/K9.java index 87fa1237d..b246c9675 100644 --- a/k9mail/src/main/java/com/fsck/k9/K9.java +++ b/k9mail/src/main/java/com/fsck/k9/K9.java @@ -237,6 +237,7 @@ public class K9 extends Application { private static boolean mHideSpecialAccounts = false; private static boolean mAutofitWidth; private static boolean mQuietTimeEnabled = false; + private static boolean mQuietTimeNotificationEnabled = false; private static String mQuietTimeStarts = null; private static String mQuietTimeEnds = null; private static String mAttachmentDefaultPath = ""; @@ -474,6 +475,7 @@ public class K9 extends Application { editor.putBoolean("useVolumeKeysForListNavigation", mUseVolumeKeysForListNavigation); editor.putBoolean("autofitWidth", mAutofitWidth); editor.putBoolean("quietTimeEnabled", mQuietTimeEnabled); + editor.putBoolean("quietTimeNotificationEnabled", mQuietTimeNotificationEnabled); editor.putString("quietTimeStarts", mQuietTimeStarts); editor.putString("quietTimeEnds", mQuietTimeEnds); @@ -708,6 +710,7 @@ public class K9 extends Application { mAutofitWidth = sprefs.getBoolean("autofitWidth", true); mQuietTimeEnabled = sprefs.getBoolean("quietTimeEnabled", false); + mQuietTimeNotificationEnabled = sprefs.getBoolean("quietTimeNotificationEnabled", false); mQuietTimeStarts = sprefs.getString("quietTimeStarts", "21:00"); mQuietTimeEnds = sprefs.getString("quietTimeEnds", "7:00"); @@ -970,6 +973,14 @@ public class K9 extends Application { mQuietTimeEnabled = quietTimeEnabled; } + public static boolean getQuietTimeNotificationEnabled() { + return mQuietTimeNotificationEnabled; + } + + public static void setQuietTimeNotificationEnabled(boolean quietTimeNotificationEnabled) { + mQuietTimeNotificationEnabled = quietTimeNotificationEnabled; + } + public static String getQuietTimeStarts() { return mQuietTimeStarts; } diff --git a/k9mail/src/main/java/com/fsck/k9/activity/setup/Prefs.java b/k9mail/src/main/java/com/fsck/k9/activity/setup/Prefs.java index 96d34846d..acd8d0a34 100644 --- a/k9mail/src/main/java/com/fsck/k9/activity/setup/Prefs.java +++ b/k9mail/src/main/java/com/fsck/k9/activity/setup/Prefs.java @@ -79,6 +79,7 @@ public class Prefs extends K9PreferenceActivity { private static final String PREFERENCE_MESSAGEVIEW_RETURN_TO_LIST = "messageview_return_to_list"; private static final String PREFERENCE_MESSAGEVIEW_SHOW_NEXT = "messageview_show_next"; private static final String PREFERENCE_QUIET_TIME_ENABLED = "quiet_time_enabled"; + private static final String PREFERENCE_QUIET_TIME_NOTIFICATION_ENABLED = "quiet_time_notification_enabled"; private static final String PREFERENCE_QUIET_TIME_STARTS = "quiet_time_starts"; private static final String PREFERENCE_QUIET_TIME_ENDS = "quiet_time_ends"; private static final String PREFERENCE_NOTIF_QUICK_DELETE = "notification_quick_delete"; @@ -142,6 +143,7 @@ public class Prefs extends K9PreferenceActivity { private CheckBoxListPreference mVisibleRefileActions; private CheckBoxPreference mQuietTimeEnabled; + private CheckBoxPreference mQuietTimeNotificationEnabled; private com.fsck.k9.preferences.TimePickerPreference mQuietTimeStarts; private com.fsck.k9.preferences.TimePickerPreference mQuietTimeEnds; private ListPreference mNotificationQuickDelete; @@ -309,6 +311,8 @@ public class Prefs extends K9PreferenceActivity { mQuietTimeEnabled = (CheckBoxPreference) findPreference(PREFERENCE_QUIET_TIME_ENABLED); mQuietTimeEnabled.setChecked(K9.getQuietTimeEnabled()); + mQuietTimeNotificationEnabled = (CheckBoxPreference) findPreference(PREFERENCE_QUIET_TIME_NOTIFICATION_ENABLED); + mQuietTimeNotificationEnabled.setChecked(K9.getQuietTimeNotificationEnabled()); mQuietTimeStarts = (TimePickerPreference) findPreference(PREFERENCE_QUIET_TIME_STARTS); mQuietTimeStarts.setDefaultValue(K9.getQuietTimeStarts()); mQuietTimeStarts.setSummary(K9.getQuietTimeStarts()); @@ -485,6 +489,7 @@ public class Prefs extends K9PreferenceActivity { K9.setMessageViewCopyActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_COPY]); K9.setMessageViewSpamActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_SPAM]); + K9.setQuietTimeNotificationEnabled(mQuietTimeNotificationEnabled.isChecked()); K9.setQuietTimeStarts(mQuietTimeStarts.getTime()); K9.setQuietTimeEnds(mQuietTimeEnds.getTime()); K9.setWrapFolderNames(mWrapFolderNames.isChecked()); diff --git a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java index bc2f79108..94bf7fe55 100644 --- a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java +++ b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java @@ -4685,6 +4685,11 @@ public class MessagingController implements Runnable { */ private void notifyAccount(Context context, Account account, LocalMessage message, int previousUnreadMessageCount) { + // if it's quiet time and notifications are disabled, then we shouldn't show a notification + if (K9.isQuietTime() && K9.getQuietTimeNotificationEnabled()) { + return; + } + final NotificationData data = getNotificationData(account, previousUnreadMessageCount); synchronized (data) { notifyAccountWithDataLocked(context, account, message, data); diff --git a/k9mail/src/main/res/values/strings.xml b/k9mail/src/main/res/values/strings.xml index 988750b5f..873f37b06 100644 --- a/k9mail/src/main/res/values/strings.xml +++ b/k9mail/src/main/res/values/strings.xml @@ -353,6 +353,8 @@ Please submit bug reports, contribute new features and ask questions at Quiet Time Disable ringing, buzzing and flashing at night + Quiet Time notifications + Disable notifications during quiet time Quiet Time starts Quiet Time ends diff --git a/k9mail/src/main/res/xml/global_preferences.xml b/k9mail/src/main/res/xml/global_preferences.xml index 70f23b192..77c18cc10 100644 --- a/k9mail/src/main/res/xml/global_preferences.xml +++ b/k9mail/src/main/res/xml/global_preferences.xml @@ -303,6 +303,13 @@ android:title="@string/quiet_time" android:summary="@string/quiet_time_description" /> + Date: Sun, 28 Jun 2015 05:08:31 +0200 Subject: [PATCH 38/44] Change naming/wording --- k9mail/src/main/java/com/fsck/k9/K9.java | 14 +++++++------- .../java/com/fsck/k9/activity/setup/Prefs.java | 12 +++++++----- .../fsck/k9/controller/MessagingController.java | 6 ++---- k9mail/src/main/res/values/strings.xml | 4 ++-- k9mail/src/main/res/xml/global_preferences.xml | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/K9.java b/k9mail/src/main/java/com/fsck/k9/K9.java index b246c9675..fedce1adb 100644 --- a/k9mail/src/main/java/com/fsck/k9/K9.java +++ b/k9mail/src/main/java/com/fsck/k9/K9.java @@ -237,7 +237,7 @@ public class K9 extends Application { private static boolean mHideSpecialAccounts = false; private static boolean mAutofitWidth; private static boolean mQuietTimeEnabled = false; - private static boolean mQuietTimeNotificationEnabled = false; + private static boolean mNotificationDuringQuietTimeEnabled = true; private static String mQuietTimeStarts = null; private static String mQuietTimeEnds = null; private static String mAttachmentDefaultPath = ""; @@ -475,7 +475,7 @@ public class K9 extends Application { editor.putBoolean("useVolumeKeysForListNavigation", mUseVolumeKeysForListNavigation); editor.putBoolean("autofitWidth", mAutofitWidth); editor.putBoolean("quietTimeEnabled", mQuietTimeEnabled); - editor.putBoolean("quietTimeNotificationEnabled", mQuietTimeNotificationEnabled); + editor.putBoolean("notificationDuringQuietTimeEnabled", mNotificationDuringQuietTimeEnabled); editor.putString("quietTimeStarts", mQuietTimeStarts); editor.putString("quietTimeEnds", mQuietTimeEnds); @@ -710,7 +710,7 @@ public class K9 extends Application { mAutofitWidth = sprefs.getBoolean("autofitWidth", true); mQuietTimeEnabled = sprefs.getBoolean("quietTimeEnabled", false); - mQuietTimeNotificationEnabled = sprefs.getBoolean("quietTimeNotificationEnabled", false); + mNotificationDuringQuietTimeEnabled = sprefs.getBoolean("notificationDuringQuietTimeEnabled", true); mQuietTimeStarts = sprefs.getString("quietTimeStarts", "21:00"); mQuietTimeEnds = sprefs.getString("quietTimeEnds", "7:00"); @@ -973,12 +973,12 @@ public class K9 extends Application { mQuietTimeEnabled = quietTimeEnabled; } - public static boolean getQuietTimeNotificationEnabled() { - return mQuietTimeNotificationEnabled; + public static boolean isNotificationDuringQuietTimeEnabled() { + return mNotificationDuringQuietTimeEnabled; } - public static void setQuietTimeNotificationEnabled(boolean quietTimeNotificationEnabled) { - mQuietTimeNotificationEnabled = quietTimeNotificationEnabled; + public static void setNotificationDuringQuietTimeEnabled(boolean notificationDuringQuietTimeEnabled) { + mNotificationDuringQuietTimeEnabled = notificationDuringQuietTimeEnabled; } public static String getQuietTimeStarts() { diff --git a/k9mail/src/main/java/com/fsck/k9/activity/setup/Prefs.java b/k9mail/src/main/java/com/fsck/k9/activity/setup/Prefs.java index acd8d0a34..c4482e9cf 100644 --- a/k9mail/src/main/java/com/fsck/k9/activity/setup/Prefs.java +++ b/k9mail/src/main/java/com/fsck/k9/activity/setup/Prefs.java @@ -79,7 +79,8 @@ public class Prefs extends K9PreferenceActivity { private static final String PREFERENCE_MESSAGEVIEW_RETURN_TO_LIST = "messageview_return_to_list"; private static final String PREFERENCE_MESSAGEVIEW_SHOW_NEXT = "messageview_show_next"; private static final String PREFERENCE_QUIET_TIME_ENABLED = "quiet_time_enabled"; - private static final String PREFERENCE_QUIET_TIME_NOTIFICATION_ENABLED = "quiet_time_notification_enabled"; + private static final String PREFERENCE_DISABLE_NOTIFICATION_DURING_QUIET_TIME = + "disable_notifications_during_quiet_time"; private static final String PREFERENCE_QUIET_TIME_STARTS = "quiet_time_starts"; private static final String PREFERENCE_QUIET_TIME_ENDS = "quiet_time_ends"; private static final String PREFERENCE_NOTIF_QUICK_DELETE = "notification_quick_delete"; @@ -143,7 +144,7 @@ public class Prefs extends K9PreferenceActivity { private CheckBoxListPreference mVisibleRefileActions; private CheckBoxPreference mQuietTimeEnabled; - private CheckBoxPreference mQuietTimeNotificationEnabled; + private CheckBoxPreference mDisableNotificationDuringQuietTime; private com.fsck.k9.preferences.TimePickerPreference mQuietTimeStarts; private com.fsck.k9.preferences.TimePickerPreference mQuietTimeEnds; private ListPreference mNotificationQuickDelete; @@ -311,8 +312,9 @@ public class Prefs extends K9PreferenceActivity { mQuietTimeEnabled = (CheckBoxPreference) findPreference(PREFERENCE_QUIET_TIME_ENABLED); mQuietTimeEnabled.setChecked(K9.getQuietTimeEnabled()); - mQuietTimeNotificationEnabled = (CheckBoxPreference) findPreference(PREFERENCE_QUIET_TIME_NOTIFICATION_ENABLED); - mQuietTimeNotificationEnabled.setChecked(K9.getQuietTimeNotificationEnabled()); + mDisableNotificationDuringQuietTime = (CheckBoxPreference) findPreference( + PREFERENCE_DISABLE_NOTIFICATION_DURING_QUIET_TIME); + mDisableNotificationDuringQuietTime.setChecked(!K9.isNotificationDuringQuietTimeEnabled()); mQuietTimeStarts = (TimePickerPreference) findPreference(PREFERENCE_QUIET_TIME_STARTS); mQuietTimeStarts.setDefaultValue(K9.getQuietTimeStarts()); mQuietTimeStarts.setSummary(K9.getQuietTimeStarts()); @@ -489,7 +491,7 @@ public class Prefs extends K9PreferenceActivity { K9.setMessageViewCopyActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_COPY]); K9.setMessageViewSpamActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_SPAM]); - K9.setQuietTimeNotificationEnabled(mQuietTimeNotificationEnabled.isChecked()); + K9.setNotificationDuringQuietTimeEnabled(!mDisableNotificationDuringQuietTime.isChecked()); K9.setQuietTimeStarts(mQuietTimeStarts.getTime()); K9.setQuietTimeEnds(mQuietTimeEnds.getTime()); K9.setWrapFolderNames(mWrapFolderNames.isChecked()); diff --git a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java index 94bf7fe55..ba3e77ede 100644 --- a/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java +++ b/k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java @@ -4683,10 +4683,8 @@ public class MessagingController implements Runnable { /** * Creates a notification of a newly received message. */ - private void notifyAccount(Context context, Account account, - LocalMessage message, int previousUnreadMessageCount) { - // if it's quiet time and notifications are disabled, then we shouldn't show a notification - if (K9.isQuietTime() && K9.getQuietTimeNotificationEnabled()) { + private void notifyAccount(Context context, Account account, LocalMessage message, int previousUnreadMessageCount) { + if (K9.isQuietTime() && !K9.isNotificationDuringQuietTimeEnabled()) { return; } diff --git a/k9mail/src/main/res/values/strings.xml b/k9mail/src/main/res/values/strings.xml index 873f37b06..22a7ddc17 100644 --- a/k9mail/src/main/res/values/strings.xml +++ b/k9mail/src/main/res/values/strings.xml @@ -353,8 +353,8 @@ Please submit bug reports, contribute new features and ask questions at Quiet Time Disable ringing, buzzing and flashing at night - Quiet Time notifications - Disable notifications during quiet time + Disable notifications + Completely disable notifications during Quiet Time Quiet Time starts Quiet Time ends diff --git a/k9mail/src/main/res/xml/global_preferences.xml b/k9mail/src/main/res/xml/global_preferences.xml index 77c18cc10..9ce88ffca 100644 --- a/k9mail/src/main/res/xml/global_preferences.xml +++ b/k9mail/src/main/res/xml/global_preferences.xml @@ -304,7 +304,7 @@ android:summary="@string/quiet_time_description" /> Date: Sun, 28 Jun 2015 05:24:30 +0200 Subject: [PATCH 39/44] Add 'notificationDuringQuietTimeEnabled' to settings import/export --- .../src/main/java/com/fsck/k9/preferences/GlobalSettings.java | 3 +++ k9mail/src/main/java/com/fsck/k9/preferences/Settings.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/k9mail/src/main/java/com/fsck/k9/preferences/GlobalSettings.java b/k9mail/src/main/java/com/fsck/k9/preferences/GlobalSettings.java index be3de86d9..6ac2ac684 100644 --- a/k9mail/src/main/java/com/fsck/k9/preferences/GlobalSettings.java +++ b/k9mail/src/main/java/com/fsck/k9/preferences/GlobalSettings.java @@ -266,6 +266,9 @@ public class GlobalSettings { new V(38, new EnumSetting(NotificationQuickDelete.class, NotificationQuickDelete.NEVER)) )); + s.put("notificationDuringQuietTimeEnabled", Settings.versions( + new V(39, new BooleanSetting(true)) + )); SETTINGS = Collections.unmodifiableMap(s); diff --git a/k9mail/src/main/java/com/fsck/k9/preferences/Settings.java b/k9mail/src/main/java/com/fsck/k9/preferences/Settings.java index 9c466dcf0..b9c55a7f3 100644 --- a/k9mail/src/main/java/com/fsck/k9/preferences/Settings.java +++ b/k9mail/src/main/java/com/fsck/k9/preferences/Settings.java @@ -35,7 +35,7 @@ public class Settings { * * @see SettingsExporter */ - public static final int VERSION = 38; + public static final int VERSION = 39; public static Map validate(int version, Map> settings, From 67d2db7c853527bbaab552a993d0ee702bc68fc7 Mon Sep 17 00:00:00 2001 From: cketti Date: Sun, 28 Jun 2015 07:27:06 +0200 Subject: [PATCH 40/44] Update README --- README.md | 85 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 1ce8851d5..c36d9c188 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,83 @@ -# k-9 -K-9 is an opensource email client based on the Email application shipped with the initial release of Android. +# K-9 Mail +[![Build Status](https://k9mail.ci.cloudbees.com/job/master/badge/icon)](https://k9mail.ci.cloudbees.com/job/master/) +[![Join the chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/k9mail/k-9) -K-9 is focused on making it easy to chew through large volumes of email. +K-9 Mail is an open-source email client for Android. -You can find out more on the [wiki](https://github.com/k9mail/k-9/wiki). -If you're interested in contributing to K-9. please drop us a line. +## Download -[ReleaseNotes](https://github.com/k9mail/k-9/wiki/ReleaseNotes) describes changes in each version of K-9 +K-9 Mail can be downloaded from a couple of sources: -[BuildingK9](https://github.com/k9mail/k-9/wiki/BuildingK9) describes how to build the project +- [Google Play](https://play.google.com/store/apps/details?id=com.fsck.k9) +- [F-Droid](https://f-droid.org/repository/browse/?fdid=com.fsck.k9) +- [Github Releases](https://github.com/k9mail/k-9/releases) +- [Amazon Appstore for Android](http://www.amazon.com/dp/B004JK61K0) -Developers: Join us on IRC on #k-9 on irc.freenode.net +You might also be interested in becoming a [beta tester](https://github.com/k9mail/k-9/wiki/BetaTester) +or an [alpha tester](https://github.com/k9mail/k-9/wiki/AlphaTester) to get an early look at new versions. -We're on [Google+](https://plus.google.com/114221735215588688400) -Download K-9 from [Google Play](https://play.google.com/store/apps/details?id=com.fsck.k9): +## Release Notes + +Check out the [Release Notes](https://github.com/k9mail/k-9/wiki/ReleaseNotes) to find out what changed +in each version of K-9 Mail. + + +## Need Help? + +If the app is not behaving like it should, you might find these resources helpful: + +- [User Manual](https://github.com/k9mail/k-9/wiki/Manual) +- [Frequently Asked Questions](https://github.com/k9mail/k-9/wiki/FrequentlyAskedQuestions) +- [Support Forum/Mailing List](http://groups.google.com/group/k-9-mail) +- [Google+ Community](https://plus.google.com/communities/109228641058741937099) + + +## Translations + +Interested in helping to translate K-9 Mail? Contribute here: + +https://www.transifex.com/projects/p/k9mail/ + + +## Contributing + +Please fork this repository and contribute back using [pull requests](https://github.com/k9mail/k-9/pulls). + +Any contributions, large or small, major features, bug fixes, unit/integration tests are welcomed and appreciated +but will be thoroughly reviewed and discussed. +Please make sure you read the [Code Style Guidelines](https://github.com/k9mail/k-9/wiki/CodeStyle). + + +## Communication + +Aside from discussing changes in [pull requests](https://github.com/k9mail/k-9/pulls) and +[issues](https://github.com/k9mail/k-9/issues) we use the following communication services: + +- IRC chat, [#k-9 on the Freenode network](http://webchat.freenode.net/?channels=%23k-9) +- [Gitter](https://gitter.im/k9mail/k-9) +- [Developer mailing list](https://groups.google.com/forum/#!forum/k-9-dev) + + +## License + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +## Sponsors + +CloudBees' [FOSS program](https://www.cloudbees.com/resources/foss) allows us to use their DEV@cloud service for free. + +![built on DEV@cloud](https://www.cloudbees.com/sites/default/files/styles/large/public/Button-Built-on-CB-1.png) -![QR Code](http://chart.apis.google.com/chart?cht=qr&chs=100x100&chl=market%3A//details%3Fid%3Dcom.fsck.k9&force-image.png) From 32cc97207c80214c34a4945317ce234840fafc3e Mon Sep 17 00:00:00 2001 From: Art O Cathain Date: Wed, 1 Jul 2015 16:57:13 +0100 Subject: [PATCH 41/44] do not throw exception in MessagingController per review comment --- .../java/com/fsck/k9/provider/MessageProvider.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/provider/MessageProvider.java b/k9mail/src/main/java/com/fsck/k9/provider/MessageProvider.java index 2bb404afa..14f483ff8 100644 --- a/k9mail/src/main/java/com/fsck/k9/provider/MessageProvider.java +++ b/k9mail/src/main/java/com/fsck/k9/provider/MessageProvider.java @@ -1035,7 +1035,7 @@ public class MessageProvider extends ContentProvider { } if (myAccount == null) { - throw new IllegalArgumentException("Could not find account with id " + accountId); + Log.e(K9.LOG_TAG, "Could not find account with id " + accountId); } // get localstore parameter @@ -1048,16 +1048,14 @@ public class MessageProvider extends ContentProvider { } msg = lf.getMessage(msgUid); } catch (MessagingException e) { - throw new RuntimeException(e); - } - - if (msg == null) { - throw new IllegalArgumentException("Could not find message with id " + msgUid); + Log.e(K9.LOG_TAG, "Unable to retrieve message", e); } // launch command to delete the message - MessagingController controller = MessagingController.getInstance(getContext()); - controller.deleteMessages(Collections.singletonList(msg), null); + if ((myAccount != null) && (msg != null)) { + MessagingController controller = MessagingController.getInstance(getContext()); + controller.deleteMessages(Collections.singletonList(msg), null); + } // FIXME return the actual number of deleted messages return 0; From e935feb0686d1395b51430824e13e842c9d3e1de Mon Sep 17 00:00:00 2001 From: Art O Cathain Date: Wed, 1 Jul 2015 16:59:57 +0100 Subject: [PATCH 42/44] extract variable per review comment --- .../src/main/java/com/fsck/k9/activity/MessageCompose.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/activity/MessageCompose.java b/k9mail/src/main/java/com/fsck/k9/activity/MessageCompose.java index 57e2fe666..31e6073d5 100644 --- a/k9mail/src/main/java/com/fsck/k9/activity/MessageCompose.java +++ b/k9mail/src/main/java/com/fsck/k9/activity/MessageCompose.java @@ -2379,8 +2379,10 @@ public class MessageCompose extends K9Activity implements OnClickListener, // Decode the identity header when loading a draft. // See buildIdentityHeader(TextBody) for a detailed description of the composition of this blob. Map k9identity = new HashMap(); - if (message.getHeader(K9.IDENTITY_HEADER).length > 0 && message.getHeader(K9.IDENTITY_HEADER)[0] != null) { - k9identity = IdentityHeaderParser.parse(message.getHeader(K9.IDENTITY_HEADER)[0]); + String[] identityHeaders = message.getHeader(K9.IDENTITY_HEADER); + + if (identityHeaders.length > 0 && identityHeaders[0] != null) { + k9identity = IdentityHeaderParser.parse(identityHeaders[0]); } Identity newIdentity = new Identity(); From ecb6893e6c2ff8d00795efc47afabde0365a44b0 Mon Sep 17 00:00:00 2001 From: cketti Date: Mon, 6 Jul 2015 20:02:19 +0200 Subject: [PATCH 43/44] Properly encode folder name in MessageProvider delete URI Fixes #706 --- .../java/com/fsck/k9/provider/MessageProvider.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/provider/MessageProvider.java b/k9mail/src/main/java/com/fsck/k9/provider/MessageProvider.java index f6fb010e8..267e58acf 100644 --- a/k9mail/src/main/java/com/fsck/k9/provider/MessageProvider.java +++ b/k9mail/src/main/java/com/fsck/k9/provider/MessageProvider.java @@ -203,9 +203,14 @@ public class MessageProvider extends ContentProvider { @Override public String getField(final MessageInfoHolder source) { final LocalMessage message = source.message; - return CONTENT_URI + "/delete_message/" - + message.getAccount().getAccountNumber() + "/" - + message.getFolder().getName() + "/" + message.getUid(); + int accountNumber = message.getAccount().getAccountNumber(); + return CONTENT_URI.buildUpon() + .appendPath("delete_message") + .appendPath(Integer.toString(accountNumber)) + .appendPath(message.getFolder().getName()) + .appendPath(message.getUid()) + .build() + .toString(); } } public static class SenderExtractor implements FieldExtractor { From d8aef84127fb6be9edf8c97ae4ae69d456ea371a Mon Sep 17 00:00:00 2001 From: cketti Date: Mon, 6 Jul 2015 20:40:10 +0200 Subject: [PATCH 44/44] Don't overwrite delete policy when editing incoming server settings Fixes #616 --- .../com/fsck/k9/activity/setup/AccountSetupIncoming.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/k9mail/src/main/java/com/fsck/k9/activity/setup/AccountSetupIncoming.java b/k9mail/src/main/java/com/fsck/k9/activity/setup/AccountSetupIncoming.java index dfca997fb..ca5013ad9 100644 --- a/k9mail/src/main/java/com/fsck/k9/activity/setup/AccountSetupIncoming.java +++ b/k9mail/src/main/java/com/fsck/k9/activity/setup/AccountSetupIncoming.java @@ -153,6 +153,8 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener mAccount = Preferences.getPreferences(this).getAccount(accountUuid); } + boolean editSettings = Intent.ACTION_EDIT.equals(getIntent().getAction()); + try { ServerSettings settings = RemoteStore.decodeStoreUri(mAccount.getStoreUri()); @@ -203,7 +205,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener findViewById(R.id.webdav_owa_path_section).setVisibility(View.GONE); findViewById(R.id.webdav_auth_path_section).setVisibility(View.GONE); - if (!Intent.ACTION_EDIT.equals(getIntent().getAction())) { + if (!editSettings) { findViewById(R.id.imap_folder_setup_section).setVisibility(View.GONE); } } else if (Type.WebDAV == settings.type) { @@ -237,7 +239,9 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener throw new Exception("Unknown account type: " + mAccount.getStoreUri()); } - mAccount.setDeletePolicy(AccountCreator.getDefaultDeletePolicy(settings.type)); + if (!editSettings) { + mAccount.setDeletePolicy(AccountCreator.getDefaultDeletePolicy(settings.type)); + } // Note that mConnectionSecurityChoices is configured above based on server type ConnectionSecurityAdapter securityTypesAdapter =