mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Merge branch '1832-mirror-remote-self-destruct-timer' into '804-self-destructing-messages'
Mirror the contact's changes to the self-destruct timer See merge request briar/briar!1312
This commit is contained in:
@@ -297,7 +297,8 @@ public class ConversationViewModel extends AndroidViewModel
|
||||
return privateMessageFactory.createPrivateMessage(groupId,
|
||||
timestamp, text, headers);
|
||||
} else {
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c);
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c,
|
||||
timestamp);
|
||||
return privateMessageFactory.createPrivateMessage(groupId,
|
||||
timestamp, text, headers, timer);
|
||||
}
|
||||
|
||||
@@ -171,7 +171,8 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
|
||||
Contact contact = contactManager.getContact(txn, c);
|
||||
long timestamp = conversationManager
|
||||
.getTimestampForOutgoingMessage(txn, c);
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c);
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c,
|
||||
timestamp);
|
||||
contexts.add(new InvitationContext(contact, timestamp, timer));
|
||||
} catch (NoSuchContactException e) {
|
||||
// Continue
|
||||
|
||||
@@ -24,8 +24,33 @@ public interface AutoDeleteManager {
|
||||
*/
|
||||
int MINOR_VERSION = 0;
|
||||
|
||||
/**
|
||||
* Returns the auto-delete timer duration for the given contact. Use
|
||||
* {@link #getAutoDeleteTimer(Transaction, ContactId, long)} if the timer
|
||||
* will be used in an outgoing message.
|
||||
*/
|
||||
long getAutoDeleteTimer(Transaction txn, ContactId c) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the auto-delete timer duration for the given contact, for use in
|
||||
* a message with the given timestamp. The timestamp is stored.
|
||||
*/
|
||||
long getAutoDeleteTimer(Transaction txn, ContactId c, long timestamp)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the auto-delete timer duration for the given contact.
|
||||
*/
|
||||
void setAutoDeleteTimer(Transaction txn, ContactId c, long timer)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Receives an auto-delete timer duration from the given contact, carried
|
||||
* in a message with the given timestamp. The local timer is set to the
|
||||
* same duration unless it has been
|
||||
* {@link #setAutoDeleteTimer(Transaction, ContactId, long) changed} more
|
||||
* recently than the remote timer.
|
||||
*/
|
||||
void receiveAutoDeleteTimer(Transaction txn, ContactId c, long timer,
|
||||
long timestamp) throws DbException;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,28 @@ package org.briarproject.briar.autodelete;
|
||||
|
||||
interface AutoDeleteConstants {
|
||||
|
||||
// Group metadata key for storing the auto-delete timer
|
||||
String GROUP_KEY_AUTO_DELETE_TIMER = "autoDeleteTimer";
|
||||
/**
|
||||
* Group metadata key for storing the auto-delete timer duration.
|
||||
*/
|
||||
String GROUP_KEY_TIMER = "autoDeleteTimer";
|
||||
|
||||
/**
|
||||
* Group metadata key for storing the timestamp of the latest incoming or
|
||||
* outgoing message carrying an auto-delete timer (including a null timer).
|
||||
*/
|
||||
String GROUP_KEY_TIMESTAMP = "autoDeleteTimestamp";
|
||||
|
||||
/**
|
||||
* Group metadata key for storing the previous auto-delete timer duration.
|
||||
* This is used to decide whether a local change to the duration should be
|
||||
* overwritten by a duration received from the contact.
|
||||
*/
|
||||
String GROUP_KEY_PREVIOUS_TIMER = "autoDeletePreviousTimer";
|
||||
|
||||
/**
|
||||
* Special value for {@link #GROUP_KEY_PREVIOUS_TIMER} indicating that
|
||||
* there are no local changes to the auto-delete timer duration that need
|
||||
* to be compared with durations received from the contact.
|
||||
*/
|
||||
long NO_PREVIOUS_TIMER = 0;
|
||||
}
|
||||
|
||||
@@ -17,19 +17,29 @@ import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.GroupFactory;
|
||||
import org.briarproject.briar.api.autodelete.AutoDeleteManager;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.MAX_AUTO_DELETE_TIMER_MS;
|
||||
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
|
||||
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||
import static org.briarproject.briar.autodelete.AutoDeleteConstants.GROUP_KEY_AUTO_DELETE_TIMER;
|
||||
import static org.briarproject.briar.autodelete.AutoDeleteConstants.GROUP_KEY_PREVIOUS_TIMER;
|
||||
import static org.briarproject.briar.autodelete.AutoDeleteConstants.GROUP_KEY_TIMER;
|
||||
import static org.briarproject.briar.autodelete.AutoDeleteConstants.GROUP_KEY_TIMESTAMP;
|
||||
import static org.briarproject.briar.autodelete.AutoDeleteConstants.NO_PREVIOUS_TIMER;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class AutoDeleteManagerImpl
|
||||
implements AutoDeleteManager, OpenDatabaseHook, ContactHook {
|
||||
|
||||
private static final Logger LOG =
|
||||
getLogger(AutoDeleteManagerImpl.class.getName());
|
||||
|
||||
private final DatabaseComponent db;
|
||||
private final ClientHelper clientHelper;
|
||||
private final GroupFactory groupFactory;
|
||||
@@ -75,8 +85,29 @@ class AutoDeleteManagerImpl
|
||||
Group g = getGroup(db.getContact(txn, c));
|
||||
BdfDictionary meta =
|
||||
clientHelper.getGroupMetadataAsDictionary(txn, g.getId());
|
||||
return meta.getLong(GROUP_KEY_AUTO_DELETE_TIMER,
|
||||
NO_AUTO_DELETE_TIMER);
|
||||
return meta.getLong(GROUP_KEY_TIMER, NO_AUTO_DELETE_TIMER);
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAutoDeleteTimer(Transaction txn, ContactId c, long timestamp)
|
||||
throws DbException {
|
||||
try {
|
||||
Group g = getGroup(db.getContact(txn, c));
|
||||
BdfDictionary meta =
|
||||
clientHelper.getGroupMetadataAsDictionary(txn, g.getId());
|
||||
long timer = meta.getLong(GROUP_KEY_TIMER, NO_AUTO_DELETE_TIMER);
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Sending message with auto-delete timer " + timer);
|
||||
}
|
||||
// Update the timestamp and clear the previous timer, if any
|
||||
meta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_TIMESTAMP, timestamp),
|
||||
new BdfEntry(GROUP_KEY_PREVIOUS_TIMER, NO_PREVIOUS_TIMER));
|
||||
clientHelper.mergeGroupMetadata(txn, g.getId(), meta);
|
||||
return timer;
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
@@ -85,18 +116,60 @@ class AutoDeleteManagerImpl
|
||||
@Override
|
||||
public void setAutoDeleteTimer(Transaction txn, ContactId c, long timer)
|
||||
throws DbException {
|
||||
if (timer != NO_AUTO_DELETE_TIMER &&
|
||||
(timer < MIN_AUTO_DELETE_TIMER_MS ||
|
||||
timer > MAX_AUTO_DELETE_TIMER_MS)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
validateTimer(timer);
|
||||
try {
|
||||
Group g = getGroup(db.getContact(txn, c));
|
||||
BdfDictionary meta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_AUTO_DELETE_TIMER, timer));
|
||||
BdfDictionary meta =
|
||||
clientHelper.getGroupMetadataAsDictionary(txn, g.getId());
|
||||
long oldTimer = meta.getLong(GROUP_KEY_TIMER, NO_AUTO_DELETE_TIMER);
|
||||
if (timer == oldTimer) return;
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Setting auto-delete timer to " + timer);
|
||||
}
|
||||
// Store the new timer and the previous timer
|
||||
meta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_TIMER, timer),
|
||||
new BdfEntry(GROUP_KEY_PREVIOUS_TIMER, oldTimer));
|
||||
clientHelper.mergeGroupMetadata(txn, g.getId(), meta);
|
||||
} catch (FormatException e) {
|
||||
throw new AssertionError(e);
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receiveAutoDeleteTimer(Transaction txn, ContactId c,
|
||||
long timer, long timestamp) throws DbException {
|
||||
validateTimer(timer);
|
||||
try {
|
||||
Group g = getGroup(db.getContact(txn, c));
|
||||
BdfDictionary meta =
|
||||
clientHelper.getGroupMetadataAsDictionary(txn, g.getId());
|
||||
long oldTimestamp = meta.getLong(GROUP_KEY_TIMESTAMP, 0L);
|
||||
if (timestamp <= oldTimestamp) return;
|
||||
long oldTimer =
|
||||
meta.getLong(GROUP_KEY_PREVIOUS_TIMER, NO_PREVIOUS_TIMER);
|
||||
meta = new BdfDictionary();
|
||||
if (oldTimer == NO_PREVIOUS_TIMER) {
|
||||
// We don't have an unsent change. Mirror their timer
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Mirroring auto-delete timer " + timer);
|
||||
}
|
||||
meta.put(GROUP_KEY_TIMER, timer);
|
||||
} else if (timer != oldTimer) {
|
||||
// Their sent change trumps our unsent change. Mirror their
|
||||
// timer and clear the previous timer to drop our unsent change
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("Mirroring auto-delete timer " + timer
|
||||
+ " and forgetting unsent change");
|
||||
}
|
||||
meta.put(GROUP_KEY_TIMER, timer);
|
||||
meta.put(GROUP_KEY_PREVIOUS_TIMER, NO_PREVIOUS_TIMER);
|
||||
}
|
||||
// Always update the timestamp
|
||||
meta.put(GROUP_KEY_TIMESTAMP, timestamp);
|
||||
clientHelper.mergeGroupMetadata(txn, g.getId(), meta);
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,4 +177,12 @@ class AutoDeleteManagerImpl
|
||||
byte[] descriptor = c.getAuthor().getId().getBytes();
|
||||
return groupFactory.createGroup(CLIENT_ID, MAJOR_VERSION, descriptor);
|
||||
}
|
||||
|
||||
private void validateTimer(long timer) {
|
||||
if (timer != NO_AUTO_DELETE_TIMER &&
|
||||
(timer < MIN_AUTO_DELETE_TIMER_MS ||
|
||||
timer > MAX_AUTO_DELETE_TIMER_MS)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,8 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
|
||||
Message m;
|
||||
ContactId c = getContactId(txn, s.getContactGroupId());
|
||||
if (contactSupportsAutoDeletion(txn, c)) {
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c);
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c,
|
||||
timestamp);
|
||||
m = messageEncoder.encodeRequestMessage(s.getContactGroupId(),
|
||||
timestamp, s.getLastLocalMessageId(), author, text, timer);
|
||||
sendMessage(txn, REQUEST, s.getSessionId(), m, true, timer);
|
||||
@@ -116,7 +117,8 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
|
||||
Message m;
|
||||
ContactId c = getContactId(txn, s.getContactGroupId());
|
||||
if (contactSupportsAutoDeletion(txn, c)) {
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c);
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c,
|
||||
timestamp);
|
||||
m = messageEncoder.encodeAcceptMessage(s.getContactGroupId(),
|
||||
timestamp, s.getLastLocalMessageId(), s.getSessionId(),
|
||||
ephemeralPublicKey, acceptTimestamp, transportProperties,
|
||||
@@ -137,7 +139,8 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
|
||||
Message m;
|
||||
ContactId c = getContactId(txn, s.getContactGroupId());
|
||||
if (contactSupportsAutoDeletion(txn, c)) {
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c);
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c,
|
||||
timestamp);
|
||||
m = messageEncoder.encodeDeclineMessage(s.getContactGroupId(),
|
||||
timestamp, s.getLastLocalMessageId(), s.getSessionId(),
|
||||
timer);
|
||||
@@ -237,6 +240,13 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
|
||||
return conversationManager.getTimestampForOutgoingMessage(txn, c);
|
||||
}
|
||||
|
||||
void receiveAutoDeleteTimer(Transaction txn, AbstractIntroductionMessage m)
|
||||
throws DbException {
|
||||
ContactId c = getContactId(txn, m.getGroupId());
|
||||
autoDeleteManager.receiveAutoDeleteTimer(txn, c, m.getAutoDeleteTimer(),
|
||||
m.getTimestamp());
|
||||
}
|
||||
|
||||
private ContactId getContactId(Transaction txn, GroupId contactGroupId)
|
||||
throws DbException {
|
||||
try {
|
||||
|
||||
@@ -257,6 +257,9 @@ class IntroduceeProtocolEngine
|
||||
messageTracker
|
||||
.trackMessage(txn, m.getGroupId(), m.getTimestamp(), false);
|
||||
|
||||
// Receive the auto-delete timer
|
||||
receiveAutoDeleteTimer(txn, m);
|
||||
|
||||
// Broadcast IntroductionRequestReceivedEvent
|
||||
LocalAuthor localAuthor = identityManager.getLocalAuthor(txn);
|
||||
Contact c = contactManager.getContact(txn, s.getIntroducer().getId(),
|
||||
@@ -332,8 +335,7 @@ class IntroduceeProtocolEngine
|
||||
}
|
||||
|
||||
private IntroduceeSession onRemoteAccept(Transaction txn,
|
||||
IntroduceeSession s, AcceptMessage m)
|
||||
throws DbException {
|
||||
IntroduceeSession s, AcceptMessage m) throws DbException {
|
||||
// The timestamp must be higher than the last request message
|
||||
if (m.getTimestamp() <= s.getRequestTimestamp())
|
||||
return abort(txn, s);
|
||||
@@ -370,6 +372,9 @@ class IntroduceeProtocolEngine
|
||||
messageTracker
|
||||
.trackMessage(txn, m.getGroupId(), m.getTimestamp(), false);
|
||||
|
||||
// Receive the auto-delete timer
|
||||
receiveAutoDeleteTimer(txn, m);
|
||||
|
||||
// Broadcast IntroductionResponseReceivedEvent
|
||||
broadcastIntroductionResponseReceivedEvent(txn, s,
|
||||
s.getIntroducer().getId(), s.getRemote().author, m, false);
|
||||
|
||||
@@ -260,6 +260,8 @@ class IntroducerProtocolEngine
|
||||
// Track the incoming message
|
||||
messageTracker
|
||||
.trackMessage(txn, m.getGroupId(), m.getTimestamp(), false);
|
||||
// Receive the auto-delete timer
|
||||
receiveAutoDeleteTimer(txn, m);
|
||||
|
||||
// Forward ACCEPT message
|
||||
Introducee i = getOtherIntroducee(s, m.getGroupId());
|
||||
@@ -321,6 +323,8 @@ class IntroducerProtocolEngine
|
||||
// Track the incoming message
|
||||
messageTracker
|
||||
.trackMessage(txn, m.getGroupId(), m.getTimestamp(), false);
|
||||
// Receive the auto-delete timer
|
||||
receiveAutoDeleteTimer(txn, m);
|
||||
|
||||
// Forward ACCEPT message
|
||||
Introducee i = getOtherIntroducee(s, m.getGroupId());
|
||||
@@ -374,6 +378,8 @@ class IntroducerProtocolEngine
|
||||
// Track the incoming message
|
||||
messageTracker
|
||||
.trackMessage(txn, m.getGroupId(), m.getTimestamp(), false);
|
||||
// Receive the auto-delete timer
|
||||
receiveAutoDeleteTimer(txn, m);
|
||||
|
||||
// Forward DECLINE message
|
||||
Introducee i = getOtherIntroducee(s, m.getGroupId());
|
||||
@@ -427,6 +433,8 @@ class IntroducerProtocolEngine
|
||||
// Track the incoming message
|
||||
messageTracker
|
||||
.trackMessage(txn, m.getGroupId(), m.getTimestamp(), false);
|
||||
// Receive the auto-delete timer
|
||||
receiveAutoDeleteTimer(txn, m);
|
||||
|
||||
// Forward DECLINE message
|
||||
Introducee i = getOtherIntroducee(s, m.getGroupId());
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.briarproject.bramble.api.sync.MessageStatus;
|
||||
import org.briarproject.bramble.api.sync.validation.IncomingMessageHook;
|
||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager;
|
||||
import org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVersioningHook;
|
||||
import org.briarproject.briar.api.autodelete.AutoDeleteManager;
|
||||
import org.briarproject.briar.api.client.MessageTracker;
|
||||
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
|
||||
import org.briarproject.briar.api.conversation.ConversationManager.ConversationClient;
|
||||
@@ -89,18 +90,24 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
||||
private final MessageTracker messageTracker;
|
||||
private final ClientVersioningManager clientVersioningManager;
|
||||
private final ContactGroupFactory contactGroupFactory;
|
||||
private final AutoDeleteManager autoDeleteManager;
|
||||
|
||||
@Inject
|
||||
MessagingManagerImpl(DatabaseComponent db, ClientHelper clientHelper,
|
||||
MessagingManagerImpl(
|
||||
DatabaseComponent db,
|
||||
ClientHelper clientHelper,
|
||||
ClientVersioningManager clientVersioningManager,
|
||||
MetadataParser metadataParser, MessageTracker messageTracker,
|
||||
ContactGroupFactory contactGroupFactory) {
|
||||
MetadataParser metadataParser,
|
||||
MessageTracker messageTracker,
|
||||
ContactGroupFactory contactGroupFactory,
|
||||
AutoDeleteManager autoDeleteManager) {
|
||||
this.db = db;
|
||||
this.clientHelper = clientHelper;
|
||||
this.metadataParser = metadataParser;
|
||||
this.messageTracker = messageTracker;
|
||||
this.clientVersioningManager = clientVersioningManager;
|
||||
this.contactGroupFactory = contactGroupFactory;
|
||||
this.autoDeleteManager = autoDeleteManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -205,6 +212,8 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
||||
new PrivateMessageReceivedEvent(header, contactId);
|
||||
txn.attach(event);
|
||||
messageTracker.trackIncomingMessage(txn, m);
|
||||
autoDeleteManager.receiveAutoDeleteTimer(txn, contactId, timer,
|
||||
timestamp);
|
||||
}
|
||||
|
||||
private List<AttachmentHeader> parseAttachmentHeaders(BdfDictionary meta)
|
||||
|
||||
@@ -152,9 +152,11 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
|
||||
ContactId c = getContactId(txn, s.getContactGroupId());
|
||||
if (contactSupportsAutoDeletion(txn, c)) {
|
||||
// Set auto-delete timer if manually accepting an invitation
|
||||
long timer = visibleInUi
|
||||
? autoDeleteManager.getAutoDeleteTimer(txn, c)
|
||||
: NO_AUTO_DELETE_TIMER;
|
||||
long timer = NO_AUTO_DELETE_TIMER;
|
||||
if (visibleInUi) {
|
||||
timer = autoDeleteManager
|
||||
.getAutoDeleteTimer(txn, c, localTimestamp);
|
||||
}
|
||||
m = messageEncoder.encodeJoinMessage(s.getContactGroupId(),
|
||||
s.getPrivateGroupId(), localTimestamp,
|
||||
s.getLastLocalMessageId(), timer);
|
||||
@@ -179,9 +181,11 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
|
||||
ContactId c = getContactId(txn, s.getContactGroupId());
|
||||
if (contactSupportsAutoDeletion(txn, c)) {
|
||||
// Set auto-delete timer if manually accepting an invitation
|
||||
long timer = visibleInUi
|
||||
? autoDeleteManager.getAutoDeleteTimer(txn, c)
|
||||
: NO_AUTO_DELETE_TIMER;
|
||||
long timer = NO_AUTO_DELETE_TIMER;
|
||||
if (visibleInUi) {
|
||||
timer = autoDeleteManager.getAutoDeleteTimer(txn, c,
|
||||
localTimestamp);
|
||||
}
|
||||
m = messageEncoder.encodeLeaveMessage(s.getContactGroupId(),
|
||||
s.getPrivateGroupId(), localTimestamp,
|
||||
s.getLastLocalMessageId(), timer);
|
||||
@@ -296,6 +300,13 @@ abstract class AbstractProtocolEngine<S extends Session<?>>
|
||||
return max(s.getLocalTimestamp(), s.getInviteTimestamp());
|
||||
}
|
||||
|
||||
void receiveAutoDeleteTimer(Transaction txn,
|
||||
DeletableGroupInvitationMessage m) throws DbException {
|
||||
ContactId c = getContactId(txn, m.getContactGroupId());
|
||||
autoDeleteManager.receiveAutoDeleteTimer(txn, c, m.getAutoDeleteTimer(),
|
||||
m.getTimestamp());
|
||||
}
|
||||
|
||||
private void sendMessage(Transaction txn, Message m, MessageType type,
|
||||
GroupId privateGroupId, boolean visibleInConversation,
|
||||
long autoDeleteTimer) throws DbException {
|
||||
|
||||
@@ -201,6 +201,8 @@ class CreatorProtocolEngine extends AbstractProtocolEngine<CreatorSession> {
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
m.getTimestamp(), false);
|
||||
// Receive the auto-delete timer
|
||||
receiveAutoDeleteTimer(txn, m);
|
||||
// Share the private group with the contact
|
||||
setPrivateGroupVisibility(txn, s, SHARED);
|
||||
// Broadcast an event
|
||||
@@ -226,6 +228,8 @@ class CreatorProtocolEngine extends AbstractProtocolEngine<CreatorSession> {
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
m.getTimestamp(), false);
|
||||
// Receive the auto-delete timer
|
||||
receiveAutoDeleteTimer(txn, m);
|
||||
// Broadcast an event
|
||||
ContactId contactId =
|
||||
clientHelper.getContactId(txn, m.getContactGroupId());
|
||||
|
||||
@@ -251,6 +251,8 @@ class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
m.getTimestamp(), false);
|
||||
// Receive the auto-delete timer
|
||||
receiveAutoDeleteTimer(txn, m);
|
||||
// Broadcast an event
|
||||
PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup(
|
||||
m.getGroupName(), m.getCreator(), m.getSalt());
|
||||
|
||||
@@ -142,7 +142,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
long localTimestamp = getTimestampForVisibleMessage(txn, s);
|
||||
ContactId c = getContactId(txn, s.getContactGroupId());
|
||||
if (contactSupportsAutoDeletion(txn, c)) {
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c);
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c,
|
||||
localTimestamp);
|
||||
m = messageEncoder.encodeInviteMessage(s.getContactGroupId(),
|
||||
localTimestamp, s.getLastLocalMessageId(), descriptor,
|
||||
text, timer);
|
||||
@@ -209,7 +210,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
long localTimestamp = getTimestampForVisibleMessage(txn, s);
|
||||
ContactId c = getContactId(txn, s.getContactGroupId());
|
||||
if (contactSupportsAutoDeletion(txn, c)) {
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c);
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c,
|
||||
localTimestamp);
|
||||
m = messageEncoder.encodeAcceptMessage(s.getContactGroupId(),
|
||||
s.getShareableId(), localTimestamp,
|
||||
s.getLastLocalMessageId(), timer);
|
||||
@@ -263,7 +265,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
long localTimestamp = getTimestampForVisibleMessage(txn, s);
|
||||
ContactId c = getContactId(txn, s.getContactGroupId());
|
||||
if (contactSupportsAutoDeletion(txn, c)) {
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c);
|
||||
long timer = autoDeleteManager.getAutoDeleteTimer(txn, c,
|
||||
localTimestamp);
|
||||
m = messageEncoder.encodeDeclineMessage(s.getContactGroupId(),
|
||||
s.getShareableId(), localTimestamp,
|
||||
s.getLastLocalMessageId(), timer);
|
||||
@@ -357,6 +360,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
m.getTimestamp(), false);
|
||||
// Receive the auto-delete timer
|
||||
receiveAutoDeleteTimer(txn, m);
|
||||
// Broadcast an event
|
||||
ContactId contactId =
|
||||
clientHelper.getContactId(txn, s.getContactGroupId());
|
||||
@@ -382,6 +387,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
m.getTimestamp(), false);
|
||||
// Receive the auto-delete timer
|
||||
receiveAutoDeleteTimer(txn, m);
|
||||
// Share the shareable with the contact
|
||||
setShareableVisibility(txn, s, SHARED);
|
||||
// Broadcast an event
|
||||
@@ -429,6 +436,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
m.getTimestamp(), false);
|
||||
// Receive the auto-delete timer
|
||||
receiveAutoDeleteTimer(txn, m);
|
||||
// Broadcast an event
|
||||
ContactId contactId =
|
||||
clientHelper.getContactId(txn, m.getContactGroupId());
|
||||
@@ -482,6 +491,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
m.getTimestamp(), false);
|
||||
// Receive the auto-delete timer
|
||||
receiveAutoDeleteTimer(txn, m);
|
||||
// Make the shareable invisible (not actually needed in REMOTE_HANGING)
|
||||
try {
|
||||
setShareableVisibility(txn, s, INVISIBLE);
|
||||
@@ -716,6 +727,13 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
return max(s.getLocalTimestamp(), s.getInviteTimestamp());
|
||||
}
|
||||
|
||||
private void receiveAutoDeleteTimer(Transaction txn,
|
||||
DeletableSharingMessage m) throws DbException {
|
||||
ContactId c = getContactId(txn, m.getContactGroupId());
|
||||
autoDeleteManager.receiveAutoDeleteTimer(txn, c, m.getAutoDeleteTimer(),
|
||||
m.getTimestamp());
|
||||
}
|
||||
|
||||
private ContactId getContactId(Transaction txn, GroupId contactGroupId)
|
||||
throws DbException {
|
||||
try {
|
||||
|
||||
@@ -18,12 +18,17 @@ import static org.briarproject.bramble.api.client.ContactGroupConstants.GROUP_KE
|
||||
import static org.briarproject.bramble.test.TestUtils.getContact;
|
||||
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
||||
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.MAX_AUTO_DELETE_TIMER_MS;
|
||||
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
|
||||
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||
import static org.briarproject.briar.api.autodelete.AutoDeleteManager.CLIENT_ID;
|
||||
import static org.briarproject.briar.api.autodelete.AutoDeleteManager.MAJOR_VERSION;
|
||||
import static org.briarproject.briar.autodelete.AutoDeleteConstants.GROUP_KEY_AUTO_DELETE_TIMER;
|
||||
import static org.briarproject.briar.autodelete.AutoDeleteConstants.GROUP_KEY_PREVIOUS_TIMER;
|
||||
import static org.briarproject.briar.autodelete.AutoDeleteConstants.GROUP_KEY_TIMER;
|
||||
import static org.briarproject.briar.autodelete.AutoDeleteConstants.GROUP_KEY_TIMESTAMP;
|
||||
import static org.briarproject.briar.autodelete.AutoDeleteConstants.NO_PREVIOUS_TIMER;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@SuppressWarnings("UnnecessaryLocalVariable") // Using them for readability
|
||||
public class AutoDeleteManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
private final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
@@ -35,6 +40,7 @@ public class AutoDeleteManagerImplTest extends BrambleMockTestCase {
|
||||
private final Group localGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
|
||||
private final Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
|
||||
private final Contact contact = getContact();
|
||||
private final long now = System.currentTimeMillis();
|
||||
|
||||
private final AutoDeleteManagerImpl autoDeleteManager;
|
||||
|
||||
@@ -113,15 +119,44 @@ public class AutoDeleteManagerImplTest extends BrambleMockTestCase {
|
||||
@Test
|
||||
public void testStoresTimer() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
long timer = MAX_AUTO_DELETE_TIMER_MS;
|
||||
BdfDictionary meta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_AUTO_DELETE_TIMER, timer));
|
||||
long oldTimer = MIN_AUTO_DELETE_TIMER_MS;
|
||||
long newTimer = MAX_AUTO_DELETE_TIMER_MS;
|
||||
BdfDictionary oldMeta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_TIMER, oldTimer),
|
||||
new BdfEntry(GROUP_KEY_PREVIOUS_TIMER, NO_PREVIOUS_TIMER),
|
||||
new BdfEntry(GROUP_KEY_TIMESTAMP, now));
|
||||
BdfDictionary newMeta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_TIMER, newTimer),
|
||||
new BdfEntry(GROUP_KEY_PREVIOUS_TIMER, oldTimer));
|
||||
|
||||
expectGetContact(txn);
|
||||
expectGetContactGroup();
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
|
||||
contactGroup.getId());
|
||||
will(returnValue(oldMeta));
|
||||
oneOf(clientHelper).mergeGroupMetadata(txn,
|
||||
contactGroup.getId(), meta);
|
||||
contactGroup.getId(), newMeta);
|
||||
}});
|
||||
|
||||
autoDeleteManager.setAutoDeleteTimer(txn, contact.getId(), newTimer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoesNotStoreTimerIfUnchanged() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
long timer = MAX_AUTO_DELETE_TIMER_MS;
|
||||
BdfDictionary meta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_TIMER, timer),
|
||||
new BdfEntry(GROUP_KEY_PREVIOUS_TIMER, NO_PREVIOUS_TIMER),
|
||||
new BdfEntry(GROUP_KEY_TIMESTAMP, now));
|
||||
|
||||
expectGetContact(txn);
|
||||
expectGetContactGroup();
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
|
||||
contactGroup.getId());
|
||||
will(returnValue(meta));
|
||||
}});
|
||||
|
||||
autoDeleteManager.setAutoDeleteTimer(txn, contact.getId(), timer);
|
||||
@@ -133,7 +168,10 @@ public class AutoDeleteManagerImplTest extends BrambleMockTestCase {
|
||||
long timer = MAX_AUTO_DELETE_TIMER_MS;
|
||||
BdfDictionary meta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_CONTACT_ID, contact.getId().getInt()),
|
||||
new BdfEntry(GROUP_KEY_AUTO_DELETE_TIMER, timer));
|
||||
new BdfEntry(GROUP_KEY_TIMER, timer));
|
||||
BdfDictionary newMeta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_TIMESTAMP, now),
|
||||
new BdfEntry(GROUP_KEY_PREVIOUS_TIMER, NO_PREVIOUS_TIMER));
|
||||
|
||||
expectGetContact(txn);
|
||||
expectGetContactGroup();
|
||||
@@ -141,10 +179,12 @@ public class AutoDeleteManagerImplTest extends BrambleMockTestCase {
|
||||
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
|
||||
contactGroup.getId());
|
||||
will(returnValue(meta));
|
||||
oneOf(clientHelper).mergeGroupMetadata(txn, contactGroup.getId(),
|
||||
newMeta);
|
||||
}});
|
||||
|
||||
assertEquals(timer,
|
||||
autoDeleteManager.getAutoDeleteTimer(txn, contact.getId()));
|
||||
assertEquals(timer, autoDeleteManager
|
||||
.getAutoDeleteTimer(txn, contact.getId(), now));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -152,6 +192,44 @@ public class AutoDeleteManagerImplTest extends BrambleMockTestCase {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
BdfDictionary meta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_CONTACT_ID, contact.getId().getInt()));
|
||||
BdfDictionary newMeta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_TIMESTAMP, now),
|
||||
new BdfEntry(GROUP_KEY_PREVIOUS_TIMER, NO_PREVIOUS_TIMER));
|
||||
|
||||
expectGetContact(txn);
|
||||
expectGetContactGroup();
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
|
||||
contactGroup.getId());
|
||||
will(returnValue(meta));
|
||||
oneOf(clientHelper).mergeGroupMetadata(txn, contactGroup.getId(),
|
||||
newMeta);
|
||||
}});
|
||||
|
||||
assertEquals(NO_AUTO_DELETE_TIMER, autoDeleteManager
|
||||
.getAutoDeleteTimer(txn, contact.getId(), now));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIgnoresReceivedTimerWithEarlierTimestamp()
|
||||
throws Exception {
|
||||
testIgnoresReceivedTimerWithTimestamp(now - 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIgnoresReceivedTimerWithEqualTimestamp() throws Exception {
|
||||
testIgnoresReceivedTimerWithTimestamp(now);
|
||||
}
|
||||
|
||||
private void testIgnoresReceivedTimerWithTimestamp(long remoteTimestamp)
|
||||
throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
long localTimer = MIN_AUTO_DELETE_TIMER_MS;
|
||||
long remoteTimer = MAX_AUTO_DELETE_TIMER_MS;
|
||||
BdfDictionary meta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_TIMER, localTimer),
|
||||
new BdfEntry(GROUP_KEY_PREVIOUS_TIMER, NO_PREVIOUS_TIMER),
|
||||
new BdfEntry(GROUP_KEY_TIMESTAMP, now));
|
||||
|
||||
expectGetContact(txn);
|
||||
expectGetContactGroup();
|
||||
@@ -161,8 +239,99 @@ public class AutoDeleteManagerImplTest extends BrambleMockTestCase {
|
||||
will(returnValue(meta));
|
||||
}});
|
||||
|
||||
assertEquals(NO_AUTO_DELETE_TIMER,
|
||||
autoDeleteManager.getAutoDeleteTimer(txn, contact.getId()));
|
||||
autoDeleteManager.receiveAutoDeleteTimer(txn, contact.getId(),
|
||||
remoteTimer, remoteTimestamp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMirrorsRemoteTimestampIfNoUnsentChange() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
long localTimer = MIN_AUTO_DELETE_TIMER_MS;
|
||||
long remoteTimer = MAX_AUTO_DELETE_TIMER_MS;
|
||||
long remoteTimestamp = now + 1;
|
||||
BdfDictionary oldMeta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_TIMER, localTimer),
|
||||
new BdfEntry(GROUP_KEY_PREVIOUS_TIMER, NO_PREVIOUS_TIMER),
|
||||
new BdfEntry(GROUP_KEY_TIMESTAMP, now));
|
||||
// The timestamp should be updated and the timer should be mirrored
|
||||
BdfDictionary newMeta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_TIMESTAMP, remoteTimestamp),
|
||||
new BdfEntry(GROUP_KEY_TIMER, remoteTimer));
|
||||
|
||||
expectGetContact(txn);
|
||||
expectGetContactGroup();
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
|
||||
contactGroup.getId());
|
||||
will(returnValue(oldMeta));
|
||||
oneOf(clientHelper).mergeGroupMetadata(txn,
|
||||
contactGroup.getId(), newMeta);
|
||||
}});
|
||||
|
||||
autoDeleteManager.receiveAutoDeleteTimer(txn, contact.getId(),
|
||||
remoteTimer, remoteTimestamp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoesNotMirrorUnchangedRemoteTimestampIfUnsentChange()
|
||||
throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
long localTimer = MIN_AUTO_DELETE_TIMER_MS;
|
||||
long remoteTimer = MAX_AUTO_DELETE_TIMER_MS;
|
||||
long remoteTimestamp = now + 1;
|
||||
BdfDictionary oldMeta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_TIMER, localTimer),
|
||||
new BdfEntry(GROUP_KEY_PREVIOUS_TIMER, remoteTimer),
|
||||
new BdfEntry(GROUP_KEY_TIMESTAMP, now));
|
||||
// The timestamp should be updated but the timer should not revert
|
||||
BdfDictionary newMeta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_TIMESTAMP, remoteTimestamp));
|
||||
|
||||
expectGetContact(txn);
|
||||
expectGetContactGroup();
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
|
||||
contactGroup.getId());
|
||||
will(returnValue(oldMeta));
|
||||
oneOf(clientHelper).mergeGroupMetadata(txn,
|
||||
contactGroup.getId(), newMeta);
|
||||
}});
|
||||
|
||||
autoDeleteManager.receiveAutoDeleteTimer(txn, contact.getId(),
|
||||
remoteTimer, remoteTimestamp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMirrorsChangedRemoteTimestampIfUnsentChange()
|
||||
throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
long localTimer = MIN_AUTO_DELETE_TIMER_MS;
|
||||
long oldRemoteTimer = MAX_AUTO_DELETE_TIMER_MS;
|
||||
long newRemoteTimer = MAX_AUTO_DELETE_TIMER_MS - 1;
|
||||
long remoteTimestamp = now + 1;
|
||||
BdfDictionary oldMeta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_TIMER, localTimer),
|
||||
new BdfEntry(GROUP_KEY_PREVIOUS_TIMER, oldRemoteTimer),
|
||||
new BdfEntry(GROUP_KEY_TIMESTAMP, now));
|
||||
// The timestamp should be updated , the timer should be mirrored and
|
||||
// the previous timer should be cleared
|
||||
BdfDictionary newMeta = BdfDictionary.of(
|
||||
new BdfEntry(GROUP_KEY_TIMESTAMP, remoteTimestamp),
|
||||
new BdfEntry(GROUP_KEY_TIMER, newRemoteTimer),
|
||||
new BdfEntry(GROUP_KEY_PREVIOUS_TIMER, NO_PREVIOUS_TIMER));
|
||||
|
||||
expectGetContact(txn);
|
||||
expectGetContactGroup();
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).getGroupMetadataAsDictionary(txn,
|
||||
contactGroup.getId());
|
||||
will(returnValue(oldMeta));
|
||||
oneOf(clientHelper).mergeGroupMetadata(txn,
|
||||
contactGroup.getId(), newMeta);
|
||||
}});
|
||||
|
||||
autoDeleteManager.receiveAutoDeleteTimer(txn, contact.getId(),
|
||||
newRemoteTimer, remoteTimestamp);
|
||||
}
|
||||
|
||||
private void expectGetContact(Transaction txn) throws Exception {
|
||||
|
||||
@@ -46,8 +46,6 @@ public class BlogManagerIntegrationTest
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
author0 = identityManager0.getLocalAuthor();
|
||||
author1 = identityManager1.getLocalAuthor();
|
||||
String rssTitle = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
rssAuthor = c0.getAuthorFactory().createLocalAuthor(rssTitle);
|
||||
|
||||
|
||||
@@ -263,8 +263,8 @@ public class IntroductionIntegrationTest
|
||||
addListeners(true, true);
|
||||
|
||||
// 0 and 1 set an auto-delete timer for their conversation
|
||||
setAutoDeleteTimer(c0, contactId1From0);
|
||||
setAutoDeleteTimer(c1, contactId0From1);
|
||||
setAutoDeleteTimer(c0, contactId1From0, MIN_AUTO_DELETE_TIMER_MS);
|
||||
setAutoDeleteTimer(c1, contactId0From1, MIN_AUTO_DELETE_TIMER_MS);
|
||||
|
||||
// Make introduction
|
||||
introductionManager0
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
package org.briarproject.briar.messaging;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.test.TestDatabaseConfigModule;
|
||||
import org.briarproject.briar.api.autodelete.AutoDeleteManager;
|
||||
import org.briarproject.briar.api.conversation.ConversationManager;
|
||||
import org.briarproject.briar.api.conversation.ConversationMessageHeader;
|
||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessage;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
||||
import org.briarproject.briar.test.BriarIntegrationTest;
|
||||
import org.briarproject.briar.test.BriarIntegrationTestComponent;
|
||||
import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.sort;
|
||||
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
|
||||
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class AutoDeleteIntegrationTest
|
||||
extends BriarIntegrationTest<BriarIntegrationTestComponent> {
|
||||
|
||||
@Override
|
||||
protected void createComponents() {
|
||||
BriarIntegrationTestComponent component =
|
||||
DaggerBriarIntegrationTestComponent.builder().build();
|
||||
BriarIntegrationTestComponent.Helper.injectEagerSingletons(component);
|
||||
component.inject(this);
|
||||
|
||||
c0 = DaggerBriarIntegrationTestComponent.builder()
|
||||
.testDatabaseConfigModule(new TestDatabaseConfigModule(t0Dir))
|
||||
.build();
|
||||
BriarIntegrationTestComponent.Helper.injectEagerSingletons(c0);
|
||||
|
||||
c1 = DaggerBriarIntegrationTestComponent.builder()
|
||||
.testDatabaseConfigModule(new TestDatabaseConfigModule(t1Dir))
|
||||
.build();
|
||||
BriarIntegrationTestComponent.Helper.injectEagerSingletons(c1);
|
||||
|
||||
c2 = DaggerBriarIntegrationTestComponent.builder()
|
||||
.testDatabaseConfigModule(new TestDatabaseConfigModule(t2Dir))
|
||||
.build();
|
||||
BriarIntegrationTestComponent.Helper.injectEagerSingletons(c2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageWithoutTimer() throws Exception {
|
||||
// 0 creates a message without a timer
|
||||
MessageId messageId = createMessageWithoutTimer(c0, contactId1From0);
|
||||
// The message should have been added to 0's view of the conversation
|
||||
List<ConversationMessageHeader> headers0 =
|
||||
getMessageHeaders(c0, contactId1From0);
|
||||
assertEquals(1, headers0.size());
|
||||
ConversationMessageHeader h0 = headers0.get(0);
|
||||
assertEquals(messageId, h0.getId());
|
||||
// The message should not have a timer
|
||||
assertEquals(NO_AUTO_DELETE_TIMER, h0.getAutoDeleteTimer());
|
||||
// Sync the message to 1
|
||||
sync0To1(1, true);
|
||||
// The message should have been added to 1's view of the conversation
|
||||
List<ConversationMessageHeader> headers1 =
|
||||
getMessageHeaders(c1, contactId0From1);
|
||||
assertEquals(1, headers1.size());
|
||||
ConversationMessageHeader h1 = headers1.get(0);
|
||||
assertEquals(messageId, h1.getId());
|
||||
// The message should not have a timer
|
||||
assertEquals(NO_AUTO_DELETE_TIMER, h1.getAutoDeleteTimer());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultTimer() throws Exception {
|
||||
// 0 creates a message with the default timer
|
||||
MessageId messageId = createMessageWithTimer(c0, contactId1From0);
|
||||
// The message should have been added to 0's view of the conversation
|
||||
List<ConversationMessageHeader> headers0 =
|
||||
getMessageHeaders(c0, contactId1From0);
|
||||
assertEquals(1, headers0.size());
|
||||
ConversationMessageHeader h0 = headers0.get(0);
|
||||
assertEquals(messageId, h0.getId());
|
||||
// The message should have the default timer (none)
|
||||
assertEquals(NO_AUTO_DELETE_TIMER, h0.getAutoDeleteTimer());
|
||||
// Sync the message to 1
|
||||
sync0To1(1, true);
|
||||
// The message should have been added to 1's view of the conversation
|
||||
List<ConversationMessageHeader> headers1 =
|
||||
getMessageHeaders(c1, contactId0From1);
|
||||
assertEquals(1, headers1.size());
|
||||
ConversationMessageHeader h1 = headers1.get(0);
|
||||
assertEquals(messageId, h1.getId());
|
||||
// The message should have the default timer (none)
|
||||
assertEquals(NO_AUTO_DELETE_TIMER, h1.getAutoDeleteTimer());
|
||||
// Both peers should still be using the default timer
|
||||
assertEquals(NO_AUTO_DELETE_TIMER,
|
||||
getAutoDeleteTimer(c0, contactId1From0));
|
||||
assertEquals(NO_AUTO_DELETE_TIMER,
|
||||
getAutoDeleteTimer(c1, contactId0From1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTimerIsMirrored() throws Exception {
|
||||
// Set 0's timer
|
||||
setAutoDeleteTimer(c0, contactId1From0, MIN_AUTO_DELETE_TIMER_MS);
|
||||
// 0 should be using the new timer
|
||||
assertEquals(MIN_AUTO_DELETE_TIMER_MS,
|
||||
getAutoDeleteTimer(c0, contactId1From0));
|
||||
// 1 should still be using the default timer
|
||||
assertEquals(NO_AUTO_DELETE_TIMER,
|
||||
getAutoDeleteTimer(c1, contactId0From1));
|
||||
// 0 creates a message with the new timer
|
||||
MessageId messageId0 = createMessageWithTimer(c0, contactId1From0);
|
||||
// The message should have been added to 0's view of the conversation
|
||||
List<ConversationMessageHeader> headers0 =
|
||||
getMessageHeaders(c0, contactId1From0);
|
||||
assertEquals(1, headers0.size());
|
||||
ConversationMessageHeader h0 = headers0.get(0);
|
||||
assertEquals(messageId0, h0.getId());
|
||||
// The message should have the new timer
|
||||
assertEquals(MIN_AUTO_DELETE_TIMER_MS, h0.getAutoDeleteTimer());
|
||||
// Sync the message to 1
|
||||
sync0To1(1, true);
|
||||
// The message should have been added to 1's view of the conversation
|
||||
List<ConversationMessageHeader> headers1 =
|
||||
getMessageHeaders(c1, contactId0From1);
|
||||
assertEquals(1, headers1.size());
|
||||
ConversationMessageHeader h1 = headers1.get(0);
|
||||
assertEquals(messageId0, h1.getId());
|
||||
// The message should have the new timer
|
||||
assertEquals(MIN_AUTO_DELETE_TIMER_MS, h1.getAutoDeleteTimer());
|
||||
// 0 and 1 should both be using the new timer
|
||||
assertEquals(MIN_AUTO_DELETE_TIMER_MS,
|
||||
getAutoDeleteTimer(c0, contactId1From0));
|
||||
assertEquals(MIN_AUTO_DELETE_TIMER_MS,
|
||||
getAutoDeleteTimer(c1, contactId0From1));
|
||||
// 1 creates a message
|
||||
MessageId messageId1 = createMessageWithTimer(c1, contactId0From1);
|
||||
// The message should have been added to 1's view of the conversation
|
||||
headers1 = getMessageHeaders(c1, contactId0From1);
|
||||
assertEquals(2, headers1.size());
|
||||
assertEquals(messageId0, headers1.get(0).getId());
|
||||
assertEquals(messageId1, headers1.get(1).getId());
|
||||
// The message should have the new timer
|
||||
assertEquals(MIN_AUTO_DELETE_TIMER_MS,
|
||||
headers1.get(1).getAutoDeleteTimer());
|
||||
// Sync the message to 0
|
||||
sync1To0(1, true);
|
||||
// The message should have been added to 0's view of the conversation
|
||||
headers0 = getMessageHeaders(c0, contactId1From0);
|
||||
assertEquals(2, headers0.size());
|
||||
assertEquals(messageId0, headers0.get(0).getId());
|
||||
assertEquals(messageId1, headers0.get(1).getId());
|
||||
// The message should have the new timer
|
||||
assertEquals(MIN_AUTO_DELETE_TIMER_MS,
|
||||
headers0.get(1).getAutoDeleteTimer());
|
||||
// 0 and 1 should both be using the new timer
|
||||
assertEquals(MIN_AUTO_DELETE_TIMER_MS,
|
||||
getAutoDeleteTimer(c0, contactId1From0));
|
||||
assertEquals(MIN_AUTO_DELETE_TIMER_MS,
|
||||
getAutoDeleteTimer(c1, contactId0From1));
|
||||
}
|
||||
|
||||
private MessageId createMessageWithoutTimer(
|
||||
BriarIntegrationTestComponent component, ContactId contactId)
|
||||
throws Exception {
|
||||
DatabaseComponent db = component.getDatabaseComponent();
|
||||
ConversationManager conversationManager =
|
||||
component.getConversationManager();
|
||||
MessagingManager messagingManager = component.getMessagingManager();
|
||||
PrivateMessageFactory factory = component.getPrivateMessageFactory();
|
||||
|
||||
GroupId groupId = messagingManager.getConversationId(contactId);
|
||||
return db.transactionWithResult(false, txn -> {
|
||||
long timestamp = conversationManager
|
||||
.getTimestampForOutgoingMessage(txn, contactId);
|
||||
PrivateMessage m = factory.createPrivateMessage(groupId, timestamp,
|
||||
"Hi!", emptyList());
|
||||
messagingManager.addLocalMessage(txn, m);
|
||||
return m.getMessage().getId();
|
||||
});
|
||||
}
|
||||
|
||||
private MessageId createMessageWithTimer(
|
||||
BriarIntegrationTestComponent component, ContactId contactId)
|
||||
throws Exception {
|
||||
DatabaseComponent db = component.getDatabaseComponent();
|
||||
ConversationManager conversationManager =
|
||||
component.getConversationManager();
|
||||
AutoDeleteManager autoDeleteManager = component.getAutoDeleteManager();
|
||||
MessagingManager messagingManager = component.getMessagingManager();
|
||||
PrivateMessageFactory factory = component.getPrivateMessageFactory();
|
||||
|
||||
GroupId groupId = messagingManager.getConversationId(contactId);
|
||||
return db.transactionWithResult(false, txn -> {
|
||||
long timestamp = conversationManager
|
||||
.getTimestampForOutgoingMessage(txn, contactId);
|
||||
long timer = autoDeleteManager
|
||||
.getAutoDeleteTimer(txn, contactId, timestamp);
|
||||
PrivateMessage m = factory.createPrivateMessage(groupId, timestamp,
|
||||
"Hi!", emptyList(), timer);
|
||||
messagingManager.addLocalMessage(txn, m);
|
||||
return m.getMessage().getId();
|
||||
});
|
||||
}
|
||||
|
||||
private List<ConversationMessageHeader> getMessageHeaders(
|
||||
BriarIntegrationTestComponent component, ContactId contactId)
|
||||
throws Exception {
|
||||
DatabaseComponent db = component.getDatabaseComponent();
|
||||
MessagingManager messagingManager = component.getMessagingManager();
|
||||
|
||||
return sortHeaders(db.transactionWithResult(true, txn ->
|
||||
messagingManager.getMessageHeaders(txn, contactId)));
|
||||
}
|
||||
|
||||
private long getAutoDeleteTimer(BriarIntegrationTestComponent component,
|
||||
ContactId contactId) throws DbException {
|
||||
DatabaseComponent db = component.getDatabaseComponent();
|
||||
AutoDeleteManager autoDeleteManager = component.getAutoDeleteManager();
|
||||
|
||||
return db.transactionWithResult(false,
|
||||
txn -> autoDeleteManager.getAutoDeleteTimer(txn, contactId));
|
||||
}
|
||||
|
||||
@SuppressWarnings({"UseCompareMethod", "Java8ListSort"}) // Animal Sniffer
|
||||
private List<ConversationMessageHeader> sortHeaders(
|
||||
Collection<ConversationMessageHeader> in) {
|
||||
List<ConversationMessageHeader> out = new ArrayList<>(in);
|
||||
sort(out, (a, b) ->
|
||||
Long.valueOf(a.getTimestamp()).compareTo(b.getTimestamp()));
|
||||
return out;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package org.briarproject.briar.messaging;
|
||||
import org.briarproject.bramble.BrambleCoreIntegrationTestEagerSingletons;
|
||||
import org.briarproject.bramble.BrambleCoreModule;
|
||||
import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule;
|
||||
import org.briarproject.briar.autodelete.AutoDeleteModule;
|
||||
import org.briarproject.briar.client.BriarClientModule;
|
||||
import org.briarproject.briar.forum.ForumModule;
|
||||
|
||||
@@ -12,6 +13,7 @@ import dagger.Component;
|
||||
|
||||
@Singleton
|
||||
@Component(modules = {
|
||||
AutoDeleteModule.class,
|
||||
BrambleCoreIntegrationTestModule.class,
|
||||
BrambleCoreModule.class,
|
||||
BriarClientModule.class,
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.bramble.test.BrambleCoreIntegrationTestModule;
|
||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
||||
import org.briarproject.briar.autodelete.AutoDeleteModule;
|
||||
import org.briarproject.briar.client.BriarClientModule;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
@@ -18,6 +19,7 @@ import dagger.Component;
|
||||
|
||||
@Singleton
|
||||
@Component(modules = {
|
||||
AutoDeleteModule.class,
|
||||
BrambleCoreIntegrationTestModule.class,
|
||||
BrambleCoreModule.class,
|
||||
BriarClientModule.class,
|
||||
|
||||
@@ -153,7 +153,7 @@ abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
|
||||
if (visible) expectGetTimestampForVisibleMessage(messageTimestamp);
|
||||
else expectGetTimestampForInvisibleMessage(messageTimestamp);
|
||||
expectCheckWhetherContactSupportsAutoDeletion();
|
||||
if (visible) expectGetAutoDeleteTimer();
|
||||
if (visible) expectGetAutoDeleteTimer(messageTimestamp);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(messageEncoder).encodeJoinMessage(m.getContactGroupId(),
|
||||
m.getPrivateGroupId(), m.getTimestamp(),
|
||||
@@ -167,7 +167,7 @@ abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
|
||||
if (visible) expectGetTimestampForVisibleMessage(messageTimestamp);
|
||||
else expectGetTimestampForInvisibleMessage(messageTimestamp);
|
||||
expectCheckWhetherContactSupportsAutoDeletion();
|
||||
if (visible) expectGetAutoDeleteTimer();
|
||||
if (visible) expectGetAutoDeleteTimer(messageTimestamp);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(messageEncoder).encodeLeaveMessage(contactGroupId,
|
||||
privateGroupId, messageTimestamp, lastLocalMessageId,
|
||||
@@ -254,10 +254,28 @@ abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
|
||||
}});
|
||||
}
|
||||
|
||||
void expectGetAutoDeleteTimer() throws Exception {
|
||||
void expectGetAutoDeleteTimer(long timestamp) throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(autoDeleteManager).getAutoDeleteTimer(txn, contactId);
|
||||
oneOf(autoDeleteManager).getAutoDeleteTimer(txn, contactId,
|
||||
timestamp);
|
||||
will(returnValue(NO_AUTO_DELETE_TIMER));
|
||||
}});
|
||||
}
|
||||
|
||||
void expectTrackUnreadMessage(long timestamp) throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(messageTracker).trackMessage(txn, contactGroupId, timestamp,
|
||||
false);
|
||||
}});
|
||||
}
|
||||
|
||||
void expectReceiveAutoDeleteTimer(DeletableGroupInvitationMessage m)
|
||||
throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).getContactId(txn, contactGroupId);
|
||||
will(returnValue(contactId));
|
||||
oneOf(autoDeleteManager).receiveAutoDeleteTimer(txn, contactId,
|
||||
m.getAutoDeleteTimer(), m.getTimestamp());
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,11 +308,8 @@ public class CreatorProtocolEngineTest extends AbstractProtocolEngineTest {
|
||||
|
||||
expectSendJoinMessage(properJoinMessage, false);
|
||||
expectMarkMessageVisibleInUi(properJoinMessage.getId());
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(messageTracker)
|
||||
.trackMessage(txn, contactGroupId, inviteTimestamp + 1,
|
||||
false);
|
||||
}});
|
||||
expectTrackUnreadMessage(properJoinMessage.getTimestamp());
|
||||
expectReceiveAutoDeleteTimer(properJoinMessage);
|
||||
expectGetContactId();
|
||||
expectSetPrivateGroupVisibility(SHARED);
|
||||
CreatorSession newSession =
|
||||
@@ -399,11 +396,8 @@ public class CreatorProtocolEngineTest extends AbstractProtocolEngineTest {
|
||||
CreatorSession session = getDefaultSession(INVITED);
|
||||
|
||||
expectMarkMessageVisibleInUi(properLeaveMessage.getId());
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(messageTracker)
|
||||
.trackMessage(txn, contactGroupId, inviteTimestamp + 1,
|
||||
false);
|
||||
}});
|
||||
expectTrackUnreadMessage(properLeaveMessage.getTimestamp());
|
||||
expectReceiveAutoDeleteTimer(properLeaveMessage);
|
||||
expectGetContactId();
|
||||
CreatorSession newSession =
|
||||
engine.onLeaveMessage(txn, session, properLeaveMessage);
|
||||
|
||||
@@ -168,8 +168,8 @@ public class GroupInvitationIntegrationTest
|
||||
@Test
|
||||
public void testInvitationDeclineWithAutoDelete() throws Exception {
|
||||
// 0 and 1 set an auto-delete timer for their conversation
|
||||
setAutoDeleteTimer(c0, contactId1From0);
|
||||
setAutoDeleteTimer(c1, contactId0From1);
|
||||
setAutoDeleteTimer(c0, contactId1From0, MIN_AUTO_DELETE_TIMER_MS);
|
||||
setAutoDeleteTimer(c1, contactId0From1, MIN_AUTO_DELETE_TIMER_MS);
|
||||
|
||||
// Send invitation
|
||||
sendInvitation(clock.currentTimeMillis(), null);
|
||||
@@ -253,8 +253,8 @@ public class GroupInvitationIntegrationTest
|
||||
@Test
|
||||
public void testInvitationAcceptWithAutoDelete() throws Exception {
|
||||
// 0 and 1 set an auto-delete timer for their conversation
|
||||
setAutoDeleteTimer(c0, contactId1From0);
|
||||
setAutoDeleteTimer(c1, contactId0From1);
|
||||
setAutoDeleteTimer(c0, contactId1From0, MIN_AUTO_DELETE_TIMER_MS);
|
||||
setAutoDeleteTimer(c1, contactId0From1, MIN_AUTO_DELETE_TIMER_MS);
|
||||
|
||||
// Send invitation
|
||||
sendInvitation(clock.currentTimeMillis(), null);
|
||||
@@ -743,7 +743,7 @@ public class GroupInvitationIntegrationTest
|
||||
throws DbException {
|
||||
byte[] signature = groupInvitationFactory.signInvitation(contact1From0,
|
||||
privateGroup.getId(), timestamp, author0.getPrivateKey());
|
||||
long timer = getAutoDeleteTimer(c0, contactId1From0);
|
||||
long timer = getAutoDeleteTimer(c0, contactId1From0, timestamp);
|
||||
groupInvitationManager0.sendInvitation(privateGroup.getId(),
|
||||
contactId1From0, text, timestamp, signature, timer);
|
||||
}
|
||||
|
||||
@@ -366,9 +366,9 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
|
||||
}});
|
||||
expectMarkMessageVisibleInUi(properInviteMessage.getId());
|
||||
expectMarkMessageAvailableToAnswer(properInviteMessage.getId(), true);
|
||||
expectTrackUnreadMessage(properInviteMessage.getTimestamp());
|
||||
expectReceiveAutoDeleteTimer(properInviteMessage);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(messageTracker).trackMessage(txn, contactGroupId,
|
||||
properInviteMessage.getTimestamp(), false);
|
||||
oneOf(privateGroupFactory)
|
||||
.createPrivateGroup(properInviteMessage.getGroupName(),
|
||||
properInviteMessage.getCreator(),
|
||||
|
||||
@@ -210,8 +210,8 @@ public class BlogSharingIntegrationTest
|
||||
listenToEvents(true);
|
||||
|
||||
// Set an auto-delete timer for the conversation
|
||||
setAutoDeleteTimer(c0, contactId1From0);
|
||||
setAutoDeleteTimer(c1, contactId0From1);
|
||||
setAutoDeleteTimer(c0, contactId1From0, MIN_AUTO_DELETE_TIMER_MS);
|
||||
setAutoDeleteTimer(c1, contactId0From1, MIN_AUTO_DELETE_TIMER_MS);
|
||||
|
||||
// Send invitation
|
||||
blogSharingManager0
|
||||
|
||||
@@ -191,8 +191,8 @@ public class ForumSharingIntegrationTest
|
||||
@Test
|
||||
public void testSuccessfulSharingWithAutoDelete() throws Exception {
|
||||
// Set an auto-delete timer for the conversation
|
||||
setAutoDeleteTimer(c0, contactId1From0);
|
||||
setAutoDeleteTimer(c1, contactId0From1);
|
||||
setAutoDeleteTimer(c0, contactId1From0, MIN_AUTO_DELETE_TIMER_MS);
|
||||
setAutoDeleteTimer(c1, contactId0From1, MIN_AUTO_DELETE_TIMER_MS);
|
||||
|
||||
// Send invitation
|
||||
forumSharingManager0
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.test.TestTransportConnectionReader;
|
||||
import org.briarproject.bramble.test.TestTransportConnectionWriter;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.briar.api.autodelete.AutoDeleteManager;
|
||||
import org.briarproject.briar.api.blog.BlogFactory;
|
||||
import org.briarproject.briar.api.blog.BlogPostFactory;
|
||||
import org.briarproject.briar.api.client.MessageTracker;
|
||||
@@ -63,7 +64,6 @@ import static org.briarproject.bramble.api.sync.validation.MessageState.PENDING;
|
||||
import static org.briarproject.bramble.test.TestPluginConfigModule.SIMPLEX_TRANSPORT_ID;
|
||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
@@ -453,16 +453,21 @@ public abstract class BriarIntegrationTest<C extends BriarIntegrationTestCompone
|
||||
}
|
||||
|
||||
protected void setAutoDeleteTimer(BriarIntegrationTestComponent component,
|
||||
ContactId contactId) throws DbException {
|
||||
component.getDatabaseComponent().transaction(false, txn ->
|
||||
component.getAutoDeleteManager().setAutoDeleteTimer(txn,
|
||||
contactId, MIN_AUTO_DELETE_TIMER_MS));
|
||||
ContactId contactId, long timer) throws DbException {
|
||||
DatabaseComponent db = component.getDatabaseComponent();
|
||||
AutoDeleteManager autoDeleteManager = component.getAutoDeleteManager();
|
||||
|
||||
db.transaction(false, txn ->
|
||||
autoDeleteManager.setAutoDeleteTimer(txn, contactId, timer));
|
||||
}
|
||||
|
||||
protected long getAutoDeleteTimer(BriarIntegrationTestComponent component,
|
||||
ContactId contactId) throws DbException {
|
||||
return component.getDatabaseComponent().transactionWithResult(true,
|
||||
txn -> component.getAutoDeleteManager().getAutoDeleteTimer(txn,
|
||||
contactId));
|
||||
ContactId contactId, long timestamp) throws DbException {
|
||||
DatabaseComponent db = component.getDatabaseComponent();
|
||||
AutoDeleteManager autoDeleteManager = component.getAutoDeleteManager();
|
||||
|
||||
return db.transactionWithResult(false,
|
||||
txn -> autoDeleteManager.getAutoDeleteTimer(txn, contactId,
|
||||
timestamp));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user