From a9ac20b96f8d2e2e97fb2878afb9df4795024450 Mon Sep 17 00:00:00 2001 From: Todd Kennedy Date: Fri, 6 May 2011 13:37:02 -0700 Subject: [PATCH] Add lastSeenMessageKey column to the mailbox table The last seen message key is the id of the last message that we've "seen" for that mailbox Change-Id: I197f8a191654225ada1ce553cc959db775809c88 --- .../emailcommon/provider/EmailContent.java | 21 ++++--- .../android/emailcommon/utility/Utility.java | 59 +++++++++++++++++++ .../email/activity/MailboxListFragment.java | 1 + .../android/email/provider/EmailProvider.java | 23 +++++++- 4 files changed, 93 insertions(+), 11 deletions(-) diff --git a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java index 9f0c855e0..e18583273 100644 --- a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java +++ b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java @@ -712,13 +712,8 @@ public abstract class EmailContent { // 8 general purpose flags (bits) that may be used at the discretion of the sync adapter public static final int FLAG_SYNC_ADAPTER_SHIFT = 9; public static final int FLAG_SYNC_ADAPTER_MASK = 255 << FLAG_SYNC_ADAPTER_SHIFT; - /** - * Bit used in mFlags indicating that the outgoing message should *not* include quoted - * original message. ("Not", in order to keep compatibility with old databases) - */ - public static final int FLAG_NOT_INCLUDE_QUOTED_TEXT_SHIFT = 17; - public static final int FLAG_NOT_INCLUDE_QUOTED_TEXT - = 1 << FLAG_NOT_INCLUDE_QUOTED_TEXT_SHIFT; + /** If set, the outgoing message should *not* include the quoted original message. */ + public static final int FLAG_NOT_INCLUDE_QUOTED_TEXT = 1 << 17; public Message() { mBaseUri = CONTENT_URI; @@ -2237,6 +2232,8 @@ public abstract class EmailContent { public static final String SYNC_STATUS = "syncStatus"; // Number of messages in the mailbox. public static final String MESSAGE_COUNT = "messageCount"; + // Number of messages in the mailbox. + public static final String LAST_SEEN_MESSAGE_KEY = "lastSeenMessageKey"; } public static final class Mailbox extends EmailContent implements SyncColumns, MailboxColumns { @@ -2261,6 +2258,7 @@ public abstract class EmailContent { public int mFlags; public int mVisibleLimit; public String mSyncStatus; + public long mLastSeenMessageKey; public static final int CONTENT_ID_COLUMN = 0; public static final int CONTENT_DISPLAY_NAME_COLUMN = 1; @@ -2278,6 +2276,8 @@ public abstract class EmailContent { public static final int CONTENT_VISIBLE_LIMIT_COLUMN = 13; public static final int CONTENT_SYNC_STATUS_COLUMN = 14; public static final int CONTENT_PARENT_KEY_COLUMN = 15; + public static final int CONTENT_LAST_SEEN_MESSAGE_KEY_COLUMN = 16; + /** * NOTE: If fields are added or removed, the method {@link #getHashes()} * MUST be updated. @@ -2288,7 +2288,8 @@ public abstract class EmailContent { MailboxColumns.DELIMITER, MailboxColumns.SYNC_KEY, MailboxColumns.SYNC_LOOKBACK, MailboxColumns.SYNC_INTERVAL, MailboxColumns.SYNC_TIME, MailboxColumns.FLAG_VISIBLE, MailboxColumns.FLAGS, MailboxColumns.VISIBLE_LIMIT, - MailboxColumns.SYNC_STATUS, MailboxColumns.PARENT_KEY + MailboxColumns.SYNC_STATUS, MailboxColumns.PARENT_KEY, + MailboxColumns.LAST_SEEN_MESSAGE_KEY, }; private static final String ACCOUNT_AND_MAILBOX_TYPE_SELECTION = @@ -2474,6 +2475,7 @@ public abstract class EmailContent { mFlags = cursor.getInt(CONTENT_FLAGS_COLUMN); mVisibleLimit = cursor.getInt(CONTENT_VISIBLE_LIMIT_COLUMN); mSyncStatus = cursor.getString(CONTENT_SYNC_STATUS_COLUMN); + mLastSeenMessageKey = cursor.getLong(CONTENT_LAST_SEEN_MESSAGE_KEY_COLUMN); } @Override @@ -2494,6 +2496,7 @@ public abstract class EmailContent { values.put(MailboxColumns.FLAGS, mFlags); values.put(MailboxColumns.VISIBLE_LIMIT, mVisibleLimit); values.put(MailboxColumns.SYNC_STATUS, mSyncStatus); + values.put(MailboxColumns.LAST_SEEN_MESSAGE_KEY, mLastSeenMessageKey); return values; } @@ -2668,6 +2671,8 @@ public abstract class EmailContent { = mSyncStatus; hash[CONTENT_PARENT_KEY_COLUMN] = mParentKey; + hash[CONTENT_LAST_SEEN_MESSAGE_KEY_COLUMN] + = mLastSeenMessageKey; return hash; } } diff --git a/emailcommon/src/com/android/emailcommon/utility/Utility.java b/emailcommon/src/com/android/emailcommon/utility/Utility.java index 654a33413..4c3f79bf9 100644 --- a/emailcommon/src/com/android/emailcommon/utility/Utility.java +++ b/emailcommon/src/com/android/emailcommon/utility/Utility.java @@ -902,6 +902,65 @@ public class Utility { } } + /** + * Updates the last seen message key in the mailbox data base for the INBOX of the currently + * shown account. If the account is {@link Account#ACCOUNT_ID_COMBINED_VIEW}, the INBOX for + * all accounts are updated. + */ + public static void updateLastSeenMessageKey(final Context context, final long accountId) { + EmailAsyncTask.runAsyncParallel(new Runnable() { + private void updateLastSeenMessageKeyForAccount(long accountId) { + ContentResolver resolver = context.getContentResolver(); + if (accountId == Account.ACCOUNT_ID_COMBINED_VIEW) { + Cursor c = resolver.query( + Account.CONTENT_URI, EmailContent.ID_PROJECTION, null, null, null); + if (c == null) throw new ProviderUnavailableException(); + try { + while (c.moveToNext()) { + final long id = c.getLong(EmailContent.ID_PROJECTION_COLUMN); + updateLastSeenMessageKeyForAccount(id); + } + } finally { + c.close(); + } + } else { + Mailbox mailbox = + Mailbox.restoreMailboxOfType(context, accountId, Mailbox.TYPE_INBOX); + + // mailbox has been removed + if (mailbox == null) { + return; + } + // We use the highest _id for the account the mailbox table as the "last seen + // message key". We don't care if the message has been read or not. We only + // need a point at which we can compare against in the future. By setting this + // value, we are claiming that every message before this has potentially been + // seen by the user. + long messageId = Utility.getFirstRowLong( + context, + Message.CONTENT_URI, + EmailContent.ID_PROJECTION, + MessageColumns.MAILBOX_KEY + "=?", + new String[] { Long.toString(mailbox.mId) }, + MessageColumns.ID + " DESC", + EmailContent.ID_PROJECTION_COLUMN, 0L); + ContentValues values = mailbox.toContentValues(); + values.put(MailboxColumns.LAST_SEEN_MESSAGE_KEY, messageId); + resolver.update( + Mailbox.CONTENT_URI, + values, + EmailContent.ID_SELECTION, + new String[] { Long.toString(mailbox.mId) }); + } + } + + @Override + public void run() { + updateLastSeenMessageKeyForAccount(accountId); + } + }); + } + public static long[] toPrimitiveLongArray(Collection collection) { // Need to do this manually because we're converting to a primitive long array, not // a Long array. diff --git a/src/com/android/email/activity/MailboxListFragment.java b/src/com/android/email/activity/MailboxListFragment.java index db205e073..9a14b9db7 100644 --- a/src/com/android/email/activity/MailboxListFragment.java +++ b/src/com/android/email/activity/MailboxListFragment.java @@ -362,6 +362,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList mResumed = false; super.onPause(); mSavedListState = getListView().onSaveInstanceState(); + Utility.updateLastSeenMessageKey(mActivity, mAccountId); } /** diff --git a/src/com/android/email/provider/EmailProvider.java b/src/com/android/email/provider/EmailProvider.java index da0ab5c53..ab598ebe8 100644 --- a/src/com/android/email/provider/EmailProvider.java +++ b/src/com/android/email/provider/EmailProvider.java @@ -130,7 +130,8 @@ public class EmailProvider extends ContentProvider { // Version 19: Add Policy table; add policyKey to Account table and trigger to delete an // Account's policy when the Account is deleted // Version 20: Add new policies to Policy table - public static final int DATABASE_VERSION = 20; + // Version 21: Add lastSeenMessageKey column to Mailbox table + public static final int DATABASE_VERSION = 21; // Any changes to the database format *must* include update-in-place code. // Original version: 2 @@ -626,7 +627,8 @@ public class EmailProvider extends ContentProvider { + MailboxColumns.FLAGS + " integer, " + MailboxColumns.VISIBLE_LIMIT + " integer, " + MailboxColumns.SYNC_STATUS + " text, " - + MailboxColumns.MESSAGE_COUNT + " integer not null default 0" + + MailboxColumns.MESSAGE_COUNT + " integer not null default 0, " + + MailboxColumns.LAST_SEEN_MESSAGE_KEY + " integer" + ");"; db.execSQL("create table " + Mailbox.TABLE_NAME + s); db.execSQL("create index mailbox_" + MailboxColumns.SERVER_ID @@ -1054,10 +1056,14 @@ public class EmailProvider extends ContentProvider { " integer;"); } catch (SQLException e) { // Shouldn't be needed unless we're debugging and interrupt the process - Log.w(TAG, "Exception upgrading EmailProvider.db from 19 to 2 " + e); + Log.w(TAG, "Exception upgrading EmailProvider.db from 19 to 20 " + e); } oldVersion = 20; } + if (oldVersion == 20) { + upgradeFromVersion20ToVersion21(db); + oldVersion = 21; + } } @Override @@ -1833,4 +1839,15 @@ public class EmailProvider extends ContentProvider { Log.w(TAG, "Exception upgrading EmailProvider.db from 17 to 18 " + e); } } + + /** Upgrades the database from v20 to v21 */ + private static void upgradeFromVersion20ToVersion21(SQLiteDatabase db) { + try { + db.execSQL("alter table " + Mailbox.TABLE_NAME + + " add column " + Mailbox.LAST_SEEN_MESSAGE_KEY + " integer;"); + } catch (SQLException e) { + // Shouldn't be needed unless we're debugging and interrupt the process + Log.w(TAG, "Exception upgrading EmailProvider.db from 20 to 21 " + e); + } + } }