Update summarized notification if a message is deleted or read remotely.

This commit is contained in:
Danny Baumann 2013-01-03 10:07:21 +01:00
parent 3e0cbb1bb6
commit 220a2da195
1 changed files with 131 additions and 60 deletions

View File

@ -48,6 +48,7 @@ import com.fsck.k9.Preferences;
import com.fsck.k9.R; import com.fsck.k9.R;
import com.fsck.k9.activity.FolderList; import com.fsck.k9.activity.FolderList;
import com.fsck.k9.activity.MessageList; import com.fsck.k9.activity.MessageList;
import com.fsck.k9.activity.MessageReference;
import com.fsck.k9.helper.Contacts; import com.fsck.k9.helper.Contacts;
import com.fsck.k9.helper.HtmlConverter; import com.fsck.k9.helper.HtmlConverter;
import com.fsck.k9.helper.power.TracingPowerManager; import com.fsck.k9.helper.power.TracingPowerManager;
@ -203,7 +204,7 @@ public class MessagingController implements Runnable {
private static class NotificationData { private static class NotificationData {
int unreadBeforeNotification; int unreadBeforeNotification;
LinkedList<Message> messages; LinkedList<Message> messages;
int droppedMessages; LinkedList<MessageReference> droppedMessages;
// There's no point in storing more than 5 messages for the notification, as a single notification // There's no point in storing more than 5 messages for the notification, as a single notification
// can't display more than that anyway. // can't display more than that anyway.
@ -212,19 +213,23 @@ public class MessagingController implements Runnable {
@SuppressWarnings("serial") @SuppressWarnings("serial")
public NotificationData(int unread) { public NotificationData(int unread) {
unreadBeforeNotification = unread; unreadBeforeNotification = unread;
droppedMessages = 0; droppedMessages = new LinkedList<MessageReference>();
messages = new LinkedList<Message>() { messages = new LinkedList<Message>() {
@Override @Override
public boolean add(Message m) { public boolean add(Message m) {
while (size() >= MAX_MESSAGES) { while (size() >= MAX_MESSAGES) {
super.remove(); Message dropped = super.remove();
droppedMessages++; droppedMessages.add(dropped.makeMessageReference());
} }
super.add(m); super.add(m);
return true; return true;
} }
}; };
} }
public int getNewMessageCount() {
return messages.size() + droppedMessages.size();
}
}; };
// Key is accountNumber // Key is accountNumber
@ -1718,6 +1723,7 @@ public class MessagingController implements Runnable {
Message localMessage = localFolder.getMessage(remoteMessage.getUid()); Message localMessage = localFolder.getMessage(remoteMessage.getUid());
boolean messageChanged = syncFlags(localMessage, remoteMessage); boolean messageChanged = syncFlags(localMessage, remoteMessage);
if (messageChanged) { if (messageChanged) {
boolean shouldBeNotifiedOf = false;
if (localMessage.isSet(Flag.DELETED) || isMessageSuppressed(account, folder, localMessage)) { if (localMessage.isSet(Flag.DELETED) || isMessageSuppressed(account, folder, localMessage)) {
for (MessagingListener l : getListeners()) { for (MessagingListener l : getListeners()) {
l.synchronizeMailboxRemovedMessage(account, folder, localMessage); l.synchronizeMailboxRemovedMessage(account, folder, localMessage);
@ -1726,8 +1732,38 @@ public class MessagingController implements Runnable {
for (MessagingListener l : getListeners()) { for (MessagingListener l : getListeners()) {
l.synchronizeMailboxAddOrUpdateMessage(account, folder, localMessage); l.synchronizeMailboxAddOrUpdateMessage(account, folder, localMessage);
} }
if (shouldNotifyForMessage(account, localFolder, localMessage)) {
shouldBeNotifiedOf = true;
}
} }
NotificationData data = getNotificationData(account, -1);
if (data != null) {
synchronized (data) {
boolean needUpdateNotification = false;
String uid = localMessage.getUid();
for (Message m : data.messages) {
if (uid.equals(m.getUid()) && !shouldBeNotifiedOf) {
data.messages.remove(m);
needUpdateNotification = true;
break;
}
}
if (!needUpdateNotification) {
for (MessageReference dropped : data.droppedMessages) {
if (uid.equals(dropped.uid) && !shouldBeNotifiedOf) {
data.droppedMessages.remove(dropped.uid);
needUpdateNotification = true;
break;
}
}
}
if (needUpdateNotification) {
notifyAccountWithDataLocked(mApplication, account, null, data);
}
}
}
} }
progress.incrementAndGet(); progress.incrementAndGet();
for (MessagingListener l : getListeners()) { for (MessagingListener l : getListeners()) {
@ -4409,7 +4445,7 @@ public class MessagingController implements Runnable {
synchronized (notificationData) { synchronized (notificationData) {
data = notificationData.get(account.getAccountNumber()); data = notificationData.get(account.getAccountNumber());
if (data == null) { if (data == null && previousUnreadMessageCount >= 0) {
data = new NotificationData(previousUnreadMessageCount); data = new NotificationData(previousUnreadMessageCount);
notificationData.put(account.getAccountNumber(), data); notificationData.put(account.getAccountNumber(), data);
} }
@ -4540,11 +4576,49 @@ public class MessagingController implements Runnable {
return Build.VERSION.SDK_INT >= 16; return Build.VERSION.SDK_INT >= 16;
} }
private Message findNewestMessageForNotificationLocked(Account account, NotificationData data) {
int count = data.messages.size();
if (count > 0) {
return data.messages.get(count - 1);
}
count = data.droppedMessages.size();
if (count > 0) {
MessageReference ref = data.droppedMessages.get(count - 1);
try {
return account.getLocalStore().getFolder(ref.folderName).getMessage(ref.uid);
} catch (MessagingException e) {
}
}
return null;
}
/** /**
* Creates a notification of a newly received message. * Creates a notification of a newly received message.
*/ */
private void notifyAccount(Context context, Account account, Message message, private void notifyAccount(Context context, Account account,
int previousUnreadMessageCount) { Message message, int previousUnreadMessageCount) {
final NotificationData data = getNotificationData(account, previousUnreadMessageCount);
synchronized (data) {
notifyAccountWithDataLocked(context, account, message, data);
}
}
private void notifyAccountWithDataLocked(Context context, Account account,
Message message, NotificationData data) {
boolean updateSilently = false;
if (message == null) {
/* this can happen if a message we previously notified for is read or deleted remotely */
message = findNewestMessageForNotificationLocked(account, data);
updateSilently = true;
if (message == null) {
return;
}
} else {
data.messages.add(message);
}
final KeyguardManager keyguardService = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); final KeyguardManager keyguardService = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
final CharSequence sender = getMessageSender(context, account, message); final CharSequence sender = getMessageSender(context, account, message);
@ -4569,13 +4643,11 @@ public class MessagingController implements Runnable {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context); NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.stat_notify_email_generic); builder.setSmallIcon(R.drawable.stat_notify_email_generic);
builder.setWhen(System.currentTimeMillis()); builder.setWhen(System.currentTimeMillis());
if (!updateSilently) {
builder.setTicker(summary); builder.setTicker(summary);
}
NotificationData data = getNotificationData(account, previousUnreadMessageCount); final int newMessages = data.getNewMessageCount();
synchronized (data) {
data.messages.add(message);
final int newMessages = data.messages.size() + data.droppedMessages;
final int unreadCount = data.unreadBeforeNotification + newMessages; final int unreadCount = data.unreadBeforeNotification + newMessages;
if (account.isNotificationShowsUnreadCount() || platformShowsNumberInNotification()) { if (account.isNotificationShowsUnreadCount() || platformShowsNumberInNotification()) {
@ -4594,9 +4666,9 @@ public class MessagingController implements Runnable {
getMessageSender(context, account, m), getMessageSender(context, account, m),
getMessageSubject(context, m))); getMessageSubject(context, m)));
} }
if (data.droppedMessages > 0) { if (data.droppedMessages.size() > 0) {
style.setSummaryText(context.getString( style.setSummaryText(context.getString(
R.string.notification_additional_messages, data.droppedMessages)); R.string.notification_additional_messages, data.droppedMessages.size()));
} }
String title = context.getString(R.string.notification_new_messages_title, newMessages, accountDescr); String title = context.getString(R.string.notification_new_messages_title, newMessages, accountDescr);
style.setBigContentTitle(title); style.setBigContentTitle(title);
@ -4628,7 +4700,6 @@ public class MessagingController implements Runnable {
builder.setContentTitle(accountNotice); builder.setContentTitle(accountNotice);
builder.setContentText(summary); builder.setContentText(summary);
} }
}
Intent i = FolderList.actionHandleNotification(context, account, Intent i = FolderList.actionHandleNotification(context, account,
message.getFolder().getName()); message.getFolder().getName());
@ -4637,7 +4708,7 @@ public class MessagingController implements Runnable {
// Only ring or vibrate if we have not done so already on this account and fetch // Only ring or vibrate if we have not done so already on this account and fetch
boolean ringAndVibrate = false; boolean ringAndVibrate = false;
if (!account.isRingNotified()) { if (!updateSilently && !account.isRingNotified()) {
account.setRingNotified(true); account.setRingNotified(true);
ringAndVibrate = true; ringAndVibrate = true;
} }