Remember when invitation was auto-declined due to deletion

And render differently
This commit is contained in:
Daniel Lublin
2021-03-05 09:47:37 +01:00
parent 9d1c49c6b6
commit 144bd7bf1d
20 changed files with 122 additions and 54 deletions

View File

@@ -102,6 +102,10 @@ class ConversationVisitor implements
text = ctx.getString( text = ctx.getString(
R.string.blogs_sharing_response_accepted_sent, R.string.blogs_sharing_response_accepted_sent,
contactName.getValue()); contactName.getValue());
} else if (r.isAutoDecline()) {
text = ctx.getString(
R.string.blogs_sharing_response_declined_auto,
contactName.getValue());
} else { } else {
text = ctx.getString( text = ctx.getString(
R.string.blogs_sharing_response_declined_sent, R.string.blogs_sharing_response_declined_sent,
@@ -155,6 +159,10 @@ class ConversationVisitor implements
text = ctx.getString( text = ctx.getString(
R.string.forum_invitation_response_accepted_sent, R.string.forum_invitation_response_accepted_sent,
contactName.getValue()); contactName.getValue());
} else if (r.isAutoDecline()) {
text = ctx.getString(
R.string.forum_invitation_response_declined_auto,
contactName.getValue());
} else { } else {
text = ctx.getString( text = ctx.getString(
R.string.forum_invitation_response_declined_sent, R.string.forum_invitation_response_declined_sent,

View File

@@ -419,6 +419,7 @@
<string name="forum_invitation_already_sharing">Already sharing</string> <string name="forum_invitation_already_sharing">Already sharing</string>
<string name="forum_invitation_response_accepted_sent">You accepted the forum invitation from %s.</string> <string name="forum_invitation_response_accepted_sent">You accepted the forum invitation from %s.</string>
<string name="forum_invitation_response_declined_sent">You declined the forum invitation from %s.</string> <string name="forum_invitation_response_declined_sent">You declined the forum invitation from %s.</string>
<string name="forum_invitation_response_declined_auto">The forum invitation from %s was automatically declined.</string>
<string name="forum_invitation_response_accepted_received">%s accepted the forum invitation.</string> <string name="forum_invitation_response_accepted_received">%s accepted the forum invitation.</string>
<string name="forum_invitation_response_declined_received">%s declined the forum invitation.</string> <string name="forum_invitation_response_declined_received">%s declined the forum invitation.</string>
@@ -456,6 +457,7 @@
<string name="blogs_sharing_snackbar">Blog shared with chosen contacts</string> <string name="blogs_sharing_snackbar">Blog shared with chosen contacts</string>
<string name="blogs_sharing_response_accepted_sent">You accepted the blog invitation from %s.</string> <string name="blogs_sharing_response_accepted_sent">You accepted the blog invitation from %s.</string>
<string name="blogs_sharing_response_declined_sent">You declined the blog invitation from %s.</string> <string name="blogs_sharing_response_declined_sent">You declined the blog invitation from %s.</string>
<string name="blogs_sharing_response_declined_auto">The blog invitation from %s was automatically declined.</string>
<string name="blogs_sharing_response_accepted_received">%s accepted the blog invitation.</string> <string name="blogs_sharing_response_accepted_received">%s accepted the blog invitation.</string>
<string name="blogs_sharing_response_declined_received">%s declined the blog invitation.</string> <string name="blogs_sharing_response_declined_received">%s declined the blog invitation.</string>
<string name="blogs_sharing_invitation_received">%1$s has shared the blog \"%2$s\" with you.</string> <string name="blogs_sharing_invitation_received">%1$s has shared the blog \"%2$s\" with you.</string>

View File

@@ -13,9 +13,9 @@ public class BlogInvitationResponse extends InvitationResponse {
public BlogInvitationResponse(MessageId id, GroupId groupId, long time, public BlogInvitationResponse(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen, boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, boolean accept, GroupId shareableId, SessionId sessionId, boolean accept, GroupId shareableId,
long autoDeleteTimer) { long autoDeleteTimer, boolean isAutoDecline) {
super(id, groupId, time, local, read, sent, seen, sessionId, super(id, groupId, time, local, read, sent, seen, sessionId,
accept, shareableId, autoDeleteTimer, false); accept, shareableId, autoDeleteTimer, isAutoDecline);
} }
@Override @Override

View File

@@ -16,9 +16,9 @@ public class ForumInvitationResponse extends InvitationResponse {
public ForumInvitationResponse(MessageId id, GroupId groupId, long time, public ForumInvitationResponse(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen, boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, boolean accept, GroupId shareableId, SessionId sessionId, boolean accept, GroupId shareableId,
long autoDeleteTimer) { long autoDeleteTimer, boolean isAutoDecline) {
super(id, groupId, time, local, read, sent, seen, sessionId, super(id, groupId, time, local, read, sent, seen, sessionId,
accept, shareableId, autoDeleteTimer, false); accept, shareableId, autoDeleteTimer, isAutoDecline);
} }
@Override @Override

View File

@@ -33,11 +33,11 @@ public class BlogInvitationFactoryImpl
public BlogInvitationResponse createInvitationResponse(MessageId id, public BlogInvitationResponse createInvitationResponse(MessageId id,
GroupId contactGroupId, long time, boolean local, boolean sent, GroupId contactGroupId, long time, boolean local, boolean sent,
boolean seen, boolean read, boolean accept, GroupId shareableId, boolean seen, boolean read, boolean accept, GroupId shareableId,
long autoDeleteTimer) { long autoDeleteTimer, boolean isAutoDecline) {
SessionId sessionId = new SessionId(shareableId.getBytes()); SessionId sessionId = new SessionId(shareableId.getBytes());
return new BlogInvitationResponse(id, contactGroupId, time, local, read, return new BlogInvitationResponse(id, contactGroupId, time, local, read,
sent, seen, sessionId, accept, shareableId, sent, seen, sessionId, accept, shareableId,
autoDeleteTimer); autoDeleteTimer, isAutoDecline);
} }
} }

View File

@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; 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.sync.MessageId;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.versioning.ClientVersioningManager; import org.briarproject.bramble.api.versioning.ClientVersioningManager;
@@ -71,7 +72,8 @@ class BlogProtocolEngineImpl extends ProtocolEngineImpl<Blog> {
BlogInvitationResponse response = invitationFactory BlogInvitationResponse response = invitationFactory
.createInvitationResponse(m.getId(), m.getContactGroupId(), .createInvitationResponse(m.getId(), m.getContactGroupId(),
m.getTimestamp(), false, false, false, false, m.getTimestamp(), false, false, false, false,
true, m.getShareableId(), m.getAutoDeleteTimer()); true, m.getShareableId(), m.getAutoDeleteTimer(),
false);
return new BlogInvitationResponseReceivedEvent(response, contactId); return new BlogInvitationResponseReceivedEvent(response, contactId);
} }
@@ -81,7 +83,18 @@ class BlogProtocolEngineImpl extends ProtocolEngineImpl<Blog> {
BlogInvitationResponse response = invitationFactory BlogInvitationResponse response = invitationFactory
.createInvitationResponse(m.getId(), m.getContactGroupId(), .createInvitationResponse(m.getId(), m.getContactGroupId(),
m.getTimestamp(), false, false, false, false, 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); return new BlogInvitationResponseReceivedEvent(response, contactId);
} }

View File

@@ -33,11 +33,11 @@ public class ForumInvitationFactoryImpl
public ForumInvitationResponse createInvitationResponse(MessageId id, public ForumInvitationResponse createInvitationResponse(MessageId id,
GroupId contactGroupId, long time, boolean local, boolean sent, GroupId contactGroupId, long time, boolean local, boolean sent,
boolean seen, boolean read, boolean accept, GroupId shareableId, boolean seen, boolean read, boolean accept, GroupId shareableId,
long autoDeleteTimer) { long autoDeleteTimer, boolean isAutoDecline) {
SessionId sessionId = new SessionId(shareableId.getBytes()); SessionId sessionId = new SessionId(shareableId.getBytes());
return new ForumInvitationResponse(id, contactGroupId, time, local, return new ForumInvitationResponse(id, contactGroupId, time, local,
read, sent, seen, sessionId, accept, shareableId, read, sent, seen, sessionId, accept, shareableId,
autoDeleteTimer); autoDeleteTimer, isAutoDecline);
} }
} }

View File

@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; 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.sync.MessageId;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.versioning.ClientVersioningManager; import org.briarproject.bramble.api.versioning.ClientVersioningManager;
@@ -71,7 +72,8 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
ForumInvitationResponse response = invitationFactory ForumInvitationResponse response = invitationFactory
.createInvitationResponse(m.getId(), m.getContactGroupId(), .createInvitationResponse(m.getId(), m.getContactGroupId(),
m.getTimestamp(), false, false, true, false, m.getTimestamp(), false, false, true, false,
true, m.getShareableId(), m.getAutoDeleteTimer()); true, m.getShareableId(), m.getAutoDeleteTimer(),
false);
return new ForumInvitationResponseReceivedEvent(response, contactId); return new ForumInvitationResponseReceivedEvent(response, contactId);
} }
@@ -81,7 +83,18 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
ForumInvitationResponse response = invitationFactory ForumInvitationResponse response = invitationFactory
.createInvitationResponse(m.getId(), m.getContactGroupId(), .createInvitationResponse(m.getId(), m.getContactGroupId(),
m.getTimestamp(), false, false, true, false, 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); return new ForumInvitationResponseReceivedEvent(response, contactId);
} }

