Notify by mailbox, rather than account
* Update EmailProvider, removing two no-longer-used columns in Account and Mailbox Change-Id: Ie0f10eb0ca315d73e82be968f7760a51a239ba3f
This commit is contained in:
parent
98412cadfb
commit
bf5caf97c5
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* <em>NOTE</em>: 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<Mailbox> CREATOR = new Parcelable.Creator<Mailbox>() {
|
||||
|
|
|
@ -897,28 +897,27 @@ public class Utility {
|
|||
* all accounts are updated.
|
||||
* @return an {@link EmailAsyncTask} for test only.
|
||||
*/
|
||||
public static EmailAsyncTask<Void, Void, Void> updateLastSeenMessageKey(final Context context,
|
||||
final long accountId) {
|
||||
public static EmailAsyncTask<Void, Void, Void> 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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<Long, ContentObserver> 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<Long> newAccountList = new HashSet<Long>();
|
||||
final HashSet<Long> removedAccountList = new HashSet<Long>();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<String, Cursor> 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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<EmailProvider> {
|
|||
testMailbox.mSyncTime = 6L;
|
||||
testMailbox.mType = 7;
|
||||
testMailbox.mVisibleLimit = 8;
|
||||
testMailbox.mLastSeenMessageKey = 9L;
|
||||
testMailbox.mLastTouchedTime = 10L;
|
||||
|
||||
return testMailbox;
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue