From bf5caf97c547c8fa4bbdc2b500e8d43ee6322fcf Mon Sep 17 00:00:00 2001 From: Marc Blank Date: Thu, 23 Feb 2012 17:15:08 -0800 Subject: [PATCH] Notify by mailbox, rather than account * Update EmailProvider, removing two no-longer-used columns in Account and Mailbox Change-Id: Ie0f10eb0ca315d73e82be968f7760a51a239ba3f --- .../android/emailcommon/provider/Account.java | 15 +- .../emailcommon/provider/EmailContent.java | 10 +- .../android/emailcommon/provider/Mailbox.java | 40 +-- .../android/emailcommon/utility/Utility.java | 27 +- .../android/email/NotificationController.java | 237 ++++++++---------- .../email/activity/MessageListFragment.java | 5 +- src/com/android/email/provider/DBHelper.java | 50 ++-- .../android/email/provider/EmailProvider.java | 60 ++++- .../email/NotificationControllerTest.java | 6 +- .../emailcommon/provider/MailboxTests.java | 17 +- .../emailcommon/utility/UtilityUnitTests.java | 32 ++- 11 files changed, 254 insertions(+), 245 deletions(-) diff --git a/emailcommon/src/com/android/emailcommon/provider/Account.java b/emailcommon/src/com/android/emailcommon/provider/Account.java index 89be59be2..35604438e 100755 --- a/emailcommon/src/com/android/emailcommon/provider/Account.java +++ b/emailcommon/src/com/android/emailcommon/provider/Account.java @@ -127,8 +127,6 @@ public final class Account extends EmailContent implements AccountColumns, Parce public String mSecuritySyncKey; public String mSignature; public long mPolicyKey; - public long mNotifiedMessageId; - public int mNotifiedMessageCount; // Convenience for creating/working with an account public transient HostAuth mHostAuthRecv; @@ -155,8 +153,6 @@ public final class Account extends EmailContent implements AccountColumns, Parce public static final int CONTENT_SECURITY_SYNC_KEY_COLUMN = 15; public static final int CONTENT_SIGNATURE_COLUMN = 16; public static final int CONTENT_POLICY_KEY = 17; - public static final int CONTENT_NOTIFIED_MESSAGE_ID = 18; - public static final int CONTENT_NOTIFIED_MESSAGE_COUNT = 19; public static final String[] CONTENT_PROJECTION = new String[] { RECORD_ID, AccountColumns.DISPLAY_NAME, @@ -166,8 +162,7 @@ public final class Account extends EmailContent implements AccountColumns, Parce AccountColumns.COMPATIBILITY_UUID, AccountColumns.SENDER_NAME, AccountColumns.RINGTONE_URI, AccountColumns.PROTOCOL_VERSION, AccountColumns.NEW_MESSAGE_COUNT, AccountColumns.SECURITY_SYNC_KEY, - AccountColumns.SIGNATURE, AccountColumns.POLICY_KEY, - AccountColumns.NOTIFIED_MESSAGE_ID, AccountColumns.NOTIFIED_MESSAGE_COUNT + AccountColumns.SIGNATURE, AccountColumns.POLICY_KEY }; public static final int CONTENT_MAILBOX_TYPE_COLUMN = 1; @@ -272,8 +267,6 @@ public final class Account extends EmailContent implements AccountColumns, Parce mSecuritySyncKey = cursor.getString(CONTENT_SECURITY_SYNC_KEY_COLUMN); mSignature = cursor.getString(CONTENT_SIGNATURE_COLUMN); mPolicyKey = cursor.getLong(CONTENT_POLICY_KEY); - mNotifiedMessageId = cursor.getLong(CONTENT_NOTIFIED_MESSAGE_ID); - mNotifiedMessageCount = cursor.getInt(CONTENT_NOTIFIED_MESSAGE_COUNT); } private long getId(Uri u) { @@ -852,8 +845,6 @@ public final class Account extends EmailContent implements AccountColumns, Parce values.put(AccountColumns.SECURITY_SYNC_KEY, mSecuritySyncKey); values.put(AccountColumns.SIGNATURE, mSignature); values.put(AccountColumns.POLICY_KEY, mPolicyKey); - values.put(AccountColumns.NOTIFIED_MESSAGE_ID, mNotifiedMessageId); - values.put(AccountColumns.NOTIFIED_MESSAGE_COUNT, mNotifiedMessageCount); return values; } @@ -905,8 +896,6 @@ public final class Account extends EmailContent implements AccountColumns, Parce dest.writeString(mSecuritySyncKey); dest.writeString(mSignature); dest.writeLong(mPolicyKey); - dest.writeLong(mNotifiedMessageId); - dest.writeInt(mNotifiedMessageCount); if (mHostAuthRecv != null) { dest.writeByte((byte)1); @@ -946,8 +935,6 @@ public final class Account extends EmailContent implements AccountColumns, Parce mSecuritySyncKey = in.readString(); mSignature = in.readString(); mPolicyKey = in.readLong(); - mNotifiedMessageId = in.readLong(); - mNotifiedMessageCount = in.readInt(); mHostAuthRecv = null; if (in.readByte() == 1) { diff --git a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java index 90112c5b1..99d9f032e 100755 --- a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java +++ b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java @@ -1374,10 +1374,6 @@ public abstract class EmailContent { public static final String SIGNATURE = "signature"; // A foreign key into the Policy table public static final String POLICY_KEY = "policyKey"; - // The last notified message id - public static final String NOTIFIED_MESSAGE_ID = "notifiedMessageId"; - // The most recent notified message count - public static final String NOTIFIED_MESSAGE_COUNT = "notifiedMessageCount"; } public interface QuickResponseColumns { @@ -1423,14 +1419,16 @@ public abstract class EmailContent { public static final String SYNC_STATUS = "syncStatus"; // Number of messages in the mailbox. public static final String MESSAGE_COUNT = "messageCount"; - // Message ID of the last 'seen' message - public static final String LAST_SEEN_MESSAGE_KEY = "lastSeenMessageKey"; // The last time a message in this mailbox has been read (in millis) public static final String LAST_TOUCHED_TIME = "lastTouchedTime"; // The UIProvider sync status public static final String UI_SYNC_STATUS = "uiSyncStatus"; // The UIProvider last sync result public static final String UI_LAST_SYNC_RESULT = "uiLastSyncResult"; + // The UIProvider sync status + public static final String LAST_NOTIFIED_MESSAGE_KEY = "lastNotifiedMessageKey"; + // The UIProvider last sync result + public static final String LAST_NOTIFIED_MESSAGE_COUNT = "lastNotifiedMessageCount"; } public interface HostAuthColumns { diff --git a/emailcommon/src/com/android/emailcommon/provider/Mailbox.java b/emailcommon/src/com/android/emailcommon/provider/Mailbox.java index 7dd14cd47..4935f6704 100644 --- a/emailcommon/src/com/android/emailcommon/provider/Mailbox.java +++ b/emailcommon/src/com/android/emailcommon/provider/Mailbox.java @@ -55,10 +55,11 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns public int mFlags; public int mVisibleLimit; public String mSyncStatus; - public long mLastSeenMessageKey; public long mLastTouchedTime; public int mUiSyncStatus; public int mUiLastSyncResult; + public long mLastNotifiedMessageKey; + public int mLastNotifiedMessageCount; public static final int CONTENT_ID_COLUMN = 0; public static final int CONTENT_DISPLAY_NAME_COLUMN = 1; @@ -76,10 +77,11 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns 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; - public static final int CONTENT_LAST_TOUCHED_TIME_COLUMN = 17; - public static final int CONTENT_UI_SYNC_STATUS_COLUMN = 18; - public static final int CONTENT_UI_LAST_SYNC_RESULT_COLUMN = 19; + public static final int CONTENT_LAST_TOUCHED_TIME_COLUMN = 16; + public static final int CONTENT_UI_SYNC_STATUS_COLUMN = 17; + public static final int CONTENT_UI_LAST_SYNC_RESULT_COLUMN = 18; + public static final int CONTENT_LAST_NOTIFIED_MESSAGE_KEY_COLUMN = 19; + public static final int CONTENT_LAST_NOTIFIED_MESSAGE_COUNT_COLUMN = 20; /** * NOTE: If fields are added or removed, the method {@link #getHashes()} @@ -91,9 +93,9 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns 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.LAST_SEEN_MESSAGE_KEY, MailboxColumns.LAST_TOUCHED_TIME, - MailboxColumns.UI_SYNC_STATUS, MailboxColumns.UI_LAST_SYNC_RESULT + MailboxColumns.SYNC_STATUS, MailboxColumns.PARENT_KEY, MailboxColumns.LAST_TOUCHED_TIME, + MailboxColumns.UI_SYNC_STATUS, MailboxColumns.UI_LAST_SYNC_RESULT, + MailboxColumns.LAST_NOTIFIED_MESSAGE_KEY, MailboxColumns.LAST_NOTIFIED_MESSAGE_COUNT }; private static final String ACCOUNT_AND_MAILBOX_TYPE_SELECTION = @@ -311,10 +313,11 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns 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); mLastTouchedTime = cursor.getLong(CONTENT_LAST_TOUCHED_TIME_COLUMN); mUiSyncStatus = cursor.getInt(CONTENT_UI_SYNC_STATUS_COLUMN); mUiLastSyncResult = cursor.getInt(CONTENT_UI_LAST_SYNC_RESULT_COLUMN); + mLastNotifiedMessageKey = cursor.getLong(CONTENT_LAST_NOTIFIED_MESSAGE_KEY_COLUMN); + mLastNotifiedMessageCount = cursor.getInt(CONTENT_LAST_NOTIFIED_MESSAGE_COUNT_COLUMN); } @Override @@ -335,10 +338,11 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns 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); values.put(MailboxColumns.LAST_TOUCHED_TIME, mLastTouchedTime); values.put(MailboxColumns.UI_SYNC_STATUS, mUiSyncStatus); values.put(MailboxColumns.UI_LAST_SYNC_RESULT, mUiLastSyncResult); + values.put(MailboxColumns.LAST_NOTIFIED_MESSAGE_KEY, mLastNotifiedMessageKey); + values.put(MailboxColumns.LAST_NOTIFIED_MESSAGE_COUNT, mLastNotifiedMessageCount); return values; } @@ -547,10 +551,16 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns = mSyncStatus; hash[CONTENT_PARENT_KEY_COLUMN] = mParentKey; - hash[CONTENT_LAST_SEEN_MESSAGE_KEY_COLUMN] - = mLastSeenMessageKey; hash[CONTENT_LAST_TOUCHED_TIME_COLUMN] = mLastTouchedTime; + hash[CONTENT_UI_SYNC_STATUS_COLUMN] + = mUiSyncStatus; + hash[CONTENT_UI_LAST_SYNC_RESULT_COLUMN] + = mUiLastSyncResult; + hash[CONTENT_LAST_NOTIFIED_MESSAGE_KEY_COLUMN] + = mLastNotifiedMessageKey; + hash[CONTENT_LAST_NOTIFIED_MESSAGE_COUNT_COLUMN] + = mLastNotifiedMessageCount; return hash; } @@ -580,10 +590,11 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns dest.writeInt(mFlags); dest.writeInt(mVisibleLimit); dest.writeString(mSyncStatus); - dest.writeLong(mLastSeenMessageKey); dest.writeLong(mLastTouchedTime); dest.writeInt(mUiSyncStatus); dest.writeInt(mUiLastSyncResult); + dest.writeLong(mLastNotifiedMessageKey); + dest.writeInt(mLastNotifiedMessageCount); } public Mailbox(Parcel in) { @@ -604,10 +615,11 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns mFlags = in.readInt(); mVisibleLimit = in.readInt(); mSyncStatus = in.readString(); - mLastSeenMessageKey = in.readLong(); mLastTouchedTime = in.readLong(); mUiSyncStatus = in.readInt(); mUiLastSyncResult = in.readInt(); + mLastNotifiedMessageKey = in.readLong(); + mLastNotifiedMessageCount = in.readInt(); } public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { diff --git a/emailcommon/src/com/android/emailcommon/utility/Utility.java b/emailcommon/src/com/android/emailcommon/utility/Utility.java index 0a698d442..fba57cc07 100644 --- a/emailcommon/src/com/android/emailcommon/utility/Utility.java +++ b/emailcommon/src/com/android/emailcommon/utility/Utility.java @@ -897,28 +897,27 @@ public class Utility { * all accounts are updated. * @return an {@link EmailAsyncTask} for test only. */ - public static EmailAsyncTask updateLastSeenMessageKey(final Context context, - final long accountId) { + public static EmailAsyncTask updateLastNotifiedMessageKey( + final Context context, final long mailboxId) { return EmailAsyncTask.runAsyncParallel(new Runnable() { - private void updateLastSeenMessageKeyForAccount(long accountId) { + private void updateLastSeenMessageKeyForMailbox(long mailboxId) { ContentResolver resolver = context.getContentResolver(); - if (accountId == Account.ACCOUNT_ID_COMBINED_VIEW) { + if (mailboxId == Mailbox.QUERY_ALL_INBOXES) { Cursor c = resolver.query( - Account.CONTENT_URI, EmailContent.ID_PROJECTION, null, null, null); + Mailbox.CONTENT_URI, EmailContent.ID_PROJECTION, Mailbox.TYPE + "=?", + new String[] { Integer.toString(Mailbox.TYPE_INBOX) }, null); if (c == null) throw new ProviderUnavailableException(); try { while (c.moveToNext()) { final long id = c.getLong(EmailContent.ID_PROJECTION_COLUMN); - updateLastSeenMessageKeyForAccount(id); + updateLastSeenMessageKeyForMailbox(id); } } finally { c.close(); } - } else if (accountId > 0L) { - Mailbox mailbox = - Mailbox.restoreMailboxOfType(context, accountId, Mailbox.TYPE_INBOX); - - // mailbox has been removed + } else if (mailboxId > 0L) { + Mailbox mailbox = Mailbox.restoreMailboxWithId(context, mailboxId); + // mailbox has been removed if (mailbox == null) { return; } @@ -937,12 +936,12 @@ public class Utility { EmailContent.ID_PROJECTION_COLUMN, 0L); long oldLastSeenMessageId = Utility.getFirstRowLong( context, ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailbox.mId), - new String[] { MailboxColumns.LAST_SEEN_MESSAGE_KEY }, + new String[] { MailboxColumns.LAST_NOTIFIED_MESSAGE_KEY }, null, null, null, 0, 0L); // Only update the db if the value has changed if (messageId != oldLastSeenMessageId) { ContentValues values = mailbox.toContentValues(); - values.put(MailboxColumns.LAST_SEEN_MESSAGE_KEY, messageId); + values.put(MailboxColumns.LAST_NOTIFIED_MESSAGE_KEY, messageId); resolver.update( Mailbox.CONTENT_URI, values, @@ -954,7 +953,7 @@ public class Utility { @Override public void run() { - updateLastSeenMessageKeyForAccount(accountId); + updateLastSeenMessageKeyForMailbox(mailboxId); } }); } diff --git a/src/com/android/email/NotificationController.java b/src/com/android/email/NotificationController.java index 859808e3c..7bd334c7e 100644 --- a/src/com/android/email/NotificationController.java +++ b/src/com/android/email/NotificationController.java @@ -42,15 +42,14 @@ import com.android.email.activity.ContactStatusLoader; import com.android.email.activity.Welcome; import com.android.email.activity.setup.AccountSecurity; import com.android.email.activity.setup.AccountSettings; +import com.android.email.provider.EmailProvider; import com.android.emailcommon.Logging; import com.android.emailcommon.mail.Address; import com.android.emailcommon.provider.Account; import com.android.emailcommon.provider.EmailContent; -import com.android.emailcommon.provider.EmailContent.AccountColumns; import com.android.emailcommon.provider.EmailContent.Attachment; import com.android.emailcommon.provider.EmailContent.MailboxColumns; import com.android.emailcommon.provider.EmailContent.Message; -import com.android.emailcommon.provider.EmailContent.MessageColumns; import com.android.emailcommon.provider.Mailbox; import com.android.emailcommon.utility.EmailAsyncTask; import com.android.emailcommon.utility.Utility; @@ -89,18 +88,15 @@ public class NotificationController { private final Bitmap mGenericSenderIcon; private final Bitmap mGenericMultipleSenderIcon; private final Clock mClock; - // TODO We're maintaining all of our structures based upon the account ID. This is fine - // for now since the assumption is that we only ever look for changes in an account's - // INBOX. We should adjust our logic to use the mailbox ID instead. - /** Maps account id to the message data */ + /** Maps account id to its observer */ private final HashMap mNotificationMap; private ContentObserver mAccountObserver; /** - * Suspend notifications for this account. If {@link Account#NO_ACCOUNT}, no - * account notifications are suspended. If {@link Account#ACCOUNT_ID_COMBINED_VIEW}, - * notifications for all accounts are suspended. + * Suspend notifications for this mailbox. If {@link Mailbox.NO_MAILBOX}, no + * account notifications are suspended. If {@link Mailbox.COMBINED_INBOX}, + * notifications for all inboxes are suspended. */ - private long mSuspendAccountId = Account.NO_ACCOUNT; + private long mSuspendMailboxId = Mailbox.NO_MAILBOX; /** * Timestamp indicating when the last message notification sound was played. @@ -167,7 +163,7 @@ public class NotificationController { * to the settings for the given account. * @return A {@link Notification} that can be sent to the notification service. */ - private Notification createAccountNotification(Account account, String ticker, + private Notification createMailboxNotification(Mailbox mailbox, String ticker, CharSequence title, String contentText, Intent intent, Bitmap largeIcon, Integer number, boolean enableAudio, boolean ongoing) { // Pending Intent @@ -190,6 +186,7 @@ public class NotificationController { .setOngoing(ongoing); if (enableAudio) { + Account account = Account.restoreAccountWithId(mContext, mailbox.mAccountKey); setupSoundAndVibration(builder, account); } @@ -207,9 +204,9 @@ public class NotificationController { * @param intent The intent to start if the user clicks on the notification. * @param notificationId The ID of the notification to register with the service. */ - private void showAccountNotification(Account account, String ticker, String title, + private void showMailboxNotification(Mailbox mailbox, String ticker, String title, String contentText, Intent intent, int notificationId) { - Notification notification = createAccountNotification(account, ticker, title, contentText, + Notification notification = createMailboxNotification(mailbox, ticker, title, contentText, intent, null, null, true, needsOngoingNotification(notificationId)); mNotificationManager.notify(notificationId, notification); } @@ -217,9 +214,9 @@ public class NotificationController { /** * Returns a notification ID for new message notifications for the given account. */ - private int getNewMessageNotificationId(long accountId) { + private int getNewMessageNotificationId(long mailboxId) { // We assume accountId will always be less than 0x0FFFFFFF; is there a better way? - return (int) (NOTIFICATION_ID_BASE_NEW_MESSAGES + accountId); + return (int) (NOTIFICATION_ID_BASE_NEW_MESSAGES + mailboxId); } /** @@ -272,36 +269,22 @@ public class NotificationController { } /** - * Temporarily suspend a single account from receiving notifications. NOTE: only a single - * account may ever be suspended at a time. So, if this method is invoked a second time, - * notifications for the previously suspended account will automatically be re-activated. - * @param suspend If {@code true}, suspend notifications for the given account. Otherwise, - * re-activate notifications for the previously suspended account. - * @param accountId The ID of the account. If this is the special account ID - * {@link Account#ACCOUNT_ID_COMBINED_VIEW}, notifications for all accounts are - * suspended. If {@code suspend} is {@code false}, the account ID is ignored. + * Temporarily suspend a single mailbox from receiving notifications. NOTE: only a single + * mailbox may ever be suspended at a time. So, if this method is invoked a second time, + * notifications for the previously mailbox will automatically be re-activated. + * @param suspend If {@code true}, suspend notifications for the given mailbox. Otherwise, + * re-activate notifications for the previously suspended mailbox. + * @param mailboxId The ID of the mailbox. If this is the special mailbox ID + * {@link Account#ACCOUNT_ID_COMBINED_VIEW}, notifications for all inboxes are + * suspended. If {@code suspend} is {@code false}, the mailbox ID is ignored. */ - public void suspendMessageNotification(boolean suspend, long accountId) { - if (mSuspendAccountId != Account.NO_ACCOUNT) { - // we're already suspending an account; un-suspend it - mSuspendAccountId = Account.NO_ACCOUNT; + public void suspendMessageNotification(boolean suspend, long mailboxId) { + if (mSuspendMailboxId != Mailbox.NO_MAILBOX) { + // we're already suspending a mailbox; un-suspend it + mSuspendMailboxId = Mailbox.NO_MAILBOX; } - if (suspend && accountId != Account.NO_ACCOUNT && accountId > 0L) { - mSuspendAccountId = accountId; - if (accountId == Account.ACCOUNT_ID_COMBINED_VIEW) { - // Only go onto the notification handler if we really, absolutely need to - ensureHandlerExists(); - sNotificationHandler.post(new Runnable() { - @Override - public void run() { - for (long accountId : mNotificationMap.keySet()) { - mNotificationManager.cancel(getNewMessageNotificationId(accountId)); - } - } - }); - } else { - mNotificationManager.cancel(getNewMessageNotificationId(accountId)); - } + if (suspend && mailboxId != Mailbox.NO_MAILBOX) { + mSuspendMailboxId = mailboxId; } } @@ -350,7 +333,7 @@ public class NotificationController { Log.i(Logging.LOG_TAG, "Registering for notifications for account " + accountId); } ContentObserver observer = new MessageContentObserver( - sNotificationHandler, mContext, mailbox.mId, accountId); + sNotificationHandler, mContext, accountId); resolver.registerContentObserver(Message.NOTIFIER_URI, true, observer); mNotificationMap.put(accountId, observer); // Now, ping the observer for any initial notifications @@ -412,9 +395,18 @@ public class NotificationController { * NOTE: DO NOT CALL THIS METHOD FROM THE UI THREAD (DATABASE ACCESS) */ @VisibleForTesting - Notification createNewMessageNotification(long accountId, long mailboxId, long messageId, + Notification createNewMessageNotification(long mailboxId, long messageId, int unseenMessageCount, int unreadCount) { - final Account account = Account.restoreAccountWithId(mContext, accountId); + final Mailbox mailbox = Mailbox.restoreMailboxWithId(mContext, mailboxId); + if (mailbox == null) { + return null; + } + // No notification if we're suspended... + if (mSuspendMailboxId == mailboxId || (mSuspendMailboxId == Mailbox.QUERY_ALL_INBOXES && + mailbox.mType == Mailbox.TYPE_INBOX)) { + return null; + } + final Account account = Account.restoreAccountWithId(mContext, mailbox.mAccountKey); if (account == null) { return null; } @@ -435,22 +427,24 @@ public class NotificationController { final SpannableString title = getNewMessageTitle(senderName, unseenMessageCount); // TODO: add in display name on the second line for the text, once framework supports // multiline texts. + // Show account name if an inbox; otherwise mailbox name final String text = multipleUnseen - ? account.mDisplayName + ? ((mailbox.mType == Mailbox.TYPE_INBOX) ? account.mDisplayName : + mailbox.mDisplayName) : message.mSubject; final Bitmap largeIcon = senderPhoto != null ? senderPhoto : mGenericSenderIcon; final Integer number = unreadCount > 1 ? unreadCount : null; final Intent intent; if (unseenMessageCount > 1) { - intent = Welcome.createOpenAccountInboxIntent(mContext, accountId); + intent = Welcome.createOpenAccountInboxIntent(mContext, account.mId); } else { - intent = Welcome.createOpenMessageIntent(mContext, accountId, mailboxId, messageId); + intent = Welcome.createOpenMessageIntent(mContext, account.mId, mailboxId, messageId); } intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); long now = mClock.getTime(); boolean enableAudio = (now - mLastMessageNotifyTime) > MIN_SOUND_INTERVAL_MS; - Notification notification = createAccountNotification( - account, title.toString(), title, text, + Notification notification = createMailboxNotification( + mailbox, title.toString(), title, text, intent, largeIcon, number, enableAudio, false); mLastMessageNotifyTime = now; return notification; @@ -505,9 +499,10 @@ public class NotificationController { * NOTE: DO NOT CALL THIS METHOD FROM THE UI THREAD (DATABASE ACCESS) */ public void showDownloadForwardFailedNotification(Attachment attachment) { - final Account account = Account.restoreAccountWithId(mContext, attachment.mAccountKey); - if (account == null) return; - showAccountNotification(account, + Message message = Message.restoreMessageWithId(mContext, attachment.mMessageKey); + if (message == null) return; + Mailbox mailbox = Mailbox.restoreMailboxWithId(mContext, message.mMailboxKey); + showMailboxNotification(mailbox, mContext.getString(R.string.forward_download_failed_ticker), mContext.getString(R.string.forward_download_failed_title), attachment.mFileName, @@ -530,7 +525,10 @@ public class NotificationController { public void showLoginFailedNotification(long accountId) { final Account account = Account.restoreAccountWithId(mContext, accountId); if (account == null) return; - showAccountNotification(account, + final Mailbox mailbox = Mailbox.restoreMailboxOfType(mContext, account.mId, + Mailbox.TYPE_INBOX); + if (mailbox == null) return; + showMailboxNotification(mailbox, mContext.getString(R.string.login_failed_ticker, account.mDisplayName), mContext.getString(R.string.login_failed_title), account.getDisplayName(), @@ -555,6 +553,9 @@ public class NotificationController { public void showPasswordExpiringNotification(long accountId) { Account account = Account.restoreAccountWithId(mContext, accountId); if (account == null) return; + final Mailbox mailbox = Mailbox.restoreMailboxOfType(mContext, account.mId, + Mailbox.TYPE_INBOX); + if (mailbox == null) return; Intent intent = AccountSecurity.actionDevicePasswordExpirationIntent(mContext, accountId, false); @@ -562,7 +563,7 @@ public class NotificationController { String ticker = mContext.getString(R.string.password_expire_warning_ticker_fmt, accountName); String title = mContext.getString(R.string.password_expire_warning_content_title); - showAccountNotification(account, ticker, title, accountName, intent, + showMailboxNotification(mailbox, ticker, title, accountName, intent, NOTIFICATION_ID_PASSWORD_EXPIRING); } @@ -575,13 +576,16 @@ public class NotificationController { public void showPasswordExpiredNotification(long accountId) { Account account = Account.restoreAccountWithId(mContext, accountId); if (account == null) return; + final Mailbox mailbox = Mailbox.restoreMailboxOfType(mContext, account.mId, + Mailbox.TYPE_INBOX); + if (mailbox == null) return; Intent intent = AccountSecurity.actionDevicePasswordExpirationIntent(mContext, accountId, true); String accountName = account.getDisplayName(); String ticker = mContext.getString(R.string.password_expired_ticker); String title = mContext.getString(R.string.password_expired_content_title); - showAccountNotification(account, ticker, title, accountName, intent, + showMailboxNotification(mailbox, ticker, title, accountName, intent, NOTIFICATION_ID_PASSWORD_EXPIRED); } @@ -598,12 +602,15 @@ public class NotificationController { * dialog asking whether he wants to update his settings. */ public void showSecurityNeededNotification(Account account) { + final Mailbox mailbox = Mailbox.restoreMailboxOfType(mContext, account.mId, + Mailbox.TYPE_INBOX); + if (mailbox == null) return; Intent intent = AccountSecurity.actionUpdateSecurityIntent(mContext, account.mId, true); String accountName = account.getDisplayName(); String ticker = mContext.getString(R.string.security_needed_ticker_fmt, accountName); String title = mContext.getString(R.string.security_notification_content_update_title); - showAccountNotification(account, ticker, title, accountName, intent, + showMailboxNotification(mailbox, ticker, title, accountName, intent, (int)(NOTIFICATION_ID_BASE_SECURITY_NEEDED + account.mId)); } @@ -612,12 +619,15 @@ public class NotificationController { * account settings screen where he can view the list of enforced policies */ public void showSecurityChangedNotification(Account account) { + final Mailbox mailbox = Mailbox.restoreMailboxOfType(mContext, account.mId, + Mailbox.TYPE_INBOX); + if (mailbox == null) return; Intent intent = AccountSettings.createAccountSettingsIntent(mContext, account.mId, null); String accountName = account.getDisplayName(); String ticker = mContext.getString(R.string.security_changed_ticker_fmt, accountName); String title = mContext.getString(R.string.security_notification_content_change_title); - showAccountNotification(account, ticker, title, accountName, intent, + showMailboxNotification(mailbox, ticker, title, accountName, intent, (int)(NOTIFICATION_ID_BASE_SECURITY_CHANGED + account.mId)); } @@ -626,12 +636,15 @@ public class NotificationController { * account settings screen where he can view the list of unsupported policies */ public void showSecurityUnsupportedNotification(Account account) { + final Mailbox mailbox = Mailbox.restoreMailboxOfType(mContext, account.mId, + Mailbox.TYPE_INBOX); + if (mailbox == null) return; Intent intent = AccountSettings.createAccountSettingsIntent(mContext, account.mId, null); String accountName = account.getDisplayName(); String ticker = mContext.getString(R.string.security_unsupported_ticker_fmt, accountName); String title = mContext.getString(R.string.security_notification_content_unsupported_title); - showAccountNotification(account, ticker, title, accountName, intent, + showMailboxNotification(mailbox, ticker, title, accountName, intent, (int)(NOTIFICATION_ID_BASE_SECURITY_NEEDED + account.mId)); } @@ -661,105 +674,56 @@ public class NotificationController { * Observer invoked whenever a message we're notifying the user about changes. */ private static class MessageContentObserver extends ContentObserver { - /** A selection to get messages the user hasn't seen before */ - private final static String MESSAGE_SELECTION = - MessageColumns.MAILBOX_KEY + "=? AND " - + MessageColumns.ID + ">? AND " - + MessageColumns.FLAG_READ + "=0 AND " - + Message.FLAG_LOADED_SELECTION; private final Context mContext; - private final long mMailboxId; private final long mAccountId; public MessageContentObserver( - Handler handler, Context context, long mailboxId, long accountId) { + Handler handler, Context context, long accountId) { super(handler); mContext = context; - mMailboxId = mailboxId; mAccountId = accountId; } @Override public void onChange(boolean selfChange) { - if (mAccountId == sInstance.mSuspendAccountId - || sInstance.mSuspendAccountId == Account.ACCOUNT_ID_COMBINED_VIEW) { - return; - } - ContentObserver observer = sInstance.mNotificationMap.get(mAccountId); - if (observer == null) { - // Notification for a mailbox that we aren't observing; account is probably - // being deleted. - Log.w(Logging.LOG_TAG, "Received notification when observer data was null"); - return; - } Account account = Account.restoreAccountWithId(mContext, mAccountId); - if (account == null) { + if (observer == null || account == null) { Log.w(Logging.LOG_TAG, "Couldn't find account for changed message notification"); return; } - long oldMessageId = account.mNotifiedMessageId; - int oldMessageCount = account.mNotifiedMessageCount; ContentResolver resolver = mContext.getContentResolver(); - Long lastSeenMessageId = Utility.getFirstRowLong( - mContext, ContentUris.withAppendedId(Mailbox.CONTENT_URI, mMailboxId), - new String[] { MailboxColumns.LAST_SEEN_MESSAGE_KEY }, - null, null, null, 0); - if (lastSeenMessageId == null) { - // Mailbox got nuked. Could be that the account is in the process of being deleted - Log.w(Logging.LOG_TAG, "Couldn't find mailbox for changed message notification"); - return; - } - - Cursor c = resolver.query( - Message.CONTENT_URI, EmailContent.ID_PROJECTION, - MESSAGE_SELECTION, - new String[] { Long.toString(mMailboxId), Long.toString(lastSeenMessageId) }, - MessageColumns.ID + " DESC"); - if (c == null) { - // Couldn't find message info - things may be getting deleted in bulk. - Log.w(Logging.LOG_TAG, "#onChange(); NULL response for message id query"); - return; - } + Cursor c = resolver.query(ContentUris.withAppendedId( + EmailProvider.MAILBOX_NOTIFICATION_URI, mAccountId), + EmailProvider.NOTIFICATION_PROJECTION, null, null, null); try { - int newMessageCount = c.getCount(); - long newMessageId = 0L; - if (c.moveToNext()) { - newMessageId = c.getLong(EmailContent.ID_PROJECTION_COLUMN); - } - - if (newMessageCount == 0) { - // No messages to notify for; clear the notification - int notificationId = sInstance.getNewMessageNotificationId(mAccountId); - sInstance.mNotificationManager.cancel(notificationId); - } else if (newMessageCount != oldMessageCount - || (newMessageId != 0 && newMessageId != oldMessageId)) { - // Either the count or last message has changed; update the notification - Integer unreadCount = Utility.getFirstRowInt( - mContext, ContentUris.withAppendedId(Mailbox.CONTENT_URI, mMailboxId), - new String[] { MailboxColumns.UNREAD_COUNT }, - null, null, null, 0); - if (unreadCount == null) { - Log.w(Logging.LOG_TAG, "Couldn't find unread count for mailbox"); - return; - } - - Notification n = sInstance.createNewMessageNotification( - mAccountId, mMailboxId, newMessageId, - newMessageCount, unreadCount); + while (c.moveToNext()) { + long mailboxId = c.getLong(EmailProvider.NOTIFICATION_MAILBOX_ID_COLUMN); + int messageCount = + c.getInt(EmailProvider.NOTIFICATION_MAILBOX_MESSAGE_COUNT_COLUMN); + int unreadCount = + c.getInt(EmailProvider.NOTIFICATION_MAILBOX_UNREAD_COUNT_COLUMN); + System.err.println("Changes in " + c.getLong(0) + ", unread: " + unreadCount); + long newMessageId = Utility.getFirstRowLong(mContext, + ContentUris.withAppendedId( + EmailProvider.MAILBOX_MOST_RECENT_MESSAGE_URI, mailboxId), + Message.ID_COLUMN_PROJECTION, null, null, null, + Message.ID_MAILBOX_COLUMN_ID, -1L); + Notification n = sInstance.createNewMessageNotification(mailboxId, newMessageId, + messageCount, unreadCount); if (n != null) { // Make the notification visible sInstance.mNotificationManager.notify( - sInstance.getNewMessageNotificationId(mAccountId), n); + sInstance.getNewMessageNotificationId(mailboxId), n); } + // Save away the new values + ContentValues cv = new ContentValues(); + cv.put(MailboxColumns.LAST_NOTIFIED_MESSAGE_KEY, newMessageId); + cv.put(MailboxColumns.LAST_NOTIFIED_MESSAGE_COUNT, messageCount); + resolver.update(ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId), cv, + null, null); } - // Save away the new values - ContentValues cv = new ContentValues(); - cv.put(AccountColumns.NOTIFIED_MESSAGE_ID, newMessageId); - cv.put(AccountColumns.NOTIFIED_MESSAGE_COUNT, newMessageCount); - resolver.update(ContentUris.withAppendedId(Account.CONTENT_URI, mAccountId), cv, - null, null); } finally { c.close(); } @@ -780,8 +744,7 @@ public class NotificationController { @Override public void onChange(boolean selfChange) { final ContentResolver resolver = mContext.getContentResolver(); - final Cursor c = resolver.query( - Account.CONTENT_URI, EmailContent.ID_PROJECTION, + final Cursor c = resolver.query(Account.CONTENT_URI, EmailContent.ID_PROJECTION, NOTIFIED_ACCOUNT_SELECTION, null, null); final HashSet newAccountList = new HashSet(); final HashSet removedAccountList = new HashSet(); diff --git a/src/com/android/email/activity/MessageListFragment.java b/src/com/android/email/activity/MessageListFragment.java index 8ece5ed60..af7fa6ec4 100644 --- a/src/com/android/email/activity/MessageListFragment.java +++ b/src/com/android/email/activity/MessageListFragment.java @@ -1221,14 +1221,13 @@ public class MessageListFragment extends ListFragment * viewed mailbox will be updated. */ private void adjustMessageNotification(boolean updateLastSeenKey) { - final long accountId = getAccountId(); final long mailboxId = getMailboxId(); if (mailboxId == Mailbox.QUERY_ALL_INBOXES || mailboxId > 0) { if (updateLastSeenKey) { - Utility.updateLastSeenMessageKey(mActivity, accountId); + Utility.updateLastNotifiedMessageKey(mActivity, mailboxId); } NotificationController notifier = NotificationController.getInstance(mActivity); - notifier.suspendMessageNotification(mResumed, accountId); + notifier.suspendMessageNotification(mResumed, mailboxId); } } diff --git a/src/com/android/email/provider/DBHelper.java b/src/com/android/email/provider/DBHelper.java index 03a3b74cd..409f26cad 100644 --- a/src/com/android/email/provider/DBHelper.java +++ b/src/com/android/email/provider/DBHelper.java @@ -113,8 +113,10 @@ public final class DBHelper { // Version 29: Add protocolPoliciesEnforced and protocolPoliciesUnsupported to Policy // Version 30: Use CSV of RFC822 addresses instead of "packed" values // Version 31: Add columns to mailbox for ui status/last result + // Version 32: Add columns to mailbox for last notified message key/count; insure not null + // for "notified" columns - public static final int DATABASE_VERSION = 31; + public static final int DATABASE_VERSION = 32; // Any changes to the database format *must* include update-in-place code. // Original version: 2 @@ -302,9 +304,7 @@ public final class DBHelper { + AccountColumns.SECURITY_FLAGS + " integer, " + AccountColumns.SECURITY_SYNC_KEY + " text, " + AccountColumns.SIGNATURE + " text, " - + AccountColumns.POLICY_KEY + " integer, " - + AccountColumns.NOTIFIED_MESSAGE_ID + " integer, " - + AccountColumns.NOTIFIED_MESSAGE_COUNT + " integer" + + AccountColumns.POLICY_KEY + " integer" + ");"; db.execSQL("create table " + Account.TABLE_NAME + s); // Deleting an account deletes associated Mailboxes and HostAuth's @@ -389,10 +389,11 @@ public final class DBHelper { + MailboxColumns.VISIBLE_LIMIT + " integer, " + MailboxColumns.SYNC_STATUS + " text, " + MailboxColumns.MESSAGE_COUNT + " integer not null default 0, " - + MailboxColumns.LAST_SEEN_MESSAGE_KEY + " integer, " + MailboxColumns.LAST_TOUCHED_TIME + " integer default 0, " + MailboxColumns.UI_SYNC_STATUS + " integer default 0, " - + MailboxColumns.UI_LAST_SYNC_RESULT + " integer default 0" + + MailboxColumns.UI_LAST_SYNC_RESULT + " integer default 0, " + + MailboxColumns.LAST_NOTIFIED_MESSAGE_KEY + " integer not null default 0, " + + MailboxColumns.LAST_NOTIFIED_MESSAGE_COUNT + " integer not null default 0" + ");"; db.execSQL("create table " + Mailbox.TABLE_NAME + s); db.execSQL("create index mailbox_" + MailboxColumns.SERVER_ID @@ -744,7 +745,6 @@ public final class DBHelper { oldVersion = 20; } if (oldVersion == 20) { - upgradeFromVersion20ToVersion21(db); oldVersion = 21; } if (oldVersion == 21) { @@ -782,15 +782,6 @@ public final class DBHelper { oldVersion = 27; } if (oldVersion == 27) { - try { - db.execSQL("alter table " + Account.TABLE_NAME - + " add column " + Account.NOTIFIED_MESSAGE_ID + " integer;"); - db.execSQL("alter table " + Account.TABLE_NAME - + " add column " + Account.NOTIFIED_MESSAGE_COUNT + " integer;"); - } catch (SQLException e) { - // Shouldn't be needed unless we're debugging and interrupt the process - Log.w(TAG, "Exception upgrading EmailProvider.db from 27 to 28 " + e); - } oldVersion = 28; } if (oldVersion == 28) { @@ -821,6 +812,22 @@ public final class DBHelper { } oldVersion = 31; } + if (oldVersion == 31) { + try { + db.execSQL("alter table " + Mailbox.TABLE_NAME + + " add column " + Mailbox.LAST_NOTIFIED_MESSAGE_KEY + " integer;"); + db.execSQL("alter table " + Mailbox.TABLE_NAME + + " add column " + Mailbox.LAST_NOTIFIED_MESSAGE_COUNT + " integer;"); + db.execSQL("update Mailbox set " + Mailbox.LAST_NOTIFIED_MESSAGE_KEY + + "=0 where " + Mailbox.LAST_NOTIFIED_MESSAGE_KEY + " IS NULL"); + db.execSQL("update Mailbox set " + Mailbox.LAST_NOTIFIED_MESSAGE_COUNT + + "=0 where " + Mailbox.LAST_NOTIFIED_MESSAGE_COUNT + " IS NULL"); + } catch (SQLException e) { + // Shouldn't be needed unless we're debugging and interrupt the process + Log.w(TAG, "Exception upgrading EmailProvider.db from 31 to 32 " + e); + } + oldVersion = 32; + } } @Override @@ -887,17 +894,6 @@ public final class DBHelper { ContentCache.invalidateAllCaches(); } - /** 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); - } - } - /** * Upgrade the database from v21 to v22 * This entails creating AccountManager accounts for all pop3 and imap accounts diff --git a/src/com/android/email/provider/EmailProvider.java b/src/com/android/email/provider/EmailProvider.java index 2c4a3dbc0..4d5f92b09 100644 --- a/src/com/android/email/provider/EmailProvider.java +++ b/src/com/android/email/provider/EmailProvider.java @@ -157,7 +157,9 @@ public class EmailProvider extends ContentProvider { private static final int MAILBOX = MAILBOX_BASE; private static final int MAILBOX_ID = MAILBOX_BASE + 1; private static final int MAILBOX_ID_FROM_ACCOUNT_AND_TYPE = MAILBOX_BASE + 2; - private static final int MAILBOX_ID_ADD_TO_FIELD = MAILBOX_BASE + 2; + private static final int MAILBOX_ID_ADD_TO_FIELD = MAILBOX_BASE + 3; + private static final int MAILBOX_NOTIFICATION = MAILBOX_BASE + 4; + private static final int MAILBOX_MOST_RECENT_MESSAGE = MAILBOX_BASE + 5; private static final int MESSAGE_BASE = 0x2000; private static final int MESSAGE = MESSAGE_BASE; @@ -329,6 +331,10 @@ public class EmailProvider extends ContentProvider { matcher.addURI(EmailContent.AUTHORITY, "mailbox/#", MAILBOX_ID); matcher.addURI(EmailContent.AUTHORITY, "mailboxIdFromAccountAndType/#/#", MAILBOX_ID_FROM_ACCOUNT_AND_TYPE); + matcher.addURI(EmailContent.AUTHORITY, "mailboxNotification/#", MAILBOX_NOTIFICATION); + matcher.addURI(EmailContent.AUTHORITY, "mailboxMostRecentMessage/#", + MAILBOX_MOST_RECENT_MESSAGE); + // All messages matcher.addURI(EmailContent.AUTHORITY, "message", MESSAGE); // A specific message @@ -1138,6 +1144,10 @@ public class EmailProvider extends ContentProvider { return c; case UI_FOLDER_REFRESH: return uiFolderRefresh(uri, projection); + case MAILBOX_NOTIFICATION: + return notificationQuery(uri); + case MAILBOX_MOST_RECENT_MESSAGE: + return mostRecentMessageQuery(uri); case ACCOUNT_DEFAULT_ID: // Start with a snapshot of the cache Map accountCache = mCacheAccount.getSnapshot(); @@ -1798,6 +1808,54 @@ outer: mAttachmentService = (as == null) ? DEFAULT_ATTACHMENT_SERVICE : as; } + public static final String[] NOTIFICATION_PROJECTION = + new String[] {MailboxColumns.ID, MailboxColumns.UNREAD_COUNT, MailboxColumns.MESSAGE_COUNT}; + public static final int NOTIFICATION_MAILBOX_ID_COLUMN = 0; + public static final int NOTIFICATION_MAILBOX_UNREAD_COUNT_COLUMN = 1; + public static final int NOTIFICATION_MAILBOX_MESSAGE_COUNT_COLUMN = 2; + + public static final Uri MAILBOX_NOTIFICATION_URI = + Uri.parse("content://" + EmailContent.AUTHORITY + "/mailboxNotification"); + public static final Uri MAILBOX_MOST_RECENT_MESSAGE_URI = + Uri.parse("content://" + EmailContent.AUTHORITY + "/mailboxMostRecentMessage"); + + // SELECT DISTINCT Boxes._id, Boxes.unreadCount from Message, (SELECT _id, unreadCount, + // messageCount, lastNotifiedMessageCount, lastNotifiedMessageKey + // FROM Mailbox WHERE accountKey=6 AND syncInterval!=0 AND syncInterval!=-1) AS Boxes + // WHERE Boxes.messageCount!=Boxes.lastNotifiedMessageCount + // OR (Boxes._id=Message.mailboxKey AND Message._id>Boxes.lastNotifiedMessageKey) + // TODO: This query can be simplified a bit + private static final String NOTIFICATION_QUERY = + "SELECT DISTINCT Boxes." + MailboxColumns.ID + ", Boxes." + MailboxColumns.UNREAD_COUNT + + ", Boxes." + MailboxColumns.MESSAGE_COUNT + + " FROM " + + Message.TABLE_NAME + "," + + "(SELECT " + MailboxColumns.ID + "," + MailboxColumns.UNREAD_COUNT + "," + + MailboxColumns.MESSAGE_COUNT + "," + MailboxColumns.LAST_NOTIFIED_MESSAGE_COUNT + + "," + MailboxColumns.LAST_NOTIFIED_MESSAGE_KEY + " FROM " + Mailbox.TABLE_NAME + + " WHERE " + MailboxColumns.ACCOUNT_KEY + "=?" + + " AND " + MailboxColumns.SYNC_INTERVAL + "!=0 AND " + + MailboxColumns.SYNC_INTERVAL + "!=-1) AS Boxes " + + "WHERE Boxes." + MailboxColumns.MESSAGE_COUNT + "!=Boxes." + + MailboxColumns.LAST_NOTIFIED_MESSAGE_COUNT + + " OR (Boxes." + MailboxColumns.ID + '=' + Message.TABLE_NAME + "." + + MessageColumns.MAILBOX_KEY + " AND " + Message.TABLE_NAME + "." + + MessageColumns.ID + ">Boxes." + MailboxColumns.LAST_NOTIFIED_MESSAGE_KEY + + " AND " + MessageColumns.FLAG_READ + "=0)"; + + public Cursor notificationQuery(Uri uri) { + SQLiteDatabase db = getDatabase(getContext()); + String accountId = uri.getLastPathSegment(); + return db.rawQuery(NOTIFICATION_QUERY, new String[] {accountId}); + } + + public Cursor mostRecentMessageQuery(Uri uri) { + SQLiteDatabase db = getDatabase(getContext()); + String mailboxId = uri.getLastPathSegment(); + return db.rawQuery("select max(_id) from Message where mailboxKey=?", + new String[] {mailboxId}); + } + /** * Support for UnifiedEmail below */ diff --git a/tests/src/com/android/email/NotificationControllerTest.java b/tests/src/com/android/email/NotificationControllerTest.java index ea5169fe3..0936eac38 100644 --- a/tests/src/com/android/email/NotificationControllerTest.java +++ b/tests/src/com/android/email/NotificationControllerTest.java @@ -213,7 +213,7 @@ public class NotificationControllerTest extends AndroidTestCase { Mailbox b1 = ProviderTestUtils.setupMailbox("inbox", a1.mId, true, c, Mailbox.TYPE_INBOX); Message m1 = ProviderTestUtils.setupMessage("message", a1.mId, b1.mId, true, true, c); - n = mTarget.createNewMessageNotification(a1.mId, b1.mId, m1.mId, 1, 1); + n = mTarget.createNewMessageNotification(b1.mId, m1.mId, 1, 1); assertEquals(R.drawable.stat_notify_email_generic, n.icon); assertEquals(mMockClock.mTime, n.when); @@ -223,7 +223,7 @@ public class NotificationControllerTest extends AndroidTestCase { // TODO Check content -- how? // Case 2: 1 account, 2 unseen message - n = mTarget.createNewMessageNotification(a1.mId, b1.mId, m1.mId, 2, 2); + n = mTarget.createNewMessageNotification(b1.mId, m1.mId, 2, 2); assertEquals(R.drawable.stat_notify_email_generic, n.icon); assertEquals(mMockClock.mTime, n.when); @@ -247,7 +247,7 @@ public class NotificationControllerTest extends AndroidTestCase { m1.save(c); // This shouldn't crash. - n = mTarget.createNewMessageNotification(a1.mId, b1.mId, m1.mId, 1, 1); + n = mTarget.createNewMessageNotification(b1.mId, m1.mId, 1, 1); // Minimum test for the result assertEquals(R.drawable.stat_notify_email_generic, n.icon); diff --git a/tests/src/com/android/emailcommon/provider/MailboxTests.java b/tests/src/com/android/emailcommon/provider/MailboxTests.java index 9d9825c0e..8ab2a3392 100644 --- a/tests/src/com/android/emailcommon/provider/MailboxTests.java +++ b/tests/src/com/android/emailcommon/provider/MailboxTests.java @@ -16,14 +16,6 @@ package com.android.emailcommon.provider; -import com.android.email.provider.ContentCache; -import com.android.email.provider.EmailProvider; -import com.android.email.provider.ProviderTestUtils; -import com.android.emailcommon.provider.EmailContent.MailboxColumns; -import com.android.emailcommon.provider.EmailContent.Message; -import com.android.emailcommon.provider.EmailContent.MessageColumns; -import com.android.emailcommon.utility.Utility; - import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; @@ -33,6 +25,14 @@ import android.test.MoreAsserts; import android.test.ProviderTestCase2; import android.test.suitebuilder.annotation.SmallTest; +import com.android.email.provider.ContentCache; +import com.android.email.provider.EmailProvider; +import com.android.email.provider.ProviderTestUtils; +import com.android.emailcommon.provider.EmailContent.MailboxColumns; +import com.android.emailcommon.provider.EmailContent.Message; +import com.android.emailcommon.provider.EmailContent.MessageColumns; +import com.android.emailcommon.utility.Utility; + import java.util.Arrays; /** @@ -520,7 +520,6 @@ public class MailboxTests extends ProviderTestCase2 { testMailbox.mSyncTime = 6L; testMailbox.mType = 7; testMailbox.mVisibleLimit = 8; - testMailbox.mLastSeenMessageKey = 9L; testMailbox.mLastTouchedTime = 10L; return testMailbox; diff --git a/tests/src/com/android/emailcommon/utility/UtilityUnitTests.java b/tests/src/com/android/emailcommon/utility/UtilityUnitTests.java index 171ace1a9..a7c60ddf5 100644 --- a/tests/src/com/android/emailcommon/utility/UtilityUnitTests.java +++ b/tests/src/com/android/emailcommon/utility/UtilityUnitTests.java @@ -16,22 +16,10 @@ package com.android.emailcommon.utility; -import com.android.email.DBTestHelper; -import com.android.email.R; -import com.android.email.TestUtils; -import com.android.email.provider.ProviderTestUtils; -import com.android.emailcommon.provider.Account; -import com.android.emailcommon.provider.EmailContent.Attachment; -import com.android.emailcommon.provider.EmailContent.MailboxColumns; -import com.android.emailcommon.provider.EmailContent.Message; -import com.android.emailcommon.provider.Mailbox; -import com.android.emailcommon.utility.Utility.NewFileCreator; - import android.content.Context; import android.database.Cursor; import android.database.CursorWrapper; import android.database.MatrixCursor; -import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Environment; import android.test.AndroidTestCase; @@ -41,6 +29,16 @@ import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.widget.TextView; +import com.android.email.DBTestHelper; +import com.android.email.TestUtils; +import com.android.email.provider.ProviderTestUtils; +import com.android.emailcommon.provider.Account; +import com.android.emailcommon.provider.EmailContent.Attachment; +import com.android.emailcommon.provider.EmailContent.MailboxColumns; +import com.android.emailcommon.provider.EmailContent.Message; +import com.android.emailcommon.provider.Mailbox; +import com.android.emailcommon.utility.Utility.NewFileCreator; + import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -310,7 +308,7 @@ public class UtilityUnitTests extends AndroidTestCase { private long getLastUpdateKey(Context mockContext, long mailboxId) { return Utility.getFirstRowLong(mockContext, Mailbox.CONTENT_URI, - new String[] { MailboxColumns.LAST_SEEN_MESSAGE_KEY }, MailboxColumns.ID + "=?", + new String[] { MailboxColumns.LAST_NOTIFIED_MESSAGE_KEY }, MailboxColumns.ID + "=?", new String[] { Long.toString(mailboxId) }, null, 0, -1L); } @@ -381,7 +379,7 @@ public class UtilityUnitTests extends AndroidTestCase { assertEquals(0L, getLastUpdateKey(mockContext, mailbox4_1.mId)); // Test account; only INBOX is modified - Utility.updateLastSeenMessageKey(mockContext, account1.mId).get(); + Utility.updateLastNotifiedMessageKey(mockContext, account1.mId).get(); assertEquals(message1_1_3.mId, getLastUpdateKey(mockContext, mailbox1_1.mId)); assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_2.mId)); assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_3.mId)); @@ -393,7 +391,7 @@ public class UtilityUnitTests extends AndroidTestCase { assertEquals(0L, getLastUpdateKey(mockContext, mailbox4_1.mId)); // Missing INBOX - Utility.updateLastSeenMessageKey(mockContext, account2.mId).get(); + Utility.updateLastNotifiedMessageKey(mockContext, account2.mId).get(); assertEquals(message1_1_3.mId, getLastUpdateKey(mockContext, mailbox1_1.mId)); assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_2.mId)); assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_3.mId)); @@ -405,7 +403,7 @@ public class UtilityUnitTests extends AndroidTestCase { assertEquals(0L, getLastUpdateKey(mockContext, mailbox4_1.mId)); // No messages in mailbox - Utility.updateLastSeenMessageKey(mockContext, account3.mId).get(); + Utility.updateLastNotifiedMessageKey(mockContext, account3.mId).get(); assertEquals(message1_1_3.mId, getLastUpdateKey(mockContext, mailbox1_1.mId)); assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_2.mId)); assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_3.mId)); @@ -417,7 +415,7 @@ public class UtilityUnitTests extends AndroidTestCase { assertEquals(0L, getLastUpdateKey(mockContext, mailbox4_1.mId)); // Test combined accounts - Utility.updateLastSeenMessageKey(mockContext, 0x1000000000000000L).get(); + Utility.updateLastNotifiedMessageKey(mockContext, 0x1000000000000000L).get(); assertEquals(message1_1_3.mId, getLastUpdateKey(mockContext, mailbox1_1.mId)); assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_2.mId)); assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_3.mId));