diff --git a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java index ab4bf27644fd8314657343bf52b5f5f7dd080b61..681132f31c9d8cd85d41240cfb4ed89c8fd7dad6 100644 --- a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java +++ b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java @@ -196,7 +196,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent { if (!db.containsGroup(txn, m.getGroupId())) throw new NoSuchGroupException(); if (!db.containsMessage(txn, m.getId())) { - addMessage(txn, m, DELIVERED, shared); + addMessage(txn, m, DELIVERED, shared, null); transaction.attach(new MessageAddedEvent(m, null)); transaction.attach(new MessageStateChangedEvent(m.getId(), true, DELIVERED)); @@ -205,12 +205,13 @@ class DatabaseComponentImpl<T> implements DatabaseComponent { db.mergeMessageMetadata(txn, m.getId(), meta); } - private void addMessage(T txn, Message m, State state, boolean shared) - throws DbException { + private void addMessage(T txn, Message m, State state, boolean shared, + @Nullable ContactId sender) throws DbException { db.addMessage(txn, m, state, shared); for (ContactId c : db.getVisibility(txn, m.getGroupId())) { boolean offered = db.removeOfferedMessage(txn, c, m.getId()); - db.addStatus(txn, c, m.getId(), offered, offered); + boolean seen = offered || c.equals(sender); + db.addStatus(txn, c, m.getId(), seen, seen); } } @@ -608,11 +609,13 @@ class DatabaseComponentImpl<T> implements DatabaseComponent { if (!db.containsContact(txn, c)) throw new NoSuchContactException(); if (db.containsVisibleGroup(txn, c, m.getGroupId())) { - if (!db.containsMessage(txn, m.getId())) { - addMessage(txn, m, UNKNOWN, false); + if (db.containsMessage(txn, m.getId())) { + db.raiseSeenFlag(txn, c, m.getId()); + db.raiseAckFlag(txn, c, m.getId()); + } else { + addMessage(txn, m, UNKNOWN, false, c); transaction.attach(new MessageAddedEvent(m, c)); } - db.raiseAckFlag(txn, c, m.getId()); transaction.attach(new MessageToAckEvent(c)); } } diff --git a/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java b/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java index 7227fcea63ad518d0c2d2a1a0670968be56e84e7..746cde446a69bae96c53c912c28a85ee5e0019ea 100644 --- a/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java +++ b/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java @@ -1136,29 +1136,42 @@ public class DatabaseComponentImplTest extends BriarTestCase { context.checking(new Expectations() {{ oneOf(database).startTransaction(); will(returnValue(txn)); + // First time oneOf(database).containsContact(txn, contactId); will(returnValue(true)); - oneOf(database).containsMessage(txn, messageId); - will(returnValue(false)); oneOf(database).containsVisibleGroup(txn, contactId, groupId); will(returnValue(true)); + oneOf(database).containsMessage(txn, messageId); + will(returnValue(false)); oneOf(database).addMessage(txn, message, UNKNOWN, false); oneOf(database).getVisibility(txn, groupId); will(returnValue(Collections.singletonList(contactId))); oneOf(database).removeOfferedMessage(txn, contactId, messageId); will(returnValue(false)); - oneOf(database).addStatus(txn, contactId, messageId, false, false); + oneOf(database).addStatus(txn, contactId, messageId, true, true); + // Second time + oneOf(database).containsContact(txn, contactId); + will(returnValue(true)); + oneOf(database).containsVisibleGroup(txn, contactId, groupId); + will(returnValue(true)); + oneOf(database).containsMessage(txn, messageId); + will(returnValue(true)); + oneOf(database).raiseSeenFlag(txn, contactId, messageId); oneOf(database).raiseAckFlag(txn, contactId, messageId); oneOf(database).commitTransaction(txn); - // The message was received and added + // First time: the message was received and added oneOf(eventBus).broadcast(with(any(MessageToAckEvent.class))); oneOf(eventBus).broadcast(with(any(MessageAddedEvent.class))); + // Second time: the message needs to be acked + oneOf(eventBus).broadcast(with(any(MessageToAckEvent.class))); }}); DatabaseComponent db = createDatabaseComponent(database, eventBus, shutdown); Transaction transaction = db.startTransaction(false); try { + // Receive the message twice + db.receiveMessage(transaction, contactId, message); db.receiveMessage(transaction, contactId, message); transaction.setComplete(); } finally {