mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-20 06:39:54 +01:00
Merge branch '68-fix-message-tracker' into 'master'
Fix MessageTracker group counts after deleting messages See merge request briar/briar!1166
This commit is contained in:
@@ -47,8 +47,8 @@ public interface MessageTracker {
|
|||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the stored message id for the respective group id or returns null
|
* Loads the stored message id for the respective group id or returns null
|
||||||
* if none is available.
|
* if none is available.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
MessageId loadStoredMessageId(GroupId g) throws DbException;
|
MessageId loadStoredMessageId(GroupId g) throws DbException;
|
||||||
@@ -64,6 +64,16 @@ public interface MessageTracker {
|
|||||||
*/
|
*/
|
||||||
void setReadFlag(GroupId g, MessageId m, boolean read) throws DbException;
|
void setReadFlag(GroupId g, MessageId m, boolean read) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the {@link GroupCount} to the given msgCount and unreadCount.
|
||||||
|
* The latestMsgTime will be set to the current time.
|
||||||
|
* <p>
|
||||||
|
* Such reset is needed when recalculating the counts
|
||||||
|
* after deleting messages from a group.
|
||||||
|
*/
|
||||||
|
void resetGroupCount(Transaction txn, GroupId g, int msgCount,
|
||||||
|
int unreadCount) throws DbException;
|
||||||
|
|
||||||
class GroupCount {
|
class GroupCount {
|
||||||
|
|
||||||
private final int msgCount, unreadCount;
|
private final int msgCount, unreadCount;
|
||||||
|
|||||||
@@ -31,15 +31,6 @@ public abstract class ConversationClientImpl extends BdfIncomingMessageHook
|
|||||||
this.messageTracker = messageTracker;
|
this.messageTracker = messageTracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the group count with zero messages,
|
|
||||||
* but uses the current time as latest message time for sorting.
|
|
||||||
*/
|
|
||||||
protected void initializeGroupCount(Transaction txn, GroupId g)
|
|
||||||
throws DbException {
|
|
||||||
messageTracker.initializeGroupCount(txn, g);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GroupCount getGroupCount(Transaction txn, ContactId contactId)
|
public GroupCount getGroupCount(Transaction txn, ContactId contactId)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
|
|||||||
@@ -169,4 +169,12 @@ class MessageTrackerImpl implements MessageTracker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetGroupCount(Transaction txn, GroupId g, int msgCount,
|
||||||
|
int unreadCount) throws DbException {
|
||||||
|
long now = clock.currentTimeMillis();
|
||||||
|
GroupCount groupCount = new GroupCount(msgCount, unreadCount, now);
|
||||||
|
storeGroupCount(txn, g, groupCount);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -603,7 +603,9 @@ class IntroductionManagerImpl extends ConversationClientImpl
|
|||||||
for (MessageStatus status : db.getMessageStatus(txn, c, g)) {
|
for (MessageStatus status : db.getMessageStatus(txn, c, g)) {
|
||||||
if (!status.isSeen()) notAcked.add(status.getMessageId());
|
if (!status.isSeen()) notAcked.add(status.getMessageId());
|
||||||
}
|
}
|
||||||
return deleteCompletedSessions(txn, sessions, notAcked);
|
boolean allDeleted = deleteCompletedSessions(txn, sessions, notAcked);
|
||||||
|
recalculateGroupCount(txn, g);
|
||||||
|
return allDeleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DeletableSession getDeletableSession(Transaction txn,
|
private DeletableSession getDeletableSession(Transaction txn,
|
||||||
@@ -671,6 +673,31 @@ class IntroductionManagerImpl extends ConversationClientImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void recalculateGroupCount(Transaction txn, GroupId g)
|
||||||
|
throws DbException {
|
||||||
|
BdfDictionary query = messageParser.getMessagesVisibleInUiQuery();
|
||||||
|
Map<MessageId, BdfDictionary> results;
|
||||||
|
try {
|
||||||
|
results =
|
||||||
|
clientHelper.getMessageMetadataAsDictionary(txn, g, query);
|
||||||
|
} catch (FormatException e) {
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
int msgCount = 0;
|
||||||
|
int unreadCount = 0;
|
||||||
|
for (Entry<MessageId, BdfDictionary> entry : results.entrySet()) {
|
||||||
|
MessageMetadata meta;
|
||||||
|
try {
|
||||||
|
meta = messageParser.parseMetadata(entry.getValue());
|
||||||
|
} catch (FormatException e) {
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
msgCount++;
|
||||||
|
if (!meta.isRead()) unreadCount++;
|
||||||
|
}
|
||||||
|
messageTracker.resetGroupCount(txn, g, msgCount, unreadCount);
|
||||||
|
}
|
||||||
|
|
||||||
private static class StoredSession {
|
private static class StoredSession {
|
||||||
|
|
||||||
private final MessageId storageId;
|
private final MessageId storageId;
|
||||||
|
|||||||
@@ -414,6 +414,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
db.deleteMessage(txn, messageId);
|
db.deleteMessage(txn, messageId);
|
||||||
db.deleteMessageMetadata(txn, messageId);
|
db.deleteMessageMetadata(txn, messageId);
|
||||||
}
|
}
|
||||||
|
messageTracker.initializeGroupCount(txn, g);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1209,15 +1209,24 @@ public class IntroductionIntegrationTest
|
|||||||
assertTrue(listener1.succeeded);
|
assertTrue(listener1.succeeded);
|
||||||
assertTrue(listener2.succeeded);
|
assertTrue(listener2.succeeded);
|
||||||
|
|
||||||
|
// check that introducer messages are tracked properly
|
||||||
|
Group g1 = introductionManager0.getContactGroup(contact1From0);
|
||||||
|
assertGroupCount(messageTracker0, g1.getId(), 2, 1);
|
||||||
|
|
||||||
// introducer can now remove messages
|
// introducer can now remove messages
|
||||||
assertTrue(deleteAllMessages1From0());
|
assertTrue(deleteAllMessages1From0());
|
||||||
assertEquals(0, getMessages1From0().size());
|
assertEquals(0, getMessages1From0().size());
|
||||||
assertTrue(deleteAllMessages1From0()); // a second time returns true
|
assertTrue(deleteAllMessages1From0()); // a second time returns true
|
||||||
|
assertGroupCount(messageTracker0, g1.getId(), 0, 0);
|
||||||
|
|
||||||
// introducee1 can not yet remove messages, because last not ACKed
|
// introducee1 can not yet remove messages, because last not ACKed
|
||||||
assertFalse(deleteAllMessages0From1());
|
assertFalse(deleteAllMessages0From1());
|
||||||
assertEquals(2, getMessages0From1().size());
|
assertEquals(2, getMessages0From1().size());
|
||||||
|
|
||||||
|
// check that introducee1 messages are tracked properly
|
||||||
|
Group g0 = introductionManager1.getContactGroup(contact0From1);
|
||||||
|
assertGroupCount(messageTracker1, g0.getId(), 2, 1);
|
||||||
|
|
||||||
// ACK last message
|
// ACK last message
|
||||||
sendAcks(c0, c1, contactId1From0, 1);
|
sendAcks(c0, c1, contactId1From0, 1);
|
||||||
|
|
||||||
@@ -1225,11 +1234,17 @@ public class IntroductionIntegrationTest
|
|||||||
assertTrue(deleteAllMessages0From1());
|
assertTrue(deleteAllMessages0From1());
|
||||||
assertEquals(0, getMessages0From1().size());
|
assertEquals(0, getMessages0From1().size());
|
||||||
assertTrue(deleteAllMessages0From1()); // a second time returns true
|
assertTrue(deleteAllMessages0From1()); // a second time returns true
|
||||||
|
assertGroupCount(messageTracker1, g0.getId(), 0, 0);
|
||||||
|
|
||||||
|
// check that introducee2 messages are tracked properly
|
||||||
|
Group g0From2 = introductionManager2.getContactGroup(contact0From2);
|
||||||
|
assertGroupCount(messageTracker2, g0From2.getId(), 2, 1);
|
||||||
|
|
||||||
// introducee2 can remove messages (last message was incoming)
|
// introducee2 can remove messages (last message was incoming)
|
||||||
assertTrue(deleteAllMessages0From2());
|
assertTrue(deleteAllMessages0From2());
|
||||||
assertEquals(0, getMessages0From2().size());
|
assertEquals(0, getMessages0From2().size());
|
||||||
assertTrue(deleteAllMessages0From2()); // a second time returns true
|
assertTrue(deleteAllMessages0From2()); // a second time returns true
|
||||||
|
assertGroupCount(messageTracker2, g0From2.getId(), 0, 0);
|
||||||
|
|
||||||
// a new introduction is still possible
|
// a new introduction is still possible
|
||||||
assertTrue(introductionManager0
|
assertTrue(introductionManager0
|
||||||
@@ -1255,6 +1270,11 @@ public class IntroductionIntegrationTest
|
|||||||
assertFalse(deleteAllMessages2From0());
|
assertFalse(deleteAllMessages2From0());
|
||||||
assertFalse(deleteAllMessages0From1());
|
assertFalse(deleteAllMessages0From1());
|
||||||
assertFalse(deleteAllMessages0From2());
|
assertFalse(deleteAllMessages0From2());
|
||||||
|
|
||||||
|
// group counts get counted up again correctly
|
||||||
|
assertGroupCount(messageTracker0, g1.getId(), 2, 1);
|
||||||
|
assertGroupCount(messageTracker1, g0.getId(), 2, 1);
|
||||||
|
assertGroupCount(messageTracker2, g0From2.getId(), 2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user