diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationVisitor.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationVisitor.java index 0b9b48bd9..53e1cc76d 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationVisitor.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationVisitor.java @@ -102,6 +102,10 @@ class ConversationVisitor implements text = ctx.getString( R.string.blogs_sharing_response_accepted_sent, contactName.getValue()); + } else if (r.isAutoDecline()) { + text = ctx.getString( + R.string.blogs_sharing_response_declined_auto, + contactName.getValue()); } else { text = ctx.getString( R.string.blogs_sharing_response_declined_sent, @@ -155,6 +159,10 @@ class ConversationVisitor implements text = ctx.getString( R.string.forum_invitation_response_accepted_sent, contactName.getValue()); + } else if (r.isAutoDecline()) { + text = ctx.getString( + R.string.forum_invitation_response_declined_auto, + contactName.getValue()); } else { text = ctx.getString( R.string.forum_invitation_response_declined_sent, diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index d9eec9975..53b1694cc 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -419,6 +419,7 @@ Already sharing You accepted the forum invitation from %s. You declined the forum invitation from %s. + The forum invitation from %s was automatically declined. %s accepted the forum invitation. %s declined the forum invitation. @@ -456,6 +457,7 @@ Blog shared with chosen contacts You accepted the blog invitation from %s. You declined the blog invitation from %s. + The blog invitation from %s was automatically declined. %s accepted the blog invitation. %s declined the blog invitation. %1$s has shared the blog \"%2$s\" with you. diff --git a/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogInvitationResponse.java b/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogInvitationResponse.java index 8d0c9cbef..c1fc813ef 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogInvitationResponse.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogInvitationResponse.java @@ -13,9 +13,9 @@ public class BlogInvitationResponse extends InvitationResponse { public BlogInvitationResponse(MessageId id, GroupId groupId, long time, boolean local, boolean read, boolean sent, boolean seen, SessionId sessionId, boolean accept, GroupId shareableId, - long autoDeleteTimer) { + long autoDeleteTimer, boolean isAutoDecline) { super(id, groupId, time, local, read, sent, seen, sessionId, - accept, shareableId, autoDeleteTimer, false); + accept, shareableId, autoDeleteTimer, isAutoDecline); } @Override diff --git a/briar-api/src/main/java/org/briarproject/briar/api/forum/ForumInvitationResponse.java b/briar-api/src/main/java/org/briarproject/briar/api/forum/ForumInvitationResponse.java index 033d7ad37..3b2e46367 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/forum/ForumInvitationResponse.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/forum/ForumInvitationResponse.java @@ -16,9 +16,9 @@ public class ForumInvitationResponse extends InvitationResponse { public ForumInvitationResponse(MessageId id, GroupId groupId, long time, boolean local, boolean read, boolean sent, boolean seen, SessionId sessionId, boolean accept, GroupId shareableId, - long autoDeleteTimer) { + long autoDeleteTimer, boolean isAutoDecline) { super(id, groupId, time, local, read, sent, seen, sessionId, - accept, shareableId, autoDeleteTimer, false); + accept, shareableId, autoDeleteTimer, isAutoDecline); } @Override diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogInvitationFactoryImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogInvitationFactoryImpl.java index afa8f4046..916d8a5af 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogInvitationFactoryImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogInvitationFactoryImpl.java @@ -33,11 +33,11 @@ public class BlogInvitationFactoryImpl public BlogInvitationResponse createInvitationResponse(MessageId id, GroupId contactGroupId, long time, boolean local, boolean sent, boolean seen, boolean read, boolean accept, GroupId shareableId, - long autoDeleteTimer) { + long autoDeleteTimer, boolean isAutoDecline) { SessionId sessionId = new SessionId(shareableId.getBytes()); return new BlogInvitationResponse(id, contactGroupId, time, local, read, sent, seen, sessionId, accept, shareableId, - autoDeleteTimer); + autoDeleteTimer, isAutoDecline); } } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogProtocolEngineImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogProtocolEngineImpl.java index 6ebaa137f..bce737d75 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogProtocolEngineImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogProtocolEngineImpl.java @@ -8,6 +8,7 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +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; @@ -71,7 +72,8 @@ class BlogProtocolEngineImpl extends ProtocolEngineImpl { BlogInvitationResponse response = invitationFactory .createInvitationResponse(m.getId(), m.getContactGroupId(), m.getTimestamp(), false, false, false, false, - true, m.getShareableId(), m.getAutoDeleteTimer()); + true, m.getShareableId(), m.getAutoDeleteTimer(), + false); return new BlogInvitationResponseReceivedEvent(response, contactId); } @@ -81,7 +83,18 @@ class BlogProtocolEngineImpl extends ProtocolEngineImpl { BlogInvitationResponse response = invitationFactory .createInvitationResponse(m.getId(), m.getContactGroupId(), m.getTimestamp(), false, false, false, false, - false, m.getShareableId(), m.getAutoDeleteTimer()); + false, m.getShareableId(), m.getAutoDeleteTimer(), + false); + return new BlogInvitationResponseReceivedEvent(response, contactId); + } + + @Override + Event getAutoDeclineInvitationResponseReceivedEvent(Session s, Message m, + ContactId contactId, long timer) { + BlogInvitationResponse response = invitationFactory + .createInvitationResponse(m.getId(), s.getContactGroupId(), + m.getTimestamp(), true, false, false, true, + false, s.getShareableId(), timer, true); return new BlogInvitationResponseReceivedEvent(response, contactId); } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/ForumInvitationFactoryImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/ForumInvitationFactoryImpl.java index a83b37102..841b8e361 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/ForumInvitationFactoryImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/ForumInvitationFactoryImpl.java @@ -33,11 +33,11 @@ public class ForumInvitationFactoryImpl public ForumInvitationResponse createInvitationResponse(MessageId id, GroupId contactGroupId, long time, boolean local, boolean sent, boolean seen, boolean read, boolean accept, GroupId shareableId, - long autoDeleteTimer) { + long autoDeleteTimer, boolean isAutoDecline) { SessionId sessionId = new SessionId(shareableId.getBytes()); return new ForumInvitationResponse(id, contactGroupId, time, local, read, sent, seen, sessionId, accept, shareableId, - autoDeleteTimer); + autoDeleteTimer, isAutoDecline); } } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/ForumProtocolEngineImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/ForumProtocolEngineImpl.java index 8a1dabcc0..a1277ac65 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/ForumProtocolEngineImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/ForumProtocolEngineImpl.java @@ -8,6 +8,7 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +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; @@ -71,7 +72,8 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl { ForumInvitationResponse response = invitationFactory .createInvitationResponse(m.getId(), m.getContactGroupId(), m.getTimestamp(), false, false, true, false, - true, m.getShareableId(), m.getAutoDeleteTimer()); + true, m.getShareableId(), m.getAutoDeleteTimer(), + false); return new ForumInvitationResponseReceivedEvent(response, contactId); } @@ -81,7 +83,18 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl { ForumInvitationResponse response = invitationFactory .createInvitationResponse(m.getId(), m.getContactGroupId(), m.getTimestamp(), false, false, true, false, - false, m.getShareableId(), m.getAutoDeleteTimer()); + false, m.getShareableId(), m.getAutoDeleteTimer(), + false); + return new ForumInvitationResponseReceivedEvent(response, contactId); + } + + @Override + Event getAutoDeclineInvitationResponseReceivedEvent(Session s, Message m, + ContactId contactId, long timer) { + ForumInvitationResponse response = invitationFactory + .createInvitationResponse(m.getId(), s.getContactGroupId(), + m.getTimestamp(), true, false, false, true, + false, s.getShareableId(), timer, true); return new ForumInvitationResponseReceivedEvent(response, contactId); } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/InvitationFactory.java b/briar-core/src/main/java/org/briarproject/briar/sharing/InvitationFactory.java index c156df0e2..99068f229 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/InvitationFactory.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/InvitationFactory.java @@ -15,6 +15,7 @@ public interface InvitationFactory * Only applies to messages of type INVITE. */ public boolean wasAccepted() { @@ -68,4 +70,8 @@ class MessageMetadata { public long getAutoDeleteTimer() { return autoDeleteTimer; } + + public boolean isAutoDecline() { + return isAutoDecline; + } } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java index 11e76cf6c..bf832bc27 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java @@ -20,6 +20,7 @@ import static org.briarproject.briar.sharing.MessageType.INVITE; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_AUTO_DELETE_TIMER; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_AVAILABLE_TO_ANSWER; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_INVITATION_ACCEPTED; +import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_IS_AUTO_DECLINE; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_LOCAL; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_MESSAGE_TYPE; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_READ; @@ -74,8 +75,9 @@ abstract class MessageParserImpl boolean accepted = meta.getBoolean(MSG_KEY_INVITATION_ACCEPTED, false); long timer = meta.getLong(MSG_KEY_AUTO_DELETE_TIMER, NO_AUTO_DELETE_TIMER); + boolean isAutoDecline = meta.getBoolean(MSG_KEY_IS_AUTO_DECLINE, false); return new MessageMetadata(type, shareableId, timestamp, local, read, - visible, available, accepted, timer); + visible, available, accepted, timer, isAutoDecline); } @Override diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngine.java b/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngine.java index 637559648..4f759fe0b 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngine.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngine.java @@ -16,8 +16,8 @@ interface ProtocolEngine { Session onAcceptAction(Transaction txn, Session session) throws DbException; - Session onDeclineAction(Transaction txn, Session session) - throws DbException; + Session onDeclineAction(Transaction txn, Session session, + boolean isAutoDecline) throws DbException; Session onLeaveAction(Transaction txn, Session session) throws DbException; diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngineImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngineImpl.java index 381c22a12..692f5e084 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngineImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngineImpl.java @@ -148,6 +148,10 @@ abstract class ProtocolEngineImpl localTimestamp, s.getLastLocalMessageId(), descriptor, text, timer); sendMessage(txn, m, INVITE, s.getShareableId(), true, timer); + // Set the auto-delete timer duration on the message + if (timer != NO_AUTO_DELETE_TIMER) { + db.setCleanupTimerDuration(txn, m.getId(), timer); + } } else { m = messageEncoder.encodeInviteMessage(s.getContactGroupId(), localTimestamp, s.getLastLocalMessageId(), descriptor, @@ -216,6 +220,10 @@ abstract class ProtocolEngineImpl s.getShareableId(), localTimestamp, s.getLastLocalMessageId(), timer); sendMessage(txn, m, ACCEPT, s.getShareableId(), true, timer); + // Set the auto-delete timer duration on the message + if (timer != NO_AUTO_DELETE_TIMER) { + db.setCleanupTimerDuration(txn, m.getId(), timer); + } } else { m = messageEncoder.encodeAcceptMessage(s.getContactGroupId(), s.getShareableId(), localTimestamp, @@ -227,11 +235,11 @@ abstract class ProtocolEngineImpl } @Override - public Session onDeclineAction(Transaction txn, Session s) - throws DbException { + public Session onDeclineAction(Transaction txn, Session s, + boolean isAutoDecline) throws DbException { switch (s.getState()) { case LOCAL_INVITED: - return onLocalDecline(txn, s); + return onLocalDecline(txn, s, isAutoDecline); case START: case REMOTE_INVITED: case SHARING: @@ -243,14 +251,14 @@ abstract class ProtocolEngineImpl } } - private Session onLocalDecline(Transaction txn, Session s) - throws DbException { + private Session onLocalDecline(Transaction txn, Session s, + boolean isAutoDecline) throws DbException { // Mark the invite message unavailable to answer MessageId inviteId = s.getLastRemoteMessageId(); if (inviteId == null) throw new IllegalStateException(); markMessageAvailableToAnswer(txn, inviteId, false); // Send a DECLINE message - Message sent = sendDeclineMessage(txn, s); + Message sent = sendDeclineMessage(txn, s, isAutoDecline); // Track the message messageTracker.trackOutgoingMessage(txn, sent); // Move to the START state @@ -259,8 +267,8 @@ abstract class ProtocolEngineImpl s.getInviteTimestamp()); } - private Message sendDeclineMessage(Transaction txn, Session s) - throws DbException { + private Message sendDeclineMessage(Transaction txn, Session s, + boolean isAutoDecline) throws DbException { Message m; long localTimestamp = getTimestampForVisibleMessage(txn, s); ContactId c = getContactId(txn, s.getContactGroupId()); @@ -270,7 +278,18 @@ abstract class ProtocolEngineImpl m = messageEncoder.encodeDeclineMessage(s.getContactGroupId(), s.getShareableId(), localTimestamp, s.getLastLocalMessageId(), timer); - sendMessage(txn, m, DECLINE, s.getShareableId(), true, timer); + sendMessage(txn, m, DECLINE, s.getShareableId(), true, timer, + isAutoDecline); + // Set the auto-delete timer duration on the local message + if (timer != NO_AUTO_DELETE_TIMER) { + db.setCleanupTimerDuration(txn, m.getId(), timer); + } + if (isAutoDecline) { + // Broadcast an event, so the auto-decline becomes visible + Event e = getAutoDeclineInvitationResponseReceivedEvent( + s, m, c, timer); + txn.attach(e); + } } else { m = messageEncoder.encodeDeclineMessage(s.getContactGroupId(), s.getShareableId(), localTimestamp, @@ -281,6 +300,9 @@ abstract class ProtocolEngineImpl return m; } + abstract Event getAutoDeclineInvitationResponseReceivedEvent(Session s, + Message m, ContactId contactId, long timer); + @Override public Session onLeaveAction(Transaction txn, Session s) throws DbException { @@ -394,8 +416,8 @@ abstract class ProtocolEngineImpl // Broadcast an event ContactId contactId = clientHelper.getContactId(txn, s.getContactGroupId()); - txn.attach( - getInvitationRequestReceivedEvent(m, contactId, false, true)); + txn.attach(getInvitationRequestReceivedEvent(m, contactId, false, + true)); // Move to the next state return new Session(SHARING, s.getContactGroupId(), s.getShareableId(), s.getLastLocalMessageId(), m.getId(), s.getLocalTimestamp(), @@ -636,9 +658,16 @@ abstract class ProtocolEngineImpl private void sendMessage(Transaction txn, Message m, MessageType type, GroupId shareableId, boolean visibleInConversation, long autoDeleteTimer) throws DbException { + sendMessage(txn, m, type, shareableId, visibleInConversation, + autoDeleteTimer, false); + } + + private void sendMessage(Transaction txn, Message m, MessageType type, + GroupId shareableId, boolean visibleInConversation, + long autoDeleteTimer, boolean isAutoDecline) throws DbException { BdfDictionary meta = messageEncoder.encodeMetadata(type, shareableId, m.getTimestamp(), true, true, visibleInConversation, false, - false, autoDeleteTimer); + false, autoDeleteTimer, isAutoDecline); try { clientHelper.addLocalMessage(txn, m, meta, true, false); } catch (FormatException e) { diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingConstants.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingConstants.java index 4ebf1d790..87ce53589 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingConstants.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingConstants.java @@ -14,6 +14,7 @@ interface SharingConstants { String MSG_KEY_AVAILABLE_TO_ANSWER = "availableToAnswer"; String MSG_KEY_INVITATION_ACCEPTED = "invitationAccepted"; String MSG_KEY_AUTO_DELETE_TIMER = "autoDeleteTimer"; + String MSG_KEY_IS_AUTO_DECLINE = "isAutoDecline"; // Session keys String SESSION_KEY_IS_SESSION = "isSession"; diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java index 8ebfbadcf..4e47b3937 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java @@ -1,6 +1,7 @@ package org.briarproject.briar.sharing; import org.briarproject.bramble.api.FormatException; +import org.briarproject.bramble.api.cleanup.CleanupHook; import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ContactGroupFactory; import org.briarproject.bramble.api.contact.Contact; @@ -24,6 +25,7 @@ import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageStatus; import org.briarproject.bramble.api.versioning.ClientVersioningManager; import org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVersioningHook; +import org.briarproject.briar.api.autodelete.event.ConversationMessagesDeletedEvent; import org.briarproject.briar.api.client.MessageTracker; import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.conversation.ConversationMessageHeader; @@ -47,18 +49,20 @@ import java.util.Set; import javax.annotation.Nullable; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; +import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER; import static org.briarproject.briar.sharing.MessageType.ABORT; import static org.briarproject.briar.sharing.MessageType.ACCEPT; import static org.briarproject.briar.sharing.MessageType.DECLINE; import static org.briarproject.briar.sharing.MessageType.INVITE; import static org.briarproject.briar.sharing.MessageType.LEAVE; +import static org.briarproject.briar.sharing.State.LOCAL_INVITED; import static org.briarproject.briar.sharing.State.SHARING; @NotNullByDefault abstract class SharingManagerImpl extends ConversationClientImpl implements SharingManager, OpenDatabaseHook, ContactHook, - ClientVersioningHook { + ClientVersioningHook, CleanupHook { private final ClientVersioningManager clientVersioningManager; private final MessageParser messageParser; @@ -133,6 +137,11 @@ abstract class SharingManagerImpl BdfDictionary d) throws DbException, FormatException { // Parse the metadata MessageMetadata meta = messageParser.parseMetadata(d); + // set the clean-up timer that will be started when message gets read + long timer = meta.getAutoDeleteTimer(); + if (timer != NO_AUTO_DELETE_TIMER) { + db.setCleanupTimerDuration(txn, m.getId(), timer); + } // Look up the session, if there is one SessionId sessionId = getSessionId(meta.getShareableId()); StoredSession ss = getSession(txn, m.getGroupId(), sessionId); @@ -293,7 +302,13 @@ abstract class SharingManagerImpl @Override public void respondToInvitation(ContactId c, SessionId id, boolean accept) throws DbException { - Transaction txn = db.startTransaction(false); + db.transaction(false, + txn -> respondToInvitation(txn, c, id, accept, false)); + } + + private void respondToInvitation(Transaction txn, ContactId c, + SessionId id, boolean accept, boolean isAutoDecline) + throws DbException { try { // Look up the session Contact contact = db.getContact(txn, c); @@ -305,14 +320,11 @@ abstract class SharingManagerImpl sessionParser.parseSession(contactGroupId, ss.bdfSession); // Handle the accept or decline action if (accept) session = engine.onAcceptAction(txn, session); - else session = engine.onDeclineAction(txn, session); + else session = engine.onDeclineAction(txn, session, isAutoDecline); // Store the updated session storeSession(txn, ss.storageId, session); - db.commitTransaction(txn); } catch (FormatException e) { throw new DbException(e); - } finally { - db.endTransaction(txn); } } @@ -371,7 +383,7 @@ abstract class SharingManagerImpl return invitationFactory.createInvitationResponse(m, contactGroupId, meta.getTimestamp(), meta.isLocal(), status.isSent(), status.isSeen(), meta.isRead(), accept, meta.getShareableId(), - meta.getAutoDeleteTimer()); + meta.getAutoDeleteTimer(), meta.isAutoDecline()); } @Override @@ -684,6 +696,57 @@ abstract class SharingManagerImpl return result; } + @Override + public void deleteMessages(Transaction txn, GroupId g, + Collection messageIds) throws DbException { + ContactId c; + Map sessions = new HashMap<>(); + try { + // get the ContactId from the given GroupId + c = clientHelper.getContactId(txn, g); + // get sessions for all messages to be deleted + for (MessageId messageId : messageIds) { + BdfDictionary d = clientHelper + .getMessageMetadataAsDictionary(txn, messageId); + MessageMetadata messageMetadata = + messageParser.parseMetadata(d); + if (!messageMetadata.isVisibleInConversation()) + throw new IllegalArgumentException(); + SessionId sessionId = + getSessionId(messageMetadata.getShareableId()); + DeletableSession deletableSession = sessions.get(sessionId); + if (deletableSession == null) { + StoredSession ss = getSession(txn, g, sessionId); + if (ss == null) throw new DbException(); + Session session = sessionParser + .parseSession(g, ss.bdfSession); + deletableSession = new DeletableSession(session.getState()); + sessions.put(sessionId, deletableSession); + } + deletableSession.messages.add(messageId); + } + } catch (FormatException e) { + throw new DbException(e); + } + + // delete given visible messages in sessions + for (Entry entry : sessions.entrySet()) { + DeletableSession session = entry.getValue(); + // first decline pending invitation to shareable + if (session.state == LOCAL_INVITED) { + // marked as autoDecline + respondToInvitation(txn, c, entry.getKey(), false, true); + } + for (MessageId m : session.messages) { + db.deleteMessage(txn, m); + db.deleteMessageMetadata(txn, m); + } + } + recalculateGroupCount(txn, g); + + txn.attach(new ConversationMessagesDeletedEvent(c, messageIds)); + } + @Override public Set getMessageIds(Transaction txn, ContactId c) throws DbException { diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java index 0bab71a49..96f6faed1 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java @@ -1,5 +1,6 @@ package org.briarproject.briar.sharing; +import org.briarproject.bramble.api.cleanup.CleanupManager; import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.data.MetadataEncoder; @@ -75,7 +76,8 @@ public class SharingModule { ValidationManager validationManager, ConversationManager conversationManager, BlogManager blogManager, ClientVersioningManager clientVersioningManager, - BlogSharingManagerImpl blogSharingManager) { + BlogSharingManagerImpl blogSharingManager, + CleanupManager cleanupManager) { lifecycleManager.registerOpenDatabaseHook(blogSharingManager); contactManager.registerContactHook(blogSharingManager); validationManager.registerIncomingMessageHook( @@ -91,6 +93,9 @@ public class SharingModule { clientVersioningManager.registerClient(BlogManager.CLIENT_ID, BlogManager.MAJOR_VERSION, BlogManager.MINOR_VERSION, blogSharingManager.getShareableClientVersioningHook()); + cleanupManager.registerCleanupHook(BlogSharingManager.CLIENT_ID, + BlogSharingManager.MAJOR_VERSION, + blogSharingManager); return blogSharingManager; } @@ -134,7 +139,8 @@ public class SharingModule { ValidationManager validationManager, ConversationManager conversationManager, ForumManager forumManager, ClientVersioningManager clientVersioningManager, - ForumSharingManagerImpl forumSharingManager) { + ForumSharingManagerImpl forumSharingManager, + CleanupManager cleanupManager) { lifecycleManager.registerOpenDatabaseHook(forumSharingManager); contactManager.registerContactHook(forumSharingManager); validationManager.registerIncomingMessageHook( @@ -150,6 +156,9 @@ public class SharingModule { clientVersioningManager.registerClient(ForumManager.CLIENT_ID, ForumManager.MAJOR_VERSION, ForumManager.MINOR_VERSION, forumSharingManager.getShareableClientVersioningHook()); + cleanupManager.registerCleanupHook(ForumSharingManager.CLIENT_ID, + ForumSharingManager.MAJOR_VERSION, + forumSharingManager); return forumSharingManager; } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingValidator.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingValidator.java index 73e34be0c..4698ff0e2 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingValidator.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingValidator.java @@ -74,7 +74,8 @@ abstract class SharingValidator extends BdfMessageValidator { } BdfDictionary meta = messageEncoder.encodeMetadata(INVITE, shareableId, - m.getTimestamp(), false, false, false, false, false, timer); + m.getTimestamp(), false, false, false, false, false, timer, + false); if (previousMessageId == null) { return new BdfMessageContext(meta); } else { @@ -96,7 +97,7 @@ abstract class SharingValidator extends BdfMessageValidator { BdfDictionary meta = messageEncoder.encodeMetadata(type, new GroupId(shareableId), m.getTimestamp(), false, false, - false, false, false, NO_AUTO_DELETE_TIMER); + false, false, false, NO_AUTO_DELETE_TIMER, false); if (previousMessageId == null) { return new BdfMessageContext(meta); } else { @@ -123,7 +124,7 @@ abstract class SharingValidator extends BdfMessageValidator { BdfDictionary meta = messageEncoder.encodeMetadata(type, new GroupId(shareableId), m.getTimestamp(), false, false, - false, false, false, timer); + false, false, false, timer, false); if (previousMessageId == null) { return new BdfMessageContext(meta); } else { diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/AbstractAutoDeleteIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/AbstractAutoDeleteIntegrationTest.java new file mode 100644 index 000000000..19a01fbf3 --- /dev/null +++ b/briar-core/src/test/java/org/briarproject/briar/sharing/AbstractAutoDeleteIntegrationTest.java @@ -0,0 +1,278 @@ +package org.briarproject.briar.sharing; + +import org.briarproject.bramble.api.contact.Contact; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.sync.MessageId; +import org.briarproject.briar.api.autodelete.event.ConversationMessagesDeletedEvent; +import org.briarproject.briar.api.blog.Blog; +import org.briarproject.briar.api.client.BaseGroup; +import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent; +import org.briarproject.briar.api.forum.Forum; +import org.briarproject.briar.api.sharing.InvitationResponse; +import org.briarproject.briar.api.sharing.Shareable; +import org.briarproject.briar.api.sharing.SharingInvitationItem; +import org.briarproject.briar.api.sharing.SharingManager; +import org.briarproject.briar.autodelete.AbstractAutoDeleteTest; + +import java.util.Collection; + +import static org.briarproject.bramble.api.cleanup.CleanupManager.BATCH_DELAY_MS; +import static org.briarproject.briar.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS; +import static org.briarproject.briar.test.TestEventListener.assertEvent; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public abstract class AbstractAutoDeleteIntegrationTest + extends AbstractAutoDeleteTest { + + protected abstract SharingManager getSharingManager0(); + + protected abstract SharingManager getSharingManager1(); + + protected abstract Shareable getShareable(); + + protected abstract Collection subscriptions0() + throws DbException; + + protected abstract Collection subscriptions1() + throws DbException; + + protected abstract Class> getResponseReceivedEventClass(); + + protected void testAutoDeclinedSharing() throws Exception { + setAutoDeleteTimer(c0, contactId1From0, MIN_AUTO_DELETE_TIMER_MS); + + // Send invitation + getSharingManager0().sendInvitation( + getShareable().getId(), contactId1From0, "This shareable!"); + + // The message should have been added to 0's view of the conversation + assertGroupCount(c0, contactId1From0, 1, 0); + forEachHeader(c0, contactId1From0, 1, h -> { + // The message should have the expected timer + assertEquals(MIN_AUTO_DELETE_TIMER_MS, h.getAutoDeleteTimer()); + }); + + // Sync invitation message + sync0To1(1, true); + ack1To0(1); + waitForEvents(c0); + + // The message should have been added to 1's view of the conversation + assertGroupCount(c1, contactId0From1, 1, 1); + forEachHeader(c1, contactId0From1, 1, h -> { + // The message should have the expected timer + assertEquals(MIN_AUTO_DELETE_TIMER_MS, h.getAutoDeleteTimer()); + }); + + // Both peers should be using the new timer + assertEquals(MIN_AUTO_DELETE_TIMER_MS, + getAutoDeleteTimer(c0, contactId1From0)); + assertEquals(MIN_AUTO_DELETE_TIMER_MS, + getAutoDeleteTimer(c1, contactId0From1)); + + // Before 0's timer elapses, both peers should still see the message + long timerLatency = MIN_AUTO_DELETE_TIMER_MS + BATCH_DELAY_MS; + c0.getTimeTravel().addCurrentTimeMillis(timerLatency - 1); + c1.getTimeTravel().addCurrentTimeMillis(timerLatency - 1); + assertGroupCount(c0, contactId1From0, 1, 0); + assertEquals(1, getMessageHeaders(c0, contactId1From0).size()); + assertGroupCount(c1, contactId0From1, 1, 1); + assertEquals(1, getMessageHeaders(c1, contactId0From1).size()); + + // When 0's timer has elapsed, the message should be deleted from 0's + // view of the conversation but 1 should still see the message + ConversationMessagesDeletedEvent event = + assertEvent(c0, ConversationMessagesDeletedEvent.class, + () -> c0.getTimeTravel().addCurrentTimeMillis(1) + ); + c1.getTimeTravel().addCurrentTimeMillis(1); + // assert that the proper event got broadcast + assertEquals(contactId1From0, event.getContactId()); + + assertGroupCount(c0, contactId1From0, 0, 0); + assertEquals(0, getMessageHeaders(c0, contactId1From0).size()); + assertGroupCount(c1, contactId0From1, 1, 1); + assertEquals(1, getMessageHeaders(c1, contactId0From1).size()); + + // 1 marks the message as read - this starts 1's timer + final MessageId messageId0 = + getMessageHeaders(c1, contactId0From1).get(0).getId(); + markMessageRead(c1, contact0From1, messageId0); + assertGroupCount(c1, contactId0From1, 1, 0); + + // Before 1's timer elapses, 1 should still see the message + c0.getTimeTravel().addCurrentTimeMillis(timerLatency - 1); + c1.getTimeTravel().addCurrentTimeMillis(timerLatency - 1); + assertGroupCount(c0, contactId1From0, 0, 0); + assertEquals(0, getMessageHeaders(c0, contactId1From0).size()); + assertGroupCount(c1, contactId0From1, 1, 0); + assertEquals(1, getMessageHeaders(c1, contactId0From1).size()); + + // When 1's timer has elapsed, the message should be deleted from 1's + // view of the conversation and the invitation auto-declined + c0.getTimeTravel().addCurrentTimeMillis(1); + ConversationMessageReceivedEvent e = + assertEvent(c1, getResponseReceivedEventClass(), + () -> c1.getTimeTravel().addCurrentTimeMillis(1) + ); + // assert that the proper event got broadcast + assertEquals(contactId0From1, e.getContactId()); + + assertGroupCount(c0, contactId1From0, 0, 0); + assertEquals(0, getMessageHeaders(c0, contactId1From0).size()); + assertGroupCount(c1, contactId0From1, 1, 0); + forEachHeader(c1, contactId0From1, 1, h -> { + // The only message is not the same as before, but declined response + assertNotEquals(messageId0, h.getId()); + assertTrue(h instanceof InvitationResponse); + assertEquals(h.getId(), e.getMessageHeader().getId()); + assertFalse(((InvitationResponse) h).wasAccepted()); + assertTrue(((InvitationResponse) h).isAutoDecline()); + // The auto-decline message should have the expected timer + assertEquals(MIN_AUTO_DELETE_TIMER_MS, + h.getAutoDeleteTimer()); + }); + + // Sync the auto-decline message to 0 + sync1To0(1, true); + // Sync the ack to 1 - this starts 1's timer + ack0To1(1); + waitForEvents(c1); + + // 0 can invite 1 again + assertTrue(getSharingManager0() + .canBeShared(getShareable().getId(), contact1From0)); + + // Before 1's timer elapses, 1 should still see the auto-decline message + c0.getTimeTravel().addCurrentTimeMillis(timerLatency - 1); + c1.getTimeTravel().addCurrentTimeMillis(timerLatency - 1); + assertGroupCount(c0, contactId1From0, 1, 1); + assertEquals(1, getMessageHeaders(c0, contactId1From0).size()); + assertGroupCount(c1, contactId0From1, 1, 0); + assertEquals(1, getMessageHeaders(c1, contactId0From1).size()); + // When 1's timer has elapsed, the auto-decline message should be + // deleted from 1's view of the conversation + c0.getTimeTravel().addCurrentTimeMillis(1); + c1.getTimeTravel().addCurrentTimeMillis(1); + assertGroupCount(c0, contactId1From0, 1, 1); + assertEquals(1, getMessageHeaders(c0, contactId1From0).size()); + assertGroupCount(c1, contactId0From1, 0, 0); + assertEquals(0, getMessageHeaders(c1, contactId0From1).size()); + + // 0 marks the message as read - this starts 0's timer + MessageId messageId1 = + getMessageHeaders(c0, contactId1From0).get(0).getId(); + markMessageRead(c0, contact1From0, messageId1); + assertGroupCount(c0, contactId1From0, 1, 0); + + // Before 0's timer elapses, 0 should still see the message + c0.getTimeTravel().addCurrentTimeMillis(timerLatency - 1); + assertGroupCount(c0, contactId1From0, 1, 0); + assertEquals(1, getMessageHeaders(c0, contactId1From0).size()); + + // When 0's timer has elapsed, the message should be deleted from 0's + // view of the conversation + c0.getTimeTravel().addCurrentTimeMillis(1); + assertGroupCount(c0, contactId1From0, 0, 0); + assertEquals(0, getMessageHeaders(c0, contactId1From0).size()); + + // 0 can invite 1 again and really does invite + assertTrue(getSharingManager0() + .canBeShared(getShareable().getId(), contact1From0)); + // Send invitation + getSharingManager0() + .sendInvitation(getShareable().getId(), contactId1From0, + "This shareable, please be quick!"); + sync0To1(1, true); + assertGroupCount(c1, contactId0From1, 1, 1); + } + + protected void testRespondAfterSenderDeletedInvitation() throws Exception { + setAutoDeleteTimer(c0, contactId1From0, MIN_AUTO_DELETE_TIMER_MS); + + assertTrue(subscriptions0().contains(getShareable())); + assertFalse(subscriptions1().contains(getShareable())); + // what we expect after 1 accepts + int expectedSubscriptions1 = subscriptions1().size() + 1; + + getSharingManager0().sendInvitation( + getShareable().getId(), contactId1From0, "This shareable!"); + + sync0To1(1, true); + // 0's timer starts when it gets the ACK of the invitation + ack1To0(1); + waitForEvents(c0); + assertGroupCount(c1, contactId0From1, 1, 1); + + // When 0's timer has elapsed, the message should be deleted from 0's + // view of the conversation but 1 should still see the message + long timerLatency = MIN_AUTO_DELETE_TIMER_MS + BATCH_DELAY_MS; + c0.getTimeTravel().addCurrentTimeMillis(timerLatency); + c1.getTimeTravel().addCurrentTimeMillis(timerLatency); + assertGroupCount(c0, contactId1From0, 0, 0); + assertEquals(0, getMessageHeaders(c0, contactId1From0).size()); + assertGroupCount(c1, contactId0From1, 1, 1); + assertEquals(1, getMessageHeaders(c1, contactId0From1).size()); + + // 1 marks as read, timer starting + markMessageRead(c1, contact0From1, + getMessageHeaders(c1, contactId0From1).get(0).getId()); + assertGroupCount(c1, contactId0From1, 1, 0); + + // 1 accepts the invitation that 0 has already deleted + assertEquals(1, getSharingManager1().getInvitations().size()); + SharingInvitationItem invitation = + getSharingManager1().getInvitations().iterator().next(); + assertEquals(getShareable(), invitation.getShareable()); + Contact c = contactManager1.getContact(contactId0From1); + if (getShareable() instanceof Blog) { + //noinspection unchecked + ((SharingManager) getSharingManager1()).respondToInvitation( + (Blog) getShareable(), c, true); + } else if (getShareable() instanceof Forum) { + //noinspection unchecked + ((SharingManager) getSharingManager1()).respondToInvitation( + (Forum) getShareable(), c, true); + } else { + fail(); + } + + // Sync the invitation response message to 0 + sync1To0(1, true); + // 1's timer starts when it gets the ACK + ack0To1(1); + waitForEvents(c1); + assertGroupCount(c0, contactId1From0, 1, 1); + assertGroupCount(c1, contactId0From1, 2, 0); + + // 0 marks as read, timer starting + markMessageRead(c0, contact1From0, + getMessageHeaders(c0, contactId1From0).get(0).getId()); + assertGroupCount(c0, contactId1From0, 1, 0); + assertGroupCount(c1, contactId0From1, 2, 0); + + // ensure accept message (invitation response) is linking to shareable + InvitationResponse acceptMessage = (InvitationResponse) + getMessageHeaders(c1, contactId0From1).get(1); + assertEquals(acceptMessage.getShareableId(), + ((BaseGroup) getShareable()).getId()); + + // both peers delete all messages after their timers expire + c0.getTimeTravel().addCurrentTimeMillis(timerLatency); + c1.getTimeTravel().addCurrentTimeMillis(timerLatency); + assertGroupCount(c0, contactId1From0, 0, 0); + assertEquals(0, getMessageHeaders(c0, contactId1From0).size()); + assertGroupCount(c1, contactId0From1, 0, 0); + assertEquals(0, getMessageHeaders(c1, contactId0From1).size()); + + // there are no invitations hanging around + assertEquals(0, getSharingManager0().getInvitations().size()); + assertEquals(0, getSharingManager1().getInvitations().size()); + + assertEquals(expectedSubscriptions1, subscriptions1().size()); + } +} diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/AutoDeleteBlogIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/AutoDeleteBlogIntegrationTest.java new file mode 100644 index 000000000..0dcc7c450 --- /dev/null +++ b/briar-core/src/test/java/org/briarproject/briar/sharing/AutoDeleteBlogIntegrationTest.java @@ -0,0 +1,87 @@ +package org.briarproject.briar.sharing; + +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.briar.api.blog.Blog; +import org.briarproject.briar.api.blog.BlogManager; +import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent; +import org.briarproject.briar.api.conversation.ConversationManager; +import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent; +import org.briarproject.briar.api.sharing.InvitationResponse; +import org.briarproject.briar.api.sharing.Shareable; +import org.briarproject.briar.api.sharing.SharingManager; +import org.briarproject.briar.test.BriarIntegrationTestComponent; +import org.junit.Before; +import org.junit.Test; + +import java.util.Collection; + +public class AutoDeleteBlogIntegrationTest + extends AbstractAutoDeleteIntegrationTest { + + private SharingManager sharingManager0; + private SharingManager sharingManager1; + private Blog shareable; + private BlogManager manager0; + private BlogManager manager1; + private Class + responseReceivedEventClass; + + @Before + @Override + public void setUp() throws Exception { + super.setUp(); + manager0 = c0.getBlogManager(); + manager1 = c1.getBlogManager(); + // personalBlog(author0) is already shared with c1 + shareable = manager0.getPersonalBlog(author2); + sharingManager0 = c0.getBlogSharingManager(); + sharingManager1 = c1.getBlogSharingManager(); + responseReceivedEventClass = BlogInvitationResponseReceivedEvent.class; + } + + @Override + protected ConversationManager.ConversationClient getConversationClient( + BriarIntegrationTestComponent component) { + return component.getBlogSharingManager(); + } + + @Override + protected SharingManager getSharingManager0() { + return sharingManager0; + } + + @Override + protected SharingManager getSharingManager1() { + return sharingManager1; + } + + @Override + protected Shareable getShareable() { + return shareable; + } + + @Override + protected Collection subscriptions0() throws DbException { + return manager0.getBlogs(); + } + + @Override + protected Collection subscriptions1() throws DbException { + return manager1.getBlogs(); + } + + @Override + protected Class> getResponseReceivedEventClass() { + return responseReceivedEventClass; + } + + @Test + public void testAutoDeclinedBlogSharing() throws Exception { + testAutoDeclinedSharing(); + } + + @Test + public void testRespondAfterSenderDeletedBlogInvitation() throws Exception { + testRespondAfterSenderDeletedInvitation(); + } +} diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/AutoDeleteForumIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/AutoDeleteForumIntegrationTest.java new file mode 100644 index 000000000..b5f87e79f --- /dev/null +++ b/briar-core/src/test/java/org/briarproject/briar/sharing/AutoDeleteForumIntegrationTest.java @@ -0,0 +1,87 @@ +package org.briarproject.briar.sharing; + +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.briar.api.conversation.ConversationManager; +import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent; +import org.briarproject.briar.api.forum.Forum; +import org.briarproject.briar.api.forum.ForumManager; +import org.briarproject.briar.api.forum.event.ForumInvitationResponseReceivedEvent; +import org.briarproject.briar.api.sharing.InvitationResponse; +import org.briarproject.briar.api.sharing.Shareable; +import org.briarproject.briar.api.sharing.SharingManager; +import org.briarproject.briar.test.BriarIntegrationTestComponent; +import org.junit.Before; +import org.junit.Test; + +import java.util.Collection; + +public class AutoDeleteForumIntegrationTest + extends AbstractAutoDeleteIntegrationTest { + + private SharingManager sharingManager0; + private SharingManager sharingManager1; + protected Forum shareable; + private ForumManager manager0; + private ForumManager manager1; + protected Class + responseReceivedEventClass; + + @Before + @Override + public void setUp() throws Exception { + super.setUp(); + manager0 = c0.getForumManager(); + manager1 = c1.getForumManager(); + shareable = manager0.addForum("Test Forum"); + sharingManager0 = c0.getForumSharingManager(); + sharingManager1 = c1.getForumSharingManager(); + responseReceivedEventClass = ForumInvitationResponseReceivedEvent.class; + } + + @Override + protected ConversationManager.ConversationClient getConversationClient( + BriarIntegrationTestComponent component) { + return component.getForumSharingManager(); + } + + @Override + protected SharingManager getSharingManager0() { + return sharingManager0; + } + + @Override + protected SharingManager getSharingManager1() { + return sharingManager1; + } + + @Override + protected Shareable getShareable() { + return shareable; + } + + @Override + protected Collection subscriptions0() throws DbException { + return manager0.getForums(); + } + + @Override + protected Collection subscriptions1() throws DbException { + return manager1.getForums(); + } + + @Override + protected Class> getResponseReceivedEventClass() { + return responseReceivedEventClass; + } + + @Test + public void testAutoDeclinedForumSharing() throws Exception { + testAutoDeclinedSharing(); + } + + @Test + public void testRespondAfterSenderDeletedForumInvitation() + throws Exception { + testRespondAfterSenderDeletedInvitation(); + } +} diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/SharingValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/SharingValidatorTest.java index 11eb4a603..c24f0c071 100644 --- a/briar-core/src/test/java/org/briarproject/briar/sharing/SharingValidatorTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/sharing/SharingValidatorTest.java @@ -210,7 +210,7 @@ public abstract class SharingValidatorTest extends ValidatorTestCase { void expectEncodeMetadata(MessageType type, long autoDeleteTimer) { context.checking(new Expectations() {{ oneOf(messageEncoder).encodeMetadata(type, groupId, timestamp, - false, false, false, false, false, autoDeleteTimer); + false, false, false, false, false, autoDeleteTimer, false); will(returnValue(meta)); }}); }