From fb36389d20c0bc2b22f74cf3457f64879af6c36e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Vimont=20=28=C2=AEom=29?= Date: Wed, 30 May 2012 12:45:37 +0200 Subject: [PATCH 01/35] Create database in a transaction (for performance) On my emulator, it takes 70ms instead of 250ms. On a very specific hardware, it takes 0,5s instead of 4,1s. I willingly did not indent the code between my try/catch (for the patch to be readable). --- src/com/fsck/k9/mail/store/LocalStore.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java index d7417c2e1..b93304ea2 100644 --- a/src/com/fsck/k9/mail/store/LocalStore.java +++ b/src/com/fsck/k9/mail/store/LocalStore.java @@ -156,6 +156,8 @@ public class LocalStore extends Store implements Serializable { AttachmentProvider.clear(mApplication); + db.beginTransaction(); + try { try { // schema version 29 was when we moved to incremental updates // in the case of a new db or a < v29 db, we blow away and start from scratch @@ -385,6 +387,11 @@ public class LocalStore extends Store implements Serializable { throw new Error("Database upgrade failed!"); } + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + // Unless we're blowing away the whole data store, there's no reason to prune attachments // every time the user upgrades. it'll just cost them money and pain. // try From 102c6153a122a173a3253d9a7cf08ef8e333e610 Mon Sep 17 00:00:00 2001 From: Joe Steele Date: Tue, 19 Jun 2012 16:11:30 -0400 Subject: [PATCH 02/35] Issue 4359: IMAP message UIDs are 32 bit unsigned values and cannot be stored in int, so we now parse them as long. --- .../k9/mail/store/ImapResponseParser.java | 4 ++ src/com/fsck/k9/mail/store/ImapStore.java | 38 +++++++++---------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/com/fsck/k9/mail/store/ImapResponseParser.java b/src/com/fsck/k9/mail/store/ImapResponseParser.java index c73324753..4a8c8cc2e 100644 --- a/src/com/fsck/k9/mail/store/ImapResponseParser.java +++ b/src/com/fsck/k9/mail/store/ImapResponseParser.java @@ -384,6 +384,10 @@ public class ImapResponseParser { return (String)get(index); } + public long getLong(int index) { + return Long.parseLong(getString(index)); + } + public int getNumber(int index) { return Integer.parseInt(getString(index)); } diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java index 77251333b..4376d7d85 100644 --- a/src/com/fsck/k9/mail/store/ImapStore.java +++ b/src/com/fsck/k9/mail/store/ImapStore.java @@ -811,12 +811,12 @@ public class ImapStore extends Store { class ImapFolder extends Folder { private String mName; protected volatile int mMessageCount = -1; - protected volatile int uidNext = -1; + protected volatile long uidNext = -1L; protected volatile ImapConnection mConnection; private OpenMode mMode; private volatile boolean mExists; private ImapStore store = null; - Map msgSeqUidMap = new ConcurrentHashMap(); + Map msgSeqUidMap = new ConcurrentHashMap(); public ImapFolder(ImapStore nStore, String name) { @@ -1305,7 +1305,7 @@ public class ImapStore extends Store { return search(searcher, listener); } - protected Message[] getMessages(final List mesgSeqs, final boolean includeDeleted, final MessageRetrievalListener listener) + protected Message[] getMessages(final List mesgSeqs, final boolean includeDeleted, final MessageRetrievalListener listener) throws MessagingException { ImapSearcher searcher = new ImapSearcher() { public List search() throws IOException, MessagingException { @@ -1472,7 +1472,7 @@ public class ImapStore extends Store { if (response.mTag == null && ImapResponseParser.equalsIgnoreCase(response.get(1), "FETCH")) { ImapList fetchList = (ImapList)response.getKeyedValue("FETCH"); String uid = fetchList.getKeyedString("UID"); - int msgSeq = response.getNumber(0); + long msgSeq = response.getLong(0); if (uid != null) { try { msgSeqUidMap.put(msgSeq, uid); @@ -1699,7 +1699,7 @@ public class ImapStore extends Store { if (keyObj instanceof String) { String key = (String)keyObj; if ("UIDNEXT".equalsIgnoreCase(key)) { - uidNext = bracketed.getNumber(1); + uidNext = bracketed.getLong(1); if (K9.DEBUG) Log.d(K9.LOG_TAG, "Got UidNext = " + uidNext + " for " + getLogId()); } @@ -2828,9 +2828,9 @@ public class ImapStore extends Store { if (stop.get()) { continue; } - int startUid = oldUidNext; + long startUid = oldUidNext; - int newUidNext = uidNext; + long newUidNext = uidNext; if (newUidNext == -1) { if (K9.DEBUG) { @@ -2858,7 +2858,7 @@ public class ImapStore extends Store { if (K9.DEBUG) Log.i(K9.LOG_TAG, "Needs sync from uid " + startUid + " to " + newUidNext + " for " + getLogId()); List messages = new ArrayList(); - for (int uid = startUid; uid < newUidNext; uid++) { + for (long uid = startUid; uid < newUidNext; uid++) { ImapMessage message = new ImapMessage("" + uid, ImapFolderPusher.this); messages.add(message); } @@ -2958,7 +2958,7 @@ public class ImapStore extends Store { if (oldMessageCount == -1) { skipSync = true; } - List flagSyncMsgSeqs = new ArrayList(); + List flagSyncMsgSeqs = new ArrayList(); List removeMsgUids = new LinkedList(); for (ImapResponse response : responses) { @@ -3023,7 +3023,7 @@ public class ImapStore extends Store { } } - private void syncMessages(List flagSyncMsgSeqs) { + private void syncMessages(List flagSyncMsgSeqs) { try { Message[] messageArray = null; @@ -3066,7 +3066,7 @@ public class ImapStore extends Store { } - protected int processUntaggedResponse(int oldMessageCount, ImapResponse response, List flagSyncMsgSeqs, List removeMsgUids) { + protected int processUntaggedResponse(long oldMessageCount, ImapResponse response, List flagSyncMsgSeqs, List removeMsgUids) { super.handleUntaggedResponse(response); int messageCountDelta = 0; if (response.mTag == null && response.size() > 1) { @@ -3074,7 +3074,7 @@ public class ImapStore extends Store { Object responseType = response.get(1); if (ImapResponseParser.equalsIgnoreCase(responseType, "FETCH")) { Log.i(K9.LOG_TAG, "Got FETCH " + response); - int msgSeq = response.getNumber(0); + long msgSeq = response.getLong(0); if (K9.DEBUG) Log.d(K9.LOG_TAG, "Got untagged FETCH for msgseq " + msgSeq + " for " + getLogId()); @@ -3084,17 +3084,17 @@ public class ImapStore extends Store { } } if (ImapResponseParser.equalsIgnoreCase(responseType, "EXPUNGE")) { - int msgSeq = response.getNumber(0); + long msgSeq = response.getLong(0); if (msgSeq <= oldMessageCount) { messageCountDelta = -1; } if (K9.DEBUG) Log.d(K9.LOG_TAG, "Got untagged EXPUNGE for msgseq " + msgSeq + " for " + getLogId()); - List newSeqs = new ArrayList(); - Iterator flagIter = flagSyncMsgSeqs.iterator(); + List newSeqs = new ArrayList(); + Iterator flagIter = flagSyncMsgSeqs.iterator(); while (flagIter.hasNext()) { - Integer flagMsg = flagIter.next(); + Long flagMsg = flagIter.next(); if (flagMsg >= msgSeq) { flagIter.remove(); if (flagMsg > msgSeq) { @@ -3105,14 +3105,14 @@ public class ImapStore extends Store { flagSyncMsgSeqs.addAll(newSeqs); - List msgSeqs = new ArrayList(msgSeqUidMap.keySet()); + List msgSeqs = new ArrayList(msgSeqUidMap.keySet()); Collections.sort(msgSeqs); // Have to do comparisons in order because of msgSeq reductions - for (Integer msgSeqNumI : msgSeqs) { + for (long msgSeqNumI : msgSeqs) { if (K9.DEBUG) { Log.v(K9.LOG_TAG, "Comparing EXPUNGEd msgSeq " + msgSeq + " to " + msgSeqNumI); } - int msgSeqNum = msgSeqNumI; + long msgSeqNum = msgSeqNumI; if (msgSeqNum == msgSeq) { String uid = msgSeqUidMap.get(msgSeqNum); if (K9.DEBUG) { From 7ae7fc9d9d1119cb43eea107705ba7c02002e5c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Fri, 6 Jul 2012 14:03:48 +0200 Subject: [PATCH 03/35] removed unread private field mFontSizes --- src/com/fsck/k9/activity/MessageCompose.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java index 671ef250f..f692bf7f0 100644 --- a/src/com/fsck/k9/activity/MessageCompose.java +++ b/src/com/fsck/k9/activity/MessageCompose.java @@ -3432,11 +3432,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc static class IdentityAdapter extends BaseAdapter { private LayoutInflater mLayoutInflater; private List mItems; - private FontSizes mFontSizes; public IdentityAdapter(Context context, LayoutInflater layoutInflater) { mLayoutInflater = layoutInflater; - mFontSizes = K9.getFontSizes(); List items = new ArrayList(); Preferences prefs = Preferences.getPreferences(context.getApplicationContext()); From 8c3b64c3d7485f6558c884965c4f8994d81ed7dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Fri, 6 Jul 2012 14:04:19 +0200 Subject: [PATCH 04/35] removed unused private fields gesture{Detector,Listener} --- src/com/fsck/k9/activity/MessageList.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java index fdea8b478..4c9af41d8 100644 --- a/src/com/fsck/k9/activity/MessageList.java +++ b/src/com/fsck/k9/activity/MessageList.java @@ -272,8 +272,6 @@ public class MessageList private Account mAccount; private int mUnreadMessageCount = 0; - private GestureDetector gestureDetector; - private View.OnTouchListener gestureListener; /** * Stores the name of the folder that we want to open as soon as possible * after load. From e3853824dbaff1e6c47856366c8158d5eb282699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Fri, 6 Jul 2012 14:04:32 +0200 Subject: [PATCH 05/35] removed empty else clause --- src/com/fsck/k9/controller/MessagingController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java index 8a2fa9403..7daf0e240 100644 --- a/src/com/fsck/k9/controller/MessagingController.java +++ b/src/com/fsck/k9/controller/MessagingController.java @@ -3267,7 +3267,6 @@ public class MessagingController implements Runnable { // "don't even bother" functionality if (getRootCauseMessage(e).startsWith("5")) { localFolder.moveMessages(new Message[] { message }, (LocalFolder) localStore.getFolder(account.getDraftsFolderName())); - } else { } message.setFlag(Flag.X_SEND_FAILED, true); From dd5ab2c2c6843e28fb1bebcd1da4ce4558aa34d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Fri, 6 Jul 2012 14:21:24 +0200 Subject: [PATCH 06/35] combined nested if statements in MessageList.removeMessages() --- src/com/fsck/k9/activity/MessageList.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java index 4c9af41d8..7d6e4ac8a 100644 --- a/src/com/fsck/k9/activity/MessageList.java +++ b/src/com/fsck/k9/activity/MessageList.java @@ -362,13 +362,13 @@ public class MessageList @Override public void run() { for (MessageInfoHolder message : messages) { - if (message != null) { - if (mFolderName == null || (message.folder != null && message.folder.name.equals(mFolderName))) { - if (message.selected && mSelectedCount > 0) { - mSelectedCount--; - } - mAdapter.messages.remove(message); + if (message != null && (mFolderName == null || ( + message.folder != null && + message.folder.name.equals(mFolderName)))) { + if (message.selected && mSelectedCount > 0) { + mSelectedCount--; } + mAdapter.messages.remove(message); } } resetUnreadCountOnThread(); From cfd77f8e32a9e87727c7061fad6a5f765ae22b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Fri, 6 Jul 2012 14:21:47 +0200 Subject: [PATCH 07/35] combined nested if statements in AccountSetupCheckSettings --- .../k9/activity/setup/AccountSetupCheckSettings.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java b/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java index c64928cfd..6ce001788 100644 --- a/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java +++ b/src/com/fsck/k9/activity/setup/AccountSetupCheckSettings.java @@ -319,11 +319,11 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList if (name.equalsIgnoreCase(storeURIHost) || name.equalsIgnoreCase(transportURIHost)) { //TODO: localize this string altNamesText.append("Subject(alt): ").append(name).append(",...\n"); - } else if (name.startsWith("*.")) { - if (storeURIHost.endsWith(name.substring(2)) || transportURIHost.endsWith(name.substring(2))) { - //TODO: localize this string - altNamesText.append("Subject(alt): ").append(name).append(",...\n"); - } + } else if (name.startsWith("*.") && ( + storeURIHost.endsWith(name.substring(2)) || + transportURIHost.endsWith(name.substring(2)))) { + //TODO: localize this string + altNamesText.append("Subject(alt): ").append(name).append(",...\n"); } } chainInfo.append(altNamesText); From 5c23549a0b9dc00d4c0b42af7a6bcead19e7e9c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Fri, 6 Jul 2012 14:22:28 +0200 Subject: [PATCH 08/35] combined nested if statements in DomainNameChecker.matchIpAddress --- src/com/fsck/k9/helper/DomainNameChecker.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/com/fsck/k9/helper/DomainNameChecker.java b/src/com/fsck/k9/helper/DomainNameChecker.java index 3ef74f9e1..5241e36b3 100644 --- a/src/com/fsck/k9/helper/DomainNameChecker.java +++ b/src/com/fsck/k9/helper/DomainNameChecker.java @@ -124,16 +124,14 @@ public class DomainNameChecker { List altNameEntry = (List)(subjectAltName); if ((altNameEntry != null) && (2 <= altNameEntry.size())) { Integer altNameType = (Integer)(altNameEntry.get(0)); - if (altNameType != null) { - if (altNameType == ALT_IPA_NAME) { - String altName = (String)(altNameEntry.get(1)); - if (altName != null) { - if (K9.DEBUG) { - Log.v(K9.LOG_TAG, "alternative IP: " + altName); - } - if (thisDomain.equalsIgnoreCase(altName)) { - return true; - } + if (altNameType != null && altNameType == ALT_IPA_NAME) { + String altName = (String)(altNameEntry.get(1)); + if (altName != null) { + if (K9.DEBUG) { + Log.v(K9.LOG_TAG, "alternative IP: " + altName); + } + if (thisDomain.equalsIgnoreCase(altName)) { + return true; } } } From f79b1eb1420ea440c04de3073cc3c25800d90396 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Fri, 6 Jul 2012 14:22:40 +0200 Subject: [PATCH 09/35] combined nested if statements in DomainNameChecker.matchDns --- src/com/fsck/k9/helper/DomainNameChecker.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/com/fsck/k9/helper/DomainNameChecker.java b/src/com/fsck/k9/helper/DomainNameChecker.java index 5241e36b3..7b831daee 100644 --- a/src/com/fsck/k9/helper/DomainNameChecker.java +++ b/src/com/fsck/k9/helper/DomainNameChecker.java @@ -164,15 +164,11 @@ public class DomainNameChecker { List altNameEntry = (List)(i.next()); if ((altNameEntry != null) && (2 <= altNameEntry.size())) { Integer altNameType = (Integer)(altNameEntry.get(0)); - if (altNameType != null) { - if (altNameType.intValue() == ALT_DNS_NAME) { - hasDns = true; - String altName = (String)(altNameEntry.get(1)); - if (altName != null) { - if (matchDns(thisDomain, altName)) { - return true; - } - } + if (altNameType != null && altNameType.intValue() == ALT_DNS_NAME) { + hasDns = true; + String altName = (String)(altNameEntry.get(1)); + if (altName != null && matchDns(thisDomain, altName)) { + return true; } } } From 57f364ca69e3367e3862f53fbfd88dff35362105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Fri, 6 Jul 2012 14:23:21 +0200 Subject: [PATCH 10/35] combined nested if statements in MimeHeader.hasToBeEncoded --- src/com/fsck/k9/mail/internet/MimeHeader.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/com/fsck/k9/mail/internet/MimeHeader.java b/src/com/fsck/k9/mail/internet/MimeHeader.java index 755425382..5175f4ad2 100644 --- a/src/com/fsck/k9/mail/internet/MimeHeader.java +++ b/src/com/fsck/k9/mail/internet/MimeHeader.java @@ -122,10 +122,9 @@ public class MimeHeader { public boolean hasToBeEncoded(String text) { for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); - if (c < 0x20 || 0x7e < c) { // non printable - if (c != 0x0a && c != 0x0d && c != 0x09) { // non LF/CR/TAB - return true; - } + if ((c < 0x20 || 0x7e < c) && // non printable + (c != 0x0a && c != 0x0d && c != 0x09)) { // non LF/CR/TAB + return true; } } From 961872edf034979721b123b56829dc47b167dc0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Fri, 6 Jul 2012 14:23:50 +0200 Subject: [PATCH 11/35] combined nested if statements in ImapStore --- src/com/fsck/k9/mail/store/ImapStore.java | 26 +++++++++++------------ 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java index 77251333b..ce56619d5 100644 --- a/src/com/fsck/k9/mail/store/ImapStore.java +++ b/src/com/fsck/k9/mail/store/ImapStore.java @@ -2204,21 +2204,19 @@ public class ImapStore extends Store { capabilityList = response; } - if (capabilityList != null) { - if (!capabilityList.isEmpty() && ImapResponseParser.equalsIgnoreCase(capabilityList.get(0), CAPABILITY_CAPABILITY)) { - if (K9.DEBUG) { - Log.d(K9.LOG_TAG, "Saving " + capabilityList.size() + " capabilities for " + getLogId()); + if (capabilityList != null && !capabilityList.isEmpty() && + ImapResponseParser.equalsIgnoreCase(capabilityList.get(0), CAPABILITY_CAPABILITY)) { + if (K9.DEBUG) { + Log.d(K9.LOG_TAG, "Saving " + capabilityList.size() + " capabilities for " + getLogId()); + } + for (Object capability : capabilityList) { + if (capability instanceof String) { +// if (K9.DEBUG) +// { +// Log.v(K9.LOG_TAG, "Saving capability '" + capability + "' for " + getLogId()); +// } + capabilities.add(((String)capability).toUpperCase(Locale.US)); } - for (Object capability : capabilityList) { - if (capability instanceof String) { -// if (K9.DEBUG) -// { -// Log.v(K9.LOG_TAG, "Saving capability '" + capability + "' for " + getLogId()); -// } - capabilities.add(((String)capability).toUpperCase(Locale.US)); - } - } - } } } From bff1602da1756c0383d5cc8c42a3d38aa0962945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Fri, 6 Jul 2012 14:24:16 +0200 Subject: [PATCH 12/35] combined nested if statements in LocalStore --- src/com/fsck/k9/mail/store/LocalStore.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java index 5eb90f5a2..d91e5e4d5 100644 --- a/src/com/fsck/k9/mail/store/LocalStore.java +++ b/src/com/fsck/k9/mail/store/LocalStore.java @@ -3303,10 +3303,8 @@ public class LocalStore extends Store implements Serializable { if (!isSet(Flag.DELETED)) { - if (flag == Flag.SEEN) { - if (set != isSet(Flag.SEEN)) { - folder.setUnreadMessageCount(folder.getUnreadMessageCount() + (set ? -1 : 1)); - } + if (flag == Flag.SEEN && set != isSet(Flag.SEEN)) { + folder.setUnreadMessageCount(folder.getUnreadMessageCount() + (set ? -1 : 1)); } if (flag == Flag.FLAGGED) { From 9413cf5c9de95ed012ae3b20a95544ff8e2e3c99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Fri, 6 Jul 2012 14:24:44 +0200 Subject: [PATCH 13/35] Removed override merely calling super() --- src/com/fsck/k9/mail/store/WebDavStore.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/com/fsck/k9/mail/store/WebDavStore.java b/src/com/fsck/k9/mail/store/WebDavStore.java index ab334f244..285215c0b 100644 --- a/src/com/fsck/k9/mail/store/WebDavStore.java +++ b/src/com/fsck/k9/mail/store/WebDavStore.java @@ -1991,11 +1991,6 @@ public class WebDavStore extends Store { return false; } - @Override - public int hashCode() { - return super.hashCode(); - } - @Override public String getUidFromMessageId(Message message) throws MessagingException { Log.e(K9.LOG_TAG, From 2f918c2307d0f1de041c866fd708455fe4700545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Fri, 6 Jul 2012 15:00:25 +0200 Subject: [PATCH 14/35] Use more efficient entrySet iterator instead of keySet + get() The loop extracted keys from `remodeUidMap` and then called `remouteUidMap.get(...)` for every key. If both the key and the value needs to be iterated on, `Map.entrySet()` is a more efficient solution as it doesn't require O(n) Map lookups. --- src/com/fsck/k9/controller/MessagingController.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java index 7daf0e240..e6382c561 100644 --- a/src/com/fsck/k9/controller/MessagingController.java +++ b/src/com/fsck/k9/controller/MessagingController.java @@ -2220,13 +2220,14 @@ public class MessagingController implements Runnable { * upto speed with the remote UIDs of remote destionation folder. */ if (!localUidMap.isEmpty() && remoteUidMap != null && !remoteUidMap.isEmpty()) { - Set remoteSrcUids = remoteUidMap.keySet(); - Iterator remoteSrcUidsIterator = remoteSrcUids.iterator(); + Set> remoteSrcEntries = remoteUidMap.entrySet(); + Iterator> remoteSrcEntriesIterator = remoteSrcEntries.iterator(); - while (remoteSrcUidsIterator.hasNext()) { - String remoteSrcUid = remoteSrcUidsIterator.next(); + while (remoteSrcEntriesIterator.hasNext()) { + Map.Entry entry = remoteSrcEntriesIterator.next(); + String remoteSrcUid = entry.getKey(); String localDestUid = localUidMap.get(remoteSrcUid); - String newUid = remoteUidMap.get(remoteSrcUid); + String newUid = entry.getValue(); Message localDestMessage = localDestFolder.getMessage(localDestUid); if (localDestMessage != null) { From d0c08fb7050ad3fbedf218fe8d67f7c648338c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Fri, 6 Jul 2012 15:04:46 +0200 Subject: [PATCH 15/35] removed unread private field mSecure --- src/com/fsck/k9/mail/transport/SmtpTransport.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/com/fsck/k9/mail/transport/SmtpTransport.java b/src/com/fsck/k9/mail/transport/SmtpTransport.java index 2ad4fa38e..050a582b3 100644 --- a/src/com/fsck/k9/mail/transport/SmtpTransport.java +++ b/src/com/fsck/k9/mail/transport/SmtpTransport.java @@ -188,7 +188,6 @@ public class SmtpTransport extends Transport { String mPassword; String mAuthType; int mConnectionSecurity; - boolean mSecure; Socket mSocket; PeekableInputStream mIn; OutputStream mOut; @@ -245,7 +244,6 @@ public class SmtpTransport extends Transport { }, new SecureRandom()); mSocket = sslContext.getSocketFactory().createSocket(); mSocket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT); - mSecure = true; } else { mSocket = new Socket(); mSocket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT); @@ -308,7 +306,6 @@ public class SmtpTransport extends Transport { mIn = new PeekableInputStream(new BufferedInputStream(mSocket.getInputStream(), 1024)); mOut = mSocket.getOutputStream(); - mSecure = true; /* * Now resend the EHLO. Required by RFC2487 Sec. 5.2, and more specifically, * Exim. From 85b2eb8315867c97dc9837b165063ce1ce2bf10c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20Veres-Szentkir=C3=A1lyi?= Date: Fri, 6 Jul 2012 15:05:53 +0200 Subject: [PATCH 16/35] removed unused private field mUID --- src/com/fsck/k9/activity/ChooseIdentity.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/com/fsck/k9/activity/ChooseIdentity.java b/src/com/fsck/k9/activity/ChooseIdentity.java index a769ddfae..87482b346 100644 --- a/src/com/fsck/k9/activity/ChooseIdentity.java +++ b/src/com/fsck/k9/activity/ChooseIdentity.java @@ -17,7 +17,6 @@ import java.util.List; public class ChooseIdentity extends K9ListActivity { Account mAccount; - String mUID; ArrayAdapter adapter; public static final String EXTRA_ACCOUNT = "com.fsck.k9.ChooseIdentity_account"; From 79253968ffdf9cbc9fe6dcab613d97c4f9ce3b8e Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 7 Jul 2012 14:19:22 +0200 Subject: [PATCH 17/35] Get rid of auto-unboxing in comparison --- src/com/fsck/k9/helper/DomainNameChecker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/fsck/k9/helper/DomainNameChecker.java b/src/com/fsck/k9/helper/DomainNameChecker.java index 7b831daee..f13748536 100644 --- a/src/com/fsck/k9/helper/DomainNameChecker.java +++ b/src/com/fsck/k9/helper/DomainNameChecker.java @@ -124,7 +124,7 @@ public class DomainNameChecker { List altNameEntry = (List)(subjectAltName); if ((altNameEntry != null) && (2 <= altNameEntry.size())) { Integer altNameType = (Integer)(altNameEntry.get(0)); - if (altNameType != null && altNameType == ALT_IPA_NAME) { + if (altNameType != null && altNameType.intValue() == ALT_IPA_NAME) { String altName = (String)(altNameEntry.get(1)); if (altName != null) { if (K9.DEBUG) { From 411117b6609ae11234d706666154f02bb67484fa Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 7 Jul 2012 14:26:16 +0200 Subject: [PATCH 18/35] Removed unused imports --- src/com/fsck/k9/Account.java | 1 - src/com/fsck/k9/activity/MessageList.java | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/com/fsck/k9/Account.java b/src/com/fsck/k9/Account.java index 907411a1a..74a6350fb 100644 --- a/src/com/fsck/k9/Account.java +++ b/src/com/fsck/k9/Account.java @@ -18,7 +18,6 @@ import com.fsck.k9.mail.store.StorageManager; import com.fsck.k9.mail.store.StorageManager.StorageProvider; import com.fsck.k9.view.ColorChip; -import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java index 7d6e4ac8a..a6c9d8b3d 100644 --- a/src/com/fsck/k9/activity/MessageList.java +++ b/src/com/fsck/k9/activity/MessageList.java @@ -54,12 +54,10 @@ import android.widget.Toast; import com.fsck.k9.Account; import com.fsck.k9.Account.SortType; import com.fsck.k9.AccountStats; -import com.fsck.k9.BaseAccount; import com.fsck.k9.FontSizes; import com.fsck.k9.K9; import com.fsck.k9.Preferences; import com.fsck.k9.R; -import com.fsck.k9.SearchAccount; import com.fsck.k9.SearchSpecification; import com.fsck.k9.activity.setup.AccountSettings; import com.fsck.k9.activity.setup.FolderSettings; From 2269f2215394f0c97517b45bb1f466b3f4d16cda Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 7 Jul 2012 14:28:15 +0200 Subject: [PATCH 19/35] Removed unused method that was used for debugging --- src/com/fsck/k9/Preferences.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/com/fsck/k9/Preferences.java b/src/com/fsck/k9/Preferences.java index b364c70b7..6f20e5b2f 100644 --- a/src/com/fsck/k9/Preferences.java +++ b/src/com/fsck/k9/Preferences.java @@ -10,7 +10,6 @@ import java.util.Map; import android.content.Context; import android.content.SharedPreferences; -import android.util.Config; import android.util.Log; import com.fsck.k9.preferences.Editor; import com.fsck.k9.preferences.Storage; @@ -155,14 +154,6 @@ public class Preferences { getPreferences().edit().putString("defaultAccountUuid", account.getUuid()).commit(); } - public void dump() { - if (Config.LOGV) { - for (String key : getPreferences().getAll().keySet()) { - Log.v(K9.LOG_TAG, key + " = " + getPreferences().getAll().get(key)); - } - } - } - public SharedPreferences getPreferences() { return mStorage; } From 84938478957623a2fa32de9cd0bd7aab8e57ac21 Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 7 Jul 2012 14:29:40 +0200 Subject: [PATCH 20/35] Removed unused class --- .../k9/mail/filter/StatusOutputStream.java | 28 ------------------- 1 file changed, 28 deletions(-) delete mode 100644 src/com/fsck/k9/mail/filter/StatusOutputStream.java diff --git a/src/com/fsck/k9/mail/filter/StatusOutputStream.java b/src/com/fsck/k9/mail/filter/StatusOutputStream.java deleted file mode 100644 index db66b6520..000000000 --- a/src/com/fsck/k9/mail/filter/StatusOutputStream.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.fsck.k9.mail.filter; - -import android.util.Config; -import android.util.Log; -import com.fsck.k9.K9; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -public class StatusOutputStream extends FilterOutputStream { - private long mCount = 0; - - public StatusOutputStream(OutputStream out) { - super(out); - } - - @Override - public void write(int oneByte) throws IOException { - super.write(oneByte); - mCount++; - if (Config.LOGV) { - if (mCount % 1024 == 0) { - Log.v(K9.LOG_TAG, "# " + mCount); - } - } - } -} From f832e08de3e88f57a0ad2f227c4c3593c75ec460 Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 7 Jul 2012 14:30:42 +0200 Subject: [PATCH 21/35] Removed unused debug message --- src/com/fsck/k9/activity/FolderList.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/com/fsck/k9/activity/FolderList.java b/src/com/fsck/k9/activity/FolderList.java index 86c0240b8..1b25aeb87 100644 --- a/src/com/fsck/k9/activity/FolderList.java +++ b/src/com/fsck/k9/activity/FolderList.java @@ -11,7 +11,6 @@ import android.os.Handler; import android.os.PowerManager; import android.text.Editable; import android.text.TextWatcher; -import android.util.Config; import android.util.Log; import android.util.TypedValue; import android.view.*; @@ -835,10 +834,6 @@ public class FolderList extends K9ListActivity { if (account.equals(mAccount)) { mHandler.progress(false); - - if (Config.LOGV) { - Log.v(K9.LOG_TAG, "listFoldersFailed " + message); - } } super.listFoldersFailed(account, message); } From ece107f6d899fa1a12a6e656342dce621cbcfcf0 Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 7 Jul 2012 14:33:15 +0200 Subject: [PATCH 22/35] Removed unused variable --- src/com/fsck/k9/controller/MessagingController.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java index e6382c561..082b1a360 100644 --- a/src/com/fsck/k9/controller/MessagingController.java +++ b/src/com/fsck/k9/controller/MessagingController.java @@ -518,9 +518,6 @@ public class MessagingController implements Runnable { List pendingMessages = new ArrayList(); - int totalDone = 0; - - @Override public void messageStarted(String message, int number, int ofTotal) {} @Override @@ -528,7 +525,6 @@ public class MessagingController implements Runnable { if (!isMessageSuppressed(account, folder, message)) { pendingMessages.add(message); - totalDone++; if (pendingMessages.size() > 10) { addPendingMessages(); } From 1f2104cae1f8f219e957a04f51376bffba403aaa Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 7 Jul 2012 14:38:57 +0200 Subject: [PATCH 23/35] Added annotations to disable Lint warnings when we're using newer APIs --- src/com/fsck/k9/helper/ClipboardManagerApi11.java | 2 ++ src/com/fsck/k9/helper/NotificationBuilderApi11.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/com/fsck/k9/helper/ClipboardManagerApi11.java b/src/com/fsck/k9/helper/ClipboardManagerApi11.java index cae25fa0f..5c142b9b4 100644 --- a/src/com/fsck/k9/helper/ClipboardManagerApi11.java +++ b/src/com/fsck/k9/helper/ClipboardManagerApi11.java @@ -1,5 +1,6 @@ package com.fsck.k9.helper; +import android.annotation.TargetApi; import android.content.ClipData; import android.content.Context; import android.content.ClipboardManager; @@ -7,6 +8,7 @@ import android.content.ClipboardManager; /** * Access the system clipboard using the new {@link ClipboardManager} introduced with API 11 */ +@TargetApi(11) public class ClipboardManagerApi11 extends com.fsck.k9.helper.ClipboardManager { public ClipboardManagerApi11(Context context) { diff --git a/src/com/fsck/k9/helper/NotificationBuilderApi11.java b/src/com/fsck/k9/helper/NotificationBuilderApi11.java index fc9772b7d..369db11ab 100644 --- a/src/com/fsck/k9/helper/NotificationBuilderApi11.java +++ b/src/com/fsck/k9/helper/NotificationBuilderApi11.java @@ -1,5 +1,6 @@ package com.fsck.k9.helper; +import android.annotation.TargetApi; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; @@ -9,6 +10,7 @@ import android.net.Uri; /** * Create notifications using the new {@link android.app.Notification.Builder} class. */ +@TargetApi(11) public class NotificationBuilderApi11 extends NotificationBuilder { private Notification.Builder mBuilder; From a281b3401e00cc9cba9318bdcd5f6f820b2e7a83 Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 7 Jul 2012 15:03:23 +0200 Subject: [PATCH 24/35] Extracted code to disable Lint warning when using newer API --- src/com/fsck/k9/view/MessageWebView.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/com/fsck/k9/view/MessageWebView.java b/src/com/fsck/k9/view/MessageWebView.java index 5783d1974..9d61b87e4 100644 --- a/src/com/fsck/k9/view/MessageWebView.java +++ b/src/com/fsck/k9/view/MessageWebView.java @@ -1,5 +1,6 @@ package com.fsck.k9.view; +import android.annotation.TargetApi; import android.content.Context; import android.os.Build; import android.util.AttributeSet; @@ -98,16 +99,7 @@ public class MessageWebView extends WebView { webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS); } - /* - * Build.VERSION.SDK is deprecated cause it just returns the - * "its raw String representation" - * http://developer.android.com/reference/android/os/Build.VERSION_CODES.html#GINGERBREAD - * http://developer.android.com/reference/android/os/Build.VERSION.html#SDK - */ - if (Build.VERSION.SDK_INT >= 9) { - setOverScrollMode(OVER_SCROLL_NEVER); - } - + disableOverscrolling(); webSettings.setTextSize(K9.getFontSizes().getMessageViewContent()); @@ -116,6 +108,13 @@ public class MessageWebView extends WebView { } + @TargetApi(9) + private void disableOverscrolling() { + if (Build.VERSION.SDK_INT >= 9) { + setOverScrollMode(OVER_SCROLL_NEVER); + } + } + public void setText(String text, String contentType) { String content = text; if (K9.getK9Theme() == K9.THEME_DARK) { From c359eb3cb7339e85c8b4e07a49e711127a5c72e8 Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 7 Jul 2012 15:36:43 +0200 Subject: [PATCH 25/35] Use auto-unboxing when iterating over a List --- src/com/fsck/k9/mail/store/ImapStore.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java index 0defbb59a..4d5790237 100644 --- a/src/com/fsck/k9/mail/store/ImapStore.java +++ b/src/com/fsck/k9/mail/store/ImapStore.java @@ -3106,11 +3106,10 @@ public class ImapStore extends Store { List msgSeqs = new ArrayList(msgSeqUidMap.keySet()); Collections.sort(msgSeqs); // Have to do comparisons in order because of msgSeq reductions - for (long msgSeqNumI : msgSeqs) { + for (long msgSeqNum : msgSeqs) { if (K9.DEBUG) { - Log.v(K9.LOG_TAG, "Comparing EXPUNGEd msgSeq " + msgSeq + " to " + msgSeqNumI); + Log.v(K9.LOG_TAG, "Comparing EXPUNGEd msgSeq " + msgSeq + " to " + msgSeqNum); } - long msgSeqNum = msgSeqNumI; if (msgSeqNum == msgSeq) { String uid = msgSeqUidMap.get(msgSeqNum); if (K9.DEBUG) { From a37c95b4569b6286f32b670b2ba1648de62d86ea Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 7 Jul 2012 15:41:55 +0200 Subject: [PATCH 26/35] Move auto-unboxing out of if-clause --- src/com/fsck/k9/mail/store/ImapStore.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java index 4d5790237..2e309720a 100644 --- a/src/com/fsck/k9/mail/store/ImapStore.java +++ b/src/com/fsck/k9/mail/store/ImapStore.java @@ -3092,7 +3092,7 @@ public class ImapStore extends Store { List newSeqs = new ArrayList(); Iterator flagIter = flagSyncMsgSeqs.iterator(); while (flagIter.hasNext()) { - Long flagMsg = flagIter.next(); + long flagMsg = flagIter.next(); if (flagMsg >= msgSeq) { flagIter.remove(); if (flagMsg > msgSeq) { From 2ad748fad77ac7ef07a724e77d243af4c072247f Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 7 Jul 2012 16:21:07 +0200 Subject: [PATCH 27/35] Change ImapUtility to use 'long' for the values of sequence sets --- .../fsck/k9/mail/store/imap/ImapUtility.java | 46 +++++++++++++------ .../k9/mail/store/imap/ImapUtilityTest.java | 22 +++++++++ 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/com/fsck/k9/mail/store/imap/ImapUtility.java b/src/com/fsck/k9/mail/store/imap/ImapUtility.java index d0ac2b31a..b7312eae7 100644 --- a/src/com/fsck/k9/mail/store/imap/ImapUtility.java +++ b/src/com/fsck/k9/mail/store/imap/ImapUtility.java @@ -54,11 +54,8 @@ public class ImapUtility { for (String item : setItems) { if (item.indexOf(':') == -1) { // simple item - try { - Integer.parseInt(item); // Don't need the value; just ensure it's valid + if (isNumberValid(item)) { list.add(item); - } catch (NumberFormatException e) { - Log.d(K9.LOG_TAG, "Invalid UID value", e); } } else { // range @@ -91,23 +88,46 @@ public class ImapUtility { if (range != null) { int colonPos = range.indexOf(':'); if (colonPos > 0) { - int first = Integer.parseInt(range.substring(0, colonPos)); - int second = Integer.parseInt(range.substring(colonPos + 1)); - if (first < second) { - for (int i = first; i <= second; i++) { - list.add(Integer.toString(i)); + long first = Long.parseLong(range.substring(0, colonPos)); + long second = Long.parseLong(range.substring(colonPos + 1)); + if (is32bitValue(first) && is32bitValue(second)) { + if (first < second) { + for (long i = first; i <= second; i++) { + list.add(Long.toString(i)); + } + } else { + for (long i = first; i >= second; i--) { + list.add(Long.toString(i)); + } } } else { - for (int i = first; i >= second; i--) { - list.add(Integer.toString(i)); - } + Log.d(K9.LOG_TAG, "Invalid range: " + range); } } } } catch (NumberFormatException e) { - Log.d(K9.LOG_TAG, "Invalid range value", e); + Log.d(K9.LOG_TAG, "Invalid range value: " + range, e); } return list; } + + private static boolean isNumberValid(String number) { + try { + long value = Long.parseLong(number); + if (is32bitValue(value)) { + return true; + } + } catch (NumberFormatException e) { + // do nothing + } + + Log.d(K9.LOG_TAG, "Invalid UID value: " + number); + + return false; + } + + private static boolean is32bitValue(long value) { + return ((value & ~0xFFFFFFFFL) == 0L); + } } diff --git a/tests/src/com/fsck/k9/mail/store/imap/ImapUtilityTest.java b/tests/src/com/fsck/k9/mail/store/imap/ImapUtilityTest.java index 496d6922e..feaef05e8 100644 --- a/tests/src/com/fsck/k9/mail/store/imap/ImapUtilityTest.java +++ b/tests/src/com/fsck/k9/mail/store/imap/ImapUtilityTest.java @@ -34,6 +34,14 @@ public class ImapUtilityTest extends TestCase { actual = ImapUtility.getImapSequenceValues("1"); MoreAsserts.assertEquals(expected, actual.toArray()); + expected = new String[] {"2147483648"}; // Integer.MAX_VALUE + 1 + actual = ImapUtility.getImapSequenceValues("2147483648"); + MoreAsserts.assertEquals(expected, actual.toArray()); + + expected = new String[] {"4294967295"}; // 2^32 - 1 + actual = ImapUtility.getImapSequenceValues("4294967295"); + MoreAsserts.assertEquals(expected, actual.toArray()); + expected = new String[] {"1", "3", "2"}; actual = ImapUtility.getImapSequenceValues("1,3,2"); MoreAsserts.assertEquals(expected, actual.toArray()); @@ -50,6 +58,11 @@ public class ImapUtilityTest extends TestCase { actual = ImapUtility.getImapSequenceValues("1,2:4,9:7"); MoreAsserts.assertEquals(expected, actual.toArray()); + // Test numbers larger than Integer.MAX_VALUE (2147483647) + expected = new String[] {"2147483646", "2147483647", "2147483648"}; + actual = ImapUtility.getImapSequenceValues("2147483646:2147483648"); + MoreAsserts.assertEquals(expected, actual.toArray()); + // Test partially invalid sets expected = new String[] { "1", "5" }; actual = ImapUtility.getImapSequenceValues("1,x,5"); @@ -75,6 +88,15 @@ public class ImapUtilityTest extends TestCase { expected = new String[0]; actual = ImapUtility.getImapSequenceValues("1:x"); MoreAsserts.assertEquals(expected, actual.toArray()); + + // Test values larger than 2^32 - 1 + expected = new String[0]; + actual = ImapUtility.getImapSequenceValues("4294967296:4294967297"); + MoreAsserts.assertEquals(expected, actual.toArray()); + + expected = new String[0]; + actual = ImapUtility.getImapSequenceValues("4294967296"); // 2^32 + MoreAsserts.assertEquals(expected, actual.toArray()); } /** From e1d9a4779d0c85bd97ad28b8a395334409da6f15 Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 7 Jul 2012 16:46:07 +0200 Subject: [PATCH 28/35] Changed the rest of ImapStore to use longs for storing UIDs --- src/com/fsck/k9/mail/store/ImapStore.java | 45 ++++++++++++----------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/com/fsck/k9/mail/store/ImapStore.java b/src/com/fsck/k9/mail/store/ImapStore.java index 2e309720a..e783da5a4 100644 --- a/src/com/fsck/k9/mail/store/ImapStore.java +++ b/src/com/fsck/k9/mail/store/ImapStore.java @@ -1246,7 +1246,7 @@ public class ImapStore extends Store { return getRemoteMessageCount("FLAGGED NOT DELETED"); } - protected int getHighestUid() { + protected long getHighestUid() { try { ImapSearcher searcher = new ImapSearcher() { public List search() throws IOException, MessagingException { @@ -1255,12 +1255,12 @@ public class ImapStore extends Store { }; Message[] messages = search(searcher, null); if (messages.length > 0) { - return Integer.parseInt(messages[0].getUid()); + return Long.parseLong(messages[0].getUid()); } } catch (Exception e) { Log.e(K9.LOG_TAG, "Unable to find highest UID in folder " + getName(), e); } - return -1; + return -1L; } @@ -1330,13 +1330,13 @@ public class ImapStore extends Store { checkOpen(); ArrayList messages = new ArrayList(); try { - ArrayList uids = new ArrayList(); + ArrayList uids = new ArrayList(); List responses = searcher.search(); // for (ImapResponse response : responses) { if (response.mTag == null) { if (ImapResponseParser.equalsIgnoreCase(response.get(0), "SEARCH")) { for (int i = 1, count = response.size(); i < count; i++) { - uids.add(Integer.parseInt(response.getString(i))); + uids.add(response.getLong(i)); } } } @@ -1345,10 +1345,11 @@ public class ImapStore extends Store { // Sort the uids in numerically ascending order Collections.sort(uids); for (int i = 0, count = uids.size(); i < count; i++) { + String uid = uids.get(i).toString(); if (listener != null) { - listener.messageStarted("" + uids.get(i), i, count); + listener.messageStarted(uid, i, count); } - ImapMessage message = new ImapMessage("" + uids.get(i), this); + ImapMessage message = new ImapMessage(uid, this); messages.add(message); if (listener != null) { listener.messageFinished(message, i, count); @@ -2091,10 +2092,10 @@ public class ImapStore extends Store { public String getNewPushState(String oldPushStateS, Message message) { try { String messageUidS = message.getUid(); - int messageUid = Integer.parseInt(messageUidS); + long messageUid = Long.parseLong(messageUidS); ImapPushState oldPushState = ImapPushState.parse(oldPushStateS); if (messageUid >= oldPushState.uidNext) { - int uidNext = messageUid + 1; + long uidNext = messageUid + 1; ImapPushState newPushState = new ImapPushState(uidNext); return newPushState.toString(); } else { @@ -2790,7 +2791,7 @@ public class ImapStore extends Store { while (!stop.get()) { try { - int oldUidNext = -1; + long oldUidNext = -1L; try { String pushStateS = receiver.getPushState(getName()); ImapPushState pushState = ImapPushState.parse(pushStateS); @@ -2834,8 +2835,8 @@ public class ImapStore extends Store { if (K9.DEBUG) { Log.d(K9.LOG_TAG, "uidNext is -1, using search to find highest UID"); } - int highestUid = getHighestUid(); - if (highestUid != -1) { + long highestUid = getHighestUid(); + if (highestUid != -1L) { if (K9.DEBUG) Log.d(K9.LOG_TAG, "highest UID = " + highestUid); newUidNext = highestUid + 1; @@ -2982,7 +2983,7 @@ public class ImapStore extends Store { } private void syncMessages(int end, boolean newArrivals) throws MessagingException { - int oldUidNext = -1; + long oldUidNext = -1L; try { String pushStateS = receiver.getPushState(getName()); ImapPushState pushState = ImapPushState.parse(pushStateS); @@ -2995,10 +2996,10 @@ public class ImapStore extends Store { Message[] messageArray = getMessages(end, end, null, true, null); if (messageArray != null && messageArray.length > 0) { - int newUid = Integer.parseInt(messageArray[0].getUid()); + long newUid = Long.parseLong(messageArray[0].getUid()); if (K9.DEBUG) Log.i(K9.LOG_TAG, "Got newUid " + newUid + " for message " + end + " on " + getLogId()); - int startUid = oldUidNext; + long startUid = oldUidNext; if (startUid < newUid - 10) { startUid = newUid - 10; } @@ -3010,8 +3011,8 @@ public class ImapStore extends Store { if (K9.DEBUG) Log.i(K9.LOG_TAG, "Needs sync from uid " + startUid + " to " + newUid + " for " + getLogId()); List messages = new ArrayList(); - for (int uid = startUid; uid <= newUid; uid++) { - ImapMessage message = new ImapMessage("" + uid, ImapFolderPusher.this); + for (long uid = startUid; uid <= newUid; uid++) { + ImapMessage message = new ImapMessage(Long.toString(uid), ImapFolderPusher.this); messages.add(message); } if (!messages.isEmpty()) { @@ -3291,12 +3292,12 @@ public class ImapStore extends Store { } protected static class ImapPushState { - protected int uidNext; - protected ImapPushState(int nUidNext) { + protected long uidNext; + protected ImapPushState(long nUidNext) { uidNext = nUidNext; } protected static ImapPushState parse(String pushState) { - int newUidNext = -1; + long newUidNext = -1L; if (pushState != null) { StringTokenizer tokenizer = new StringTokenizer(pushState, ";"); while (tokenizer.hasMoreTokens()) { @@ -3307,8 +3308,8 @@ public class ImapStore extends Store { if ("uidNext".equalsIgnoreCase(key) && thisState.hasMoreTokens()) { String value = thisState.nextToken(); try { - newUidNext = Integer.parseInt(value); - } catch (Exception e) { + newUidNext = Long.parseLong(value); + } catch (NumberFormatException e) { Log.e(K9.LOG_TAG, "Unable to part uidNext value " + value, e); } From d08169b004fc1dd1a398645031afd96d721ee40c Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 7 Jul 2012 17:14:03 +0200 Subject: [PATCH 29/35] Corrected indentation --- src/com/fsck/k9/mail/store/LocalStore.java | 394 ++++++++++----------- 1 file changed, 195 insertions(+), 199 deletions(-) diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java index 99529d8fd..7165b9cca 100644 --- a/src/com/fsck/k9/mail/store/LocalStore.java +++ b/src/com/fsck/k9/mail/store/LocalStore.java @@ -158,236 +158,232 @@ public class LocalStore extends Store implements Serializable { db.beginTransaction(); try { - try { - // schema version 29 was when we moved to incremental updates - // in the case of a new db or a < v29 db, we blow away and start from scratch - if (db.getVersion() < 29) { + try { + // schema version 29 was when we moved to incremental updates + // in the case of a new db or a < v29 db, we blow away and start from scratch + if (db.getVersion() < 29) { - db.execSQL("DROP TABLE IF EXISTS folders"); - db.execSQL("CREATE TABLE folders (id INTEGER PRIMARY KEY, name TEXT, " - + "last_updated INTEGER, unread_count INTEGER, visible_limit INTEGER, status TEXT, " - + "push_state TEXT, last_pushed INTEGER, flagged_count INTEGER default 0, " - + "integrate INTEGER, top_group INTEGER, poll_class TEXT, push_class TEXT, display_class TEXT" - + ")"); + db.execSQL("DROP TABLE IF EXISTS folders"); + db.execSQL("CREATE TABLE folders (id INTEGER PRIMARY KEY, name TEXT, " + + "last_updated INTEGER, unread_count INTEGER, visible_limit INTEGER, status TEXT, " + + "push_state TEXT, last_pushed INTEGER, flagged_count INTEGER default 0, " + + "integrate INTEGER, top_group INTEGER, poll_class TEXT, push_class TEXT, display_class TEXT" + + ")"); - db.execSQL("CREATE INDEX IF NOT EXISTS folder_name ON folders (name)"); - db.execSQL("DROP TABLE IF EXISTS messages"); - db.execSQL("CREATE TABLE messages (id INTEGER PRIMARY KEY, deleted INTEGER default 0, folder_id INTEGER, uid TEXT, subject TEXT, " - + "date INTEGER, flags TEXT, sender_list TEXT, to_list TEXT, cc_list TEXT, bcc_list TEXT, reply_to_list TEXT, " - + "html_content TEXT, text_content TEXT, attachment_count INTEGER, internal_date INTEGER, message_id TEXT, preview TEXT, " - + "mime_type TEXT)"); + db.execSQL("CREATE INDEX IF NOT EXISTS folder_name ON folders (name)"); + db.execSQL("DROP TABLE IF EXISTS messages"); + db.execSQL("CREATE TABLE messages (id INTEGER PRIMARY KEY, deleted INTEGER default 0, folder_id INTEGER, uid TEXT, subject TEXT, " + + "date INTEGER, flags TEXT, sender_list TEXT, to_list TEXT, cc_list TEXT, bcc_list TEXT, reply_to_list TEXT, " + + "html_content TEXT, text_content TEXT, attachment_count INTEGER, internal_date INTEGER, message_id TEXT, preview TEXT, " + + "mime_type TEXT)"); - db.execSQL("DROP TABLE IF EXISTS headers"); - db.execSQL("CREATE TABLE headers (id INTEGER PRIMARY KEY, message_id INTEGER, name TEXT, value TEXT)"); - db.execSQL("CREATE INDEX IF NOT EXISTS header_folder ON headers (message_id)"); + db.execSQL("DROP TABLE IF EXISTS headers"); + db.execSQL("CREATE TABLE headers (id INTEGER PRIMARY KEY, message_id INTEGER, name TEXT, value TEXT)"); + db.execSQL("CREATE INDEX IF NOT EXISTS header_folder ON headers (message_id)"); - db.execSQL("CREATE INDEX IF NOT EXISTS msg_uid ON messages (uid, folder_id)"); - db.execSQL("DROP INDEX IF EXISTS msg_folder_id"); - db.execSQL("DROP INDEX IF EXISTS msg_folder_id_date"); - db.execSQL("CREATE INDEX IF NOT EXISTS msg_folder_id_deleted_date ON messages (folder_id,deleted,internal_date)"); - db.execSQL("DROP TABLE IF EXISTS attachments"); - db.execSQL("CREATE TABLE attachments (id INTEGER PRIMARY KEY, message_id INTEGER," - + "store_data TEXT, content_uri TEXT, size INTEGER, name TEXT," - + "mime_type TEXT, content_id TEXT, content_disposition TEXT)"); - - db.execSQL("DROP TABLE IF EXISTS pending_commands"); - db.execSQL("CREATE TABLE pending_commands " + - "(id INTEGER PRIMARY KEY, command TEXT, arguments TEXT)"); - - db.execSQL("DROP TRIGGER IF EXISTS delete_folder"); - db.execSQL("CREATE TRIGGER delete_folder BEFORE DELETE ON folders BEGIN DELETE FROM messages WHERE old.id = folder_id; END;"); - - db.execSQL("DROP TRIGGER IF EXISTS delete_message"); - db.execSQL("CREATE TRIGGER delete_message BEFORE DELETE ON messages BEGIN DELETE FROM attachments WHERE old.id = message_id; " - + "DELETE FROM headers where old.id = message_id; END;"); - } else { - // in the case that we're starting out at 29 or newer, run all the needed updates - - if (db.getVersion() < 30) { - try { - db.execSQL("ALTER TABLE messages ADD deleted INTEGER default 0"); - } catch (SQLiteException e) { - if (! e.toString().startsWith("duplicate column name: deleted")) { - throw e; - } - } - } - if (db.getVersion() < 31) { + db.execSQL("CREATE INDEX IF NOT EXISTS msg_uid ON messages (uid, folder_id)"); + db.execSQL("DROP INDEX IF EXISTS msg_folder_id"); db.execSQL("DROP INDEX IF EXISTS msg_folder_id_date"); db.execSQL("CREATE INDEX IF NOT EXISTS msg_folder_id_deleted_date ON messages (folder_id,deleted,internal_date)"); - } - if (db.getVersion() < 32) { - db.execSQL("UPDATE messages SET deleted = 1 WHERE flags LIKE '%DELETED%'"); - } - if (db.getVersion() < 33) { + db.execSQL("DROP TABLE IF EXISTS attachments"); + db.execSQL("CREATE TABLE attachments (id INTEGER PRIMARY KEY, message_id INTEGER," + + "store_data TEXT, content_uri TEXT, size INTEGER, name TEXT," + + "mime_type TEXT, content_id TEXT, content_disposition TEXT)"); - try { - db.execSQL("ALTER TABLE messages ADD preview TEXT"); - } catch (SQLiteException e) { - if (! e.toString().startsWith("duplicate column name: preview")) { - throw e; - } - } + db.execSQL("DROP TABLE IF EXISTS pending_commands"); + db.execSQL("CREATE TABLE pending_commands " + + "(id INTEGER PRIMARY KEY, command TEXT, arguments TEXT)"); - } - if (db.getVersion() < 34) { - try { - db.execSQL("ALTER TABLE folders ADD flagged_count INTEGER default 0"); - } catch (SQLiteException e) { - if (! e.getMessage().startsWith("duplicate column name: flagged_count")) { - throw e; - } - } - } - if (db.getVersion() < 35) { - try { - db.execSQL("update messages set flags = replace(flags, 'X_NO_SEEN_INFO', 'X_BAD_FLAG')"); - } catch (SQLiteException e) { - Log.e(K9.LOG_TAG, "Unable to get rid of obsolete flag X_NO_SEEN_INFO", e); - } - } - if (db.getVersion() < 36) { - try { - db.execSQL("ALTER TABLE attachments ADD content_id TEXT"); - } catch (SQLiteException e) { - Log.e(K9.LOG_TAG, "Unable to add content_id column to attachments"); - } - } - if (db.getVersion() < 37) { - try { - db.execSQL("ALTER TABLE attachments ADD content_disposition TEXT"); - } catch (SQLiteException e) { - Log.e(K9.LOG_TAG, "Unable to add content_disposition column to attachments"); - } - } + db.execSQL("DROP TRIGGER IF EXISTS delete_folder"); + db.execSQL("CREATE TRIGGER delete_folder BEFORE DELETE ON folders BEGIN DELETE FROM messages WHERE old.id = folder_id; END;"); - // Database version 38 is solely to prune cached attachments now that we clear them better - if (db.getVersion() < 39) { - try { - db.execSQL("DELETE FROM headers WHERE id in (SELECT headers.id FROM headers LEFT JOIN messages ON headers.message_id = messages.id WHERE messages.id IS NULL)"); - } catch (SQLiteException e) { - Log.e(K9.LOG_TAG, "Unable to remove extra header data from the database"); - } - } + db.execSQL("DROP TRIGGER IF EXISTS delete_message"); + db.execSQL("CREATE TRIGGER delete_message BEFORE DELETE ON messages BEGIN DELETE FROM attachments WHERE old.id = message_id; " + + "DELETE FROM headers where old.id = message_id; END;"); + } else { + // in the case that we're starting out at 29 or newer, run all the needed updates - // V40: Store the MIME type for a message. - if (db.getVersion() < 40) { - try { - db.execSQL("ALTER TABLE messages ADD mime_type TEXT"); - } catch (SQLiteException e) { - Log.e(K9.LOG_TAG, "Unable to add mime_type column to messages"); - } - } - - if (db.getVersion() < 41) { - try { - db.execSQL("ALTER TABLE folders ADD integrate INTEGER"); - db.execSQL("ALTER TABLE folders ADD top_group INTEGER"); - db.execSQL("ALTER TABLE folders ADD poll_class TEXT"); - db.execSQL("ALTER TABLE folders ADD push_class TEXT"); - db.execSQL("ALTER TABLE folders ADD display_class TEXT"); - } catch (SQLiteException e) { - if (! e.getMessage().startsWith("duplicate column name:")) { - throw e; - } - } - Cursor cursor = null; - - try { - - SharedPreferences prefs = getPreferences(); - cursor = db.rawQuery("SELECT id, name FROM folders", null); - while (cursor.moveToNext()) { - try { - int id = cursor.getInt(0); - String name = cursor.getString(1); - update41Metadata(db, prefs, id, name); - } catch (Exception e) { - Log.e(K9.LOG_TAG, " error trying to ugpgrade a folder class", e); + if (db.getVersion() < 30) { + try { + db.execSQL("ALTER TABLE messages ADD deleted INTEGER default 0"); + } catch (SQLiteException e) { + if (! e.toString().startsWith("duplicate column name: deleted")) { + throw e; } } } - - - catch (SQLiteException e) { - Log.e(K9.LOG_TAG, "Exception while upgrading database to v41. folder classes may have vanished", e); - - } finally { - Utility.closeQuietly(cursor); + if (db.getVersion() < 31) { + db.execSQL("DROP INDEX IF EXISTS msg_folder_id_date"); + db.execSQL("CREATE INDEX IF NOT EXISTS msg_folder_id_deleted_date ON messages (folder_id,deleted,internal_date)"); } - } - if (db.getVersion() == 41) { - try { - long startTime = System.currentTimeMillis(); - SharedPreferences.Editor editor = getPreferences().edit(); + if (db.getVersion() < 32) { + db.execSQL("UPDATE messages SET deleted = 1 WHERE flags LIKE '%DELETED%'"); + } + if (db.getVersion() < 33) { - List folders = getPersonalNamespaces(true); - for (Folder folder : folders) { - if (folder instanceof LocalFolder) { - LocalFolder lFolder = (LocalFolder)folder; - lFolder.save(editor); + try { + db.execSQL("ALTER TABLE messages ADD preview TEXT"); + } catch (SQLiteException e) { + if (! e.toString().startsWith("duplicate column name: preview")) { + throw e; } } - editor.commit(); - long endTime = System.currentTimeMillis(); - Log.i(K9.LOG_TAG, "Putting folder preferences for " + folders.size() + " folders back into Preferences took " + (endTime - startTime) + " ms"); - } catch (Exception e) { - Log.e(K9.LOG_TAG, "Could not replace Preferences in upgrade from DB_VERSION 41", e); } - } - if (db.getVersion() < 43) { - try { - // If folder "OUTBOX" (old, v3.800 - v3.802) exists, rename it to - // "K9MAIL_INTERNAL_OUTBOX" (new) - LocalFolder oldOutbox = new LocalFolder("OUTBOX"); - if (oldOutbox.exists()) { - ContentValues cv = new ContentValues(); - cv.put("name", Account.OUTBOX); - db.update("folders", cv, "name = ?", new String[] { "OUTBOX" }); - Log.i(K9.LOG_TAG, "Renamed folder OUTBOX to " + Account.OUTBOX); + if (db.getVersion() < 34) { + try { + db.execSQL("ALTER TABLE folders ADD flagged_count INTEGER default 0"); + } catch (SQLiteException e) { + if (! e.getMessage().startsWith("duplicate column name: flagged_count")) { + throw e; + } + } + } + if (db.getVersion() < 35) { + try { + db.execSQL("update messages set flags = replace(flags, 'X_NO_SEEN_INFO', 'X_BAD_FLAG')"); + } catch (SQLiteException e) { + Log.e(K9.LOG_TAG, "Unable to get rid of obsolete flag X_NO_SEEN_INFO", e); + } + } + if (db.getVersion() < 36) { + try { + db.execSQL("ALTER TABLE attachments ADD content_id TEXT"); + } catch (SQLiteException e) { + Log.e(K9.LOG_TAG, "Unable to add content_id column to attachments"); + } + } + if (db.getVersion() < 37) { + try { + db.execSQL("ALTER TABLE attachments ADD content_disposition TEXT"); + } catch (SQLiteException e) { + Log.e(K9.LOG_TAG, "Unable to add content_disposition column to attachments"); + } + } + + // Database version 38 is solely to prune cached attachments now that we clear them better + if (db.getVersion() < 39) { + try { + db.execSQL("DELETE FROM headers WHERE id in (SELECT headers.id FROM headers LEFT JOIN messages ON headers.message_id = messages.id WHERE messages.id IS NULL)"); + } catch (SQLiteException e) { + Log.e(K9.LOG_TAG, "Unable to remove extra header data from the database"); + } + } + + // V40: Store the MIME type for a message. + if (db.getVersion() < 40) { + try { + db.execSQL("ALTER TABLE messages ADD mime_type TEXT"); + } catch (SQLiteException e) { + Log.e(K9.LOG_TAG, "Unable to add mime_type column to messages"); + } + } + + if (db.getVersion() < 41) { + try { + db.execSQL("ALTER TABLE folders ADD integrate INTEGER"); + db.execSQL("ALTER TABLE folders ADD top_group INTEGER"); + db.execSQL("ALTER TABLE folders ADD poll_class TEXT"); + db.execSQL("ALTER TABLE folders ADD push_class TEXT"); + db.execSQL("ALTER TABLE folders ADD display_class TEXT"); + } catch (SQLiteException e) { + if (! e.getMessage().startsWith("duplicate column name:")) { + throw e; + } + } + Cursor cursor = null; + + try { + + SharedPreferences prefs = getPreferences(); + cursor = db.rawQuery("SELECT id, name FROM folders", null); + while (cursor.moveToNext()) { + try { + int id = cursor.getInt(0); + String name = cursor.getString(1); + update41Metadata(db, prefs, id, name); + } catch (Exception e) { + Log.e(K9.LOG_TAG, " error trying to ugpgrade a folder class", e); + } + } } - // Check if old (pre v3.800) localized outbox folder exists - String localizedOutbox = K9.app.getString(R.string.special_mailbox_name_outbox); - LocalFolder obsoleteOutbox = new LocalFolder(localizedOutbox); - if (obsoleteOutbox.exists()) { - // Get all messages from the localized outbox ... - Message[] messages = obsoleteOutbox.getMessages(null, false); - if (messages.length > 0) { - // ... and move them to the drafts folder (we don't want to - // surprise the user by sending potentially very old messages) - LocalFolder drafts = new LocalFolder(mAccount.getDraftsFolderName()); - obsoleteOutbox.moveMessages(messages, drafts); + catch (SQLiteException e) { + Log.e(K9.LOG_TAG, "Exception while upgrading database to v41. folder classes may have vanished", e); + + } finally { + Utility.closeQuietly(cursor); + } + } + if (db.getVersion() == 41) { + try { + long startTime = System.currentTimeMillis(); + SharedPreferences.Editor editor = getPreferences().edit(); + + List folders = getPersonalNamespaces(true); + for (Folder folder : folders) { + if (folder instanceof LocalFolder) { + LocalFolder lFolder = (LocalFolder)folder; + lFolder.save(editor); + } } - // Now get rid of the localized outbox - obsoleteOutbox.delete(); - obsoleteOutbox.delete(true); + editor.commit(); + long endTime = System.currentTimeMillis(); + Log.i(K9.LOG_TAG, "Putting folder preferences for " + folders.size() + " folders back into Preferences took " + (endTime - startTime) + " ms"); + } catch (Exception e) { + Log.e(K9.LOG_TAG, "Could not replace Preferences in upgrade from DB_VERSION 41", e); + } + } + if (db.getVersion() < 43) { + try { + // If folder "OUTBOX" (old, v3.800 - v3.802) exists, rename it to + // "K9MAIL_INTERNAL_OUTBOX" (new) + LocalFolder oldOutbox = new LocalFolder("OUTBOX"); + if (oldOutbox.exists()) { + ContentValues cv = new ContentValues(); + cv.put("name", Account.OUTBOX); + db.update("folders", cv, "name = ?", new String[] { "OUTBOX" }); + Log.i(K9.LOG_TAG, "Renamed folder OUTBOX to " + Account.OUTBOX); + } + + // Check if old (pre v3.800) localized outbox folder exists + String localizedOutbox = K9.app.getString(R.string.special_mailbox_name_outbox); + LocalFolder obsoleteOutbox = new LocalFolder(localizedOutbox); + if (obsoleteOutbox.exists()) { + // Get all messages from the localized outbox ... + Message[] messages = obsoleteOutbox.getMessages(null, false); + + if (messages.length > 0) { + // ... and move them to the drafts folder (we don't want to + // surprise the user by sending potentially very old messages) + LocalFolder drafts = new LocalFolder(mAccount.getDraftsFolderName()); + obsoleteOutbox.moveMessages(messages, drafts); + } + + // Now get rid of the localized outbox + obsoleteOutbox.delete(); + obsoleteOutbox.delete(true); + } + } catch (Exception e) { + Log.e(K9.LOG_TAG, "Error trying to fix the outbox folders", e); } - } catch (Exception e) { - Log.e(K9.LOG_TAG, "Error trying to fix the outbox folders", e); } } + } catch (SQLiteException e) { + Log.e(K9.LOG_TAG, "Exception while upgrading database. Resetting the DB to v0"); + db.setVersion(0); + throw new Error("Database upgrade failed! Resetting your DB version to 0 to force a full schema recreation."); } - } - catch (SQLiteException e) { - Log.e(K9.LOG_TAG, "Exception while upgrading database. Resetting the DB to v0"); - db.setVersion(0); - throw new Error("Database upgrade failed! Resetting your DB version to 0 to force a full schema recreation."); - } + db.setVersion(DB_VERSION); + if (db.getVersion() != DB_VERSION) { + throw new Error("Database upgrade failed!"); + } - - db.setVersion(DB_VERSION); - - if (db.getVersion() != DB_VERSION) { - throw new Error("Database upgrade failed!"); - } - - db.setTransactionSuccessful(); + db.setTransactionSuccessful(); } finally { db.endTransaction(); } From 83e57064ffb4b2c62eeace7bb802a0411c6be3f0 Mon Sep 17 00:00:00 2001 From: cketti Date: Sat, 7 Jul 2012 17:15:14 +0200 Subject: [PATCH 30/35] Check database version after ending the transaction --- src/com/fsck/k9/mail/store/LocalStore.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java index 7165b9cca..d7be8b8b0 100644 --- a/src/com/fsck/k9/mail/store/LocalStore.java +++ b/src/com/fsck/k9/mail/store/LocalStore.java @@ -379,15 +379,15 @@ public class LocalStore extends Store implements Serializable { db.setVersion(DB_VERSION); - if (db.getVersion() != DB_VERSION) { - throw new Error("Database upgrade failed!"); - } - db.setTransactionSuccessful(); } finally { db.endTransaction(); } + if (db.getVersion() != DB_VERSION) { + throw new Error("Database upgrade failed!"); + } + // Unless we're blowing away the whole data store, there's no reason to prune attachments // every time the user upgrades. it'll just cost them money and pain. // try From b72fcd9d4b1deee73617ecd852dde72d09e7241c Mon Sep 17 00:00:00 2001 From: cketti Date: Fri, 13 Jul 2012 23:04:04 +0200 Subject: [PATCH 31/35] Only use the single-column layout on known good Android versions Fixes issue 3820 --- src/com/fsck/k9/activity/setup/Prefs.java | 11 +++++----- src/com/fsck/k9/view/MessageWebView.java | 25 ++++++++++++++++++++--- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/com/fsck/k9/activity/setup/Prefs.java b/src/com/fsck/k9/activity/setup/Prefs.java index 20e77a455..734c7761a 100644 --- a/src/com/fsck/k9/activity/setup/Prefs.java +++ b/src/com/fsck/k9/activity/setup/Prefs.java @@ -33,6 +33,7 @@ import com.fsck.k9.preferences.CheckBoxListPreference; import com.fsck.k9.preferences.TimePickerPreference; import com.fsck.k9.service.MailService; +import com.fsck.k9.view.MessageWebView; public class Prefs extends K9PreferenceActivity { @@ -279,13 +280,13 @@ public class Prefs extends K9PreferenceActivity { mZoomControlsEnabled.setChecked(K9.zoomControlsEnabled()); mMobileOptimizedLayout = (CheckBoxPreference) findPreference(PREFERENCE_MESSAGEVIEW_MOBILE_LAYOUT); - if (Build.VERSION.SDK_INT <= 7) { + if (!MessageWebView.isSingleColumnLayoutSupported()) { mMobileOptimizedLayout.setEnabled(false); + mMobileOptimizedLayout.setChecked(false); + } else { + mMobileOptimizedLayout.setChecked(K9.mobileOptimizedLayout()); } - - mMobileOptimizedLayout.setChecked(K9.mobileOptimizedLayout()); - mQuietTimeEnabled = (CheckBoxPreference) findPreference(PREFERENCE_QUIET_TIME_ENABLED); mQuietTimeEnabled.setChecked(K9.getQuietTimeEnabled()); @@ -354,7 +355,7 @@ public class Prefs extends K9PreferenceActivity { } }; }); - + mBatchButtonsMarkRead = (CheckBoxPreference)findPreference(PREFERENCE_BATCH_BUTTONS_MARK_READ); mBatchButtonsDelete = (CheckBoxPreference)findPreference(PREFERENCE_BATCH_BUTTONS_DELETE); mBatchButtonsArchive = (CheckBoxPreference)findPreference(PREFERENCE_BATCH_BUTTONS_ARCHIVE); diff --git a/src/com/fsck/k9/view/MessageWebView.java b/src/com/fsck/k9/view/MessageWebView.java index 9d61b87e4..563262203 100644 --- a/src/com/fsck/k9/view/MessageWebView.java +++ b/src/com/fsck/k9/view/MessageWebView.java @@ -25,6 +25,27 @@ public class MessageWebView extends WebView { */ public static final Method mGetBlockNetworkLoads = K9.getMethod(WebSettings.class, "setBlockNetworkLoads"); + /** + * Check whether the single column layout algorithm can be used on this version of Android. + * + *

+ * Single column layout was broken on Android < 2.2 (see + * issue 5024). + *

+ * + *

+ * Android versions >= 3.0 have problems with unclickable links when single column layout is + * enabled (see + * issue 34886 + * in Android's bug tracker, and + * issue 3820 + * in K-9 Mail's bug tracker). + */ + public static boolean isSingleColumnLayoutSupported() { + return (Build.VERSION.SDK_INT > 7 && Build.VERSION.SDK_INT < 11); + } + + public MessageWebView(Context context) { super(context); } @@ -91,9 +112,7 @@ public class MessageWebView extends WebView { webSettings.setBuiltInZoomControls(true); } - // SINGLE_COLUMN layout was broken on Android < 2.2, so we - // administratively disable it - if (Build.VERSION.SDK_INT > 7 && K9.mobileOptimizedLayout()) { + if (isSingleColumnLayoutSupported() && K9.mobileOptimizedLayout()) { webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); } else { webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS); From 5467a71cbfb06b38a3aff97381a5595c762da9ea Mon Sep 17 00:00:00 2001 From: cketti Date: Mon, 16 Jul 2012 02:08:22 +0200 Subject: [PATCH 32/35] Added work-around for image loading bug in Android 4.0's WebView Fixes issue 3997 --- src/com/fsck/k9/view/SingleMessageView.java | 25 ++++++++++++--------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/com/fsck/k9/view/SingleMessageView.java b/src/com/fsck/k9/view/SingleMessageView.java index 09fab78e4..13cc7885a 100644 --- a/src/com/fsck/k9/view/SingleMessageView.java +++ b/src/com/fsck/k9/view/SingleMessageView.java @@ -104,6 +104,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, private LinearLayout mInsideAttachmentsContainer; private SavedState mSavedState; private ClipboardManager mClipboardManager; + private String mText; public void initialize(Activity activity) { @@ -400,7 +401,10 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, break; } case R.id.show_pictures: { + // Allow network access first... setLoadPictures(true); + // ...then re-populate the WebView with the message text + loadBodyFromText(mText, "text/html"); break; } } @@ -538,28 +542,20 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, MessagingController controller, MessagingListener listener) throws MessagingException { resetView(); - String type; String text = null; if (pgpData != null) { text = pgpData.getDecryptedData(); } if (text != null) { - type = "text/html"; text = "

" + text + "
"; } else { // getTextForDisplay() always returns HTML-ified content. text = message.getTextForDisplay(); - type = "text/html"; - } - if (text != null) { - final String emailText = text; - final String contentType = type; - loadBodyFromText(emailText, contentType); - updateCryptoLayout(account.getCryptoProvider(), pgpData, message); - } else { - showStatusMessage(getContext().getString(R.string.webview_empty_message)); } + // Save the text so we can reset the WebView when the user clicks the "Show pictures" button + mText = text; + mHasAttachments = message.hasAttachments(); if (mHasAttachments) { @@ -607,6 +603,13 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, } } } + + if (text != null) { + loadBodyFromText(text, "text/html"); + updateCryptoLayout(account.getCryptoProvider(), pgpData, message); + } else { + showStatusMessage(getContext().getString(R.string.webview_empty_message)); + } } public void showStatusMessage(String status) { From eb7f94a500f0828302e1dec997f23e0e38839cf3 Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 19 Jul 2012 02:23:09 +0200 Subject: [PATCH 33/35] Hide "Show unread count" (notifications) on Honeycomb+ devices On Android 3.0 and newer the notification icon is no longer overlaid with the 'notification number', so we hide the setting. --- .../k9/activity/setup/AccountSettings.java | 25 ++++++++++++++++--- .../k9/controller/MessagingController.java | 6 ++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/com/fsck/k9/activity/setup/AccountSettings.java b/src/com/fsck/k9/activity/setup/AccountSettings.java index 5d130d4a1..ce4b87cb1 100644 --- a/src/com/fsck/k9/activity/setup/AccountSettings.java +++ b/src/com/fsck/k9/activity/setup/AccountSettings.java @@ -6,6 +6,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; import android.os.Vibrator; import android.preference.*; @@ -50,6 +51,7 @@ public class AccountSettings extends K9PreferenceActivity { private static final String PREFERENCE_SCREEN_COMPOSING = "composing"; private static final String PREFERENCE_SCREEN_INCOMING = "incoming_prefs"; private static final String PREFERENCE_SCREEN_PUSH_ADVANCED = "push_advanced"; + private static final String PREFERENCE_SCREEN_NOTIFICATIONS = "notifications"; private static final String PREFERENCE_DESCRIPTION = "account_description"; private static final String PREFERENCE_MARK_MESSAGE_AS_READ_ON_VIEW = "mark_message_as_read_on_view"; @@ -572,8 +574,23 @@ public class AccountSettings extends K9PreferenceActivity { mNotificationOpensUnread = (CheckBoxPreference)findPreference(PREFERENCE_NOTIFICATION_OPENS_UNREAD); mNotificationOpensUnread.setChecked(mAccount.goToUnreadMessageSearch()); - mNotificationUnreadCount = (CheckBoxPreference)findPreference(PREFERENCE_NOTIFICATION_UNREAD_COUNT); - mNotificationUnreadCount.setChecked(mAccount.isNotificationShowsUnreadCount()); + CheckBoxPreference notificationUnreadCount = + (CheckBoxPreference) findPreference(PREFERENCE_NOTIFICATION_UNREAD_COUNT); + + /* + * Honeycomb and newer don't show the notification number as overlay on the notification + * icon in the status bar, so we hide the setting. + * + * See http://code.google.com/p/android/issues/detail?id=21477 + */ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + PreferenceScreen notificationsPrefs = + (PreferenceScreen) findPreference(PREFERENCE_SCREEN_NOTIFICATIONS); + notificationsPrefs.removePreference(notificationUnreadCount); + } else { + notificationUnreadCount.setChecked(mAccount.isNotificationShowsUnreadCount()); + mNotificationUnreadCount = notificationUnreadCount; + } new PopulateFolderPrefsTask().execute(); @@ -690,7 +707,9 @@ public class AccountSettings extends K9PreferenceActivity { mAccount.getNotificationSetting().setVibrateTimes(Integer.parseInt(mAccountVibrateTimes.getValue())); mAccount.getNotificationSetting().setLed(mAccountLed.isChecked()); mAccount.setGoToUnreadMessageSearch(mNotificationOpensUnread.isChecked()); - mAccount.setNotificationShowsUnreadCount(mNotificationUnreadCount.isChecked()); + if (mNotificationUnreadCount != null) { + mAccount.setNotificationShowsUnreadCount(mNotificationUnreadCount.isChecked()); + } mAccount.setFolderTargetMode(Account.FolderMode.valueOf(mTargetMode.getValue())); mAccount.setDeletePolicy(Integer.parseInt(mDeletePolicy.getValue())); if (mIsExpungeCapable) { diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java index 082b1a360..8819b3d13 100644 --- a/src/com/fsck/k9/controller/MessagingController.java +++ b/src/com/fsck/k9/controller/MessagingController.java @@ -21,6 +21,7 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.net.Uri; +import android.os.Build; import android.os.PowerManager; import android.os.Process; import android.text.TextUtils; @@ -4188,7 +4189,10 @@ public class MessagingController implements Runnable { builder.setTicker(messageNotice); final int unreadCount = previousUnreadMessageCount + newMessageCount.get(); - if (account.isNotificationShowsUnreadCount()) { + if (account.isNotificationShowsUnreadCount() || + // Honeycomb and newer don't show the number as overlay on the notification icon. + // However, the number will appear in the detailed notification view. + Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { builder.setNumber(unreadCount); } From 853b4681b2bb8c974f128dc147c3f7ad57650ec2 Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 19 Jul 2012 05:25:23 +0200 Subject: [PATCH 34/35] Hide 'Background data' option on ICS+ devices --- res/values/arrays.xml | 1 + res/values/strings.xml | 1 + src/com/fsck/k9/activity/setup/Prefs.java | 27 +++++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/res/values/arrays.xml b/res/values/arrays.xml index e6fe55cee..6538086d5 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -502,6 +502,7 @@ dark + @string/background_ops_enabled @string/background_ops_auto_sync diff --git a/res/values/strings.xml b/res/values/strings.xml index 45ce6409a..9e638588a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -833,6 +833,7 @@ http://k9mail.googlecode.com/ Always When \'Background data\' is checked When \'Background data\' & \'Auto-sync\' are checked + When \'Auto-sync\' is checked No message selected diff --git a/src/com/fsck/k9/activity/setup/Prefs.java b/src/com/fsck/k9/activity/setup/Prefs.java index 734c7761a..d23eb84b9 100644 --- a/src/com/fsck/k9/activity/setup/Prefs.java +++ b/src/com/fsck/k9/activity/setup/Prefs.java @@ -316,6 +316,33 @@ public class Prefs extends K9PreferenceActivity { mBackgroundOps = setupListPreference(PREFERENCE_BACKGROUND_OPS, K9.getBackgroundOps().toString()); + // In ICS+ there is no 'background data' setting that apps can chose to ignore anymore. So + // we hide that option for "Background Sync". + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + CharSequence[] oldEntries = mBackgroundOps.getEntries(); + CharSequence[] newEntries = new CharSequence[3]; + // Use "When 'Auto-sync' is checked" instead of "When 'Background data' & 'Auto-sync' + // are checked" as description. + newEntries[0] = getString(R.string.background_ops_auto_sync_only); + newEntries[1] = oldEntries[2]; + newEntries[2] = oldEntries[3]; + + CharSequence[] oldValues = mBackgroundOps.getEntryValues(); + CharSequence[] newValues = new CharSequence[3]; + newValues[0] = oldValues[1]; + newValues[1] = oldValues[2]; + newValues[2] = oldValues[3]; + + mBackgroundOps.setEntries(newEntries); + mBackgroundOps.setEntryValues(newValues); + + // Since ConnectivityManager.getBackgroundDataSetting() always returns 'true' on ICS+ + // we map WHEN_CHECKED to ALWAYS. + if (K9.getBackgroundOps() == K9.BACKGROUND_OPS.WHEN_CHECKED) { + mBackgroundOps.setValue(K9.BACKGROUND_OPS.ALWAYS.toString()); + mBackgroundOps.setSummary(mBackgroundOps.getEntry()); + } + } mUseGalleryBugWorkaround = (CheckBoxPreference)findPreference(PREFERENCE_GALLERY_BUG_WORKAROUND); mUseGalleryBugWorkaround.setChecked(K9.useGalleryBugWorkaround()); From b15148662d9642f21bc0a758029248b23ef789f7 Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Sun, 22 Jul 2012 11:09:24 -0700 Subject: [PATCH 35/35] Bumped manifest to 4.121 --- AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 6692e231f..23f34bfe2 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@