mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Move lookup of latest conversation timestamp to core.
This commit is contained in:
@@ -736,18 +736,10 @@ public class ConversationActivity extends BriarActivity
|
||||
List<AttachmentHeader> attachmentHeaders) {
|
||||
if (isNullOrEmpty(text) && attachmentHeaders.isEmpty())
|
||||
throw new AssertionError();
|
||||
long timestamp = System.currentTimeMillis();
|
||||
timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
|
||||
viewModel.sendMessage(text, attachmentHeaders, timestamp);
|
||||
viewModel.sendMessage(text, attachmentHeaders);
|
||||
textInputView.clearText();
|
||||
}
|
||||
|
||||
private long getMinTimestampForNewMessage() {
|
||||
// Don't use an earlier timestamp than the newest message
|
||||
ConversationItem item = adapter.getLastItem();
|
||||
return item == null ? 0 : item.getTime() + 1;
|
||||
}
|
||||
|
||||
private void onAddedPrivateMessage(@Nullable PrivateMessageHeader h) {
|
||||
if (h == null) return;
|
||||
addConversationItem(h.accept(visitor));
|
||||
@@ -955,13 +947,11 @@ public class ConversationActivity extends BriarActivity
|
||||
adapter.notifyItemChanged(position, item);
|
||||
}
|
||||
runOnDbThread(() -> {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
|
||||
try {
|
||||
switch (item.getRequestType()) {
|
||||
case INTRODUCTION:
|
||||
respondToIntroductionRequest(item.getSessionId(),
|
||||
accept, timestamp);
|
||||
accept);
|
||||
break;
|
||||
case FORUM:
|
||||
respondToForumRequest(item.getSessionId(), accept);
|
||||
@@ -1037,9 +1027,8 @@ public class ConversationActivity extends BriarActivity
|
||||
|
||||
@DatabaseExecutor
|
||||
private void respondToIntroductionRequest(SessionId sessionId,
|
||||
boolean accept, long time) throws DbException {
|
||||
introductionManager.respondToIntroduction(contactId, sessionId, time,
|
||||
accept);
|
||||
boolean accept) throws DbException {
|
||||
introductionManager.respondToIntroduction(contactId, sessionId, accept);
|
||||
}
|
||||
|
||||
@DatabaseExecutor
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
||||
import org.briarproject.briar.api.attachment.AttachmentHeader;
|
||||
import org.briarproject.briar.api.autodelete.AutoDeleteManager;
|
||||
import org.briarproject.briar.api.avatar.event.AvatarUpdatedEvent;
|
||||
import org.briarproject.briar.api.conversation.ConversationManager;
|
||||
import org.briarproject.briar.api.identity.AuthorInfo;
|
||||
import org.briarproject.briar.api.identity.AuthorManager;
|
||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||
@@ -90,6 +91,7 @@ public class ConversationViewModel extends DbViewModel
|
||||
private final AttachmentRetriever attachmentRetriever;
|
||||
private final AttachmentCreator attachmentCreator;
|
||||
private final AutoDeleteManager autoDeleteManager;
|
||||
private final ConversationManager conversationManager;
|
||||
|
||||
@Nullable
|
||||
private ContactId contactId = null;
|
||||
@@ -125,7 +127,8 @@ public class ConversationViewModel extends DbViewModel
|
||||
PrivateMessageFactory privateMessageFactory,
|
||||
AttachmentRetriever attachmentRetriever,
|
||||
AttachmentCreator attachmentCreator,
|
||||
AutoDeleteManager autoDeleteManager) {
|
||||
AutoDeleteManager autoDeleteManager,
|
||||
ConversationManager conversationManager) {
|
||||
super(application, dbExecutor, lifecycleManager, db, androidExecutor);
|
||||
this.db = db;
|
||||
this.eventBus = eventBus;
|
||||
@@ -137,6 +140,7 @@ public class ConversationViewModel extends DbViewModel
|
||||
this.attachmentRetriever = attachmentRetriever;
|
||||
this.attachmentCreator = attachmentCreator;
|
||||
this.autoDeleteManager = autoDeleteManager;
|
||||
this.conversationManager = conversationManager;
|
||||
messagingGroupId = map(contactItem, c ->
|
||||
messagingManager.getContactGroup(c.getContact()).getId());
|
||||
contactDeleted.setValue(false);
|
||||
@@ -244,14 +248,13 @@ public class ConversationViewModel extends DbViewModel
|
||||
}
|
||||
|
||||
@UiThread
|
||||
void sendMessage(@Nullable String text,
|
||||
List<AttachmentHeader> headers, long timestamp) {
|
||||
void sendMessage(@Nullable String text, List<AttachmentHeader> headers) {
|
||||
// messagingGroupId is loaded with the contact
|
||||
observeForeverOnce(messagingGroupId, groupId -> {
|
||||
requireNonNull(groupId);
|
||||
observeForeverOnce(privateMessageFormat, format ->
|
||||
storeMessage(requireNonNull(contactId), groupId, text,
|
||||
headers, timestamp, format));
|
||||
headers, format));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -313,8 +316,10 @@ public class ConversationViewModel extends DbViewModel
|
||||
|
||||
private PrivateMessage createMessage(Transaction txn, ContactId c,
|
||||
GroupId groupId, @Nullable String text,
|
||||
List<AttachmentHeader> headers, long timestamp,
|
||||
PrivateMessageFormat format) throws DbException {
|
||||
List<AttachmentHeader> headers, PrivateMessageFormat format)
|
||||
throws DbException {
|
||||
long timestamp =
|
||||
conversationManager.getTimestampForOutgoingMessage(txn, c);
|
||||
try {
|
||||
if (format == TEXT_ONLY) {
|
||||
return privateMessageFactory.createLegacyPrivateMessage(
|
||||
@@ -335,13 +340,13 @@ public class ConversationViewModel extends DbViewModel
|
||||
@UiThread
|
||||
private void storeMessage(ContactId c, GroupId groupId,
|
||||
@Nullable String text, List<AttachmentHeader> headers,
|
||||
long timestamp, PrivateMessageFormat format) {
|
||||
PrivateMessageFormat format) {
|
||||
runOnDbThread(() -> {
|
||||
try {
|
||||
db.transaction(false, txn -> {
|
||||
long start = now();
|
||||
PrivateMessage m = createMessage(txn, c, groupId, text,
|
||||
headers, timestamp, format);
|
||||
headers, format);
|
||||
messagingManager.addLocalMessage(txn, m);
|
||||
logDuration(LOG, "Storing message", start);
|
||||
Message message = m.getMessage();
|
||||
|
||||
@@ -219,8 +219,7 @@ public class IntroductionMessageFragment extends BaseFragment
|
||||
introductionActivity.runOnDbThread(() -> {
|
||||
// actually make the introduction
|
||||
try {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
introductionManager.makeIntroduction(c1, c2, text, timestamp);
|
||||
introductionManager.makeIntroduction(c1, c2, text);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
introductionError();
|
||||
|
||||
@@ -48,6 +48,13 @@ public interface ConversationManager {
|
||||
*/
|
||||
GroupCount getGroupCount(Transaction txn, ContactId c) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns a timestamp for an outgoing message, which is later than the
|
||||
* timestamp of any visible message sent or received so far.
|
||||
*/
|
||||
long getTimestampForOutgoingMessage(Transaction txn, ContactId c)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Deletes all messages exchanged with the given contact.
|
||||
*/
|
||||
|
||||
@@ -36,13 +36,13 @@ public interface IntroductionManager extends ConversationClient {
|
||||
/**
|
||||
* Sends two initial introduction messages.
|
||||
*/
|
||||
void makeIntroduction(Contact c1, Contact c2, @Nullable String text,
|
||||
long timestamp) throws DbException;
|
||||
void makeIntroduction(Contact c1, Contact c2, @Nullable String text)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Responds to an introduction.
|
||||
*/
|
||||
void respondToIntroduction(ContactId contactId, SessionId sessionId,
|
||||
long timestamp, boolean accept) throws DbException;
|
||||
boolean accept) throws DbException;
|
||||
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@ import org.briarproject.bramble.api.properties.TransportProperties;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
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.client.SessionId;
|
||||
import org.briarproject.briar.api.conversation.ConversationManager;
|
||||
import org.briarproject.briar.api.identity.AuthorInfo;
|
||||
import org.briarproject.briar.api.identity.AuthorManager;
|
||||
import org.briarproject.briar.api.introduction.IntroductionResponse;
|
||||
@@ -61,7 +61,7 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
|
||||
protected final MessageEncoder messageEncoder;
|
||||
protected final ClientVersioningManager clientVersioningManager;
|
||||
protected final AutoDeleteManager autoDeleteManager;
|
||||
protected final Clock clock;
|
||||
protected final ConversationManager conversationManager;
|
||||
|
||||
AbstractProtocolEngine(
|
||||
DatabaseComponent db,
|
||||
@@ -75,7 +75,7 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
|
||||
MessageEncoder messageEncoder,
|
||||
ClientVersioningManager clientVersioningManager,
|
||||
AutoDeleteManager autoDeleteManager,
|
||||
Clock clock) {
|
||||
ConversationManager conversationManager) {
|
||||
this.db = db;
|
||||
this.clientHelper = clientHelper;
|
||||
this.contactManager = contactManager;
|
||||
@@ -87,7 +87,7 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
|
||||
this.messageEncoder = messageEncoder;
|
||||
this.clientVersioningManager = clientVersioningManager;
|
||||
this.autoDeleteManager = autoDeleteManager;
|
||||
this.clock = clock;
|
||||
this.conversationManager = conversationManager;
|
||||
}
|
||||
|
||||
Message sendRequestMessage(Transaction txn, PeerSession s,
|
||||
@@ -231,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)
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.briarproject.bramble.api.properties.TransportProperties;
|
||||
import org.briarproject.bramble.api.properties.TransportPropertyManager;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.api.transport.KeyManager;
|
||||
import org.briarproject.bramble.api.transport.KeySetId;
|
||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
||||
@@ -30,6 +29,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.identity.AuthorInfo;
|
||||
import org.briarproject.briar.api.identity.AuthorManager;
|
||||
import org.briarproject.briar.api.introduction.IntroductionRequest;
|
||||
@@ -44,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;
|
||||
@@ -77,16 +78,16 @@ class IntroduceeProtocolEngine
|
||||
AuthorManager authorManager,
|
||||
MessageParser messageParser,
|
||||
MessageEncoder messageEncoder,
|
||||
Clock clock,
|
||||
IntroductionCrypto crypto,
|
||||
KeyManager keyManager,
|
||||
TransportPropertyManager transportPropertyManager,
|
||||
ClientVersioningManager clientVersioningManager,
|
||||
AutoDeleteManager autoDeleteManager) {
|
||||
AutoDeleteManager autoDeleteManager,
|
||||
ConversationManager conversationManager) {
|
||||
super(db, clientHelper, contactManager, contactGroupFactory,
|
||||
messageTracker, identityManager, authorManager, messageParser,
|
||||
messageEncoder, clientVersioningManager, autoDeleteManager,
|
||||
clock);
|
||||
conversationManager);
|
||||
this.crypto = crypto;
|
||||
this.keyManager = keyManager;
|
||||
this.transportPropertyManager = transportPropertyManager;
|
||||
@@ -94,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:
|
||||
@@ -119,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:
|
||||
@@ -275,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);
|
||||
|
||||
@@ -287,7 +288,7 @@ class IntroduceeProtocolEngine
|
||||
transportPropertyManager.getLocalProperties(txn);
|
||||
|
||||
// Send a ACCEPT message
|
||||
long localTimestamp = Math.max(timestamp + 1, getLocalTimestamp(s));
|
||||
long localTimestamp = getLocalTimestamp(txn, s);
|
||||
Message sent = sendAcceptMessage(txn, s, localTimestamp, publicKey,
|
||||
localTimestamp, transportProperties, true);
|
||||
// Track the message
|
||||
@@ -312,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 = getLocalTimestamp(txn, s);
|
||||
Message sent = sendDeclineMessage(txn, s, localTimestamp, true);
|
||||
|
||||
// Track the message
|
||||
@@ -415,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 = getLocalTimestamp(txn, s);
|
||||
Message sent = sendAuthMessage(txn, s, localTimestamp, mac, signature);
|
||||
return IntroduceeSession.addLocalAuth(s, AWAIT_AUTH, sent, masterKey,
|
||||
aliceMacKey, bobMacKey);
|
||||
}
|
||||
@@ -465,7 +466,8 @@ class IntroduceeProtocolEngine
|
||||
|
||||
// send ACTIVATE message with a MAC
|
||||
byte[] mac = crypto.activateMac(s);
|
||||
Message sent = sendActivateMessage(txn, s, getLocalTimestamp(s), mac);
|
||||
long localTimestamp = getLocalTimestamp(txn, 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);
|
||||
@@ -516,7 +518,8 @@ class IntroduceeProtocolEngine
|
||||
markRequestsUnavailableToAnswer(txn, s);
|
||||
|
||||
// Send an ABORT message
|
||||
Message sent = sendAbortMessage(txn, s, getLocalTimestamp(s));
|
||||
long localTimestamp = getLocalTimestamp(txn, s);
|
||||
Message sent = sendAbortMessage(txn, s, localTimestamp);
|
||||
|
||||
// Broadcast abort event for testing
|
||||
txn.attach(new IntroductionAbortedEvent(s.getSessionId()));
|
||||
@@ -531,9 +534,18 @@ class IntroduceeProtocolEngine
|
||||
return isInvalidDependency(s.getLastRemoteMessageId(), dependency);
|
||||
}
|
||||
|
||||
private long getLocalTimestamp(IntroduceeSession s) {
|
||||
return getLocalTimestamp(s.getLocalTimestamp(),
|
||||
s.getRequestTimestamp());
|
||||
/**
|
||||
* Returns a timestamp for an outgoing message, which is later than the
|
||||
* timestamp of any message sent or received so far in the conversation
|
||||
* or the session.
|
||||
*/
|
||||
private long getLocalTimestamp(Transaction txn, IntroduceeSession s)
|
||||
throws DbException {
|
||||
long conversationTimestamp =
|
||||
getTimestampForOutgoingMessage(txn, s.getContactGroupId());
|
||||
long sessionTimestamp =
|
||||
max(s.getLocalTimestamp(), s.getRequestTimestamp()) + 1;
|
||||
return max(conversationTimestamp, sessionTimestamp);
|
||||
}
|
||||
|
||||
private void addSessionId(Transaction txn, MessageId m, SessionId sessionId)
|
||||
|
||||
@@ -12,11 +12,11 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
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.client.ProtocolStateException;
|
||||
import org.briarproject.briar.api.conversation.ConversationManager;
|
||||
import org.briarproject.briar.api.identity.AuthorManager;
|
||||
import org.briarproject.briar.api.introduction.event.IntroductionAbortedEvent;
|
||||
import org.briarproject.briar.introduction.IntroducerSession.Introducee;
|
||||
@@ -25,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;
|
||||
@@ -56,20 +57,20 @@ class IntroducerProtocolEngine
|
||||
MessageEncoder messageEncoder,
|
||||
ClientVersioningManager clientVersioningManager,
|
||||
AutoDeleteManager autoDeleteManager,
|
||||
Clock clock) {
|
||||
ConversationManager conversationManager) {
|
||||
super(db, clientHelper, contactManager, contactGroupFactory,
|
||||
messageTracker, identityManager, authorManager, messageParser,
|
||||
messageEncoder, clientVersioningManager, autoDeleteManager,
|
||||
clock);
|
||||
conversationManager);
|
||||
}
|
||||
|
||||
@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:
|
||||
@@ -89,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
|
||||
@@ -229,13 +217,11 @@ 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 = getLocalTimestamp(txn, s, s.getIntroduceeA());
|
||||
long timestampB = getLocalTimestamp(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(),
|
||||
@@ -275,11 +261,10 @@ 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);
|
||||
long localTimestamp = getLocalTimestamp(txn, s, i);
|
||||
Message sent = sendAcceptMessage(txn, i, localTimestamp,
|
||||
m.getEphemeralPublicKey(), m.getAcceptTimestamp(),
|
||||
m.getTransportProperties(), false);
|
||||
|
||||
// Create the next state
|
||||
IntroducerState state = AWAIT_AUTHS;
|
||||
@@ -336,7 +321,8 @@ class IntroducerProtocolEngine
|
||||
|
||||
// Forward ACCEPT message
|
||||
Introducee i = getOtherIntroducee(s, m.getGroupId());
|
||||
Message sent = sendAcceptMessage(txn, i, getLocalTimestamp(s, i),
|
||||
long localTimestamp = getLocalTimestamp(txn, s, i);
|
||||
Message sent = sendAcceptMessage(txn, i, localTimestamp,
|
||||
m.getEphemeralPublicKey(), m.getAcceptTimestamp(),
|
||||
m.getTransportProperties(), false);
|
||||
|
||||
@@ -387,8 +373,8 @@ class IntroducerProtocolEngine
|
||||
|
||||
// Forward DECLINE message
|
||||
Introducee i = getOtherIntroducee(s, m.getGroupId());
|
||||
long timestamp = getLocalTimestamp(s, i);
|
||||
Message sent = sendDeclineMessage(txn, i, timestamp, false);
|
||||
long localTimestamp = getLocalTimestamp(txn, s, i);
|
||||
Message sent = sendDeclineMessage(txn, i, localTimestamp, false);
|
||||
|
||||
// Create the next state
|
||||
IntroducerState state = START;
|
||||
@@ -439,8 +425,8 @@ class IntroducerProtocolEngine
|
||||
|
||||
// Forward DECLINE message
|
||||
Introducee i = getOtherIntroducee(s, m.getGroupId());
|
||||
long timestamp = getLocalTimestamp(s, i);
|
||||
Message sent = sendDeclineMessage(txn, i, timestamp, false);
|
||||
long localTimestamp = getLocalTimestamp(txn, s, i);
|
||||
Message sent = sendDeclineMessage(txn, i, localTimestamp, false);
|
||||
|
||||
Introducee introduceeA, introduceeB;
|
||||
Author sender, other;
|
||||
@@ -480,8 +466,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 = getLocalTimestamp(txn, s, i);
|
||||
Message sent = sendAuthMessage(txn, i, localTimestamp, m.getMac(),
|
||||
m.getSignature());
|
||||
|
||||
// Move to the next state
|
||||
@@ -516,8 +502,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 = getLocalTimestamp(txn, s, i);
|
||||
Message sent = sendActivateMessage(txn, i, localTimestamp, m.getMac());
|
||||
|
||||
// Move to the next state
|
||||
IntroducerState state = START;
|
||||
@@ -539,8 +525,9 @@ 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 = max(i.getLocalTimestamp(),
|
||||
s.getRequestTimestamp()) + 1;
|
||||
Message sent = sendAbortMessage(txn, i, localTimestamp);
|
||||
|
||||
// Broadcast abort event for testing
|
||||
txn.attach(new IntroductionAbortedEvent(s.getSessionId()));
|
||||
@@ -558,15 +545,42 @@ 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 = getLocalTimestamp(txn, 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 = getLocalTimestamp(txn, s, s.getIntroduceeA());
|
||||
Message sentA = sendAbortMessage(txn, s.getIntroduceeA(), timestampA);
|
||||
long timestampB = getLocalTimestamp(s, s.getIntroduceeB());
|
||||
long timestampB = getLocalTimestamp(txn, s, s.getIntroduceeB());
|
||||
Message sentB = sendAbortMessage(txn, s.getIntroduceeB(), timestampB);
|
||||
// Reset the session back to initial state
|
||||
Introducee introduceeA = new Introducee(s.getIntroduceeA(), sentA);
|
||||
@@ -596,9 +610,17 @@ class IntroducerProtocolEngine
|
||||
return isInvalidDependency(expected, dependency);
|
||||
}
|
||||
|
||||
private long getLocalTimestamp(IntroducerSession s, PeerSession p) {
|
||||
return getLocalTimestamp(p.getLocalTimestamp(),
|
||||
s.getRequestTimestamp());
|
||||
/**
|
||||
* Returns a timestamp for an outgoing message, which is later than the
|
||||
* timestamp of any message sent or received so far in the conversation
|
||||
* or the session.
|
||||
*/
|
||||
private long getLocalTimestamp(Transaction txn, IntroducerSession s,
|
||||
PeerSession p) throws DbException {
|
||||
long conversationTimestamp =
|
||||
getTimestampForOutgoingMessage(txn, p.getContactGroupId());
|
||||
long sessionTimestamp =
|
||||
max(p.getLocalTimestamp(), s.getRequestTimestamp()) + 1;
|
||||
return max(conversationTimestamp, sessionTimestamp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -315,8 +315,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
|
||||
@@ -348,8 +348,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);
|
||||
@@ -362,7 +361,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
|
||||
@@ -380,11 +379,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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<>();
|
||||
}
|
||||
|
||||
@@ -76,6 +81,14 @@ class ConversationManagerImpl implements ConversationManager {
|
||||
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 -> {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user