Merge branch '1832-use-conversation-timestamp' into '804-self-destructing-messages'

Use latest conversation timestamp for all invitation/introduction messages

See merge request briar/briar!1310
This commit is contained in:
akwizgran
2020-12-03 17:32:33 +00:00
40 changed files with 639 additions and 453 deletions

View File

@@ -26,6 +26,7 @@ import org.briarproject.bramble.api.versioning.ClientVersioningManager;
import org.briarproject.briar.api.autodelete.AutoDeleteManager;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.conversation.ConversationManager;
import org.briarproject.briar.api.introduction.IntroductionResponse;
import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent;
@@ -59,6 +60,7 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
protected final MessageEncoder messageEncoder;
protected final ClientVersioningManager clientVersioningManager;
protected final AutoDeleteManager autoDeleteManager;
protected final ConversationManager conversationManager;
protected final Clock clock;
AbstractProtocolEngine(
@@ -72,6 +74,7 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
MessageEncoder messageEncoder,
ClientVersioningManager clientVersioningManager,
AutoDeleteManager autoDeleteManager,
ConversationManager conversationManager,
Clock clock) {
this.db = db;
this.clientHelper = clientHelper;
@@ -83,6 +86,7 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
this.messageEncoder = messageEncoder;
this.clientVersioningManager = clientVersioningManager;
this.autoDeleteManager = autoDeleteManager;
this.conversationManager = conversationManager;
this.clock = clock;
}
@@ -227,14 +231,10 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
return !dependency.equals(lastRemoteMessageId);
}
long getLocalTimestamp(long localTimestamp, long requestTimestamp) {
return Math.max(
clock.currentTimeMillis(),
Math.max(
localTimestamp,
requestTimestamp
) + 1
);
long getTimestampForOutgoingMessage(Transaction txn, GroupId contactGroupId)
throws DbException {
ContactId c = getContactId(txn, contactGroupId);
return conversationManager.getTimestampForOutgoingMessage(txn, c);
}
private ContactId getContactId(Transaction txn, GroupId contactGroupId)

View File

@@ -31,6 +31,7 @@ import org.briarproject.briar.api.autodelete.AutoDeleteManager;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.client.ProtocolStateException;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.conversation.ConversationManager;
import org.briarproject.briar.api.introduction.IntroductionRequest;
import org.briarproject.briar.api.introduction.event.IntroductionAbortedEvent;
import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent;
@@ -43,6 +44,7 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static java.lang.Math.max;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.introduction.IntroduceeState.AWAIT_AUTH;
@@ -75,15 +77,17 @@ class IntroduceeProtocolEngine
IdentityManager identityManager,
MessageParser messageParser,
MessageEncoder messageEncoder,
Clock clock,
IntroductionCrypto crypto,
KeyManager keyManager,
TransportPropertyManager transportPropertyManager,
ClientVersioningManager clientVersioningManager,
AutoDeleteManager autoDeleteManager) {
AutoDeleteManager autoDeleteManager,
ConversationManager conversationManager,
Clock clock) {
super(db, clientHelper, contactManager, contactGroupFactory,
messageTracker, identityManager, messageParser, messageEncoder,
clientVersioningManager, autoDeleteManager, clock);
clientVersioningManager, autoDeleteManager,
conversationManager, clock);
this.crypto = crypto;
this.keyManager = keyManager;
this.transportPropertyManager = transportPropertyManager;
@@ -91,18 +95,18 @@ class IntroduceeProtocolEngine
@Override
public IntroduceeSession onRequestAction(Transaction txn,
IntroduceeSession session, @Nullable String text, long timestamp) {
IntroduceeSession session, @Nullable String text) {
throw new UnsupportedOperationException(); // Invalid in this role
}
@Override
public IntroduceeSession onAcceptAction(Transaction txn,
IntroduceeSession session, long timestamp) throws DbException {
IntroduceeSession session) throws DbException {
switch (session.getState()) {
case AWAIT_RESPONSES:
case REMOTE_DECLINED:
case REMOTE_ACCEPTED:
return onLocalAccept(txn, session, timestamp);
return onLocalAccept(txn, session);
case START:
case LOCAL_DECLINED:
case LOCAL_ACCEPTED:
@@ -116,12 +120,12 @@ class IntroduceeProtocolEngine
@Override
public IntroduceeSession onDeclineAction(Transaction txn,
IntroduceeSession session, long timestamp) throws DbException {
IntroduceeSession session) throws DbException {
switch (session.getState()) {
case AWAIT_RESPONSES:
case REMOTE_DECLINED:
case REMOTE_ACCEPTED:
return onLocalDecline(txn, session, timestamp);
return onLocalDecline(txn, session);
case START:
case LOCAL_DECLINED:
case LOCAL_ACCEPTED:
@@ -272,7 +276,7 @@ class IntroduceeProtocolEngine
}
private IntroduceeSession onLocalAccept(Transaction txn,
IntroduceeSession s, long timestamp) throws DbException {
IntroduceeSession s) throws DbException {
// Mark the request message unavailable to answer
markRequestsUnavailableToAnswer(txn, s);
@@ -283,8 +287,8 @@ class IntroduceeProtocolEngine
Map<TransportId, TransportProperties> transportProperties =
transportPropertyManager.getLocalProperties(txn);
// Send a ACCEPT message
long localTimestamp = Math.max(timestamp + 1, getLocalTimestamp(s));
// Send an ACCEPT message
long localTimestamp = getTimestampForVisibleMessage(txn, s);
Message sent = sendAcceptMessage(txn, s, localTimestamp, publicKey,
localTimestamp, transportProperties, true);
// Track the message
@@ -309,12 +313,12 @@ class IntroduceeProtocolEngine
}
private IntroduceeSession onLocalDecline(Transaction txn,
IntroduceeSession s, long timestamp) throws DbException {
IntroduceeSession s) throws DbException {
// Mark the request message unavailable to answer
markRequestsUnavailableToAnswer(txn, s);
// Send a DECLINE message
long localTimestamp = Math.max(timestamp + 1, getLocalTimestamp(s));
long localTimestamp = getTimestampForVisibleMessage(txn, s);
Message sent = sendDeclineMessage(txn, s, localTimestamp, true);
// Track the message
@@ -412,8 +416,8 @@ class IntroduceeProtocolEngine
return abort(txn, s);
}
if (s.getState() != AWAIT_AUTH) throw new AssertionError();
Message sent = sendAuthMessage(txn, s, getLocalTimestamp(s), mac,
signature);
long localTimestamp = getTimestampForInvisibleMessage(s);
Message sent = sendAuthMessage(txn, s, localTimestamp, mac, signature);
return IntroduceeSession.addLocalAuth(s, AWAIT_AUTH, sent, masterKey,
aliceMacKey, bobMacKey);
}
@@ -464,7 +468,8 @@ class IntroduceeProtocolEngine
// send ACTIVATE message with a MAC
byte[] mac = crypto.activateMac(s);
Message sent = sendActivateMessage(txn, s, getLocalTimestamp(s), mac);
long localTimestamp = getTimestampForInvisibleMessage(s);
Message sent = sendActivateMessage(txn, s, localTimestamp, mac);
// Move to AWAIT_ACTIVATE state and clear key material from session
return IntroduceeSession.awaitActivate(s, m, sent, keys);
@@ -515,7 +520,8 @@ class IntroduceeProtocolEngine
markRequestsUnavailableToAnswer(txn, s);
// Send an ABORT message
Message sent = sendAbortMessage(txn, s, getLocalTimestamp(s));
long localTimestamp = getTimestampForInvisibleMessage(s);
Message sent = sendAbortMessage(txn, s, localTimestamp);
// Broadcast abort event for testing
txn.attach(new IntroductionAbortedEvent(s.getSessionId()));
@@ -530,9 +536,34 @@ class IntroduceeProtocolEngine
return isInvalidDependency(s.getLastRemoteMessageId(), dependency);
}
private long getLocalTimestamp(IntroduceeSession s) {
return getLocalTimestamp(s.getLocalTimestamp(),
s.getRequestTimestamp());
/**
* Returns a timestamp for a visible outgoing message. The timestamp is
* later than the timestamp of any message sent or received so far in the
* conversation, and later than the {@link
* #getSessionTimestamp(IntroduceeSession) session timestamp}.
*/
private long getTimestampForVisibleMessage(Transaction txn,
IntroduceeSession s) throws DbException {
long conversationTimestamp =
getTimestampForOutgoingMessage(txn, s.getContactGroupId());
return max(conversationTimestamp, getSessionTimestamp(s) + 1);
}
/**
* Returns a timestamp for an invisible outgoing message. The timestamp is
* later than the {@link #getSessionTimestamp(IntroduceeSession) session
* timestamp}.
*/
private long getTimestampForInvisibleMessage(IntroduceeSession s) {
return max(clock.currentTimeMillis(), getSessionTimestamp(s) + 1);
}
/**
* Returns the latest timestamp of any message sent so far in the session,
* and any request message received so far in the session.
*/
private long getSessionTimestamp(IntroduceeSession s) {
return max(s.getLocalTimestamp(), s.getRequestTimestamp());
}
private void addSessionId(Transaction txn, MessageId m, SessionId sessionId)

View File

@@ -17,6 +17,7 @@ import org.briarproject.bramble.api.versioning.ClientVersioningManager;
import org.briarproject.briar.api.autodelete.AutoDeleteManager;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.client.ProtocolStateException;
import org.briarproject.briar.api.conversation.ConversationManager;
import org.briarproject.briar.api.introduction.event.IntroductionAbortedEvent;
import org.briarproject.briar.introduction.IntroducerSession.Introducee;
@@ -24,6 +25,7 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static java.lang.Math.max;
import static org.briarproject.briar.introduction.IntroducerState.AWAIT_ACTIVATES;
import static org.briarproject.briar.introduction.IntroducerState.AWAIT_ACTIVATE_A;
import static org.briarproject.briar.introduction.IntroducerState.AWAIT_ACTIVATE_B;
@@ -54,19 +56,21 @@ class IntroducerProtocolEngine
MessageEncoder messageEncoder,
ClientVersioningManager clientVersioningManager,
AutoDeleteManager autoDeleteManager,
ConversationManager conversationManager,
Clock clock) {
super(db, clientHelper, contactManager, contactGroupFactory,
messageTracker, identityManager, messageParser, messageEncoder,
clientVersioningManager, autoDeleteManager, clock);
clientVersioningManager, autoDeleteManager,
conversationManager, clock);
}
@Override
public IntroducerSession onRequestAction(Transaction txn,
IntroducerSession s, @Nullable String text, long timestamp)
IntroducerSession s, @Nullable String text)
throws DbException {
switch (s.getState()) {
case START:
return onLocalRequest(txn, s, text, timestamp);
return onLocalRequest(txn, s, text);
case AWAIT_RESPONSES:
case AWAIT_RESPONSE_A:
case AWAIT_RESPONSE_B:
@@ -86,37 +90,24 @@ class IntroducerProtocolEngine
@Override
public IntroducerSession onAcceptAction(Transaction txn,
IntroducerSession s, long timestamp) {
IntroducerSession s) {
throw new UnsupportedOperationException(); // Invalid in this role
}
@Override
public IntroducerSession onDeclineAction(Transaction txn,
IntroducerSession s, long timestamp) {
IntroducerSession s) {
throw new UnsupportedOperationException(); // Invalid in this role
}
IntroducerSession onIntroduceeRemoved(Transaction txn,
Introducee remainingIntroducee, IntroducerSession session)
throws DbException {
// abort session
IntroducerSession s = abort(txn, session);
// reset information for introducee that was removed
Introducee introduceeA, introduceeB;
if (remainingIntroducee.author.equals(s.getIntroduceeA().author)) {
introduceeA = s.getIntroduceeA();
introduceeB =
new Introducee(s.getSessionId(), s.getIntroduceeB().groupId,
s.getIntroduceeB().author);
} else if (remainingIntroducee.author
.equals(s.getIntroduceeB().author)) {
introduceeA =
new Introducee(s.getSessionId(), s.getIntroduceeA().groupId,
s.getIntroduceeA().author);
introduceeB = s.getIntroduceeB();
} else throw new DbException();
// abort session with remaining introducee
IntroducerSession s = abort(txn, session, remainingIntroducee);
return new IntroducerSession(s.getSessionId(), s.getState(),
s.getRequestTimestamp(), introduceeA, introduceeB);
s.getRequestTimestamp(), s.getIntroduceeA(),
s.getIntroduceeB());
}
@Override
@@ -226,13 +217,13 @@ class IntroducerProtocolEngine
}
private IntroducerSession onLocalRequest(Transaction txn,
IntroducerSession s, @Nullable String text, long timestamp)
throws DbException {
IntroducerSession s, @Nullable String text) throws DbException {
// Send REQUEST messages
long maxIntroduceeTimestamp =
Math.max(getLocalTimestamp(s, s.getIntroduceeA()),
getLocalTimestamp(s, s.getIntroduceeB()));
long localTimestamp = Math.max(timestamp, maxIntroduceeTimestamp);
long timestampA =
getTimestampForVisibleMessage(txn, s, s.getIntroduceeA());
long timestampB =
getTimestampForVisibleMessage(txn, s, s.getIntroduceeB());
long localTimestamp = max(timestampA, timestampB);
Message sentA = sendRequestMessage(txn, s.getIntroduceeA(),
localTimestamp, s.getIntroduceeB().author, text);
Message sentB = sendRequestMessage(txn, s.getIntroduceeB(),
@@ -272,11 +263,11 @@ class IntroducerProtocolEngine
// Forward ACCEPT message
Introducee i = getOtherIntroducee(s, m.getGroupId());
long timestamp = getLocalTimestamp(s, i);
Message sent =
sendAcceptMessage(txn, i, timestamp, m.getEphemeralPublicKey(),
m.getAcceptTimestamp(), m.getTransportProperties(),
false);
// The forwarded message will not be visible to the introducee
long localTimestamp = getTimestampForInvisibleMessage(s, i);
Message sent = sendAcceptMessage(txn, i, localTimestamp,
m.getEphemeralPublicKey(), m.getAcceptTimestamp(),
m.getTransportProperties(), false);
// Create the next state
IntroducerState state = AWAIT_AUTHS;
@@ -333,7 +324,9 @@ class IntroducerProtocolEngine
// Forward ACCEPT message
Introducee i = getOtherIntroducee(s, m.getGroupId());
Message sent = sendAcceptMessage(txn, i, getLocalTimestamp(s, i),
// The forwarded message will not be visible to the introducee
long localTimestamp = getTimestampForInvisibleMessage(s, i);
Message sent = sendAcceptMessage(txn, i, localTimestamp,
m.getEphemeralPublicKey(), m.getAcceptTimestamp(),
m.getTransportProperties(), false);
@@ -384,8 +377,9 @@ class IntroducerProtocolEngine
// Forward DECLINE message
Introducee i = getOtherIntroducee(s, m.getGroupId());
long timestamp = getLocalTimestamp(s, i);
Message sent = sendDeclineMessage(txn, i, timestamp, false);
// The forwarded message will be visible to the introducee
long localTimestamp = getTimestampForVisibleMessage(txn, s, i);
Message sent = sendDeclineMessage(txn, i, localTimestamp, false);
// Create the next state
IntroducerState state = START;
@@ -436,8 +430,9 @@ class IntroducerProtocolEngine
// Forward DECLINE message
Introducee i = getOtherIntroducee(s, m.getGroupId());
long timestamp = getLocalTimestamp(s, i);
Message sent = sendDeclineMessage(txn, i, timestamp, false);
// The forwarded message will be visible to the introducee
long localTimestamp = getTimestampForVisibleMessage(txn, s, i);
Message sent = sendDeclineMessage(txn, i, localTimestamp, false);
Introducee introduceeA, introduceeB;
Author sender, other;
@@ -477,8 +472,8 @@ class IntroducerProtocolEngine
// Forward AUTH message
Introducee i = getOtherIntroducee(s, m.getGroupId());
long timestamp = getLocalTimestamp(s, i);
Message sent = sendAuthMessage(txn, i, timestamp, m.getMac(),
long localTimestamp = getTimestampForInvisibleMessage(s, i);
Message sent = sendAuthMessage(txn, i, localTimestamp, m.getMac(),
m.getSignature());
// Move to the next state
@@ -513,8 +508,8 @@ class IntroducerProtocolEngine
// Forward ACTIVATE message
Introducee i = getOtherIntroducee(s, m.getGroupId());
long timestamp = getLocalTimestamp(s, i);
Message sent = sendActivateMessage(txn, i, timestamp, m.getMac());
long localTimestamp = getTimestampForInvisibleMessage(s, i);
Message sent = sendActivateMessage(txn, i, localTimestamp, m.getMac());
// Move to the next state
IntroducerState state = START;
@@ -536,8 +531,8 @@ class IntroducerProtocolEngine
IntroducerSession s, AbortMessage m) throws DbException {
// Forward ABORT message
Introducee i = getOtherIntroducee(s, m.getGroupId());
long timestamp = getLocalTimestamp(s, i);
Message sent = sendAbortMessage(txn, i, timestamp);
long localTimestamp = getTimestampForInvisibleMessage(s, i);
Message sent = sendAbortMessage(txn, i, localTimestamp);
// Broadcast abort event for testing
txn.attach(new IntroductionAbortedEvent(s.getSessionId()));
@@ -555,15 +550,45 @@ class IntroducerProtocolEngine
s.getRequestTimestamp(), introduceeA, introduceeB);
}
private IntroducerSession abort(Transaction txn,
IntroducerSession s) throws DbException {
private IntroducerSession abort(Transaction txn, IntroducerSession s,
Introducee remainingIntroducee) throws DbException {
// Broadcast abort event for testing
txn.attach(new IntroductionAbortedEvent(s.getSessionId()));
// Send an ABORT message to the remaining introducee
long localTimestamp =
getTimestampForInvisibleMessage(s, remainingIntroducee);
Message sent =
sendAbortMessage(txn, remainingIntroducee, localTimestamp);
// Reset the session back to initial state
Introducee introduceeA = s.getIntroduceeA();
Introducee introduceeB = s.getIntroduceeB();
if (remainingIntroducee.author.equals(introduceeA.author)) {
introduceeA = new Introducee(introduceeA, sent);
introduceeB = new Introducee(s.getSessionId(), introduceeB.groupId,
introduceeB.author);
} else if (remainingIntroducee.author.equals(introduceeB.author)) {
introduceeA = new Introducee(s.getSessionId(), introduceeA.groupId,
introduceeA.author);
introduceeB = new Introducee(introduceeB, sent);
} else {
throw new DbException();
}
return new IntroducerSession(s.getSessionId(), START,
s.getRequestTimestamp(), introduceeA, introduceeB);
}
private IntroducerSession abort(Transaction txn, IntroducerSession s)
throws DbException {
// Broadcast abort event for testing
txn.attach(new IntroductionAbortedEvent(s.getSessionId()));
// Send an ABORT message to both introducees
long timestampA = getLocalTimestamp(s, s.getIntroduceeA());
long timestampA =
getTimestampForInvisibleMessage(s, s.getIntroduceeA());
Message sentA = sendAbortMessage(txn, s.getIntroduceeA(), timestampA);
long timestampB = getLocalTimestamp(s, s.getIntroduceeB());
long timestampB =
getTimestampForInvisibleMessage(s, s.getIntroduceeB());
Message sentB = sendAbortMessage(txn, s.getIntroduceeB(), timestampB);
// Reset the session back to initial state
Introducee introduceeA = new Introducee(s.getIntroduceeA(), sentA);
@@ -593,9 +618,33 @@ class IntroducerProtocolEngine
return isInvalidDependency(expected, dependency);
}
private long getLocalTimestamp(IntroducerSession s, PeerSession p) {
return getLocalTimestamp(p.getLocalTimestamp(),
s.getRequestTimestamp());
/**
* Returns a timestamp for a visible outgoing message. The timestamp is
* later than the timestamp of any message sent or received so far in the
* conversation, and later than the {@link
* #getSessionTimestamp(IntroducerSession, PeerSession) session timestamp}.
*/
private long getTimestampForVisibleMessage(Transaction txn,
IntroducerSession s, PeerSession p) throws DbException {
long conversationTimestamp =
getTimestampForOutgoingMessage(txn, p.getContactGroupId());
return max(conversationTimestamp, getSessionTimestamp(s, p) + 1);
}
/**
* Returns a timestamp for an invisible outgoing message. The timestamp is
* later than the {@link #getSessionTimestamp(IntroducerSession, PeerSession)
* session timestamp}.
*/
private long getTimestampForInvisibleMessage(IntroducerSession s,
PeerSession p) {
return max(clock.currentTimeMillis(), getSessionTimestamp(s, p) + 1);
}
/**
* Returns the latest timestamp of any message sent so far in the session.
*/
private long getSessionTimestamp(IntroducerSession s, PeerSession p) {
return max(p.getLocalTimestamp(), s.getRequestTimestamp());
}
}

View File

@@ -311,8 +311,8 @@ class IntroductionManagerImpl extends ConversationClientImpl
}
@Override
public void makeIntroduction(Contact c1, Contact c2, @Nullable String text,
long timestamp) throws DbException {
public void makeIntroduction(Contact c1, Contact c2, @Nullable String text)
throws DbException {
Transaction txn = db.startTransaction(false);
try {
// Look up the session, if there is one
@@ -344,8 +344,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
storageId = ss.storageId;
}
// Handle the request action
session = introducerEngine
.onRequestAction(txn, session, text, timestamp);
session = introducerEngine.onRequestAction(txn, session, text);
// Store the updated session
storeSession(txn, storageId, session);
db.commitTransaction(txn);
@@ -358,7 +357,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
@Override
public void respondToIntroduction(ContactId contactId, SessionId sessionId,
long timestamp, boolean accept) throws DbException {
boolean accept) throws DbException {
Transaction txn = db.startTransaction(false);
try {
// Look up the session
@@ -376,11 +375,9 @@ class IntroductionManagerImpl extends ConversationClientImpl
.parseIntroduceeSession(contactGroupId, ss.bdfSession);
// Handle the join or leave action
if (accept) {
session = introduceeEngine
.onAcceptAction(txn, session, timestamp);
session = introduceeEngine.onAcceptAction(txn, session);
} else {
session = introduceeEngine
.onDeclineAction(txn, session, timestamp);
session = introduceeEngine.onDeclineAction(txn, session);
}
// Store the updated session
storeSession(txn, ss.storageId, session);

View File

@@ -8,16 +8,14 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
@NotNullByDefault
interface ProtocolEngine<S extends Session> {
interface ProtocolEngine<S extends Session<?>> {
S onRequestAction(Transaction txn, S session, @Nullable String text,
long timestamp) throws DbException;
S onAcceptAction(Transaction txn, S session, long timestamp)
S onRequestAction(Transaction txn, S session, @Nullable String text)
throws DbException;
S onDeclineAction(Transaction txn, S session, long timestamp)
throws DbException;
S onAcceptAction(Transaction txn, S session) throws DbException;
S onDeclineAction(Transaction txn, S session) throws DbException;
S onRequestMessage(Transaction txn, S session, RequestMessage m)
throws DbException, FormatException;

View File

@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
import org.briarproject.briar.api.conversation.ConversationManager;
import org.briarproject.briar.api.conversation.ConversationMessageHeader;
@@ -20,16 +21,20 @@ import java.util.concurrent.CopyOnWriteArraySet;
import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
import static java.lang.Math.max;
@ThreadSafe
@NotNullByDefault
class ConversationManagerImpl implements ConversationManager {
private final DatabaseComponent db;
private final Clock clock;
private final Set<ConversationClient> clients;
@Inject
ConversationManagerImpl(DatabaseComponent db) {
ConversationManagerImpl(DatabaseComponent db, Clock clock) {
this.db = db;
this.clock = clock;
clients = new CopyOnWriteArraySet<>();
}
@@ -57,24 +62,33 @@ class ConversationManagerImpl implements ConversationManager {
@Override
public GroupCount getGroupCount(ContactId contactId) throws DbException {
return db.transactionWithResult(true, txn ->
getGroupCount(txn, contactId));
}
@Override
public GroupCount getGroupCount(Transaction txn, ContactId contactId)
throws DbException {
int msgCount = 0, unreadCount = 0;
long latestTime = 0;
Transaction txn = db.startTransaction(true);
try {
for (ConversationClient client : clients) {
GroupCount count = client.getGroupCount(txn, contactId);
msgCount += count.getMsgCount();
unreadCount += count.getUnreadCount();
if (count.getLatestMsgTime() > latestTime)
latestTime = count.getLatestMsgTime();
}
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
for (ConversationClient client : clients) {
GroupCount count = client.getGroupCount(txn, contactId);
msgCount += count.getMsgCount();
unreadCount += count.getUnreadCount();
if (count.getLatestMsgTime() > latestTime)
latestTime = count.getLatestMsgTime();
}
return new GroupCount(msgCount, unreadCount, latestTime);
}
@Override
public long getTimestampForOutgoingMessage(Transaction txn, ContactId c)
throws DbException {
long now = clock.currentTimeMillis();
GroupCount gc = getGroupCount(txn, c);
return max(now, gc.getLatestMsgTime() + 1);
}
@Override
public DeletionResult deleteAllMessages(ContactId c) throws DbException {
return db.transactionWithResult(false, txn -> {
@@ -87,8 +101,8 @@ class ConversationManagerImpl implements ConversationManager {
}
@Override
public DeletionResult deleteMessages(ContactId c, Collection<MessageId> toDelete)
throws DbException {
public DeletionResult deleteMessages(ContactId c,
Collection<MessageId> toDelete) throws DbException {
return db.transactionWithResult(false, txn -> {
DeletionResult result = new DeletionResult();
for (ConversationClient client : clients) {

View File

@@ -19,6 +19,7 @@ import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
import org.briarproject.briar.api.autodelete.AutoDeleteManager;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.conversation.ConversationManager;
import org.briarproject.briar.api.privategroup.GroupMessage;
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
import org.briarproject.briar.api.privategroup.PrivateGroup;
@@ -31,6 +32,7 @@ import java.util.Map;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import static java.lang.Math.max;
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
import static org.briarproject.briar.privategroup.invitation.MessageType.ABORT;
import static org.briarproject.briar.privategroup.invitation.MessageType.INVITE;
@@ -54,6 +56,7 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
private final MessageParser messageParser;
private final MessageEncoder messageEncoder;
private final AutoDeleteManager autoDeleteManager;
private final ConversationManager conversationManager;
private final Clock clock;
AbstractProtocolEngine(
@@ -68,6 +71,7 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
MessageEncoder messageEncoder,
MessageTracker messageTracker,
AutoDeleteManager autoDeleteManager,
ConversationManager conversationManager,
Clock clock) {
this.db = db;
this.clientHelper = clientHelper;
@@ -80,6 +84,7 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
this.messageEncoder = messageEncoder;
this.messageTracker = messageTracker;
this.autoDeleteManager = autoDeleteManager;
this.conversationManager = conversationManager;
this.clock = clock;
}
@@ -110,8 +115,8 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
}
Message sendInviteMessage(Transaction txn, S s,
@Nullable String text, long timestamp, byte[] signature)
throws DbException {
@Nullable String text, long timestamp, byte[] signature,
long timer) throws DbException {
Group g = db.getGroup(txn, s.getPrivateGroupId());
PrivateGroup privateGroup;
try {
@@ -122,7 +127,6 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
Message m;
ContactId c = getContactId(txn, s.getContactGroupId());
if (contactSupportsAutoDeletion(txn, c)) {
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c);
m = messageEncoder.encodeInviteMessage(s.getContactGroupId(),
privateGroup.getId(), timestamp, privateGroup.getName(),
privateGroup.getCreator(), privateGroup.getSalt(), text,
@@ -142,6 +146,9 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
Message sendJoinMessage(Transaction txn, S s, boolean visibleInUi)
throws DbException {
Message m;
long localTimestamp = visibleInUi
? getTimestampForVisibleMessage(txn, s)
: getTimestampForInvisibleMessage(s);
ContactId c = getContactId(txn, s.getContactGroupId());
if (contactSupportsAutoDeletion(txn, c)) {
// Set auto-delete timer if manually accepting an invitation
@@ -149,13 +156,13 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
? autoDeleteManager.getAutoDeleteTimer(txn, c)
: NO_AUTO_DELETE_TIMER;
m = messageEncoder.encodeJoinMessage(s.getContactGroupId(),
s.getPrivateGroupId(), getLocalTimestamp(s),
s.getPrivateGroupId(), localTimestamp,
s.getLastLocalMessageId(), timer);
sendMessage(txn, m, JOIN, s.getPrivateGroupId(), visibleInUi,
timer);
} else {
m = messageEncoder.encodeJoinMessage(s.getContactGroupId(),
s.getPrivateGroupId(), getLocalTimestamp(s),
s.getPrivateGroupId(), localTimestamp,
s.getLastLocalMessageId());
sendMessage(txn, m, JOIN, s.getPrivateGroupId(), visibleInUi,
NO_AUTO_DELETE_TIMER);
@@ -166,6 +173,9 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
Message sendLeaveMessage(Transaction txn, S s, boolean visibleInUi)
throws DbException {
Message m;
long localTimestamp = visibleInUi
? getTimestampForVisibleMessage(txn, s)
: getTimestampForInvisibleMessage(s);
ContactId c = getContactId(txn, s.getContactGroupId());
if (contactSupportsAutoDeletion(txn, c)) {
// Set auto-delete timer if manually accepting an invitation
@@ -173,13 +183,13 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
? autoDeleteManager.getAutoDeleteTimer(txn, c)
: NO_AUTO_DELETE_TIMER;
m = messageEncoder.encodeLeaveMessage(s.getContactGroupId(),
s.getPrivateGroupId(), getLocalTimestamp(s),
s.getPrivateGroupId(), localTimestamp,
s.getLastLocalMessageId(), timer);
sendMessage(txn, m, LEAVE, s.getPrivateGroupId(), visibleInUi,
timer);
} else {
m = messageEncoder.encodeLeaveMessage(s.getContactGroupId(),
s.getPrivateGroupId(), getLocalTimestamp(s),
s.getPrivateGroupId(), localTimestamp,
s.getLastLocalMessageId());
sendMessage(txn, m, LEAVE, s.getPrivateGroupId(), visibleInUi,
NO_AUTO_DELETE_TIMER);
@@ -190,7 +200,7 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
Message sendAbortMessage(Transaction txn, S session) throws DbException {
Message m = messageEncoder.encodeAbortMessage(
session.getContactGroupId(), session.getPrivateGroupId(),
getLocalTimestamp(session));
getTimestampForInvisibleMessage(session));
sendMessage(txn, m, ABORT, session.getPrivateGroupId(), false,
NO_AUTO_DELETE_TIMER);
return m;
@@ -246,7 +256,7 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup(
invite.getGroupName(), invite.getCreator(), invite.getSalt());
long timestamp =
Math.max(clock.currentTimeMillis(), invite.getTimestamp() + 1);
max(clock.currentTimeMillis(), invite.getTimestamp() + 1);
// TODO: Create the join message on the crypto executor
LocalAuthor member = identityManager.getLocalAuthor(txn);
GroupMessage joinMessage = groupMessageFactory.createJoinMessage(
@@ -256,10 +266,34 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
.addPrivateGroup(txn, privateGroup, joinMessage, false);
}
long getLocalTimestamp(S session) {
return Math.max(clock.currentTimeMillis(),
Math.max(session.getLocalTimestamp(),
session.getInviteTimestamp()) + 1);
/**
* Returns a timestamp for a visible outgoing message. The timestamp is
* later than the timestamp of any message sent or received so far in the
* conversation, and later than the {@link #getSessionTimestamp(Session)
* session timestamp}.
*/
long getTimestampForVisibleMessage(Transaction txn, S s)
throws DbException {
ContactId c = getContactId(txn, s.getContactGroupId());
long conversationTimestamp =
conversationManager.getTimestampForOutgoingMessage(txn, c);
return max(conversationTimestamp, getSessionTimestamp(s) + 1);
}
/**
* Returns a timestamp for an invisible outgoing message. The timestamp is
* later than the {@link #getSessionTimestamp(Session) session timestamp}.
*/
long getTimestampForInvisibleMessage(S s) {
return max(clock.currentTimeMillis(), getSessionTimestamp(s) + 1);
}
/**
* Returns the latest timestamp of any message sent so far in the session,
* and any invite message sent or received so far in the session.
*/
private long getSessionTimestamp(S s) {
return max(s.getLocalTimestamp(), s.getInviteTimestamp());
}
private void sendMessage(Transaction txn, Message m, MessageType type,

View File

@@ -15,6 +15,7 @@ import org.briarproject.briar.api.autodelete.AutoDeleteManager;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.client.ProtocolStateException;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.conversation.ConversationManager;
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
import org.briarproject.briar.api.privategroup.PrivateGroupManager;
@@ -24,6 +25,7 @@ import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRespons
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import static java.lang.Math.max;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.briar.privategroup.invitation.CreatorState.DISSOLVED;
@@ -49,20 +51,22 @@ class CreatorProtocolEngine extends AbstractProtocolEngine<CreatorSession> {
MessageEncoder messageEncoder,
MessageTracker messageTracker,
AutoDeleteManager autoDeleteManager,
ConversationManager conversationManager,
Clock clock) {
super(db, clientHelper, clientVersioningManager, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker,
autoDeleteManager, clock);
autoDeleteManager, conversationManager, clock);
}
@Override
public CreatorSession onInviteAction(Transaction txn, CreatorSession s,
@Nullable String text, long timestamp, byte[] signature)
throws DbException {
@Nullable String text, long timestamp, byte[] signature,
long autoDeleteTimer) throws DbException {
switch (s.getState()) {
case START:
return onLocalInvite(txn, s, text, timestamp, signature);
return onLocalInvite(txn, s, text, timestamp, signature,
autoDeleteTimer);
case INVITED:
case JOINED:
case LEFT:
@@ -152,14 +156,16 @@ class CreatorProtocolEngine extends AbstractProtocolEngine<CreatorSession> {
}
private CreatorSession onLocalInvite(Transaction txn, CreatorSession s,
@Nullable String text, long timestamp, byte[] signature)
throws DbException {
@Nullable String text, long timestamp, byte[] signature,
long autoDeleteTimer) throws DbException {
// Send an INVITE message
Message sent = sendInviteMessage(txn, s, text, timestamp, signature);
Message sent = sendInviteMessage(txn, s, text, timestamp, signature,
autoDeleteTimer);
// Track the message
messageTracker.trackOutgoingMessage(txn, sent);
// Move to the INVITED state
long localTimestamp = Math.max(timestamp, getLocalTimestamp(s));
long localTimestamp =
max(timestamp, getTimestampForVisibleMessage(txn, s));
return new CreatorSession(s.getContactGroupId(), s.getPrivateGroupId(),
sent.getId(), s.getLastRemoteMessageId(), localTimestamp,
timestamp, INVITED);

View File

@@ -257,8 +257,8 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
@Override
public void sendInvitation(GroupId privateGroupId, ContactId c,
@Nullable String text, long timestamp, byte[] signature)
throws DbException {
@Nullable String text, long timestamp, byte[] signature,
long autoDeleteTimer) throws DbException {
SessionId sessionId = getSessionId(privateGroupId);
Transaction txn = db.startTransaction(false);
try {
@@ -281,7 +281,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
}
// Handle the invite action
session = creatorEngine.onInviteAction(txn, session, text,
timestamp, signature);
timestamp, signature, autoDeleteTimer);
// Store the updated session
storeSession(txn, storageId, session);
db.commitTransaction(txn);

View File

@@ -17,6 +17,7 @@ import org.briarproject.briar.api.autodelete.AutoDeleteManager;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.client.ProtocolStateException;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.conversation.ConversationManager;
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
import org.briarproject.briar.api.privategroup.PrivateGroup;
import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
@@ -42,7 +43,8 @@ import static org.briarproject.briar.privategroup.invitation.InviteeState.START;
@NotNullByDefault
class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
InviteeProtocolEngine(DatabaseComponent db,
InviteeProtocolEngine(
DatabaseComponent db,
ClientHelper clientHelper,
ClientVersioningManager clientVersioningManager,
PrivateGroupManager privateGroupManager,
@@ -53,16 +55,18 @@ class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
MessageEncoder messageEncoder,
MessageTracker messageTracker,
AutoDeleteManager autoDeleteManager,
ConversationManager conversationManager,
Clock clock) {
super(db, clientHelper, clientVersioningManager, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker,
autoDeleteManager, clock);
autoDeleteManager, conversationManager, clock);
}
@Override
public InviteeSession onInviteAction(Transaction txn, InviteeSession s,
@Nullable String text, long timestamp, byte[] signature) {
@Nullable String text, long timestamp, byte[] signature,
long autoDeleteTimer) {
throw new UnsupportedOperationException(); // Invalid in this role
}

View File

@@ -15,6 +15,7 @@ import org.briarproject.bramble.api.versioning.ClientVersioningManager;
import org.briarproject.briar.api.autodelete.AutoDeleteManager;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.client.ProtocolStateException;
import org.briarproject.briar.api.conversation.ConversationManager;
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
import org.briarproject.briar.api.privategroup.PrivateGroupManager;
@@ -49,16 +50,18 @@ class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
MessageEncoder messageEncoder,
MessageTracker messageTracker,
AutoDeleteManager autoDeleteManager,
ConversationManager conversationManager,
Clock clock) {
super(db, clientHelper, clientVersioningManager, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker,
autoDeleteManager, clock);
autoDeleteManager, conversationManager, clock);
}
@Override
public PeerSession onInviteAction(Transaction txn, PeerSession s,
@Nullable String text, long timestamp, byte[] signature) {
@Nullable String text, long timestamp, byte[] signature,
long autoDeleteTimer) {
throw new UnsupportedOperationException(); // Invalid in this role
}

View File

@@ -8,10 +8,11 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable;
@NotNullByDefault
interface ProtocolEngine<S extends Session> {
interface ProtocolEngine<S extends Session<?>> {
S onInviteAction(Transaction txn, S session, @Nullable String text,
long timestamp, byte[] signature) throws DbException;
long timestamp, byte[] signature, long autoDeleteTimer)
throws DbException;
S onJoinAction(Transaction txn, S session) throws DbException;

View File

@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
import org.briarproject.briar.api.autodelete.AutoDeleteManager;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.conversation.ConversationManager;
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
import org.briarproject.briar.api.privategroup.PrivateGroupManager;
@@ -30,6 +31,7 @@ class ProtocolEngineFactoryImpl implements ProtocolEngineFactory {
private final MessageEncoder messageEncoder;
private final MessageTracker messageTracker;
private final AutoDeleteManager autoDeleteManager;
private final ConversationManager conversationManager;
private final Clock clock;
@Inject
@@ -45,6 +47,7 @@ class ProtocolEngineFactoryImpl implements ProtocolEngineFactory {
MessageEncoder messageEncoder,
MessageTracker messageTracker,
AutoDeleteManager autoDeleteManager,
ConversationManager conversationManager,
Clock clock) {
this.db = db;
this.clientHelper = clientHelper;
@@ -57,6 +60,7 @@ class ProtocolEngineFactoryImpl implements ProtocolEngineFactory {
this.messageEncoder = messageEncoder;
this.messageTracker = messageTracker;
this.autoDeleteManager = autoDeleteManager;
this.conversationManager = conversationManager;
this.clock = clock;
}
@@ -66,7 +70,7 @@ class ProtocolEngineFactoryImpl implements ProtocolEngineFactory {
clientVersioningManager, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker,
autoDeleteManager, clock);
autoDeleteManager, conversationManager, clock);
}
@Override
@@ -75,7 +79,7 @@ class ProtocolEngineFactoryImpl implements ProtocolEngineFactory {
clientVersioningManager, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker,
autoDeleteManager, clock);
autoDeleteManager, conversationManager, clock);
}
@Override
@@ -84,6 +88,6 @@ class ProtocolEngineFactoryImpl implements ProtocolEngineFactory {
clientVersioningManager, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker,
autoDeleteManager, clock);
autoDeleteManager, conversationManager, clock);
}
}

View File

@@ -19,6 +19,7 @@ import org.briarproject.briar.api.blog.BlogSharingManager;
import org.briarproject.briar.api.blog.event.BlogInvitationRequestReceivedEvent;
import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.conversation.ConversationManager;
import org.briarproject.briar.api.conversation.ConversationRequest;
import javax.annotation.concurrent.Immutable;
@@ -41,13 +42,15 @@ class BlogProtocolEngineImpl extends ProtocolEngineImpl<Blog> {
MessageParser<Blog> messageParser,
MessageTracker messageTracker,
AutoDeleteManager autoDeleteManager,
ConversationManager conversationManager,
Clock clock,
BlogManager blogManager,
InvitationFactory<Blog, BlogInvitationResponse> invitationFactory) {
super(db, clientHelper, clientVersioningManager, messageEncoder,
messageParser, messageTracker, autoDeleteManager, clock,
BlogSharingManager.CLIENT_ID, BlogSharingManager.MAJOR_VERSION,
BlogManager.CLIENT_ID, BlogManager.MAJOR_VERSION);
messageParser, messageTracker, autoDeleteManager,
conversationManager, clock, BlogSharingManager.CLIENT_ID,
BlogSharingManager.MAJOR_VERSION, BlogManager.CLIENT_ID,
BlogManager.MAJOR_VERSION);
this.blogManager = blogManager;
this.invitationFactory = invitationFactory;
}

View File

@@ -13,6 +13,7 @@ import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
import org.briarproject.briar.api.autodelete.AutoDeleteManager;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.conversation.ConversationManager;
import org.briarproject.briar.api.conversation.ConversationRequest;
import org.briarproject.briar.api.forum.Forum;
import org.briarproject.briar.api.forum.ForumInvitationResponse;
@@ -41,14 +42,15 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
MessageParser<Forum> messageParser,
MessageTracker messageTracker,
AutoDeleteManager autoDeleteManager,
ConversationManager conversationManager,
Clock clock,
ForumManager forumManager,
InvitationFactory<Forum, ForumInvitationResponse> invitationFactory) {
super(db, clientHelper, clientVersioningManager, messageEncoder,
messageParser, messageTracker, autoDeleteManager, clock,
ForumSharingManager.CLIENT_ID,
ForumSharingManager.MAJOR_VERSION,
ForumManager.CLIENT_ID, ForumManager.MAJOR_VERSION);
messageParser, messageTracker, autoDeleteManager,
conversationManager, clock, ForumSharingManager.CLIENT_ID,
ForumSharingManager.MAJOR_VERSION, ForumManager.CLIENT_ID,
ForumManager.MAJOR_VERSION);
this.forumManager = forumManager;
this.invitationFactory = invitationFactory;
}

View File

@@ -12,7 +12,7 @@ import javax.annotation.Nullable;
interface ProtocolEngine<S extends Shareable> {
Session onInviteAction(Transaction txn, Session session,
@Nullable String text, long timestamp) throws DbException;
@Nullable String text) throws DbException;
Session onAcceptAction(Transaction txn, Session session) throws DbException;

View File

@@ -21,6 +21,7 @@ import org.briarproject.bramble.api.versioning.ClientVersioningManager;
import org.briarproject.briar.api.autodelete.AutoDeleteManager;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.client.ProtocolStateException;
import org.briarproject.briar.api.conversation.ConversationManager;
import org.briarproject.briar.api.sharing.Shareable;
import org.briarproject.briar.api.sharing.event.ContactLeftShareableEvent;
@@ -29,6 +30,7 @@ import java.util.Map;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import static java.lang.Math.max;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
@@ -58,6 +60,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
private final MessageEncoder messageEncoder;
private final MessageTracker messageTracker;
private final AutoDeleteManager autoDeleteManager;
private final ConversationManager conversationManager;
private final Clock clock;
private final ClientId sharingClientId, shareableClientId;
private final int sharingClientMajorVersion, shareableClientMajorVersion;
@@ -70,6 +73,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
MessageParser<S> messageParser,
MessageTracker messageTracker,
AutoDeleteManager autoDeleteManager,
ConversationManager conversationManager,
Clock clock,
ClientId sharingClientId,
int sharingClientMajorVersion,
@@ -82,6 +86,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
this.messageParser = messageParser;
this.messageTracker = messageTracker;
this.autoDeleteManager = autoDeleteManager;
this.conversationManager = conversationManager;
this.clock = clock;
this.sharingClientId = sharingClientId;
this.sharingClientMajorVersion = sharingClientMajorVersion;
@@ -91,10 +96,10 @@ abstract class ProtocolEngineImpl<S extends Shareable>
@Override
public Session onInviteAction(Transaction txn, Session s,
@Nullable String text, long timestamp) throws DbException {
@Nullable String text) throws DbException {
switch (s.getState()) {
case START:
return onLocalInvite(txn, s, text, timestamp);
return onLocalInvite(txn, s, text);
case LOCAL_INVITED:
case REMOTE_INVITED:
case SHARING:
@@ -107,9 +112,9 @@ abstract class ProtocolEngineImpl<S extends Shareable>
}
private Session onLocalInvite(Transaction txn, Session s,
@Nullable String text, long timestamp) throws DbException {
@Nullable String text) throws DbException {
// Send an INVITE message
Message sent = sendInviteMessage(txn, s, text, timestamp);
Message sent = sendInviteMessage(txn, s, text);
// Track the message
messageTracker.trackOutgoingMessage(txn, sent);
// Make the shareable visible to the contact
@@ -125,7 +130,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
}
private Message sendInviteMessage(Transaction txn, Session s,
@Nullable String text, long timestamp) throws DbException {
@Nullable String text) throws DbException {
Group g = db.getGroup(txn, s.getShareableId());
BdfList descriptor;
try {
@@ -133,8 +138,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
} catch (FormatException e) {
throw new DbException(e); // Invalid group descriptor
}
long localTimestamp = Math.max(timestamp, getLocalTimestamp(s));
Message m;
long localTimestamp = getTimestampForVisibleMessage(txn, s);
ContactId c = getContactId(txn, s.getContactGroupId());
if (contactSupportsAutoDeletion(txn, c)) {
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c);
@@ -201,16 +206,17 @@ abstract class ProtocolEngineImpl<S extends Shareable>
private Message sendAcceptMessage(Transaction txn, Session s)
throws DbException {
Message m;
long localTimestamp = getTimestampForVisibleMessage(txn, s);
ContactId c = getContactId(txn, s.getContactGroupId());
if (contactSupportsAutoDeletion(txn, c)) {
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c);
m = messageEncoder.encodeAcceptMessage(s.getContactGroupId(),
s.getShareableId(), getLocalTimestamp(s),
s.getShareableId(), localTimestamp,
s.getLastLocalMessageId(), timer);
sendMessage(txn, m, ACCEPT, s.getShareableId(), true, timer);
} else {
m = messageEncoder.encodeAcceptMessage(s.getContactGroupId(),
s.getShareableId(), getLocalTimestamp(s),
s.getShareableId(), localTimestamp,
s.getLastLocalMessageId());
sendMessage(txn, m, ACCEPT, s.getShareableId(), true,
NO_AUTO_DELETE_TIMER);
@@ -254,16 +260,17 @@ abstract class ProtocolEngineImpl<S extends Shareable>
private Message sendDeclineMessage(Transaction txn, Session s)
throws DbException {
Message m;
long localTimestamp = getTimestampForVisibleMessage(txn, s);
ContactId c = getContactId(txn, s.getContactGroupId());
if (contactSupportsAutoDeletion(txn, c)) {
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c);
m = messageEncoder.encodeDeclineMessage(s.getContactGroupId(),
s.getShareableId(), getLocalTimestamp(s),
s.getShareableId(), localTimestamp,
s.getLastLocalMessageId(), timer);
sendMessage(txn, m, DECLINE, s.getShareableId(), true, timer);
} else {
m = messageEncoder.encodeDeclineMessage(s.getContactGroupId(),
s.getShareableId(), getLocalTimestamp(s),
s.getShareableId(), localTimestamp,
s.getLastLocalMessageId());
sendMessage(txn, m, DECLINE, s.getShareableId(), true,
NO_AUTO_DELETE_TIMER);
@@ -307,9 +314,10 @@ abstract class ProtocolEngineImpl<S extends Shareable>
private Message sendLeaveMessage(Transaction txn, Session session)
throws DbException {
long localTimestamp = getTimestampForInvisibleMessage(session);
Message m = messageEncoder.encodeLeaveMessage(
session.getContactGroupId(), session.getShareableId(),
getLocalTimestamp(session), session.getLastLocalMessageId());
localTimestamp, session.getLastLocalMessageId());
sendMessage(txn, m, LEAVE, session.getShareableId(), false,
NO_AUTO_DELETE_TIMER);
return m;
@@ -605,9 +613,10 @@ abstract class ProtocolEngineImpl<S extends Shareable>
private Message sendAbortMessage(Transaction txn, Session session)
throws DbException {
long localTimestamp = getTimestampForInvisibleMessage(session);
Message m = messageEncoder.encodeAbortMessage(
session.getContactGroupId(), session.getShareableId(),
getLocalTimestamp(session), session.getLastLocalMessageId());
localTimestamp, session.getLastLocalMessageId());
sendMessage(txn, m, ABORT, session.getShareableId(), false,
NO_AUTO_DELETE_TIMER);
return m;
@@ -677,10 +686,34 @@ abstract class ProtocolEngineImpl<S extends Shareable>
return !dependency.equals(expected);
}
private long getLocalTimestamp(Session session) {
return Math.max(clock.currentTimeMillis(),
Math.max(session.getLocalTimestamp(),
session.getInviteTimestamp()) + 1);
/**
* Returns a timestamp for a visible outgoing message. The timestamp is
* later than the timestamp of any message sent or received so far in the
* conversation, and later than the {@link #getSessionTimestamp(Session)
* session timestamp}.
*/
private long getTimestampForVisibleMessage(Transaction txn, Session s)
throws DbException {
ContactId c = getContactId(txn, s.getContactGroupId());
long conversationTimestamp =
conversationManager.getTimestampForOutgoingMessage(txn, c);
return max(conversationTimestamp, getSessionTimestamp(s) + 1);
}
/**
* Returns a timestamp for an invisible outgoing message. The timestamp is
* later than the {@link #getSessionTimestamp(Session) session timestamp}.
*/
private long getTimestampForInvisibleMessage(Session s) {
return max(clock.currentTimeMillis(), getSessionTimestamp(s) + 1);
}
/**
* Returns the latest timestamp of any message sent so far in the session,
* and any invite message sent or received so far in the session.
*/
private long getSessionTimestamp(Session s) {
return max(s.getLocalTimestamp(), s.getInviteTimestamp());
}
private ContactId getContactId(Transaction txn, GroupId contactGroupId)

View File

@@ -248,7 +248,7 @@ abstract class SharingManagerImpl<S extends Shareable>
@Override
public void sendInvitation(GroupId shareableId, ContactId contactId,
@Nullable String text, long timestamp) throws DbException {
@Nullable String text) throws DbException {
SessionId sessionId = getSessionId(shareableId);
Transaction txn = db.startTransaction(false);
try {
@@ -273,7 +273,7 @@ abstract class SharingManagerImpl<S extends Shareable>
storageId = ss.storageId;
}
// Handle the invite action
session = engine.onInviteAction(txn, session, text, timestamp);
session = engine.onInviteAction(txn, session, text);
// Store the updated session
storeSession(txn, storageId, session);
db.commitTransaction(txn);

View File

@@ -45,8 +45,7 @@ public class ForumManagerTest
forum0 = forumManager0.addForum("Test Forum");
groupId0 = forum0.getId();
// share forum
forumSharingManager0.sendInvitation(groupId0, contactId1From0, null,
clock.currentTimeMillis());
forumSharingManager0.sendInvitation(groupId0, contactId1From0, null);
sync0To1(1, true);
forumSharingManager1.respondToInvitation(forum0, contact0From1, true);
sync1To0(1, true);
@@ -194,8 +193,7 @@ public class ForumManagerTest
// share a second forum
Forum forum1 = forumManager0.addForum("Test Forum1");
GroupId g1 = forum1.getId();
forumSharingManager0.sendInvitation(g1, contactId1From0, null,
clock.currentTimeMillis());
forumSharingManager0.sendInvitation(g1, contactId1From0, null);
sync0To1(1, true);
forumSharingManager1.respondToInvitation(forum1, contact0From1, true);
sync1To0(1, true);

View File

@@ -140,11 +140,9 @@ public class IntroductionIntegrationTest
addListeners(true, true);
// make introduction
long time = clock.currentTimeMillis();
Contact introducee1 = contact1From0;
Contact introducee2 = contact2From0;
introductionManager0
.makeIntroduction(introducee1, introducee2, "Hi!", time);
introductionManager0.makeIntroduction(introducee1, introducee2, "Hi!");
// check that messages are tracked properly
Group g1 = introductionManager0.getContactGroup(introducee1);
@@ -264,11 +262,9 @@ public class IntroductionIntegrationTest
addListeners(false, true);
// make introduction
long time = clock.currentTimeMillis();
Contact introducee1 = contact1From0;
Contact introducee2 = contact2From0;
introductionManager0
.makeIntroduction(introducee1, introducee2, null, time);
introductionManager0.makeIntroduction(introducee1, introducee2, null);
// sync request messages
sync0To1(1, true);
@@ -356,9 +352,8 @@ public class IntroductionIntegrationTest
addListeners(true, false);
// make introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, null, time);
.makeIntroduction(contact1From0, contact2From0, null);
// sync request messages
sync0To1(1, true);
@@ -412,9 +407,8 @@ public class IntroductionIntegrationTest
addListeners(false, true);
// make introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, null, time);
.makeIntroduction(contact1From0, contact2From0, null);
// sync request messages
sync0To1(1, true);
@@ -438,9 +432,8 @@ public class IntroductionIntegrationTest
assertFalse(listener1.aborted);
assertFalse(listener2.aborted);
time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, null, time);
.makeIntroduction(contact1From0, contact2From0, null);
// sync request messages
sync0To1(1, true);
@@ -457,9 +450,8 @@ public class IntroductionIntegrationTest
addListeners(true, true);
// make introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, "Hi!", time);
.makeIntroduction(contact1From0, contact2From0, "Hi!");
// sync first request message
sync0To1(1, true);
@@ -482,7 +474,7 @@ public class IntroductionIntegrationTest
// answer request manually
introductionManager2.respondToIntroduction(contactId0From2,
listener2.sessionId, time, true);
listener2.sessionId, true);
// sync second response and AUTH
sync2To0(2, true);
@@ -518,11 +510,10 @@ public class IntroductionIntegrationTest
listener2.answerRequests = false;
// make introduction
long time = clock.currentTimeMillis();
Contact introducee1 = contact1From0;
Contact introducee2 = contact2From0;
introductionManager0
.makeIntroduction(introducee1, introducee2, null, time);
.makeIntroduction(introducee1, introducee2, null);
// sync request messages
sync0To1(1, true);
@@ -564,7 +555,7 @@ public class IntroductionIntegrationTest
// answer request manually
introductionManager2.respondToIntroduction(contactId0From2,
listener2.sessionId, time, false);
listener2.sessionId, false);
// now introducee2 should have returned to the START state
introduceeSession = getIntroduceeSession(c2);
@@ -611,9 +602,8 @@ public class IntroductionIntegrationTest
addListeners(true, false);
// make introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact1From0, null, time);
.makeIntroduction(contact1From0, contact1From0, null);
// sync request messages
sync0To1(1, false);
@@ -637,9 +627,8 @@ public class IntroductionIntegrationTest
.canIntroduce(contact1From0, contact2From0));
// make the introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, null, time);
.makeIntroduction(contact1From0, contact2From0, null);
// no more introduction allowed while the existing one is in progress
assertFalse(introductionManager0
@@ -647,7 +636,7 @@ public class IntroductionIntegrationTest
// try it anyway and fail
introductionManager0
.makeIntroduction(contact1From0, contact2From0, null, time);
.makeIntroduction(contact1From0, contact2From0, null);
}
@Test
@@ -661,9 +650,8 @@ public class IntroductionIntegrationTest
addListeners(true, true);
// make the introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, null, time);
.makeIntroduction(contact1From0, contact2From0, null);
// sync REQUEST messages
sync0To1(1, true);
@@ -719,9 +707,8 @@ public class IntroductionIntegrationTest
addListeners(true, true);
// make the introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, null, time);
.makeIntroduction(contact1From0, contact2From0, null);
// sync REQUEST messages
sync0To1(1, true);
@@ -766,9 +753,8 @@ public class IntroductionIntegrationTest
addListeners(true, true);
// make the introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, null, time);
.makeIntroduction(contact1From0, contact2From0, null);
// sync REQUEST to introducee1
sync0To1(1, true);
@@ -803,9 +789,8 @@ public class IntroductionIntegrationTest
addListeners(true, true);
// make the introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, null, time);
.makeIntroduction(contact1From0, contact2From0, null);
// sync REQUEST to introducee1
sync0To1(1, true);
@@ -838,9 +823,8 @@ public class IntroductionIntegrationTest
addListeners(false, true);
// make the introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, null, time);
.makeIntroduction(contact1From0, contact2From0, null);
// sync REQUEST to introducee1
sync0To1(1, true);
@@ -873,9 +857,8 @@ public class IntroductionIntegrationTest
addListeners(true, true);
// make the introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, null, time);
.makeIntroduction(contact1From0, contact2From0, null);
// sync REQUEST messages
sync0To1(1, true);
@@ -914,9 +897,8 @@ public class IntroductionIntegrationTest
addListeners(true, true);
// make introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, "Hi!", time);
.makeIntroduction(contact1From0, contact2From0, "Hi!");
// sync first request message
sync0To1(1, true);
@@ -943,9 +925,8 @@ public class IntroductionIntegrationTest
addListeners(true, true);
// make introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, "Hi!", time);
.makeIntroduction(contact1From0, contact2From0, "Hi!");
// sync first request message
sync0To1(1, true);
@@ -987,9 +968,8 @@ public class IntroductionIntegrationTest
@Test
public void testIntroductionAfterReAddingContacts() throws Exception {
// make introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, null, time);
.makeIntroduction(contact1From0, contact2From0, null);
// 0 and 1 remove and re-add each other
contactManager0.removeContact(contactId1From0);
@@ -1016,9 +996,8 @@ public class IntroductionIntegrationTest
addListeners(true, true);
// make new introduction
time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, null, time);
.makeIntroduction(contact1From0, contact2From0, null);
// introduction should sync and not be INVALID or PENDING
sync0To1(1, true);
@@ -1032,9 +1011,8 @@ public class IntroductionIntegrationTest
addListeners(true, true);
// make introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, "Hi!", time);
.makeIntroduction(contact1From0, contact2From0, "Hi!");
// sync request messages
sync0To1(1, true);
@@ -1147,9 +1125,8 @@ public class IntroductionIntegrationTest
addListeners(true, true);
// make introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, "Hi!", time);
.makeIntroduction(contact1From0, contact2From0, "Hi!");
// sync first REQUEST message
sync0To1(1, true);
@@ -1292,7 +1269,7 @@ public class IntroductionIntegrationTest
assertTrue(introductionManager0
.canIntroduce(contact1From0, contact2From0));
introductionManager0
.makeIntroduction(contact1From0, contact2From0, "Ho!", time);
.makeIntroduction(contact1From0, contact2From0, "Ho!");
sync0To1(1, true);
sync0To2(1, true);
@@ -1332,9 +1309,8 @@ public class IntroductionIntegrationTest
addListeners(false, false);
// make introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, "Hi!", time);
.makeIntroduction(contact1From0, contact2From0, "Hi!");
// sync REQUEST messages
sync0To1(1, true);
@@ -1399,9 +1375,8 @@ public class IntroductionIntegrationTest
// a new introduction is still possible
assertTrue(introductionManager0
.canIntroduce(contact1From0, contact2From0));
time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, "Ho!", time);
.makeIntroduction(contact1From0, contact2From0, "Ho!");
sync0To1(1, true);
sync0To2(1, true);
@@ -1428,9 +1403,8 @@ public class IntroductionIntegrationTest
addListeners(false, false);
// make introduction
long time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, "Hi!", time);
.makeIntroduction(contact1From0, contact2From0, "Hi!");
// sync REQUEST messages
sync0To1(1, true);
@@ -1458,9 +1432,8 @@ public class IntroductionIntegrationTest
// a new introduction is still possible
assertTrue(introductionManager0
.canIntroduce(contact1From0, contact2From0));
time = clock.currentTimeMillis();
introductionManager0
.makeIntroduction(contact1From0, contact2From0, "Ho!", time);
.makeIntroduction(contact1From0, contact2From0, "Ho!");
sync0To1(1, true);
sync0To2(1, true);
@@ -1496,9 +1469,8 @@ public class IntroductionIntegrationTest
addListeners(false, false);
// make introduction
long time = clock.currentTimeMillis();
introductionManager0.makeIntroduction(contact1From0, contact2From0,
"Hi!", time);
introductionManager0
.makeIntroduction(contact1From0, contact2From0, "Hi!");
// deleting the introduction for introducee1 will fail
Collection<ConversationMessageHeader> m1From0 = getMessages1From0();
@@ -1795,16 +1767,13 @@ public class IntroductionIntegrationTest
IntroductionRequest ir = introEvent.getMessageHeader();
ContactId contactId = introEvent.getContactId();
sessionId = ir.getSessionId();
long time = clock.currentTimeMillis();
try {
if (introducee == 1 && answerRequests) {
introductionManager1
.respondToIntroduction(contactId, sessionId,
time, accept);
introductionManager1.respondToIntroduction(contactId,
sessionId, accept);
} else if (introducee == 2 && answerRequests) {
introductionManager2
.respondToIntroduction(contactId, sessionId,
time, accept);
introductionManager2.respondToIntroduction(contactId,
sessionId, accept);
}
} catch (DbException exception) {
eventWaiter.rethrow(exception);

View File

@@ -25,6 +25,7 @@ import java.util.Collection;
import javax.annotation.Nullable;
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.OURSELVES;
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
import static org.briarproject.briar.api.privategroup.Visibility.INVISIBLE;
import static org.briarproject.briar.api.privategroup.Visibility.REVEALED_BY_CONTACT;
import static org.briarproject.briar.api.privategroup.Visibility.REVEALED_BY_US;
@@ -220,8 +221,8 @@ public class PrivateGroupIntegrationTest
byte[] signature = groupInvitationFactory
.signInvitation(contact, groupId0, timestamp,
author0.getPrivateKey());
groupInvitationManager0
.sendInvitation(groupId0, c, text, timestamp, signature);
groupInvitationManager0.sendInvitation(groupId0, c, text, timestamp,
signature, NO_AUTO_DELETE_TIMER);
}
private GroupMember getGroupMember(PrivateGroupManager groupManager,

View File

@@ -19,6 +19,7 @@ import org.briarproject.bramble.api.versioning.ClientVersioningManager;
import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.briar.api.autodelete.AutoDeleteManager;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.conversation.ConversationManager;
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
import org.briarproject.briar.api.privategroup.PrivateGroup;
import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
@@ -62,6 +63,8 @@ abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
final MessageTracker messageTracker = context.mock(MessageTracker.class);
final AutoDeleteManager autoDeleteManager =
context.mock(AutoDeleteManager.class);
final ConversationManager conversationManager =
context.mock(ConversationManager.class);
final Clock clock = context.mock(Clock.class);
final Transaction txn = new Transaction(null, false);
@@ -115,16 +118,26 @@ abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
assertEquals(inviteTimestamp, s.getInviteTimestamp());
}
void expectGetLocalTimestamp(long time) {
void expectGetTimestampForInvisibleMessage(long time) {
context.checking(new Expectations() {{
oneOf(clock).currentTimeMillis();
will(returnValue(time));
}});
}
void expectGetTimestampForVisibleMessage(long time) throws Exception {
context.checking(new Expectations() {{
oneOf(clientHelper).getContactId(txn, contactGroupId);
will(returnValue(contactId));
oneOf(conversationManager)
.getTimestampForOutgoingMessage(txn, contactId);
will(returnValue(time));
}});
}
void expectSendInviteMessage(String text) throws Exception {
expectCheckWhetherContactSupportsAutoDeletion(true);
expectGetLocalTimestamp(messageTimestamp);
expectGetTimestampForVisibleMessage(messageTimestamp);
expectCheckWhetherContactSupportsAutoDeletion();
context.checking(new Expectations() {{
oneOf(messageEncoder).encodeInviteMessage(contactGroupId,
privateGroupId, inviteTimestamp, privateGroup.getName(),
@@ -137,8 +150,10 @@ abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
void expectSendJoinMessage(JoinMessage m, boolean visible)
throws Exception {
expectCheckWhetherContactSupportsAutoDeletion(visible);
expectGetLocalTimestamp(messageTimestamp);
if (visible) expectGetTimestampForVisibleMessage(messageTimestamp);
else expectGetTimestampForInvisibleMessage(messageTimestamp);
expectCheckWhetherContactSupportsAutoDeletion();
if (visible) expectGetAutoDeleteTimer();
context.checking(new Expectations() {{
oneOf(messageEncoder).encodeJoinMessage(m.getContactGroupId(),
m.getPrivateGroupId(), m.getTimestamp(),
@@ -149,8 +164,10 @@ abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
}
void expectSendLeaveMessage(boolean visible) throws Exception {
expectCheckWhetherContactSupportsAutoDeletion(visible);
expectGetLocalTimestamp(messageTimestamp);
if (visible) expectGetTimestampForVisibleMessage(messageTimestamp);
else expectGetTimestampForInvisibleMessage(messageTimestamp);
expectCheckWhetherContactSupportsAutoDeletion();
if (visible) expectGetAutoDeleteTimer();
context.checking(new Expectations() {{
oneOf(messageEncoder).encodeLeaveMessage(contactGroupId,
privateGroupId, messageTimestamp, lastLocalMessageId,
@@ -161,7 +178,7 @@ abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
}
void expectSendAbortMessage() throws Exception {
expectGetLocalTimestamp(messageTimestamp);
expectGetTimestampForInvisibleMessage(messageTimestamp);
context.checking(new Expectations() {{
oneOf(messageEncoder)
.encodeAbortMessage(contactGroupId, privateGroupId,
@@ -226,8 +243,7 @@ abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
}});
}
void expectCheckWhetherContactSupportsAutoDeletion(boolean visible)
throws Exception {
void expectCheckWhetherContactSupportsAutoDeletion() throws Exception {
context.checking(new Expectations() {{
oneOf(clientHelper).getContactId(txn, contactGroupId);
will(returnValue(contactId));
@@ -235,10 +251,13 @@ abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
GroupInvitationManager.CLIENT_ID,
GroupInvitationManager.MAJOR_VERSION);
will(returnValue(GroupInvitationManager.MINOR_VERSION));
if (visible) {
oneOf(autoDeleteManager).getAutoDeleteTimer(txn, contactId);
will(returnValue(NO_AUTO_DELETE_TIMER));
}
}});
}
void expectGetAutoDeleteTimer() throws Exception {
context.checking(new Expectations() {{
oneOf(autoDeleteManager).getAutoDeleteTimer(txn, contactId);
will(returnValue(NO_AUTO_DELETE_TIMER));
}});
}
}

View File

@@ -24,7 +24,8 @@ public class CreatorProtocolEngineTest extends AbstractProtocolEngineTest {
new CreatorProtocolEngine(db, clientHelper, clientVersioningManager,
privateGroupManager, privateGroupFactory,
groupMessageFactory, identityManager, messageParser,
messageEncoder, messageTracker, autoDeleteManager, clock);
messageEncoder, messageTracker, autoDeleteManager,
conversationManager, clock);
private CreatorSession getDefaultSession(CreatorState state) {
return new CreatorSession(contactGroupId, privateGroupId,
@@ -43,7 +44,7 @@ public class CreatorProtocolEngineTest extends AbstractProtocolEngineTest {
expectOnLocalInvite(text);
CreatorSession newSession =
engine.onInviteAction(txn, session, text, inviteTimestamp,
signature);
signature, NO_AUTO_DELETE_TIMER);
assertEquals(INVITED, newSession.getState());
assertEquals(messageId, newSession.getLastLocalMessageId());
assertNull(newSession.getLastRemoteMessageId());
@@ -60,7 +61,7 @@ public class CreatorProtocolEngineTest extends AbstractProtocolEngineTest {
expectOnLocalInvite(null);
CreatorSession newSession =
engine.onInviteAction(txn, session, null, inviteTimestamp,
signature);
signature, NO_AUTO_DELETE_TIMER);
assertEquals(INVITED, newSession.getState());
assertEquals(messageId, newSession.getLastLocalMessageId());
assertNull(newSession.getLastRemoteMessageId());
@@ -83,31 +84,31 @@ public class CreatorProtocolEngineTest extends AbstractProtocolEngineTest {
@Test(expected = ProtocolStateException.class)
public void testOnInviteActionFromInvited() throws Exception {
engine.onInviteAction(txn, getDefaultSession(INVITED), null,
inviteTimestamp, signature);
inviteTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = ProtocolStateException.class)
public void testOnInviteActionFromJoined() throws Exception {
engine.onInviteAction(txn, getDefaultSession(JOINED), null,
inviteTimestamp, signature);
inviteTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = ProtocolStateException.class)
public void testOnInviteActionFromLeft() throws Exception {
engine.onInviteAction(txn, getDefaultSession(LEFT), null,
inviteTimestamp, signature);
inviteTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = ProtocolStateException.class)
public void testOnInviteActionFromDissolved() throws Exception {
engine.onInviteAction(txn, getDefaultSession(DISSOLVED), null,
inviteTimestamp, signature);
inviteTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = ProtocolStateException.class)
public void testOnInviteActionFromError() throws Exception {
engine.onInviteAction(txn, getDefaultSession(ERROR), null,
inviteTimestamp, signature);
inviteTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
// onJoinAction

View File

@@ -27,6 +27,7 @@ import java.util.Set;
import javax.annotation.Nullable;
import static java.util.Collections.emptySet;
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
import static org.briarproject.briar.test.BriarTestUtils.assertGroupCount;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -687,7 +688,8 @@ public class GroupInvitationIntegrationTest
byte[] signature = groupInvitationFactory.signInvitation(contact1From0,
privateGroup.getId(), timestamp, author0.getPrivateKey());
groupInvitationManager0.sendInvitation(privateGroup.getId(),
contactId1From0, text, timestamp, signature);
contactId1From0, text, timestamp, signature,
NO_AUTO_DELETE_TIMER);
}
}

View File

@@ -482,7 +482,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
context.checking(new Expectations() {{
oneOf(creatorEngine).onInviteAction(with(txn),
with(any(CreatorSession.class)), with(text), with(time),
with(signature));
with(signature), with(NO_AUTO_DELETE_TIMER));
will(returnValue(creatorSession));
}});
expectStoreSession(creatorSession, storageMessage.getId());
@@ -491,7 +491,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
oneOf(db).endTransaction(txn);
}});
groupInvitationManager.sendInvitation(privateGroup.getId(), contactId,
text, time, signature);
text, time, signature, NO_AUTO_DELETE_TIMER);
}
@Test
@@ -514,7 +514,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
will(returnValue(creatorSession));
oneOf(creatorEngine).onInviteAction(with(txn),
with(any(CreatorSession.class)), with(text), with(time),
with(signature));
with(signature), with(NO_AUTO_DELETE_TIMER));
will(returnValue(creatorSession));
}});
expectStoreSession(creatorSession, storageMessage.getId());
@@ -523,7 +523,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
oneOf(db).endTransaction(txn);
}});
groupInvitationManager.sendInvitation(privateGroup.getId(), contactId,
text, time, signature);
text, time, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = IllegalArgumentException.class)

View File

@@ -43,7 +43,8 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
new InviteeProtocolEngine(db, clientHelper, clientVersioningManager,
privateGroupManager, privateGroupFactory,
groupMessageFactory, identityManager, messageParser,
messageEncoder, messageTracker, autoDeleteManager, clock);
messageEncoder, messageTracker, autoDeleteManager,
conversationManager, clock);
private final LocalAuthor localAuthor = getLocalAuthor();
private InviteeSession getDefaultSession(InviteeState state) {
@@ -57,43 +58,43 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
@Test(expected = UnsupportedOperationException.class)
public void testOnInviteActionFromStart() {
engine.onInviteAction(txn, getDefaultSession(START), null,
messageTimestamp, signature);
messageTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = UnsupportedOperationException.class)
public void testOnInviteActionFromLeft() {
engine.onInviteAction(txn, getDefaultSession(ACCEPTED), null,
messageTimestamp, signature);
messageTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = UnsupportedOperationException.class)
public void testOnInviteActionFromInvited() {
engine.onInviteAction(txn, getDefaultSession(INVITED), null,
messageTimestamp, signature);
messageTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = UnsupportedOperationException.class)
public void testOnInviteActionFromDissolved() {
engine.onInviteAction(txn, getDefaultSession(DISSOLVED), null,
messageTimestamp, signature);
messageTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = UnsupportedOperationException.class)
public void testOnInviteActionFromAccepted() {
engine.onInviteAction(txn, getDefaultSession(ACCEPTED), null,
messageTimestamp, signature);
messageTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = UnsupportedOperationException.class)
public void testOnInviteActionFromJoined() {
engine.onInviteAction(txn, getDefaultSession(JOINED), null,
messageTimestamp, signature);
messageTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = UnsupportedOperationException.class)
public void testOnInviteActionFromError() {
engine.onInviteAction(txn, getDefaultSession(ERROR), null,
messageTimestamp, signature);
messageTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
// onJoinAction

View File

@@ -27,7 +27,8 @@ public class PeerProtocolEngineTest extends AbstractProtocolEngineTest {
new PeerProtocolEngine(db, clientHelper, clientVersioningManager,
privateGroupManager, privateGroupFactory,
groupMessageFactory, identityManager, messageParser,
messageEncoder, messageTracker, autoDeleteManager, clock);
messageEncoder, messageTracker, autoDeleteManager,
conversationManager, clock);
private PeerSession getDefaultSession(PeerState state) {
return new PeerSession(contactGroupId, privateGroupId,
@@ -39,43 +40,43 @@ public class PeerProtocolEngineTest extends AbstractProtocolEngineTest {
@Test(expected = UnsupportedOperationException.class)
public void testOnInviteActionFromStart() {
engine.onInviteAction(txn, getDefaultSession(START), null,
messageTimestamp, signature);
messageTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = UnsupportedOperationException.class)
public void testOnInviteActionFromAwaitMember() {
engine.onInviteAction(txn, getDefaultSession(AWAIT_MEMBER), null,
messageTimestamp, signature);
messageTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = UnsupportedOperationException.class)
public void testOnInviteActionFromNeitherJoined() {
engine.onInviteAction(txn, getDefaultSession(NEITHER_JOINED), null,
messageTimestamp, signature);
messageTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = UnsupportedOperationException.class)
public void testOnInviteActionFromLocalJoined() {
engine.onInviteAction(txn, getDefaultSession(LOCAL_JOINED), null,
messageTimestamp, signature);
messageTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = UnsupportedOperationException.class)
public void testOnInviteActionFromBothJoined() {
engine.onInviteAction(txn, getDefaultSession(BOTH_JOINED), null,
messageTimestamp, signature);
messageTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = UnsupportedOperationException.class)
public void testOnInviteActionFromLocalLeft() {
engine.onInviteAction(txn, getDefaultSession(LOCAL_LEFT), null,
messageTimestamp, signature);
messageTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
@Test(expected = UnsupportedOperationException.class)
public void testOnInviteActionFromError() {
engine.onInviteAction(txn, getDefaultSession(ERROR), null,
messageTimestamp, signature);
messageTimestamp, signature, NO_AUTO_DELETE_TIMER);
}
// onJoinAction

View File

@@ -122,8 +122,7 @@ public class BlogSharingIntegrationTest
// send invitation
blogSharingManager0
.sendInvitation(blog2.getId(), contactId1From0, "Hi!",
clock.currentTimeMillis());
.sendInvitation(blog2.getId(), contactId1From0, "Hi!");
// invitee has own blog and that of the sharer
assertEquals(2, blogManager1.getBlogs().size());
@@ -213,8 +212,8 @@ public class BlogSharingIntegrationTest
blogManager0.addBlog(rssBlog);
// send invitation
blogSharingManager0.sendInvitation(rssBlog.getId(), contactId1From0,
"Hi!", clock.currentTimeMillis());
blogSharingManager0
.sendInvitation(rssBlog.getId(), contactId1From0, "Hi!");
// invitee has own blog and that of the sharer
assertEquals(2, blogManager1.getBlogs().size());
@@ -285,8 +284,7 @@ public class BlogSharingIntegrationTest
// send invitation
blogSharingManager0
.sendInvitation(blog2.getId(), contactId1From0, null,
clock.currentTimeMillis());
.sendInvitation(blog2.getId(), contactId1From0, null);
// sync first request message
sync0To1(1, true);
@@ -341,8 +339,7 @@ public class BlogSharingIntegrationTest
// send invitation
blogSharingManager0
.sendInvitation(blog2.getId(), contactId1From0, "Hi!",
clock.currentTimeMillis());
.sendInvitation(blog2.getId(), contactId1From0, "Hi!");
// sync first request message
sync0To1(1, true);
@@ -398,8 +395,7 @@ public class BlogSharingIntegrationTest
// sharer sends invitation for 2's blog to 1
blogSharingManager0
.sendInvitation(blog2.getId(), contactId1From0, "Hi!",
clock.currentTimeMillis());
.sendInvitation(blog2.getId(), contactId1From0, "Hi!");
// sync first request message
sync0To1(1, true);
@@ -436,8 +432,7 @@ public class BlogSharingIntegrationTest
// send invitation
blogSharingManager0
.sendInvitation(blog2.getId(), contactId1From0, "Hi!",
clock.currentTimeMillis());
.sendInvitation(blog2.getId(), contactId1From0, "Hi!");
// sync first request message
sync0To1(1, true);
@@ -515,8 +510,7 @@ public class BlogSharingIntegrationTest
// sharer sends invitation for 2's blog to 1
blogSharingManager0
.sendInvitation(blog2.getId(), contactId1From0, "Hi!",
clock.currentTimeMillis());
.sendInvitation(blog2.getId(), contactId1From0, "Hi!");
// sync first request message
sync0To1(1, true);

View File

@@ -126,8 +126,7 @@ public class ForumSharingIntegrationTest
public void testSuccessfulSharing() throws Exception {
// send invitation
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, "Hi!",
clock.currentTimeMillis());
.sendInvitation(forum.getId(), contactId1From0, "Hi!");
// check that request message state is correct
Collection<ConversationMessageHeader> messages = getMessages1From0();
@@ -191,8 +190,8 @@ public class ForumSharingIntegrationTest
@Test
public void testDeclinedSharing() throws Exception {
// send invitation
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
null, clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, null);
// sync request message
sync0To1(1, true);
@@ -243,8 +242,8 @@ public class ForumSharingIntegrationTest
// send a new invitation again after re-adding the forum
db0.transaction(false, txn -> forumManager0.addForum(txn, forum));
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
null, clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, null);
// reset listener state for new request
listener1.requestReceived = false;
@@ -259,8 +258,8 @@ public class ForumSharingIntegrationTest
@Test
public void testInviteeLeavesAfterFinished() throws Exception {
// send invitation
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
"Hi!", clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, "Hi!");
// sync request message
sync0To1(1, true);
@@ -322,8 +321,8 @@ public class ForumSharingIntegrationTest
@Test
public void testSharerLeavesAfterFinished() throws Exception {
// send invitation
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
null, clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, null);
// sync request message
sync0To1(1, true);
@@ -383,8 +382,8 @@ public class ForumSharingIntegrationTest
// send a new invitation again after re-adding the forum
db0.transaction(false, txn -> forumManager0.addForum(txn, forum));
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
null, clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, null);
// reset listener state for new request
listener1.requestReceived = false;
@@ -399,8 +398,8 @@ public class ForumSharingIntegrationTest
@Test
public void testSharerLeavesBeforeResponse() throws Exception {
// send invitation
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
null, clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, null);
// sharer un-subscribes from forum
forumManager0.removeForum(forum);
@@ -420,8 +419,7 @@ public class ForumSharingIntegrationTest
// send invitation
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, null,
clock.currentTimeMillis());
.sendInvitation(forum.getId(), contactId1From0, null);
// sync request message
sync0To1(1, true);
@@ -445,8 +443,8 @@ public class ForumSharingIntegrationTest
@Test
public void testSharingSameForumWithEachOther() throws Exception {
// send invitation
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
"Hi!", clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, "Hi!");
// sync request message
sync0To1(1, true);
@@ -471,10 +469,9 @@ public class ForumSharingIntegrationTest
assertEquals(1, forumManager1.getForums().size());
// invitee now shares same forum back
forumSharingManager1.sendInvitation(forum.getId(),
contactId0From1,
"I am re-sharing this forum with you.",
clock.currentTimeMillis());
forumSharingManager1
.sendInvitation(forum.getId(), contactId0From1,
"I am re-sharing this forum with you.");
// assert that the last invitation wasn't send
assertEquals(2, c1.getMessageTracker().getGroupCount(group.getId())
@@ -485,8 +482,8 @@ public class ForumSharingIntegrationTest
public void testSharingSameForumWithEachOtherBeforeAccept()
throws Exception {
// send invitation
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
"Hi!", clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, "Hi!");
sync0To1(1, true);
eventWaiter.await(TIMEOUT, 1);
assertRequestReceived(listener1, contactId0From1);
@@ -501,10 +498,9 @@ public class ForumSharingIntegrationTest
.getMsgCount());
// invitee now shares same forum back
forumSharingManager1.sendInvitation(forum.getId(),
contactId0From1,
"I am re-sharing this forum with you.",
clock.currentTimeMillis());
forumSharingManager1
.sendInvitation(forum.getId(), contactId0From1,
"I am re-sharing this forum with you.");
// assert that the last invitation wasn't send
assertEquals(1, c1.getMessageTracker().getGroupCount(group.getId())
@@ -518,13 +514,12 @@ public class ForumSharingIntegrationTest
// send invitation
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, "Hi!",
clock.currentTimeMillis());
.sendInvitation(forum.getId(), contactId1From0, "Hi!");
// invitee now shares same forum back
forumSharingManager1.sendInvitation(forum.getId(),
contactId0From1, "I am re-sharing this forum with you.",
clock.currentTimeMillis());
forumSharingManager1
.sendInvitation(forum.getId(), contactId0From1,
"I am re-sharing this forum with you.");
// only now sync request message
sync0To1(1, true);
@@ -554,8 +549,8 @@ public class ForumSharingIntegrationTest
@Test
public void testContactRemoved() throws Exception {
// send invitation
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
"Hi!", clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, "Hi!");
// sync request message
sync0To1(1, true);
@@ -597,8 +592,7 @@ public class ForumSharingIntegrationTest
// send invitation
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, "Hi!",
clock.currentTimeMillis());
.sendInvitation(forum.getId(), contactId1From0, "Hi!");
// sync request message
sync0To1(1, true);
@@ -626,8 +620,7 @@ public class ForumSharingIntegrationTest
// send invitation
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, "Hi!",
clock.currentTimeMillis());
.sendInvitation(forum.getId(), contactId1From0, "Hi!");
// sync request message
sync0To1(1, true);
@@ -637,8 +630,7 @@ public class ForumSharingIntegrationTest
// second sharer sends invitation for same forum
assertNotNull(contactId1From2);
forumSharingManager2
.sendInvitation(forum.getId(), contactId1From2, null,
clock.currentTimeMillis());
.sendInvitation(forum.getId(), contactId1From2, null);
// sync second request message
sync2To1(1, true);
@@ -680,8 +672,8 @@ public class ForumSharingIntegrationTest
@Test
public void testSyncAfterReSharing() throws Exception {
// send invitation
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
"Hi!", clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, "Hi!");
// sync request message
sync0To1(1, true);
@@ -745,8 +737,7 @@ public class ForumSharingIntegrationTest
// send invitation again
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, "Hi!",
clock.currentTimeMillis());
.sendInvitation(forum.getId(), contactId1From0, "Hi!");
// sync request message
sync0To1(1, true);
@@ -787,8 +778,8 @@ public class ForumSharingIntegrationTest
@Test
public void testSessionResetAfterAbort() throws Exception {
// send invitation
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
"Hi!", clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, "Hi!");
// sync request message
sync0To1(1, true);
@@ -836,8 +827,7 @@ public class ForumSharingIntegrationTest
// new invitation is possible now
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, null,
clock.currentTimeMillis());
.sendInvitation(forum.getId(), contactId1From0, null);
sync0To1(1, true);
eventWaiter.await(TIMEOUT, 1);
assertRequestReceived(listener1, contactId0From1);
@@ -859,8 +849,8 @@ public class ForumSharingIntegrationTest
public void testDeletingAllMessagesWhenCompletingSession()
throws Exception {
// send invitation
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
null, clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, null);
sync0To1(1, true);
eventWaiter.await(TIMEOUT, 1);
@@ -909,8 +899,8 @@ public class ForumSharingIntegrationTest
sync1To0(1, true);
// sending invitation is possible again
forumSharingManager1.sendInvitation(forum.getId(), contactId0From1,
null, clock.currentTimeMillis());
forumSharingManager1
.sendInvitation(forum.getId(), contactId0From1, null);
sync1To0(1, true);
eventWaiter.await(TIMEOUT, 1);
@@ -944,8 +934,8 @@ public class ForumSharingIntegrationTest
public void testDeletingAllMessagesAfterDecline()
throws Exception {
// send invitation
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
null, clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, null);
sync0To1(1, true);
eventWaiter.await(TIMEOUT, 1);
@@ -969,8 +959,8 @@ public class ForumSharingIntegrationTest
assertEquals(0, getMessages0From1().size());
// re-sending invitation is possible
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
null, clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, null);
sync0To1(1, true);
eventWaiter.await(TIMEOUT, 1);
@@ -984,8 +974,8 @@ public class ForumSharingIntegrationTest
@Test
public void testDeletingSomeMessages() throws Exception {
// send invitation
forumSharingManager0.sendInvitation(forum.getId(), contactId1From0,
null, clock.currentTimeMillis());
forumSharingManager0
.sendInvitation(forum.getId(), contactId1From0, null);
sync0To1(1, true);
eventWaiter.await(TIMEOUT, 1);
@@ -996,7 +986,8 @@ public class ForumSharingIntegrationTest
Set<MessageId> toDelete = new HashSet<>();
toDelete.add(messageId);
assertFalse(deleteMessages1From0(toDelete).allDeleted());
assertTrue(deleteMessages1From0(toDelete).hasInvitationSessionInProgress());
assertTrue(deleteMessages1From0(toDelete)
.hasInvitationSessionInProgress());
// decline invitation
respondToRequest(contactId0From1, true);
@@ -1006,9 +997,11 @@ public class ForumSharingIntegrationTest
// both can still not delete the invitation,
// because the response was not selected for deletion as well
assertFalse(deleteMessages1From0(toDelete).allDeleted());
assertTrue(deleteMessages1From0(toDelete).hasNotAllInvitationSelected());
assertTrue(
deleteMessages1From0(toDelete).hasNotAllInvitationSelected());
assertFalse(deleteMessages0From1(toDelete).allDeleted());
assertTrue(deleteMessages0From1(toDelete).hasNotAllInvitationSelected());
assertTrue(
deleteMessages0From1(toDelete).hasNotAllInvitationSelected());
// after selecting response, both messages can be deleted
m0 = getMessages1From0();
@@ -1023,8 +1016,10 @@ public class ForumSharingIntegrationTest
// 1 can still not delete the messages, as last one has not been ACKed
assertFalse(deleteMessages0From1(toDelete).allDeleted());
assertFalse(deleteMessages0From1(toDelete).hasNotAllInvitationSelected());
assertTrue(deleteMessages0From1(toDelete).hasInvitationSessionInProgress());
assertFalse(
deleteMessages0From1(toDelete).hasNotAllInvitationSelected());
assertTrue(deleteMessages0From1(toDelete)
.hasInvitationSessionInProgress());
// 0 sends an ACK to their last message
sendAcks(c0, c1, contactId1From0, 1);