View File

@@ -15,6 +15,7 @@ public interface InvitationFactory<S extends Shareable, R extends InvitationResp
R createInvitationResponse(MessageId id, GroupId contactGroupId, long time, R createInvitationResponse(MessageId id, GroupId contactGroupId, long time,
boolean local, boolean sent, boolean seen, boolean read, boolean local, boolean sent, boolean seen, boolean read,
boolean accept, GroupId shareableId, long autoDeleteTimer); boolean accept, GroupId shareableId, long autoDeleteTimer,
boolean isAutoDecline);
} }

View File

@@ -14,7 +14,8 @@ interface MessageEncoder {
BdfDictionary encodeMetadata(MessageType type, GroupId shareableId, BdfDictionary encodeMetadata(MessageType type, GroupId shareableId,
long timestamp, boolean local, boolean read, boolean visible, long timestamp, boolean local, boolean read, boolean visible,
boolean available, boolean accepted, long autoDeleteTimer); boolean available, boolean accepted, long autoDeleteTimer,
boolean isAutoDecline);
void setVisibleInUi(BdfDictionary meta, boolean visible); void setVisibleInUi(BdfDictionary meta, boolean visible);

View File

@@ -23,6 +23,7 @@ import static org.briarproject.briar.sharing.MessageType.LEAVE;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_AUTO_DELETE_TIMER; 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_AVAILABLE_TO_ANSWER;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_INVITATION_ACCEPTED; 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_LOCAL;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_MESSAGE_TYPE; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_MESSAGE_TYPE;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_READ; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_READ;
@@ -48,7 +49,7 @@ class MessageEncoderImpl implements MessageEncoder {
public BdfDictionary encodeMetadata(MessageType type, public BdfDictionary encodeMetadata(MessageType type,
GroupId shareableId, long timestamp, boolean local, boolean read, GroupId shareableId, long timestamp, boolean local, boolean read,
boolean visible, boolean available, boolean accepted, boolean visible, boolean available, boolean accepted,
long autoDeleteTimer) { long autoDeleteTimer, boolean isAutoDecline) {
BdfDictionary meta = new BdfDictionary(); BdfDictionary meta = new BdfDictionary();
meta.put(MSG_KEY_MESSAGE_TYPE, type.getValue()); meta.put(MSG_KEY_MESSAGE_TYPE, type.getValue());
meta.put(MSG_KEY_SHAREABLE_ID, shareableId); meta.put(MSG_KEY_SHAREABLE_ID, shareableId);
@@ -61,6 +62,9 @@ class MessageEncoderImpl implements MessageEncoder {
if (autoDeleteTimer != NO_AUTO_DELETE_TIMER) { if (autoDeleteTimer != NO_AUTO_DELETE_TIMER) {
meta.put(MSG_KEY_AUTO_DELETE_TIMER, autoDeleteTimer); meta.put(MSG_KEY_AUTO_DELETE_TIMER, autoDeleteTimer);
} }
if (isAutoDecline) {
meta.put(MSG_KEY_IS_AUTO_DECLINE, isAutoDecline);
}
return meta; return meta;
} }

View File

@@ -13,10 +13,11 @@ class MessageMetadata {
private final GroupId shareableId; private final GroupId shareableId;
private final long timestamp, autoDeleteTimer; private final long timestamp, autoDeleteTimer;
private final boolean local, read, visible, available, accepted; private final boolean local, read, visible, available, accepted;
private final boolean isAutoDecline;
MessageMetadata(MessageType type, GroupId shareableId, long timestamp, MessageMetadata(MessageType type, GroupId shareableId, long timestamp,
boolean local, boolean read, boolean visible, boolean available, boolean local, boolean read, boolean visible, boolean available,
boolean accepted, long autoDeleteTimer) { boolean accepted, long autoDeleteTimer, boolean isAutoDecline) {
this.shareableId = shareableId; this.shareableId = shareableId;
this.type = type; this.type = type;
this.timestamp = timestamp; this.timestamp = timestamp;
@@ -26,6 +27,7 @@ class MessageMetadata {
this.available = available; this.available = available;
this.accepted = accepted; this.accepted = accepted;
this.autoDeleteTimer = autoDeleteTimer; this.autoDeleteTimer = autoDeleteTimer;
this.isAutoDecline = isAutoDecline;
} }
MessageType getMessageType() { MessageType getMessageType() {
@@ -58,7 +60,7 @@ class MessageMetadata {
/** /**
* Returns true if the invitation was accepted. * Returns true if the invitation was accepted.
* * <p>
* Only applies to messages of type INVITE. * Only applies to messages of type INVITE.
*/ */
public boolean wasAccepted() { public boolean wasAccepted() {
@@ -68,4 +70,8 @@ class MessageMetadata {
public long getAutoDeleteTimer() { public long getAutoDeleteTimer() {
return autoDeleteTimer; return autoDeleteTimer;
} }
public boolean isAutoDecline() {
return isAutoDecline;
}
} }

View File

@@ -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_AUTO_DELETE_TIMER;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_AVAILABLE_TO_ANSWER; 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_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_LOCAL;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_MESSAGE_TYPE; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_MESSAGE_TYPE;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_READ; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_READ;
@@ -74,8 +75,9 @@ abstract class MessageParserImpl<S extends Shareable>
boolean accepted = meta.getBoolean(MSG_KEY_INVITATION_ACCEPTED, false); boolean accepted = meta.getBoolean(MSG_KEY_INVITATION_ACCEPTED, false);
long timer = meta.getLong(MSG_KEY_AUTO_DELETE_TIMER, long timer = meta.getLong(MSG_KEY_AUTO_DELETE_TIMER,
NO_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, return new MessageMetadata(type, shareableId, timestamp, local, read,
visible, available, accepted, timer); visible, available, accepted, timer, isAutoDecline);
} }
@Override @Override

View File

@@ -16,8 +16,8 @@ interface ProtocolEngine<S extends Shareable> {
Session onAcceptAction(Transaction txn, Session session) throws DbException; Session onAcceptAction(Transaction txn, Session session) throws DbException;
Session onDeclineAction(Transaction txn, Session session) Session onDeclineAction(Transaction txn, Session session,
throws DbException; boolean isAutoDecline) throws DbException;
Session onLeaveAction(Transaction txn, Session session) throws DbException; Session onLeaveAction(Transaction txn, Session session) throws DbException;

View File

@@ -235,11 +235,11 @@ abstract class ProtocolEngineImpl<S extends Shareable>
} }
@Override @Override
public Session onDeclineAction(Transaction txn, Session s) public Session onDeclineAction(Transaction txn, Session s,
throws DbException { boolean isAutoDecline) throws DbException {
switch (s.getState()) { switch (s.getState()) {
case LOCAL_INVITED: case LOCAL_INVITED:
return onLocalDecline(txn, s); return onLocalDecline(txn, s, isAutoDecline);
case START: case START:
case REMOTE_INVITED: case REMOTE_INVITED:
case SHARING: case SHARING:
@@ -251,14 +251,14 @@ abstract class ProtocolEngineImpl<S extends Shareable>
} }
} }
private Session onLocalDecline(Transaction txn, Session s) private Session onLocalDecline(Transaction txn, Session s,
throws DbException { boolean isAutoDecline) throws DbException {
// Mark the invite message unavailable to answer // Mark the invite message unavailable to answer
MessageId inviteId = s.getLastRemoteMessageId(); MessageId inviteId = s.getLastRemoteMessageId();
if (inviteId == null) throw new IllegalStateException(); if (inviteId == null) throw new IllegalStateException();
markMessageAvailableToAnswer(txn, inviteId, false); markMessageAvailableToAnswer(txn, inviteId, false);
// Send a DECLINE message // Send a DECLINE message
Message sent = sendDeclineMessage(txn, s); Message sent = sendDeclineMessage(txn, s, isAutoDecline);
// Track the message // Track the message
messageTracker.trackOutgoingMessage(txn, sent); messageTracker.trackOutgoingMessage(txn, sent);
// Move to the START state // Move to the START state
@@ -267,8 +267,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
s.getInviteTimestamp()); s.getInviteTimestamp());
} }
private Message sendDeclineMessage(Transaction txn, Session s) private Message sendDeclineMessage(Transaction txn, Session s,
throws DbException { boolean isAutoDecline) throws DbException {
Message m; Message m;
long localTimestamp = getTimestampForVisibleMessage(txn, s); long localTimestamp = getTimestampForVisibleMessage(txn, s);
ContactId c = getContactId(txn, s.getContactGroupId()); ContactId c = getContactId(txn, s.getContactGroupId());
@@ -278,11 +278,18 @@ abstract class ProtocolEngineImpl<S extends Shareable>
m = messageEncoder.encodeDeclineMessage(s.getContactGroupId(), m = messageEncoder.encodeDeclineMessage(s.getContactGroupId(),
s.getShareableId(), localTimestamp, s.getShareableId(), localTimestamp,
s.getLastLocalMessageId(), timer); 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 // Set the auto-delete timer duration on the local message
if (timer != NO_AUTO_DELETE_TIMER) { if (timer != NO_AUTO_DELETE_TIMER) {
db.setCleanupTimerDuration(txn, m.getId(), 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 { } else {
m = messageEncoder.encodeDeclineMessage(s.getContactGroupId(), m = messageEncoder.encodeDeclineMessage(s.getContactGroupId(),
s.getShareableId(), localTimestamp, s.getShareableId(), localTimestamp,
@@ -293,6 +300,9 @@ abstract class ProtocolEngineImpl<S extends Shareable>
return m; return m;
} }
abstract Event getAutoDeclineInvitationResponseReceivedEvent(Session s,
Message m, ContactId contactId, long timer);
@Override @Override
public Session onLeaveAction(Transaction txn, Session s) public Session onLeaveAction(Transaction txn, Session s)
throws DbException { throws DbException {
@@ -406,8 +416,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
// Broadcast an event // Broadcast an event
ContactId contactId = ContactId contactId =
clientHelper.getContactId(txn, s.getContactGroupId()); clientHelper.getContactId(txn, s.getContactGroupId());
txn.attach( txn.attach(getInvitationRequestReceivedEvent(m, contactId, false,
getInvitationRequestReceivedEvent(m, contactId, false, true)); true));
// Move to the next state // Move to the next state
return new Session(SHARING, s.getContactGroupId(), s.getShareableId(), return new Session(SHARING, s.getContactGroupId(), s.getShareableId(),
s.getLastLocalMessageId(), m.getId(), s.getLocalTimestamp(), s.getLastLocalMessageId(), m.getId(), s.getLocalTimestamp(),
@@ -648,9 +658,16 @@ abstract class ProtocolEngineImpl<S extends Shareable>
private void sendMessage(Transaction txn, Message m, MessageType type, private void sendMessage(Transaction txn, Message m, MessageType type,
GroupId shareableId, boolean visibleInConversation, GroupId shareableId, boolean visibleInConversation,
long autoDeleteTimer) throws DbException { 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, BdfDictionary meta = messageEncoder.encodeMetadata(type, shareableId,
m.getTimestamp(), true, true, visibleInConversation, false, m.getTimestamp(), true, true, visibleInConversation, false,
false, autoDeleteTimer); false, autoDeleteTimer, isAutoDecline);
try { try {
clientHelper.addLocalMessage(txn, m, meta, true, false); clientHelper.addLocalMessage(txn, m, meta, true, false);
} catch (FormatException e) { } catch (FormatException e) {

View File

@@ -14,6 +14,7 @@ interface SharingConstants {
String MSG_KEY_AVAILABLE_TO_ANSWER = "availableToAnswer"; String MSG_KEY_AVAILABLE_TO_ANSWER = "availableToAnswer";
String MSG_KEY_INVITATION_ACCEPTED = "invitationAccepted"; String MSG_KEY_INVITATION_ACCEPTED = "invitationAccepted";
String MSG_KEY_AUTO_DELETE_TIMER = "autoDeleteTimer"; String MSG_KEY_AUTO_DELETE_TIMER = "autoDeleteTimer";
String MSG_KEY_IS_AUTO_DECLINE = "isAutoDecline";
// Session keys // Session keys
String SESSION_KEY_IS_SESSION = "isSession"; String SESSION_KEY_IS_SESSION = "isSession";

View File

@@ -302,11 +302,13 @@ abstract class SharingManagerImpl<S extends Shareable>
@Override @Override
public void respondToInvitation(ContactId c, SessionId id, boolean accept) public void respondToInvitation(ContactId c, SessionId id, boolean accept)
throws DbException { throws DbException {
db.transaction(false, txn -> respondToInvitation(txn, c, id, accept)); db.transaction(false,
txn -> respondToInvitation(txn, c, id, accept, false));
} }
private void respondToInvitation(Transaction txn, ContactId c, private void respondToInvitation(Transaction txn, ContactId c,
SessionId id, boolean accept) throws DbException { SessionId id, boolean accept, boolean isAutoDecline)
throws DbException {
try { try {
// Look up the session // Look up the session
Contact contact = db.getContact(txn, c); Contact contact = db.getContact(txn, c);
@@ -318,7 +320,7 @@ abstract class SharingManagerImpl<S extends Shareable>
sessionParser.parseSession(contactGroupId, ss.bdfSession); sessionParser.parseSession(contactGroupId, ss.bdfSession);
// Handle the accept or decline action // Handle the accept or decline action
if (accept) session = engine.onAcceptAction(txn, session); if (accept) session = engine.onAcceptAction(txn, session);
else session = engine.onDeclineAction(txn, session); else session = engine.onDeclineAction(txn, session, isAutoDecline);
// Store the updated session // Store the updated session
storeSession(txn, ss.storageId, session); storeSession(txn, ss.storageId, session);
} catch (FormatException e) { } catch (FormatException e) {
@@ -381,7 +383,7 @@ abstract class SharingManagerImpl<S extends Shareable>
return invitationFactory.createInvitationResponse(m, contactGroupId, return invitationFactory.createInvitationResponse(m, contactGroupId,
meta.getTimestamp(), meta.isLocal(), status.isSent(), meta.getTimestamp(), meta.isLocal(), status.isSent(),
status.isSeen(), meta.isRead(), accept, meta.getShareableId(), status.isSeen(), meta.isRead(), accept, meta.getShareableId(),
meta.getAutoDeleteTimer()); meta.getAutoDeleteTimer(), meta.isAutoDecline());
} }
@Override @Override
@@ -583,7 +585,6 @@ abstract class SharingManagerImpl<S extends Shareable>
}, messageId -> false); }, messageId -> false);
} }
@Override @Override
public DeletionResult deleteMessages(Transaction txn, ContactId c, public DeletionResult deleteMessages(Transaction txn, ContactId c,
Set<MessageId> messageIds) throws DbException { Set<MessageId> messageIds) throws DbException {
@@ -731,9 +732,10 @@ abstract class SharingManagerImpl<S extends Shareable>
// delete given visible messages in sessions // delete given visible messages in sessions
for (Entry<SessionId, DeletableSession> entry : sessions.entrySet()) { for (Entry<SessionId, DeletableSession> entry : sessions.entrySet()) {
DeletableSession session = entry.getValue(); DeletableSession session = entry.getValue();
// first decline pending shareable we're invited to // first decline pending invitation to shareable
if (session.state == LOCAL_INVITED) { if (session.state == LOCAL_INVITED) {
respondToInvitation(txn, c, entry.getKey(), false); // marked as autoDecline
respondToInvitation(txn, c, entry.getKey(), false, true);
} }
for (MessageId m : session.messages) { for (MessageId m : session.messages) {
db.deleteMessage(txn, m); db.deleteMessage(txn, m);

View File

@@ -74,7 +74,8 @@ abstract class SharingValidator extends BdfMessageValidator {
} }
BdfDictionary meta = messageEncoder.encodeMetadata(INVITE, shareableId, 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) { if (previousMessageId == null) {
return new BdfMessageContext(meta); return new BdfMessageContext(meta);
} else { } else {
@@ -96,7 +97,7 @@ abstract class SharingValidator extends BdfMessageValidator {
BdfDictionary meta = messageEncoder.encodeMetadata(type, BdfDictionary meta = messageEncoder.encodeMetadata(type,
new GroupId(shareableId), m.getTimestamp(), false, false, 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) { if (previousMessageId == null) {
return new BdfMessageContext(meta); return new BdfMessageContext(meta);
} else { } else {
@@ -123,7 +124,7 @@ abstract class SharingValidator extends BdfMessageValidator {
BdfDictionary meta = messageEncoder.encodeMetadata(type, BdfDictionary meta = messageEncoder.encodeMetadata(type,
new GroupId(shareableId), m.getTimestamp(), false, false, new GroupId(shareableId), m.getTimestamp(), false, false,
false, false, false, timer); false, false, false, timer, false);
if (previousMessageId == null) { if (previousMessageId == null) {
return new BdfMessageContext(meta); return new BdfMessageContext(meta);
} else { } else {

View File

@@ -16,19 +16,17 @@ import static org.junit.Assert.assertTrue;
public abstract class AbstractAutoDeleteIntegrationTest public abstract class AbstractAutoDeleteIntegrationTest
extends AbstractAutoDeleteTest { extends AbstractAutoDeleteTest {
protected SharingManager<?> sharingManager0; protected SharingManager<? extends Shareable> sharingManager0;
protected Shareable shareable; protected Shareable shareable;
protected void testAutoDeclinedSharing(SharingManager<?> sharingManager0, protected void testAutoDeclinedSharing(
SharingManager<? extends Shareable> sharingManager0,
Shareable shareable) throws Exception { Shareable shareable) throws Exception {
setAutoDeleteTimer(c0, contactId1From0, MIN_AUTO_DELETE_TIMER_MS); setAutoDeleteTimer(c0, contactId1From0, MIN_AUTO_DELETE_TIMER_MS);
assertGroupCount(c0, contactId1From0, 1, 0);
// Send invitation // Send invitation
sharingManager0 sharingManager0.sendInvitation(
.sendInvitation(shareable.getId(), contactId1From0, shareable.getId(), contactId1From0, "This shareable!");
"This shareable!");
// The message should have been added to 0's view of the conversation // The message should have been added to 0's view of the conversation
assertGroupCount(c0, contactId1From0, 1, 0); assertGroupCount(c0, contactId1From0, 1, 0);
@@ -99,7 +97,7 @@ public abstract class AbstractAutoDeleteIntegrationTest
assertNotEquals(messageId0, h.getId()); assertNotEquals(messageId0, h.getId());
assertTrue(h instanceof InvitationResponse); assertTrue(h instanceof InvitationResponse);
assertFalse(((InvitationResponse) h).wasAccepted()); assertFalse(((InvitationResponse) h).wasAccepted());
//TODO assertTrue(((InvitationResponse) h).isAutoDecline()); assertTrue(((InvitationResponse) h).isAutoDecline());
// The auto-decline message should have the expected timer // The auto-decline message should have the expected timer
assertEquals(MIN_AUTO_DELETE_TIMER_MS, assertEquals(MIN_AUTO_DELETE_TIMER_MS,
h.getAutoDeleteTimer()); h.getAutoDeleteTimer());
@@ -152,9 +150,8 @@ public abstract class AbstractAutoDeleteIntegrationTest
assertTrue(sharingManager0 assertTrue(sharingManager0
.canBeShared(shareable.getId(), contact1From0)); .canBeShared(shareable.getId(), contact1From0));
// Send invitation // Send invitation
sharingManager0 sharingManager0.sendInvitation(shareable.getId(), contactId1From0,
.sendInvitation(shareable.getId(), contactId1From0, "This shareable, please be quick!");
"This shareable, please be quick!");
sync0To1(1, true); sync0To1(1, true);
assertGroupCount(c1, contactId0From1, 1, 1); assertGroupCount(c1, contactId0From1, 1, 1);
} }

View File

@@ -210,7 +210,7 @@ public abstract class SharingValidatorTest extends ValidatorTestCase {
void expectEncodeMetadata(MessageType type, long autoDeleteTimer) { void expectEncodeMetadata(MessageType type, long autoDeleteTimer) {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(messageEncoder).encodeMetadata(type, groupId, timestamp, oneOf(messageEncoder).encodeMetadata(type, groupId, timestamp,
false, false, false, false, false, autoDeleteTimer); false, false, false, false, false, autoDeleteTimer, false);
will(returnValue(meta)); will(returnValue(meta));
}}); }});
} }