diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/Nameable.java b/bramble-api/src/main/java/org/briarproject/bramble/api/Nameable.java new file mode 100644 index 000000000..8e6ad4981 --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/Nameable.java @@ -0,0 +1,10 @@ +package org.briarproject.bramble.api; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +@NotNullByDefault +public interface Nameable { + + String getName(); + +} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/Author.java b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/Author.java index 8a3682e6c..0df402c28 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/Author.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/Author.java @@ -1,5 +1,6 @@ package org.briarproject.bramble.api.identity; +import org.briarproject.bramble.api.Nameable; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.util.StringUtils; @@ -13,7 +14,7 @@ import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_K */ @Immutable @NotNullByDefault -public class Author { +public class Author implements Nameable { public enum Status { NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java index 561945bca..24295f22f 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java @@ -41,13 +41,9 @@ import org.briarproject.briar.android.util.BriarNotificationBuilder; import org.briarproject.briar.api.android.AndroidNotificationManager; import org.briarproject.briar.api.blog.event.BlogPostAddedEvent; import org.briarproject.briar.api.forum.event.ForumPostReceivedEvent; -import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent; -import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent; import org.briarproject.briar.api.introduction.event.IntroductionSucceededEvent; import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; import org.briarproject.briar.api.privategroup.event.GroupMessageAddedEvent; -import org.briarproject.briar.api.sharing.event.InvitationRequestReceivedEvent; -import org.briarproject.briar.api.sharing.event.InvitationResponseReceivedEvent; import java.util.Set; import java.util.concurrent.Callable; @@ -235,19 +231,6 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, } else if (e instanceof BlogPostAddedEvent) { BlogPostAddedEvent b = (BlogPostAddedEvent) e; showBlogPostNotification(b.getGroupId()); - } else if (e instanceof IntroductionRequestReceivedEvent) { - ContactId c = ((IntroductionRequestReceivedEvent) e).getContactId(); - showContactNotification(c); - } else if (e instanceof IntroductionResponseReceivedEvent) { - ContactId c = - ((IntroductionResponseReceivedEvent) e).getContactId(); - showContactNotification(c); - } else if (e instanceof InvitationRequestReceivedEvent) { - ContactId c = ((InvitationRequestReceivedEvent) e).getContactId(); - showContactNotification(c); - } else if (e instanceof InvitationResponseReceivedEvent) { - ContactId c = ((InvitationResponseReceivedEvent) e).getContactId(); - showContactNotification(c); } else if (e instanceof IntroductionSucceededEvent) { showIntroductionNotification(); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java index 6b29f6f44..1b7058503 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java @@ -21,11 +21,11 @@ import org.briarproject.briar.android.controller.ActivityLifecycleController; import org.briarproject.briar.android.controller.handler.ResultExceptionHandler; import org.briarproject.briar.api.android.AndroidNotificationManager; import org.briarproject.briar.api.blog.Blog; +import org.briarproject.briar.api.blog.BlogInvitationResponse; import org.briarproject.briar.api.blog.BlogManager; import org.briarproject.briar.api.blog.BlogSharingManager; import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent; import org.briarproject.briar.api.blog.event.BlogPostAddedEvent; -import org.briarproject.briar.api.sharing.InvitationResponse; import org.briarproject.briar.api.sharing.event.ContactLeftShareableEvent; import java.util.ArrayList; @@ -107,7 +107,7 @@ class BlogControllerImpl extends BaseControllerImpl } else if (e instanceof BlogInvitationResponseReceivedEvent) { BlogInvitationResponseReceivedEvent b = (BlogInvitationResponseReceivedEvent) e; - InvitationResponse r = b.getResponse(); + BlogInvitationResponse r = b.getMessageHeader(); if (r.getShareableId().equals(groupId) && r.wasAccepted()) { LOG.info("Blog invitation accepted"); onBlogInvitationAccepted(b.getContactId()); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java index 5ab78c73c..a3ca713b8 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java @@ -36,19 +36,10 @@ import org.briarproject.briar.android.fragment.BaseFragment; import org.briarproject.briar.android.keyagreement.ContactExchangeActivity; import org.briarproject.briar.android.view.BriarRecyclerView; import org.briarproject.briar.api.android.AndroidNotificationManager; -import org.briarproject.briar.api.client.BaseMessageHeader; import org.briarproject.briar.api.client.MessageTracker.GroupCount; -import org.briarproject.briar.api.introduction.IntroductionRequest; -import org.briarproject.briar.api.introduction.IntroductionResponse; -import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent; -import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent; import org.briarproject.briar.api.messaging.ConversationManager; import org.briarproject.briar.api.messaging.PrivateMessageHeader; import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; -import org.briarproject.briar.api.sharing.InvitationRequest; -import org.briarproject.briar.api.sharing.InvitationResponse; -import org.briarproject.briar.api.sharing.event.InvitationRequestReceivedEvent; -import org.briarproject.briar.api.sharing.event.InvitationResponseReceivedEvent; import java.util.ArrayList; import java.util.List; @@ -256,40 +247,16 @@ public class ContactListFragment extends BaseFragment implements EventListener { PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e; PrivateMessageHeader h = p.getMessageHeader(); updateItem(p.getContactId(), h); - } else if (e instanceof IntroductionRequestReceivedEvent) { - LOG.info("Introduction request received, updating item"); - IntroductionRequestReceivedEvent m = - (IntroductionRequestReceivedEvent) e; - IntroductionRequest ir = m.getIntroductionRequest(); - updateItem(m.getContactId(), ir); - } else if (e instanceof IntroductionResponseReceivedEvent) { - LOG.info("Introduction response received, updating item"); - IntroductionResponseReceivedEvent m = - (IntroductionResponseReceivedEvent) e; - IntroductionResponse ir = m.getIntroductionResponse(); - updateItem(m.getContactId(), ir); - } else if (e instanceof InvitationRequestReceivedEvent) { - LOG.info("Invitation Request received, update item"); - InvitationRequestReceivedEvent m = - (InvitationRequestReceivedEvent) e; - InvitationRequest ir = m.getRequest(); - updateItem(m.getContactId(), ir); - } else if (e instanceof InvitationResponseReceivedEvent) { - LOG.info("Invitation response received, updating item"); - InvitationResponseReceivedEvent m = - (InvitationResponseReceivedEvent) e; - InvitationResponse ir = m.getResponse(); - updateItem(m.getContactId(), ir); } } - private void updateItem(ContactId c, BaseMessageHeader h) { + private void updateItem(ContactId c, PrivateMessageHeader h) { runOnUiThreadUnlessDestroyed(() -> { adapter.incrementRevision(); int position = adapter.findItemPosition(c); ContactListItem item = adapter.getItemAt(position); if (item != null) { - ConversationItem i = ConversationItem.from(getContext(), h); + ConversationItem i = ConversationItem.from(getContext(), "", h); item.addMessage(i); adapter.updateItemAt(position, item); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java index 38ed62ea7..381cd5f92 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationActivity.java @@ -1,8 +1,11 @@ package org.briarproject.briar.android.contact; +import android.arch.lifecycle.MutableLiveData; +import android.arch.lifecycle.Observer; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; +import android.support.annotation.Nullable; import android.support.annotation.UiThread; import android.support.design.widget.Snackbar; import android.support.v4.content.ContextCompat; @@ -62,24 +65,15 @@ import org.briarproject.briar.api.client.ProtocolStateException; import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.forum.ForumSharingManager; import org.briarproject.briar.api.introduction.IntroductionManager; -import org.briarproject.briar.api.introduction.IntroductionMessage; -import org.briarproject.briar.api.introduction.IntroductionRequest; -import org.briarproject.briar.api.introduction.IntroductionResponse; -import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent; -import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent; +import org.briarproject.briar.api.messaging.ConversationManager; 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.api.messaging.PrivateMessageHeader; +import org.briarproject.briar.api.messaging.PrivateRequest; +import org.briarproject.briar.api.messaging.PrivateResponse; import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager; -import org.briarproject.briar.api.sharing.InvitationMessage; -import org.briarproject.briar.api.sharing.InvitationRequest; -import org.briarproject.briar.api.sharing.InvitationResponse; -import org.briarproject.briar.api.sharing.event.InvitationRequestReceivedEvent; -import org.briarproject.briar.api.sharing.event.InvitationResponseReceivedEvent; -import org.thoughtcrime.securesms.components.util.FutureTaskListener; -import org.thoughtcrime.securesms.components.util.ListenableFutureTask; import java.util.ArrayList; import java.util.Collection; @@ -87,13 +81,10 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Logger; -import javax.annotation.Nullable; import javax.inject.Inject; import de.hdodenhof.circleimageview.CircleImageView; @@ -138,6 +129,7 @@ public class ConversationActivity extends BriarActivity Executor cryptoExecutor; private final Map bodyCache = new ConcurrentHashMap<>(); + private final MutableLiveData contactName = new MutableLiveData<>(); private ConversationAdapter adapter; private Toolbar toolbar; @@ -147,24 +139,14 @@ public class ConversationActivity extends BriarActivity private BriarRecyclerView list; private TextInputView textInputView; - private final ListenableFutureTask contactNameTask = - new ListenableFutureTask<>(new Callable() { - @Override - public String call() throws Exception { - Contact c = contactManager.getContact(contactId); - contactName = c.getAuthor().getName(); - return c.getAuthor().getName(); - } - }); - private final AtomicBoolean contactNameTaskStarted = - new AtomicBoolean(false); - // Fields that are accessed from background threads must be volatile @Inject volatile ContactManager contactManager; @Inject volatile MessagingManager messagingManager; @Inject + volatile ConversationManager conversationManager; + @Inject volatile EventBus eventBus; @Inject volatile SettingsManager settingsManager; @@ -181,8 +163,6 @@ public class ConversationActivity extends BriarActivity private volatile ContactId contactId; @Nullable - private volatile String contactName; - @Nullable private volatile AuthorId contactAuthorId; @Nullable private volatile GroupId messagingGroupId; @@ -294,9 +274,9 @@ public class ConversationActivity extends BriarActivity runOnDbThread(() -> { try { long start = now(); - if (contactName == null || contactAuthorId == null) { + if (contactAuthorId == null) { Contact contact = contactManager.getContact(contactId); - contactName = contact.getAuthor().getName(); + contactName.postValue(contact.getAuthor().getName()); contactAuthorId = contact.getAuthor().getId(); } logDuration(LOG, "Loading contact", start); @@ -310,12 +290,13 @@ public class ConversationActivity extends BriarActivity }); } + // contactAuthorId and contactName are expected to be set private void displayContactDetails() { runOnUiThreadUnlessDestroyed(() -> { //noinspection ConstantConditions toolbarAvatar.setImageDrawable( new IdenticonDrawable(contactAuthorId.getBytes())); - toolbarTitle.setText(contactName); + toolbarTitle.setText(contactName.getValue()); }); } @@ -343,23 +324,9 @@ public class ConversationActivity extends BriarActivity try { long start = now(); Collection headers = - messagingManager.getMessageHeaders(contactId); - Collection introductions = - introductionManager.getIntroductionMessages(contactId); - Collection forumInvitations = - forumSharingManager.getInvitationMessages(contactId); - Collection blogInvitations = - blogSharingManager.getInvitationMessages(contactId); - Collection groupInvitations = - groupInvitationManager.getInvitationMessages(contactId); - List invitations = new ArrayList<>( - forumInvitations.size() + blogInvitations.size() + - groupInvitations.size()); - invitations.addAll(forumInvitations); - invitations.addAll(blogInvitations); - invitations.addAll(groupInvitations); + conversationManager.getMessageHeaders(contactId); logDuration(LOG, "Loading messages", start); - displayMessages(revision, headers, introductions, invitations); + displayMessages(revision, headers); } catch (NoSuchContactException e) { finishOnUiThread(); } catch (DbException e) { @@ -369,15 +336,12 @@ public class ConversationActivity extends BriarActivity } private void displayMessages(int revision, - Collection headers, - Collection introductions, - Collection invitations) { + Collection headers) { runOnUiThreadUnlessDestroyed(() -> { if (revision == adapter.getRevision()) { adapter.incrementRevision(); textInputView.setSendButtonEnabled(true); - List items = createItems(headers, - introductions, invitations); + List items = createItems(headers); adapter.addAll(items); list.showData(); // Scroll to the bottom @@ -396,38 +360,17 @@ public class ConversationActivity extends BriarActivity */ @SuppressWarnings("ConstantConditions") private List createItems( - Collection headers, - Collection introductions, - Collection invitations) { - int size = - headers.size() + introductions.size() + invitations.size(); - List items = new ArrayList<>(size); + Collection headers) { + List items = new ArrayList<>(headers.size()); for (PrivateMessageHeader h : headers) { - ConversationItem item = ConversationItem.from(h); - String body = bodyCache.get(h.getId()); - if (body == null) loadMessageBody(h.getId()); - else item.setBody(body); - items.add(item); - } - for (IntroductionMessage m : introductions) { ConversationItem item; - if (m instanceof IntroductionRequest) { - IntroductionRequest i = (IntroductionRequest) m; - item = ConversationItem.from(this, contactName, i); + if (h instanceof PrivateRequest || h instanceof PrivateResponse) { + item = ConversationItem.from(this, contactName.getValue(), h); } else { - IntroductionResponse i = (IntroductionResponse) m; - item = ConversationItem.from(this, contactName, i); - } - items.add(item); - } - for (InvitationMessage i : invitations) { - ConversationItem item; - if (i instanceof InvitationRequest) { - InvitationRequest r = (InvitationRequest) i; - item = ConversationItem.from(this, contactName, r); - } else { - InvitationResponse r = (InvitationResponse) i; - item = ConversationItem.from(this, contactName, r); + item = ConversationItem.from(h); + String body = bodyCache.get(h.getId()); + if (body == null) loadMessageBody(h.getId()); + else item.setBody(body); } items.add(item); } @@ -476,9 +419,7 @@ public class ConversationActivity extends BriarActivity PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e; if (p.getContactId().equals(contactId)) { LOG.info("Message received, adding"); - PrivateMessageHeader h = p.getMessageHeader(); - addConversationItem(ConversationItem.from(h)); - loadMessageBody(h.getId()); + onNewPrivateMessage(p.getMessageHeader()); } } else if (e instanceof MessagesSentEvent) { MessagesSentEvent m = (MessagesSentEvent) e; @@ -504,38 +445,6 @@ public class ConversationActivity extends BriarActivity LOG.info("Contact disconnected"); displayContactOnlineStatus(); } - } else if (e instanceof IntroductionRequestReceivedEvent) { - IntroductionRequestReceivedEvent event = - (IntroductionRequestReceivedEvent) e; - if (event.getContactId().equals(contactId)) { - LOG.info("Introduction request received, adding..."); - IntroductionRequest ir = event.getIntroductionRequest(); - handleIntroductionRequest(ir); - } - } else if (e instanceof IntroductionResponseReceivedEvent) { - IntroductionResponseReceivedEvent event = - (IntroductionResponseReceivedEvent) e; - if (event.getContactId().equals(contactId)) { - LOG.info("Introduction response received, adding..."); - IntroductionResponse ir = event.getIntroductionResponse(); - handleIntroductionResponse(ir); - } - } else if (e instanceof InvitationRequestReceivedEvent) { - InvitationRequestReceivedEvent event = - (InvitationRequestReceivedEvent) e; - if (event.getContactId().equals(contactId)) { - LOG.info("Invitation received, adding..."); - InvitationRequest ir = event.getRequest(); - handleInvitationRequest(ir); - } - } else if (e instanceof InvitationResponseReceivedEvent) { - InvitationResponseReceivedEvent event = - (InvitationResponseReceivedEvent) e; - if (event.getContactId().equals(contactId)) { - LOG.info("Invitation response received, adding..."); - InvitationResponse ir = event.getResponse(); - handleInvitationResponse(ir); - } } } @@ -548,84 +457,39 @@ public class ConversationActivity extends BriarActivity }); } - private void handleIntroductionRequest(IntroductionRequest m) { - getContactNameTask().addListener(new FutureTaskListener() { - @Override - public void onSuccess(String contactName) { - runOnUiThreadUnlessDestroyed(() -> { - ConversationItem item = ConversationItem - .from(ConversationActivity.this, contactName, m); - addConversationItem(item); - }); - } - - @Override - public void onFailure(Throwable exception) { - runOnUiThreadUnlessDestroyed( - () -> handleDbException((DbException) exception)); + private void onNewPrivateMessage(PrivateMessageHeader h) { + runOnUiThreadUnlessDestroyed(() -> { + if (h instanceof PrivateRequest || h instanceof PrivateResponse) { + String cName = contactName.getValue(); + if (cName == null) { + // Wait for the contact name to be loaded + contactName.observe(this, new Observer() { + @Override + public void onChanged(@Nullable String cName) { + if (cName != null) { + onNewPrivateRequestOrResponse(h, cName); + contactName.removeObserver(this); + } + } + }); + } else { + onNewPrivateRequestOrResponse(h, cName); + } + } else { + addConversationItem(ConversationItem.from(h)); + loadMessageBody(h.getId()); } }); } - private void handleIntroductionResponse(IntroductionResponse m) { - getContactNameTask().addListener(new FutureTaskListener() { - @Override - public void onSuccess(String contactName) { - runOnUiThreadUnlessDestroyed(() -> { - ConversationItem item = ConversationItem - .from(ConversationActivity.this, contactName, m); - addConversationItem(item); - }); - } - - @Override - public void onFailure(Throwable exception) { - runOnUiThreadUnlessDestroyed( - () -> handleDbException((DbException) exception)); - } - }); + @UiThread + private void onNewPrivateRequestOrResponse(PrivateMessageHeader h, + String cName) { + addConversationItem(ConversationItem.from(this, cName, h)); } - private void handleInvitationRequest(InvitationRequest m) { - getContactNameTask().addListener(new FutureTaskListener() { - @Override - public void onSuccess(String contactName) { - runOnUiThreadUnlessDestroyed(() -> { - ConversationItem item = ConversationItem - .from(ConversationActivity.this, contactName, m); - addConversationItem(item); - }); - } - - @Override - public void onFailure(Throwable exception) { - runOnUiThreadUnlessDestroyed( - () -> handleDbException((DbException) exception)); - } - }); - } - - private void handleInvitationResponse(InvitationResponse m) { - getContactNameTask().addListener(new FutureTaskListener() { - @Override - public void onSuccess(String contactName) { - runOnUiThreadUnlessDestroyed(() -> { - ConversationItem item = ConversationItem - .from(ConversationActivity.this, contactName, m); - addConversationItem(item); - }); - } - - @Override - public void onFailure(Throwable exception) { - runOnUiThreadUnlessDestroyed( - () -> handleDbException((DbException) exception)); - } - }); - } - - private void markMessages(Collection messageIds, - boolean sent, boolean seen) { + private void markMessages(Collection messageIds, boolean sent, + boolean seen) { runOnUiThreadUnlessDestroyed(() -> { adapter.incrementRevision(); Set messages = new HashSet<>(messageIds); @@ -678,7 +542,8 @@ public class ConversationActivity extends BriarActivity //noinspection ConstantConditions init in loadGroupId() storeMessage(privateMessageFactory.createPrivateMessage( messagingGroupId, timestamp, body), body); - } catch (FormatException e) {throw new RuntimeException(e); + } catch (FormatException e) { + throw new RuntimeException(e); } }); } @@ -823,7 +688,7 @@ public class ConversationActivity extends BriarActivity @UiThread @Override public void respondToRequest(ConversationRequestItem item, boolean accept) { - item.setAnswered(true); + item.setAnswered(); int position = adapter.findItemPosition(item); if (position != INVALID_POSITION) { adapter.notifyItemChanged(position, item); @@ -908,11 +773,4 @@ public class ConversationActivity extends BriarActivity throws DbException { groupInvitationManager.respondToInvitation(contactId, id, accept); } - - private ListenableFutureTask getContactNameTask() { - if (!contactNameTaskStarted.getAndSet(true)) - runOnDbThread(contactNameTask); - return contactNameTask; - } - } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationItem.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationItem.java index 9070c738f..671f7c6d2 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationItem.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationItem.java @@ -2,39 +2,23 @@ package org.briarproject.briar.android.contact; import android.content.Context; import android.support.annotation.LayoutRes; -import android.support.annotation.StringRes; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; -import org.briarproject.briar.R; -import org.briarproject.briar.android.contact.ConversationRequestItem.RequestType; -import org.briarproject.briar.api.blog.BlogInvitationRequest; -import org.briarproject.briar.api.blog.BlogInvitationResponse; -import org.briarproject.briar.api.client.BaseMessageHeader; -import org.briarproject.briar.api.forum.ForumInvitationRequest; -import org.briarproject.briar.api.forum.ForumInvitationResponse; -import org.briarproject.briar.api.introduction.IntroductionRequest; -import org.briarproject.briar.api.introduction.IntroductionResponse; import org.briarproject.briar.api.messaging.PrivateMessageHeader; -import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest; -import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse; -import org.briarproject.briar.api.sharing.InvitationRequest; -import org.briarproject.briar.api.sharing.InvitationResponse; +import org.briarproject.briar.api.messaging.PrivateRequest; +import org.briarproject.briar.api.messaging.PrivateResponse; import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; -import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.BLOG; -import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.FORUM; -import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.GROUP; -import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.INTRODUCTION; - @NotThreadSafe @NotNullByDefault abstract class ConversationItem { - protected @Nullable String body; + @Nullable + protected String body; private final MessageId id; private final GroupId groupId; private final long time; @@ -88,205 +72,37 @@ abstract class ConversationItem { } static ConversationItem from(Context ctx, String contactName, - IntroductionRequest ir) { - if (ir.isLocal()) { - String text = ctx.getString(R.string.introduction_request_sent, - contactName, ir.getName()); - return new ConversationNoticeOutItem(ir.getMessageId(), - ir.getGroupId(), text, ir.getMessage(), ir.getTimestamp(), - ir.isSent(), ir.isSeen()); + PrivateMessageHeader h) { + if (h.isLocal()) { + return fromLocal(ctx, contactName, h); } else { - String text; - if (ir.wasAnswered()) { - text = ctx.getString( - R.string.introduction_request_answered_received, - contactName, ir.getName()); - } else if (ir.contactExists()){ - text = ctx.getString( - R.string.introduction_request_exists_received, - contactName, ir.getName()); - } else { - text = ctx.getString(R.string.introduction_request_received, - contactName, ir.getName()); - } - return new ConversationRequestItem(ir.getMessageId(), - ir.getGroupId(), INTRODUCTION, ir.getSessionId(), text, - ir.getMessage(), ir.getTimestamp(), ir.isRead(), null, - ir.wasAnswered(), false); + return fromRemote(ctx, contactName, h); } } - static ConversationItem from(Context ctx, String contactName, - IntroductionResponse ir) { - if (ir.isLocal()) { - String text; - if (ir.wasAccepted()) { - text = ctx.getString( - R.string.introduction_response_accepted_sent, - ir.getName()); - text += "\n\n" + ctx.getString( - R.string.introduction_response_accepted_sent_info, - ir.getName()); - } else { - text = ctx.getString( - R.string.introduction_response_declined_sent, - ir.getName()); - } - return new ConversationNoticeOutItem(ir.getMessageId(), - ir.getGroupId(), text, null, ir.getTimestamp(), ir.isSent(), - ir.isSeen()); + private static ConversationItem fromLocal(Context ctx, String contactName, + PrivateMessageHeader h) { + if (h instanceof PrivateRequest) { + PrivateRequest r = (PrivateRequest) h; + return new ConversationNoticeOutItem(ctx, contactName, r); + } else if (h instanceof PrivateResponse) { + PrivateResponse r = (PrivateResponse) h; + return new ConversationNoticeOutItem(ctx, contactName, r); } else { - String text; - if (ir.wasAccepted()) { - text = ctx.getString( - R.string.introduction_response_accepted_received, - contactName, ir.getName()); - } else { - if (ir.isIntroducer()) { - text = ctx.getString( - R.string.introduction_response_declined_received, - contactName, ir.getName()); - } else { - text = ctx.getString( - R.string.introduction_response_declined_received_by_introducee, - contactName, ir.getName()); - } - } - return new ConversationNoticeInItem(ir.getMessageId(), - ir.getGroupId(), text, null, ir.getTimestamp(), - ir.isRead()); + return new ConversationMessageOutItem(h); } } - static ConversationItem from(Context ctx, String contactName, - InvitationRequest ir) { - if (ir.isLocal()) { - String text; - if (ir instanceof ForumInvitationRequest) { - text = ctx.getString(R.string.forum_invitation_sent, - ((ForumInvitationRequest) ir).getForumName(), - contactName); - } else if (ir instanceof BlogInvitationRequest) { - text = ctx.getString(R.string.blogs_sharing_invitation_sent, - ((BlogInvitationRequest) ir).getBlogAuthorName(), - contactName); - } else if (ir instanceof GroupInvitationRequest) { - text = ctx.getString( - R.string.groups_invitations_invitation_sent, - contactName, ir.getShareable().getName()); - } else { - throw new IllegalArgumentException("Unknown InvitationRequest"); - } - return new ConversationNoticeOutItem(ir.getId(), ir.getGroupId(), - text, ir.getMessage(), ir.getTimestamp(), ir.isSent(), - ir.isSeen()); + private static ConversationItem fromRemote(Context ctx, String contactName, + PrivateMessageHeader h) { + if (h instanceof PrivateRequest) { + PrivateRequest r = (PrivateRequest) h; + return new ConversationRequestItem(ctx, contactName, r); + } else if (h instanceof PrivateResponse) { + PrivateResponse r = (PrivateResponse) h; + return new ConversationNoticeInItem(ctx, contactName, r); } else { - String text; - RequestType type; - if (ir instanceof ForumInvitationRequest) { - text = ctx.getString(R.string.forum_invitation_received, - contactName, - ((ForumInvitationRequest) ir).getForumName()); - type = FORUM; - } else if (ir instanceof BlogInvitationRequest) { - text = ctx.getString(R.string.blogs_sharing_invitation_received, - contactName, - ((BlogInvitationRequest) ir).getBlogAuthorName()); - type = BLOG; - } else if (ir instanceof GroupInvitationRequest) { - text = ctx.getString( - R.string.groups_invitations_invitation_received, - contactName, ir.getShareable().getName()); - type = GROUP; - } else { - throw new IllegalArgumentException("Unknown InvitationRequest"); - } - return new ConversationRequestItem(ir.getId(), - ir.getGroupId(), type, ir.getSessionId(), text, - ir.getMessage(), ir.getTimestamp(), ir.isRead(), - ir.getShareable().getId(), !ir.isAvailable(), - ir.canBeOpened()); - } - } - - static ConversationItem from(Context ctx, String contactName, - InvitationResponse ir) { - @StringRes int res; - if (ir.isLocal()) { - if (ir.wasAccepted()) { - if (ir instanceof ForumInvitationResponse) { - res = R.string.forum_invitation_response_accepted_sent; - } else if (ir instanceof BlogInvitationResponse) { - res = R.string.blogs_sharing_response_accepted_sent; - } else if (ir instanceof GroupInvitationResponse) { - res = R.string.groups_invitations_response_accepted_sent; - } else { - throw new IllegalArgumentException( - "Unknown InvitationResponse"); - } - } else { - if (ir instanceof ForumInvitationResponse) { - res = R.string.forum_invitation_response_declined_sent; - } else if (ir instanceof BlogInvitationResponse) { - res = R.string.blogs_sharing_response_declined_sent; - } else if (ir instanceof GroupInvitationResponse) { - res = R.string.groups_invitations_response_declined_sent; - } else { - throw new IllegalArgumentException( - "Unknown InvitationResponse"); - } - } - String text = ctx.getString(res, contactName); - return new ConversationNoticeOutItem(ir.getId(), ir.getGroupId(), - text, null, ir.getTimestamp(), ir.isSent(), ir.isSeen()); - } else { - if (ir.wasAccepted()) { - if (ir instanceof ForumInvitationResponse) { - res = R.string.forum_invitation_response_accepted_received; - } else if (ir instanceof BlogInvitationResponse) { - res = R.string.blogs_sharing_response_accepted_received; - } else if (ir instanceof GroupInvitationResponse) { - res = R.string.groups_invitations_response_accepted_received; - } else { - throw new IllegalArgumentException( - "Unknown InvitationResponse"); - } - } else { - if (ir instanceof ForumInvitationResponse) { - res = R.string.forum_invitation_response_declined_received; - } else if (ir instanceof BlogInvitationResponse) { - res = R.string.blogs_sharing_response_declined_received; - } else if (ir instanceof GroupInvitationResponse) { - res = R.string.groups_invitations_response_declined_received; - } else { - throw new IllegalArgumentException( - "Unknown InvitationResponse"); - } - } - String text = ctx.getString(res, contactName); - return new ConversationNoticeInItem(ir.getId(), ir.getGroupId(), - text, null, ir.getTimestamp(), ir.isRead()); - } - } - - /** - * This method should not be used to display the resulting ConversationItem - * in the UI, but only to update list information based on the - * BaseMessageHeader. - **/ - static ConversationItem from(Context ctx, BaseMessageHeader h) { - if (h instanceof PrivateMessageHeader) { - return from((PrivateMessageHeader) h); - } else if(h instanceof IntroductionRequest) { - return from(ctx, "", (IntroductionRequest) h); - } else if(h instanceof IntroductionResponse) { - return from(ctx, "", (IntroductionResponse) h); - } else if(h instanceof InvitationRequest) { - return from(ctx, "", (InvitationRequest) h); - } else if(h instanceof InvitationResponse) { - return from(ctx, "", (InvitationResponse) h); - } else { - throw new IllegalArgumentException("Unknown message header"); + return new ConversationMessageInItem(h); } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationNoticeInItem.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationNoticeInItem.java index efbc6e4f7..2873ad64c 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationNoticeInItem.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationNoticeInItem.java @@ -1,11 +1,18 @@ package org.briarproject.briar.android.contact; +import android.content.Context; import android.support.annotation.LayoutRes; +import android.support.annotation.StringRes; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.R; +import org.briarproject.briar.api.blog.BlogInvitationResponse; +import org.briarproject.briar.api.forum.ForumInvitationResponse; +import org.briarproject.briar.api.introduction.IntroductionResponse; +import org.briarproject.briar.api.messaging.PrivateResponse; +import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse; import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; @@ -24,6 +31,13 @@ class ConversationNoticeInItem extends ConversationItem { this.msgText = msgText; } + public ConversationNoticeInItem(Context ctx, String contactName, + PrivateResponse r) { + super(r.getId(), r.getGroupId(), getText(ctx, contactName, r), + r.getTimestamp(), r.isRead()); + this.msgText = null; + } + @Nullable String getMsgText() { return msgText; @@ -40,4 +54,54 @@ class ConversationNoticeInItem extends ConversationItem { return R.layout.list_item_conversation_notice_in; } + private static String getText(Context ctx, String contactName, + PrivateResponse r) { + if (r.wasAccepted()) { + if (r instanceof IntroductionResponse) { + IntroductionResponse ir = (IntroductionResponse) r; + return ctx.getString( + R.string.introduction_response_accepted_received, + contactName, ir.getIntroducedAuthor().getName()); + } else if (r instanceof ForumInvitationResponse) { + return ctx.getString( + R.string.forum_invitation_response_accepted_received, + contactName); + } else if (r instanceof BlogInvitationResponse) { + return ctx.getString( + R.string.blogs_sharing_response_accepted_received, + contactName); + } else if (r instanceof GroupInvitationResponse) { + return ctx.getString( + R.string.groups_invitations_response_accepted_received, + contactName); + } + } else { + if (r instanceof IntroductionResponse) { + IntroductionResponse ir = (IntroductionResponse) r; + @StringRes int res; + if (ir.isIntroducer()) { + res = R.string.introduction_response_declined_received; + } else { + res = + R.string.introduction_response_declined_received_by_introducee; + } + return ctx.getString(res, contactName, + ir.getIntroducedAuthor().getName()); + } else if (r instanceof ForumInvitationResponse) { + return ctx.getString( + R.string.forum_invitation_response_declined_received, + contactName); + } else if (r instanceof BlogInvitationResponse) { + return ctx.getString( + R.string.blogs_sharing_response_declined_received, + contactName); + } else if (r instanceof GroupInvitationResponse) { + return ctx.getString( + R.string.groups_invitations_response_declined_received, + contactName); + } + } + throw new IllegalArgumentException("Unknown PrivateResponse"); + } + } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationNoticeOutItem.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationNoticeOutItem.java index 637c928b9..b5b22203b 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationNoticeOutItem.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationNoticeOutItem.java @@ -1,11 +1,20 @@ package org.briarproject.briar.android.contact; +import android.content.Context; import android.support.annotation.LayoutRes; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.GroupId; -import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.R; +import org.briarproject.briar.api.blog.BlogInvitationRequest; +import org.briarproject.briar.api.blog.BlogInvitationResponse; +import org.briarproject.briar.api.forum.ForumInvitationRequest; +import org.briarproject.briar.api.forum.ForumInvitationResponse; +import org.briarproject.briar.api.introduction.IntroductionRequest; +import org.briarproject.briar.api.introduction.IntroductionResponse; +import org.briarproject.briar.api.messaging.PrivateRequest; +import org.briarproject.briar.api.messaging.PrivateResponse; +import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest; +import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse; import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; @@ -17,11 +26,18 @@ class ConversationNoticeOutItem extends ConversationOutItem { @Nullable private final String msgText; - ConversationNoticeOutItem(MessageId id, GroupId groupId, - String text, @Nullable String msgText, long time, - boolean sent, boolean seen) { - super(id, groupId, text, time, sent, seen); - this.msgText = msgText; + ConversationNoticeOutItem(Context ctx, String contactName, + PrivateRequest r) { + super(r.getId(), r.getGroupId(), getText(ctx, contactName, r), + r.getTimestamp(), r.isSent(), r.isSeen()); + this.msgText = r.getMessage(); + } + + ConversationNoticeOutItem(Context ctx, String contactName, + PrivateResponse r) { + super(r.getId(), r.getGroupId(), getText(ctx, contactName, r), + r.getTimestamp(), r.isSent(), r.isSeen()); + this.msgText = null; } @Nullable @@ -35,4 +51,57 @@ class ConversationNoticeOutItem extends ConversationOutItem { return R.layout.list_item_conversation_notice_out; } + private static String getText(Context ctx, String contactName, + PrivateRequest r) { + if (r instanceof IntroductionRequest) { + return ctx.getString(R.string.introduction_request_sent, + contactName, r.getName()); + } else if (r instanceof ForumInvitationRequest) { + return ctx.getString(R.string.forum_invitation_sent, + r.getName(), contactName); + } else if (r instanceof BlogInvitationRequest) { + return ctx.getString(R.string.blogs_sharing_invitation_sent, + r.getName(), contactName); + } else if (r instanceof GroupInvitationRequest) { + return ctx.getString(R.string.groups_invitations_invitation_sent, + contactName, r.getName()); + } + throw new IllegalArgumentException("Unknown PrivateRequest"); + } + + private static String getText(Context ctx, String contactName, + PrivateResponse r) { + if (r.wasAccepted()) { + if (r instanceof IntroductionResponse) { + String name = ((IntroductionResponse) r).getIntroducedAuthor() + .getName(); + return ctx.getString( + R.string.introduction_response_accepted_sent, + name) + "\n\n" + ctx.getString( + R.string.introduction_response_accepted_sent_info, + name); + } else if (r instanceof ForumInvitationResponse) { + return ctx.getString(R.string.forum_invitation_response_accepted_sent, contactName); + } else if (r instanceof BlogInvitationResponse) { + return ctx.getString(R.string.blogs_sharing_response_accepted_sent, contactName); + } else if (r instanceof GroupInvitationResponse) { + return ctx.getString(R.string.groups_invitations_response_accepted_sent, contactName); + } + } else { + if (r instanceof IntroductionResponse) { + String name = ((IntroductionResponse) r).getIntroducedAuthor() + .getName(); + return ctx.getString( + R.string.introduction_response_declined_sent, name); + } else if (r instanceof ForumInvitationResponse) { + return ctx.getString(R.string.forum_invitation_response_declined_sent, contactName); + } else if (r instanceof BlogInvitationResponse) { + return ctx.getString(R.string.blogs_sharing_response_declined_sent, contactName); + } else if (r instanceof GroupInvitationResponse) { + return ctx.getString(R.string.groups_invitations_response_declined_sent, contactName); + } + } + throw new IllegalArgumentException("Unknown PrivateResponse"); + } + } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationRequestItem.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationRequestItem.java index b11a00c60..e61ebec22 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationRequestItem.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ConversationRequestItem.java @@ -1,16 +1,28 @@ package org.briarproject.briar.android.contact; +import android.content.Context; import android.support.annotation.LayoutRes; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; -import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.R; +import org.briarproject.briar.api.blog.BlogInvitationRequest; import org.briarproject.briar.api.client.SessionId; +import org.briarproject.briar.api.forum.ForumInvitationRequest; +import org.briarproject.briar.api.introduction.IntroductionRequest; +import org.briarproject.briar.api.messaging.PrivateRequest; +import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest; +import org.briarproject.briar.api.sharing.InvitationRequest; +import org.briarproject.briar.api.sharing.Shareable; import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; +import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.BLOG; +import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.FORUM; +import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.GROUP; +import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.INTRODUCTION; + @NotThreadSafe @NotNullByDefault class ConversationRequestItem extends ConversationNoticeInItem { @@ -24,17 +36,20 @@ class ConversationRequestItem extends ConversationNoticeInItem { private final boolean canBeOpened; private boolean answered; - ConversationRequestItem(MessageId id, GroupId groupId, - RequestType requestType, SessionId sessionId, String text, - @Nullable String msgText, long time, boolean read, - @Nullable GroupId requestedGroupId, boolean answered, - boolean canBeOpened) { - super(id, groupId, text, msgText, time, read); - this.requestType = requestType; - this.sessionId = sessionId; - this.requestedGroupId = requestedGroupId; - this.answered = answered; - this.canBeOpened = canBeOpened; + ConversationRequestItem(Context ctx, String contactName, + PrivateRequest r) { + super(r.getId(), r.getGroupId(), getText(ctx, contactName, r), + r.getMessage(), r.getTimestamp(), r.isRead()); + this.requestType = getType(r); + this.sessionId = r.getSessionId(); + this.answered = r.wasAnswered(); + if (r instanceof InvitationRequest) { + this.requestedGroupId = ((Shareable) r.getNameable()).getId(); + this.canBeOpened = ((InvitationRequest) r).canBeOpened(); + } else { + this.requestedGroupId = null; + this.canBeOpened = false; + } } RequestType getRequestType() { @@ -54,8 +69,8 @@ class ConversationRequestItem extends ConversationNoticeInItem { return answered; } - void setAnswered(boolean answered) { - this.answered = answered; + void setAnswered() { + this.answered = true; } public boolean canBeOpened() { @@ -68,4 +83,46 @@ class ConversationRequestItem extends ConversationNoticeInItem { return R.layout.list_item_conversation_request; } + private static String getText(Context ctx, String contactName, + PrivateRequest r) { + if (r instanceof IntroductionRequest) { + if (r.wasAnswered()) { + return ctx.getString( + R.string.introduction_request_answered_received, + contactName, r.getName()); + } else if (((IntroductionRequest) r).isContact()) { + return ctx.getString( + R.string.introduction_request_exists_received, + contactName, r.getName()); + } else { + return ctx.getString(R.string.introduction_request_received, + contactName, r.getName()); + } + } else if (r instanceof ForumInvitationRequest) { + return ctx.getString(R.string.forum_invitation_received, + contactName, r.getName()); + } else if (r instanceof BlogInvitationRequest) { + return ctx.getString(R.string.blogs_sharing_invitation_received, + contactName, r.getName()); + } else if (r instanceof GroupInvitationRequest) { + return ctx.getString( + R.string.groups_invitations_invitation_received, + contactName, r.getName()); + } + throw new IllegalArgumentException("Unknown PrivateRequest"); + } + + private static RequestType getType(PrivateRequest r) { + if (r instanceof IntroductionRequest) { + return INTRODUCTION; + } else if (r instanceof ForumInvitationRequest) { + return FORUM; + } else if (r instanceof BlogInvitationRequest) { + return BLOG; + } else if (r instanceof GroupInvitationRequest) { + return GROUP; + } + throw new IllegalArgumentException("Unknown PrivateRequest"); + } + } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java index bd28b4864..9abe8a137 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumControllerImpl.java @@ -84,11 +84,10 @@ class ForumControllerImpl extends } else if (e instanceof ForumInvitationResponseReceivedEvent) { ForumInvitationResponseReceivedEvent f = (ForumInvitationResponseReceivedEvent) e; - ForumInvitationResponse r = - (ForumInvitationResponse) f.getResponse(); + ForumInvitationResponse r = f.getMessageHeader(); if (r.getShareableId().equals(getGroupId()) && r.wasAccepted()) { LOG.info("Forum invitation was accepted"); - onForumInvitationAccepted(r.getContactId()); + onForumInvitationAccepted(f.getContactId()); } } else if (e instanceof ContactLeftShareableEvent) { ContactLeftShareableEvent c = (ContactLeftShareableEvent) e; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java index 97a64c1a7..35a318265 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/conversation/GroupControllerImpl.java @@ -99,11 +99,10 @@ class GroupControllerImpl extends } else if (e instanceof GroupInvitationResponseReceivedEvent) { GroupInvitationResponseReceivedEvent g = (GroupInvitationResponseReceivedEvent) e; - GroupInvitationResponse r = - (GroupInvitationResponse) g.getResponse(); + GroupInvitationResponse r = g.getMessageHeader(); if (getGroupId().equals(r.getShareableId()) && r.wasAccepted()) { listener.runOnUiThreadUnlessDestroyed( - () -> listener.onInvitationAccepted(r.getContactId())); + () -> listener.onInvitationAccepted(g.getContactId())); } } else if (e instanceof GroupDissolvedEvent) { GroupDissolvedEvent g = (GroupDissolvedEvent) e; diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/util/FutureTaskListener.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/util/FutureTaskListener.java deleted file mode 100644 index 80da2eccf..000000000 --- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/util/FutureTaskListener.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (C) 2014 Open Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms.components.util; - -public interface FutureTaskListener { - void onSuccess(V result); - - void onFailure(Throwable error); -} diff --git a/briar-android/src/main/java/org/thoughtcrime/securesms/components/util/ListenableFutureTask.java b/briar-android/src/main/java/org/thoughtcrime/securesms/components/util/ListenableFutureTask.java deleted file mode 100644 index 3d8303f07..000000000 --- a/briar-android/src/main/java/org/thoughtcrime/securesms/components/util/ListenableFutureTask.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2014 Open Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms.components.util; - -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.FutureTask; - -import javax.annotation.Nullable; - -public class ListenableFutureTask extends FutureTask { - - private final List> listeners = new LinkedList<>(); - - @Nullable - private final Object identifier; - - public ListenableFutureTask(Callable callable) { - this(callable, null); - } - - private ListenableFutureTask(Callable callable, - @Nullable Object identifier) { - super(callable); - this.identifier = identifier; - } - - public ListenableFutureTask(V result) { - this(result, null); - } - - private ListenableFutureTask(V result, @Nullable Object identifier) { - super(() -> result); - this.identifier = identifier; - this.run(); - } - - public synchronized void addListener(FutureTaskListener listener) { - if (this.isDone()) { - callback(listener); - } else { - this.listeners.add(listener); - } - } - - public synchronized void removeListener(FutureTaskListener listener) { - this.listeners.remove(listener); - } - - @Override - protected synchronized void done() { - callback(); - } - - private void callback() { - for (FutureTaskListener listener : listeners) { - callback(listener); - } - } - - private void callback(FutureTaskListener listener) { - if (listener != null) { - try { - listener.onSuccess(get()); - } catch (InterruptedException e) { - throw new AssertionError(e); - } catch (ExecutionException e) { - listener.onFailure(e); - } - } - } - - @Override - public boolean equals(Object other) { - if (other != null && other instanceof ListenableFutureTask && - this.identifier != null) { - return identifier.equals(other); - } else { - return super.equals(other); - } - } - - @Override - public int hashCode() { - if (identifier != null) return identifier.hashCode(); - else return super.hashCode(); - } - -} diff --git a/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogInvitationRequest.java b/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogInvitationRequest.java index 77dddbbe0..9c700727f 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogInvitationRequest.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogInvitationRequest.java @@ -1,6 +1,5 @@ package org.briarproject.briar.api.blog; -import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; @@ -14,14 +13,10 @@ public class BlogInvitationRequest extends InvitationRequest { public BlogInvitationRequest(MessageId id, GroupId groupId, long time, boolean local, boolean sent, boolean seen, boolean read, - SessionId sessionId, Blog blog, ContactId contactId, - @Nullable String message, boolean available, boolean canBeOpened) { + SessionId sessionId, Blog blog, @Nullable String message, + boolean available, boolean canBeOpened) { super(id, groupId, time, local, sent, seen, read, sessionId, blog, - contactId, message, available, canBeOpened); - } - - public String getBlogAuthorName() { - return getShareable().getName(); + message, available, canBeOpened); } } 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 e49142300..cf3ac3ac8 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 @@ -1,6 +1,5 @@ package org.briarproject.briar.api.blog; -import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; @@ -12,10 +11,9 @@ public class BlogInvitationResponse extends InvitationResponse { public BlogInvitationResponse(MessageId id, GroupId groupId, long time, boolean local, boolean sent, boolean seen, boolean read, - SessionId sessionId, GroupId blogId, ContactId contactId, - boolean accept) { - super(id, groupId, time, local, sent, seen, read, sessionId, blogId, - contactId, accept); + SessionId sessionId, boolean accept, GroupId shareableId) { + super(id, groupId, time, local, sent, seen, read, sessionId, + accept, shareableId); } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/blog/event/BlogInvitationRequestReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/blog/event/BlogInvitationRequestReceivedEvent.java index cbb5381ca..699717407 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/blog/event/BlogInvitationRequestReceivedEvent.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/blog/event/BlogInvitationRequestReceivedEvent.java @@ -3,19 +3,19 @@ package org.briarproject.briar.api.blog.event; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.api.blog.Blog; -import org.briarproject.briar.api.sharing.InvitationRequest; -import org.briarproject.briar.api.sharing.event.InvitationRequestReceivedEvent; +import org.briarproject.briar.api.messaging.PrivateRequest; +import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault public class BlogInvitationRequestReceivedEvent extends - InvitationRequestReceivedEvent { + PrivateMessageReceivedEvent> { - public BlogInvitationRequestReceivedEvent(Blog blog, ContactId contactId, - InvitationRequest request) { - super(blog, contactId, request); + public BlogInvitationRequestReceivedEvent(PrivateRequest request, + ContactId contactId) { + super(request, contactId); } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/blog/event/BlogInvitationResponseReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/blog/event/BlogInvitationResponseReceivedEvent.java index 0b9ae9005..28df8444a 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/blog/event/BlogInvitationResponseReceivedEvent.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/blog/event/BlogInvitationResponseReceivedEvent.java @@ -3,18 +3,18 @@ package org.briarproject.briar.api.blog.event; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.api.blog.BlogInvitationResponse; -import org.briarproject.briar.api.sharing.event.InvitationResponseReceivedEvent; +import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault public class BlogInvitationResponseReceivedEvent - extends InvitationResponseReceivedEvent { + extends PrivateMessageReceivedEvent { - public BlogInvitationResponseReceivedEvent(ContactId contactId, - BlogInvitationResponse response) { - super(contactId, response); + public BlogInvitationResponseReceivedEvent(BlogInvitationResponse response, + ContactId contactId) { + super(response, contactId); } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/client/BaseMessageHeader.java b/briar-api/src/main/java/org/briarproject/briar/api/client/BaseMessageHeader.java deleted file mode 100644 index 8cbbceb32..000000000 --- a/briar-api/src/main/java/org/briarproject/briar/api/client/BaseMessageHeader.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.briarproject.briar.api.client; - -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.GroupId; -import org.briarproject.bramble.api.sync.MessageId; - -import javax.annotation.concurrent.Immutable; - -@Immutable -@NotNullByDefault -public abstract class BaseMessageHeader { - - private final MessageId id; - private final GroupId groupId; - private final long timestamp; - private final boolean local, sent, seen, read; - - public BaseMessageHeader(MessageId id, GroupId groupId, long timestamp, - boolean local, boolean sent, boolean seen, boolean read) { - - this.id = id; - this.groupId = groupId; - this.timestamp = timestamp; - this.local = local; - this.sent = sent; - this.seen = seen; - this.read = read; - } - - public MessageId getId() { - return id; - } - - public GroupId getGroupId() { - return groupId; - } - - public long getTimestamp() { - return timestamp; - } - - public boolean isLocal() { - return local; - } - - public boolean isSent() { - return sent; - } - - public boolean isSeen() { - return seen; - } - - public boolean isRead() { - return read; - } - -} diff --git a/briar-api/src/main/java/org/briarproject/briar/api/forum/ForumInvitationRequest.java b/briar-api/src/main/java/org/briarproject/briar/api/forum/ForumInvitationRequest.java index 2d23ab0e8..8d1028a9d 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/forum/ForumInvitationRequest.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/forum/ForumInvitationRequest.java @@ -1,6 +1,5 @@ package org.briarproject.briar.api.forum; -import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; @@ -16,14 +15,10 @@ public class ForumInvitationRequest extends InvitationRequest { public ForumInvitationRequest(MessageId id, GroupId groupId, long time, boolean local, boolean sent, boolean seen, boolean read, - SessionId sessionId, Forum forum, ContactId contactId, - @Nullable String message, boolean available, boolean canBeOpened) { + SessionId sessionId, Forum forum, @Nullable String message, + boolean available, boolean canBeOpened) { super(id, groupId, time, local, sent, seen, read, sessionId, forum, - contactId, message, available, canBeOpened); - } - - public String getForumName() { - return getShareable().getName(); + message, available, canBeOpened); } } 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 48f03ce85..d0536ca91 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 @@ -1,6 +1,5 @@ package org.briarproject.briar.api.forum; -import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; @@ -15,10 +14,9 @@ public class ForumInvitationResponse extends InvitationResponse { public ForumInvitationResponse(MessageId id, GroupId groupId, long time, boolean local, boolean sent, boolean seen, boolean read, - SessionId sessionId, GroupId forumId, ContactId contactId, - boolean accept) { - super(id, groupId, time, local, sent, seen, read, sessionId, forumId, - contactId, accept); + SessionId sessionId, boolean accept, GroupId shareableId) { + super(id, groupId, time, local, sent, seen, read, sessionId, + accept, shareableId); } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/forum/event/ForumInvitationRequestReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/forum/event/ForumInvitationRequestReceivedEvent.java index 8d1b0ea39..673cdd2eb 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/forum/event/ForumInvitationRequestReceivedEvent.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/forum/event/ForumInvitationRequestReceivedEvent.java @@ -3,19 +3,19 @@ package org.briarproject.briar.api.forum.event; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.api.forum.Forum; -import org.briarproject.briar.api.sharing.InvitationRequest; -import org.briarproject.briar.api.sharing.event.InvitationRequestReceivedEvent; +import org.briarproject.briar.api.messaging.PrivateRequest; +import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault public class ForumInvitationRequestReceivedEvent extends - InvitationRequestReceivedEvent { + PrivateMessageReceivedEvent> { - public ForumInvitationRequestReceivedEvent(Forum forum, ContactId contactId, - InvitationRequest request) { - super(forum, contactId, request); + public ForumInvitationRequestReceivedEvent(PrivateRequest request, + ContactId contactId) { + super(request, contactId); } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/forum/event/ForumInvitationResponseReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/forum/event/ForumInvitationResponseReceivedEvent.java index 460ea3cab..13d3081e8 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/forum/event/ForumInvitationResponseReceivedEvent.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/forum/event/ForumInvitationResponseReceivedEvent.java @@ -3,18 +3,18 @@ package org.briarproject.briar.api.forum.event; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.api.forum.ForumInvitationResponse; -import org.briarproject.briar.api.sharing.event.InvitationResponseReceivedEvent; +import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault public class ForumInvitationResponseReceivedEvent extends - InvitationResponseReceivedEvent { + PrivateMessageReceivedEvent { - public ForumInvitationResponseReceivedEvent(ContactId contactId, - ForumInvitationResponse response) { - super(contactId, response); + public ForumInvitationResponseReceivedEvent( + ForumInvitationResponse response, ContactId contactId) { + super(response, contactId); } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionManager.java b/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionManager.java index 532d63353..b52273daf 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionManager.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionManager.java @@ -8,8 +8,6 @@ import org.briarproject.bramble.api.sync.ClientId; import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.messaging.ConversationManager.ConversationClient; -import java.util.Collection; - import javax.annotation.Nullable; @NotNullByDefault @@ -47,10 +45,4 @@ public interface IntroductionManager extends ConversationClient { void respondToIntroduction(ContactId contactId, SessionId sessionId, long timestamp, boolean accept) throws DbException; - /** - * Returns all introduction messages for the given contact. - */ - Collection getIntroductionMessages(ContactId contactId) - throws DbException; - } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionMessage.java b/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionMessage.java deleted file mode 100644 index 009487fa2..000000000 --- a/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionMessage.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.briarproject.briar.api.introduction; - -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.GroupId; -import org.briarproject.bramble.api.sync.MessageId; -import org.briarproject.briar.api.client.BaseMessageHeader; -import org.briarproject.briar.api.client.SessionId; - -import javax.annotation.concurrent.Immutable; - -import static org.briarproject.briar.api.introduction.Role.INTRODUCER; - -@Immutable -@NotNullByDefault -public class IntroductionMessage extends BaseMessageHeader { - - private final SessionId sessionId; - private final MessageId messageId; - private final Role role; - - IntroductionMessage(SessionId sessionId, MessageId messageId, - GroupId groupId, Role role, long time, boolean local, boolean sent, - boolean seen, boolean read) { - - super(messageId, groupId, time, local, sent, seen, read); - this.sessionId = sessionId; - this.messageId = messageId; - this.role = role; - } - - public SessionId getSessionId() { - return sessionId; - } - - public MessageId getMessageId() { - return messageId; - } - - public boolean isIntroducer() { - return role == INTRODUCER; - } - -} diff --git a/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionRequest.java b/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionRequest.java index b2a804bd8..91d52c255 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionRequest.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionRequest.java @@ -1,44 +1,31 @@ package org.briarproject.briar.api.introduction; +import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.api.client.SessionId; +import org.briarproject.briar.api.messaging.PrivateRequest; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault -public class IntroductionRequest extends IntroductionResponse { +public class IntroductionRequest extends PrivateRequest { - @Nullable - private final String message; - private final boolean answered, exists; + private final boolean contact; - public IntroductionRequest(SessionId sessionId, MessageId messageId, - GroupId groupId, Role role, long time, boolean local, boolean sent, - boolean seen, boolean read, String name, boolean accepted, - @Nullable String message, boolean answered, boolean exists) { - - super(sessionId, messageId, groupId, role, time, local, sent, seen, - read, name, accepted); - - this.message = message; - this.answered = answered; - this.exists = exists; + public IntroductionRequest(MessageId messageId, GroupId groupId, + long time, boolean local, boolean sent, boolean seen, boolean read, + SessionId sessionId, Author author, @Nullable String message, + boolean answered, boolean contact) { + super(messageId, groupId, time, local, sent, seen, read, sessionId, + author, message, answered); + this.contact = contact; } - @Nullable - public String getMessage() { - return message; - } - - public boolean wasAnswered() { - return answered; - } - - public boolean contactExists() { - return exists; + public boolean isContact() { + return contact; } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionResponse.java b/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionResponse.java index 816135d43..6ff9d8830 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionResponse.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/introduction/IntroductionResponse.java @@ -1,35 +1,38 @@ package org.briarproject.briar.api.introduction; +import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.api.client.SessionId; +import org.briarproject.briar.api.messaging.PrivateResponse; import javax.annotation.concurrent.Immutable; +import static org.briarproject.briar.api.introduction.Role.INTRODUCER; + @Immutable @NotNullByDefault -public class IntroductionResponse extends IntroductionMessage { +public class IntroductionResponse extends PrivateResponse { - private final String name; - private final boolean accepted; + private final Author introducedAuthor; + private final Role ourRole; - public IntroductionResponse(SessionId sessionId, MessageId messageId, - GroupId groupId, Role role, long time, boolean local, boolean sent, - boolean seen, boolean read, String name, boolean accepted) { - super(sessionId, messageId, groupId, role, time, local, sent, seen, - read); - - this.name = name; - this.accepted = accepted; + public IntroductionResponse(MessageId messageId, GroupId groupId, long time, + boolean local, boolean sent, boolean seen, boolean read, + SessionId sessionId, boolean accepted, Author author, Role role) { + super(messageId, groupId, time, local, sent, seen, read, sessionId, + accepted); + this.introducedAuthor = author; + this.ourRole = role; } - public String getName() { - return name; + public Author getIntroducedAuthor() { + return introducedAuthor; } - public boolean wasAccepted() { - return accepted; + public boolean isIntroducer() { + return ourRole == INTRODUCER; } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/introduction/event/IntroductionRequestReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/introduction/event/IntroductionRequestReceivedEvent.java index 9fe4871e2..a07a66cac 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/introduction/event/IntroductionRequestReceivedEvent.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/introduction/event/IntroductionRequestReceivedEvent.java @@ -1,32 +1,20 @@ package org.briarproject.briar.api.introduction.event; import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.api.introduction.IntroductionRequest; +import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault -public class IntroductionRequestReceivedEvent extends Event { +public class IntroductionRequestReceivedEvent extends + PrivateMessageReceivedEvent { - private final ContactId contactId; - private final IntroductionRequest introductionRequest; - - public IntroductionRequestReceivedEvent(ContactId contactId, - IntroductionRequest introductionRequest) { - - this.contactId = contactId; - this.introductionRequest = introductionRequest; - } - - public ContactId getContactId() { - return contactId; - } - - public IntroductionRequest getIntroductionRequest() { - return introductionRequest; + public IntroductionRequestReceivedEvent( + IntroductionRequest introductionRequest, ContactId contactId) { + super(introductionRequest, contactId); } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/introduction/event/IntroductionResponseReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/introduction/event/IntroductionResponseReceivedEvent.java index 2cd3d1c29..d1aeb1495 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/introduction/event/IntroductionResponseReceivedEvent.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/introduction/event/IntroductionResponseReceivedEvent.java @@ -1,31 +1,20 @@ package org.briarproject.briar.api.introduction.event; import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.api.introduction.IntroductionResponse; +import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault -public class IntroductionResponseReceivedEvent extends Event { +public class IntroductionResponseReceivedEvent extends + PrivateMessageReceivedEvent { - private final ContactId contactId; - private final IntroductionResponse introductionResponse; - - public IntroductionResponseReceivedEvent(ContactId contactId, - IntroductionResponse introductionResponse) { - - this.contactId = contactId; - this.introductionResponse = introductionResponse; + public IntroductionResponseReceivedEvent( + IntroductionResponse introductionResponse, ContactId contactId) { + super(introductionResponse, contactId); } - public ContactId getContactId() { - return contactId; - } - - public IntroductionResponse getIntroductionResponse() { - return introductionResponse; - } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/messaging/ConversationManager.java b/briar-api/src/main/java/org/briarproject/briar/api/messaging/ConversationManager.java index 8e8ddac0d..be2eeab2c 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/messaging/ConversationManager.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/messaging/ConversationManager.java @@ -10,6 +10,8 @@ import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.api.client.MessageTracker.GroupCount; +import java.util.Collection; + @NotNullByDefault public interface ConversationManager { @@ -19,6 +21,15 @@ public interface ConversationManager { */ void registerConversationClient(ConversationClient client); + /** + * Returns the headers of all messages in the given private conversation. + * + * Only {@link MessagingManager} returns only headers. + * The others also return the message body. + */ + Collection getMessageHeaders(ContactId c) + throws DbException; + /** * Returns the unified group count for all private conversation messages. */ @@ -29,6 +40,9 @@ public interface ConversationManager { Group getContactGroup(Contact c); + Collection getMessageHeaders(Transaction txn, + ContactId contactId) throws DbException; + GroupCount getGroupCount(Transaction txn, ContactId c) throws DbException; diff --git a/briar-api/src/main/java/org/briarproject/briar/api/messaging/MessagingManager.java b/briar-api/src/main/java/org/briarproject/briar/api/messaging/MessagingManager.java index f29d2c9e4..47c4f66b0 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/messaging/MessagingManager.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/messaging/MessagingManager.java @@ -8,8 +8,6 @@ import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.api.messaging.ConversationManager.ConversationClient; -import java.util.Collection; - @NotNullByDefault public interface MessagingManager extends ConversationClient { @@ -43,12 +41,6 @@ public interface MessagingManager extends ConversationClient { */ GroupId getConversationId(ContactId c) throws DbException; - /** - * Returns the headers of all messages in the given private conversation. - */ - Collection getMessageHeaders(ContactId c) - throws DbException; - /** * Returns the body of the private message with the given ID. */ diff --git a/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessageHeader.java b/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessageHeader.java index 9caf3bd56..619f0303b 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessageHeader.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessageHeader.java @@ -3,18 +3,55 @@ package org.briarproject.briar.api.messaging; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; -import org.briarproject.briar.api.client.BaseMessageHeader; import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault -public class PrivateMessageHeader extends BaseMessageHeader { +public class PrivateMessageHeader { + + private final MessageId id; + private final GroupId groupId; + private final long timestamp; + private final boolean local, sent, seen, read; public PrivateMessageHeader(MessageId id, GroupId groupId, long timestamp, boolean local, boolean read, boolean sent, boolean seen) { + this.id = id; + this.groupId = groupId; + this.timestamp = timestamp; + this.local = local; + this.sent = sent; + this.seen = seen; + this.read = read; + } - super(id, groupId, timestamp, local, sent, seen, read); + public MessageId getId() { + return id; + } + + public GroupId getGroupId() { + return groupId; + } + + public long getTimestamp() { + return timestamp; + } + + public boolean isLocal() { + return local; + } + + public boolean isSent() { + return sent; + } + + public boolean isSeen() { + return seen; + } + + public boolean isRead() { + return read; } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateRequest.java b/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateRequest.java new file mode 100644 index 000000000..b980cea30 --- /dev/null +++ b/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateRequest.java @@ -0,0 +1,53 @@ +package org.briarproject.briar.api.messaging; + +import org.briarproject.bramble.api.Nameable; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.sync.GroupId; +import org.briarproject.bramble.api.sync.MessageId; +import org.briarproject.briar.api.client.SessionId; + +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +@Immutable +@NotNullByDefault +public class PrivateRequest extends PrivateMessageHeader { + + private final SessionId sessionId; + private final N nameable; + @Nullable + private final String message; + private final boolean answered; + + public PrivateRequest(MessageId messageId, GroupId groupId, long time, + boolean local, boolean sent, boolean seen, boolean read, + SessionId sessionId, N nameable, @Nullable String message, + boolean answered) { + super(messageId, groupId, time, local, sent, seen, read); + this.sessionId = sessionId; + this.nameable = nameable; + this.message = message; + this.answered = answered; + } + + public SessionId getSessionId() { + return sessionId; + } + + public N getNameable() { + return nameable; + } + + public String getName() { + return nameable.getName(); + } + + @Nullable + public String getMessage() { + return message; + } + + public boolean wasAnswered() { + return answered; + } +} diff --git a/briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationMessage.java b/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateResponse.java similarity index 54% rename from briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationMessage.java rename to briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateResponse.java index df93ebdfa..01c74faed 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationMessage.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateResponse.java @@ -1,36 +1,33 @@ -package org.briarproject.briar.api.sharing; +package org.briarproject.briar.api.messaging; -import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; -import org.briarproject.briar.api.client.BaseMessageHeader; import org.briarproject.briar.api.client.SessionId; import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault -public class InvitationMessage extends BaseMessageHeader { +public abstract class PrivateResponse extends PrivateMessageHeader { private final SessionId sessionId; - private final ContactId contactId; + private final boolean accepted; - public InvitationMessage(MessageId id, GroupId groupId, long time, + public PrivateResponse(MessageId id, GroupId groupId, long time, boolean local, boolean sent, boolean seen, boolean read, - SessionId sessionId, ContactId contactId) { - + SessionId sessionId, boolean accepted) { super(id, groupId, time, local, sent, seen, read); this.sessionId = sessionId; - this.contactId = contactId; + this.accepted = accepted; } public SessionId getSessionId() { return sessionId; } - public ContactId getContactId() { - return contactId; + public boolean wasAccepted() { + return accepted; } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/messaging/event/PrivateMessageReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/messaging/event/PrivateMessageReceivedEvent.java index d82bff8f6..584bdfe31 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/messaging/event/PrivateMessageReceivedEvent.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/messaging/event/PrivateMessageReceivedEvent.java @@ -3,7 +3,6 @@ package org.briarproject.briar.api.messaging.event; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.briar.api.messaging.PrivateMessageHeader; import javax.annotation.concurrent.Immutable; @@ -13,28 +12,22 @@ import javax.annotation.concurrent.Immutable; */ @Immutable @NotNullByDefault -public class PrivateMessageReceivedEvent extends Event { +public class PrivateMessageReceivedEvent + extends Event { - private final PrivateMessageHeader messageHeader; + private final H messageHeader; private final ContactId contactId; - private final GroupId groupId; - public PrivateMessageReceivedEvent(PrivateMessageHeader messageHeader, - ContactId contactId, GroupId groupId) { + public PrivateMessageReceivedEvent(H messageHeader, ContactId contactId) { this.messageHeader = messageHeader; this.contactId = contactId; - this.groupId = groupId; } - public PrivateMessageHeader getMessageHeader() { + public H getMessageHeader() { return messageHeader; } public ContactId getContactId() { return contactId; } - - public GroupId getGroupId() { - return groupId; - } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/privategroup/event/GroupInvitationRequestReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/privategroup/event/GroupInvitationRequestReceivedEvent.java index 6ce0ff1ac..2edd5f022 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/privategroup/event/GroupInvitationRequestReceivedEvent.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/privategroup/event/GroupInvitationRequestReceivedEvent.java @@ -2,20 +2,19 @@ package org.briarproject.briar.api.privategroup.event; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.briar.api.privategroup.PrivateGroup; +import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest; -import org.briarproject.briar.api.sharing.event.InvitationRequestReceivedEvent; import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault public class GroupInvitationRequestReceivedEvent extends - InvitationRequestReceivedEvent { + PrivateMessageReceivedEvent { - public GroupInvitationRequestReceivedEvent(PrivateGroup group, - ContactId contactId, GroupInvitationRequest request) { - super(group, contactId, request); + public GroupInvitationRequestReceivedEvent(GroupInvitationRequest request, + ContactId contactId) { + super(request, contactId); } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/privategroup/event/GroupInvitationResponseReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/privategroup/event/GroupInvitationResponseReceivedEvent.java index 705c93074..bc016a890 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/privategroup/event/GroupInvitationResponseReceivedEvent.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/privategroup/event/GroupInvitationResponseReceivedEvent.java @@ -2,18 +2,18 @@ package org.briarproject.briar.api.privategroup.event; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.briar.api.sharing.InvitationResponse; -import org.briarproject.briar.api.sharing.event.InvitationResponseReceivedEvent; +import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; +import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse; import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault public class GroupInvitationResponseReceivedEvent - extends InvitationResponseReceivedEvent { + extends PrivateMessageReceivedEvent { - public GroupInvitationResponseReceivedEvent(ContactId contactId, - InvitationResponse response) { - super(contactId, response); + public GroupInvitationResponseReceivedEvent( + GroupInvitationResponse response, ContactId contactId) { + super(response, contactId); } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/privategroup/invitation/GroupInvitationManager.java b/briar-api/src/main/java/org/briarproject/briar/api/privategroup/invitation/GroupInvitationManager.java index 1062d0ce1..913edbbc6 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/privategroup/invitation/GroupInvitationManager.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/privategroup/invitation/GroupInvitationManager.java @@ -10,7 +10,6 @@ import org.briarproject.briar.api.client.ProtocolStateException; import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.messaging.ConversationManager.ConversationClient; import org.briarproject.briar.api.privategroup.PrivateGroup; -import org.briarproject.briar.api.sharing.InvitationMessage; import java.util.Collection; @@ -73,13 +72,6 @@ public interface GroupInvitationManager extends ConversationClient { */ void revealRelationship(ContactId c, GroupId g) throws DbException; - /** - * Returns all private group invitation messages related to the given - * contact. - */ - Collection getInvitationMessages(ContactId c) - throws DbException; - /** * Returns all private groups to which the user has been invited. */ diff --git a/briar-api/src/main/java/org/briarproject/briar/api/privategroup/invitation/GroupInvitationRequest.java b/briar-api/src/main/java/org/briarproject/briar/api/privategroup/invitation/GroupInvitationRequest.java index d447ae8ef..8067def68 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/privategroup/invitation/GroupInvitationRequest.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/privategroup/invitation/GroupInvitationRequest.java @@ -1,6 +1,5 @@ package org.briarproject.briar.api.privategroup.invitation; -import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; @@ -17,10 +16,10 @@ public class GroupInvitationRequest extends InvitationRequest { public GroupInvitationRequest(MessageId id, GroupId groupId, long time, boolean local, boolean sent, boolean seen, boolean read, - SessionId sessionId, PrivateGroup shareable, ContactId contactId, + SessionId sessionId, PrivateGroup shareable, @Nullable String message, boolean available, boolean canBeOpened) { super(id, groupId, time, local, sent, seen, read, sessionId, shareable, - contactId, message, available, canBeOpened); + message, available, canBeOpened); } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/privategroup/invitation/GroupInvitationResponse.java b/briar-api/src/main/java/org/briarproject/briar/api/privategroup/invitation/GroupInvitationResponse.java index b2e7d54b5..4b260eb62 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/privategroup/invitation/GroupInvitationResponse.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/privategroup/invitation/GroupInvitationResponse.java @@ -1,6 +1,5 @@ package org.briarproject.briar.api.privategroup.invitation; -import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; @@ -15,10 +14,9 @@ public class GroupInvitationResponse extends InvitationResponse { public GroupInvitationResponse(MessageId id, GroupId groupId, long time, boolean local, boolean sent, boolean seen, boolean read, - SessionId sessionId, GroupId shareableId, ContactId contactId, - boolean accept) { + SessionId sessionId, boolean accept, GroupId shareableId) { super(id, groupId, time, local, sent, seen, read, sessionId, - shareableId, contactId, accept); + accept, shareableId); } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationRequest.java b/briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationRequest.java index c5239310d..7cf456eb6 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationRequest.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationRequest.java @@ -1,49 +1,27 @@ package org.briarproject.briar.api.sharing; -import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.api.client.SessionId; +import org.briarproject.briar.api.messaging.PrivateRequest; import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; -@Immutable -@NotNullByDefault -public class InvitationRequest extends InvitationMessage { +public abstract class InvitationRequest extends + PrivateRequest { - private final S shareable; - @Nullable - private final String message; - private final boolean available, canBeOpened; + private final boolean canBeOpened; - public InvitationRequest(MessageId id, GroupId groupId, long time, + public InvitationRequest(MessageId messageId, GroupId groupId, long time, boolean local, boolean sent, boolean seen, boolean read, - SessionId sessionId, S shareable, ContactId contactId, - @Nullable String message, boolean available, boolean canBeOpened) { - super(id, groupId, time, local, sent, seen, read, sessionId, contactId); - this.shareable = shareable; - this.message = message; - this.available = available; + SessionId sessionId, S object, @Nullable String message, + boolean available, boolean canBeOpened) { + super(messageId, groupId, time, local, sent, seen, read, sessionId, + object, message, !available); this.canBeOpened = canBeOpened; } - @Nullable - public String getMessage() { - return message; - } - - public boolean isAvailable() { - return available; - } - public boolean canBeOpened() { return canBeOpened; } - - public S getShareable() { - return shareable; - } - } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationResponse.java b/briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationResponse.java index 517b6068e..826c2b81f 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationResponse.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationResponse.java @@ -1,31 +1,19 @@ package org.briarproject.briar.api.sharing; -import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.api.client.SessionId; +import org.briarproject.briar.api.messaging.PrivateResponse; -import javax.annotation.concurrent.Immutable; - -@Immutable -@NotNullByDefault -public class InvitationResponse extends InvitationMessage { +public abstract class InvitationResponse extends PrivateResponse { private final GroupId shareableId; - private final boolean accept; - public InvitationResponse(MessageId id, GroupId groupId, - long time, boolean local, boolean sent, boolean seen, - boolean read, SessionId sessionId, GroupId shareableId, - ContactId contactId, boolean accept) { - super(id, groupId, time, local, sent, seen, read, sessionId, contactId); + public InvitationResponse(MessageId id, GroupId groupId, long time, + boolean local, boolean sent, boolean seen, boolean read, + SessionId sessionId, boolean accepted, GroupId shareableId) { + super(id, groupId, time, local, sent, seen, read, sessionId, accepted); this.shareableId = shareableId; - this.accept = accept; - } - - public boolean wasAccepted() { - return accept; } public GroupId getShareableId() { diff --git a/briar-api/src/main/java/org/briarproject/briar/api/sharing/Shareable.java b/briar-api/src/main/java/org/briarproject/briar/api/sharing/Shareable.java index 409e4ba21..4d43715f5 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/sharing/Shareable.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/sharing/Shareable.java @@ -1,16 +1,12 @@ package org.briarproject.briar.api.sharing; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.GroupId; +import org.briarproject.bramble.api.Nameable; @NotNullByDefault -public interface Shareable { +public interface Shareable extends Nameable { GroupId getId(); - Group getGroup(); - - String getName(); - } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingManager.java b/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingManager.java index b593d2fdf..64f4af762 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingManager.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingManager.java @@ -35,13 +35,6 @@ public interface SharingManager void respondToInvitation(ContactId c, SessionId id, boolean accept) throws DbException; - /** - * Returns all group sharing messages sent by the Contact - * identified by contactId. - */ - Collection getInvitationMessages( - ContactId contactId) throws DbException; - /** * Returns all invitations to groups. */ diff --git a/briar-api/src/main/java/org/briarproject/briar/api/sharing/event/InvitationRequestReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/sharing/event/InvitationRequestReceivedEvent.java deleted file mode 100644 index 149124013..000000000 --- a/briar-api/src/main/java/org/briarproject/briar/api/sharing/event/InvitationRequestReceivedEvent.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.briarproject.briar.api.sharing.event; - -import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.event.Event; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.briar.api.sharing.InvitationRequest; -import org.briarproject.briar.api.sharing.Shareable; - -import javax.annotation.concurrent.Immutable; - -@Immutable -@NotNullByDefault -public abstract class InvitationRequestReceivedEvent - extends Event { - - private final S shareable; - private final ContactId contactId; - private final InvitationRequest request; - - protected InvitationRequestReceivedEvent(S shareable, ContactId contactId, - InvitationRequest request) { - this.shareable = shareable; - this.contactId = contactId; - this.request = request; - } - - public ContactId getContactId() { - return contactId; - } - - public InvitationRequest getRequest() { - return request; - } - - public S getShareable() { - return shareable; - } -} diff --git a/briar-api/src/main/java/org/briarproject/briar/api/sharing/event/InvitationResponseReceivedEvent.java b/briar-api/src/main/java/org/briarproject/briar/api/sharing/event/InvitationResponseReceivedEvent.java deleted file mode 100644 index ac9ebce86..000000000 --- a/briar-api/src/main/java/org/briarproject/briar/api/sharing/event/InvitationResponseReceivedEvent.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.briarproject.briar.api.sharing.event; - -import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.event.Event; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.briar.api.sharing.InvitationResponse; - -import javax.annotation.concurrent.Immutable; - -@Immutable -@NotNullByDefault -public abstract class InvitationResponseReceivedEvent extends Event { - - private final ContactId contactId; - private final InvitationResponse response; - - public InvitationResponseReceivedEvent(ContactId contactId, - InvitationResponse response) { - this.contactId = contactId; - this.response = response; - } - - public ContactId getContactId() { - return contactId; - } - - public InvitationResponse getResponse() { - return response; - } -} diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/AbstractProtocolEngine.java b/briar-core/src/main/java/org/briarproject/briar/introduction/AbstractProtocolEngine.java index 03b3486ad..68d8d61c4 100644 --- a/briar-core/src/main/java/org/briarproject/briar/introduction/AbstractProtocolEngine.java +++ b/briar-core/src/main/java/org/briarproject/briar/introduction/AbstractProtocolEngine.java @@ -150,12 +150,12 @@ abstract class AbstractProtocolEngine AuthorId localAuthorId = identityManager.getLocalAuthor(txn).getId(); Contact c = contactManager.getContact(txn, sender, localAuthorId); IntroductionResponse response = - new IntroductionResponse(s.getSessionId(), m.getMessageId(), - m.getGroupId(), s.getRole(), m.getTimestamp(), false, - false, false, false, otherAuthor.getName(), - m instanceof AcceptMessage); + new IntroductionResponse(m.getMessageId(), m.getGroupId(), + m.getTimestamp(), false, false, false, false, + s.getSessionId(), m instanceof AcceptMessage, + otherAuthor, s.getRole()); IntroductionResponseReceivedEvent e = - new IntroductionResponseReceivedEvent(c.getId(), response); + new IntroductionResponseReceivedEvent(response, c.getId()); txn.attach(e); } diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeProtocolEngine.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeProtocolEngine.java index 6bdaea9d2..a0a871ac8 100644 --- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeProtocolEngine.java +++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeProtocolEngine.java @@ -41,7 +41,6 @@ import javax.inject.Inject; import static java.util.logging.Level.WARNING; import static org.briarproject.bramble.util.LogUtils.logException; -import static org.briarproject.briar.api.introduction.Role.INTRODUCEE; import static org.briarproject.briar.introduction.IntroduceeState.AWAIT_AUTH; import static org.briarproject.briar.introduction.IntroduceeState.AWAIT_RESPONSES; import static org.briarproject.briar.introduction.IntroduceeState.LOCAL_ACCEPTED; @@ -255,13 +254,12 @@ class IntroduceeProtocolEngine localAuthor.getId()); boolean contactExists = contactManager .contactExists(txn, m.getAuthor().getId(), localAuthor.getId()); - IntroductionRequest request = - new IntroductionRequest(s.getSessionId(), m.getMessageId(), - m.getGroupId(), INTRODUCEE, m.getTimestamp(), false, - false, false, false, m.getAuthor().getName(), false, - m.getMessage(), false, contactExists); + IntroductionRequest request = new IntroductionRequest(m.getMessageId(), + m.getGroupId(), m.getTimestamp(), false, false, false, false, + s.getSessionId(), m.getAuthor(), m.getMessage(), false, + contactExists); IntroductionRequestReceivedEvent e = - new IntroductionRequestReceivedEvent(c.getId(), request); + new IntroductionRequestReceivedEvent(request, c.getId()); txn.attach(e); // Move to the AWAIT_RESPONSES state diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java index b6a56f709..50c6fefcb 100644 --- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java @@ -30,10 +30,10 @@ import org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVer import org.briarproject.briar.api.client.MessageTracker; import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.introduction.IntroductionManager; -import org.briarproject.briar.api.introduction.IntroductionMessage; import org.briarproject.briar.api.introduction.IntroductionRequest; import org.briarproject.briar.api.introduction.IntroductionResponse; import org.briarproject.briar.api.introduction.Role; +import org.briarproject.briar.api.messaging.PrivateMessageHeader; import org.briarproject.briar.client.ConversationClientImpl; import org.briarproject.briar.introduction.IntroducerSession.Introducee; @@ -398,17 +398,16 @@ class IntroductionManagerImpl extends ConversationClientImpl } @Override - public Collection getIntroductionMessages(ContactId c) - throws DbException { - List messages; - Transaction txn = db.startTransaction(true); + public Collection getMessageHeaders(Transaction txn, + ContactId c) throws DbException { try { Contact contact = db.getContact(txn, c); GroupId contactGroupId = getContactGroup(contact).getId(); BdfDictionary query = messageParser.getMessagesVisibleInUiQuery(); Map results = clientHelper .getMessageMetadataAsDictionary(txn, contactGroupId, query); - messages = new ArrayList<>(results.size()); + List messages = + new ArrayList<>(results.size()); for (Entry e : results.entrySet()) { MessageId m = e.getKey(); MessageMetadata meta = @@ -431,13 +430,10 @@ class IntroductionManagerImpl extends ConversationClientImpl status, ss.bdfSession, false)); } } - db.commitTransaction(txn); + return messages; } catch (FormatException e) { throw new DbException(e); - } finally { - db.endTransaction(txn); } - return messages; } private IntroductionRequest parseInvitationRequest(Transaction txn, @@ -470,11 +466,9 @@ class IntroductionManagerImpl extends ConversationClientImpl boolean contactExists = contactManager .contactExists(txn, rm.getAuthor().getId(), localAuthor.getId()); - - return new IntroductionRequest(sessionId, m, contactGroupId, - role, meta.getTimestamp(), meta.isLocal(), - status.isSent(), status.isSeen(), meta.isRead(), - author.getName(), false, message, !meta.isAvailableToAnswer(), + return new IntroductionRequest(m, contactGroupId, meta.getTimestamp(), + meta.isLocal(), status.isSent(), status.isSeen(), meta.isRead(), + sessionId, author, message, !meta.isAvailableToAnswer(), contactExists); } @@ -499,9 +493,9 @@ class IntroductionManagerImpl extends ConversationClientImpl sessionId = session.getSessionId(); author = session.getRemote().author; } else throw new AssertionError(); - return new IntroductionResponse(sessionId, m, contactGroupId, - role, meta.getTimestamp(), meta.isLocal(), status.isSent(), - status.isSeen(), meta.isRead(), author.getName(), accept); + return new IntroductionResponse(m, contactGroupId, meta.getTimestamp(), + meta.isLocal(), status.isSent(), status.isSeen(), meta.isRead(), + sessionId, accept, author, role); } private void removeSessionWithIntroducer(Transaction txn, diff --git a/briar-core/src/main/java/org/briarproject/briar/messaging/ConversationManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/messaging/ConversationManagerImpl.java index 95aef43c6..9499ccad6 100644 --- a/briar-core/src/main/java/org/briarproject/briar/messaging/ConversationManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/messaging/ConversationManagerImpl.java @@ -7,7 +7,11 @@ import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.api.client.MessageTracker.GroupCount; import org.briarproject.briar.api.messaging.ConversationManager; +import org.briarproject.briar.api.messaging.PrivateMessageHeader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; @@ -33,6 +37,22 @@ class ConversationManagerImpl implements ConversationManager { throw new IllegalStateException("Client is already registered"); } + @Override + public Collection getMessageHeaders(ContactId c) + throws DbException { + List messages = new ArrayList<>(); + Transaction txn = db.startTransaction(true); + try { + for (ConversationClient client : clients) { + messages.addAll(client.getMessageHeaders(txn, c)); + } + db.commitTransaction(txn); + } finally { + db.endTransaction(txn); + } + return messages; + } + @Override public GroupCount getGroupCount(ContactId contactId) throws DbException { int msgCount = 0, unreadCount = 0; diff --git a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java index 4ee791aea..cf97a32b2 100644 --- a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java @@ -116,8 +116,8 @@ class MessagingManagerImpl extends ConversationClientImpl PrivateMessageHeader header = new PrivateMessageHeader( m.getId(), groupId, timestamp, local, read, false, false); ContactId contactId = getContactId(txn, groupId); - PrivateMessageReceivedEvent event = new PrivateMessageReceivedEvent( - header, contactId, groupId); + PrivateMessageReceivedEvent event = + new PrivateMessageReceivedEvent<>(header, contactId); txn.attach(event); messageTracker.trackIncomingMessage(txn, m); @@ -178,21 +178,17 @@ class MessagingManagerImpl extends ConversationClientImpl } @Override - public Collection getMessageHeaders(ContactId c) - throws DbException { + public Collection getMessageHeaders(Transaction txn, + ContactId c) throws DbException { Map metadata; Collection statuses; GroupId g; - Transaction txn = db.startTransaction(true); try { g = getContactGroup(db.getContact(txn, c)).getId(); metadata = clientHelper.getMessageMetadataAsDictionary(txn, g); statuses = db.getMessageStatus(txn, c, g); - db.commitTransaction(txn); } catch (FormatException e) { throw new DbException(e); - } finally { - db.endTransaction(txn); } Collection headers = new ArrayList<>(); for (MessageStatus s : statuses) { @@ -203,9 +199,8 @@ class MessagingManagerImpl extends ConversationClientImpl long timestamp = meta.getLong("timestamp"); boolean local = meta.getBoolean("local"); boolean read = meta.getBoolean("read"); - headers.add( - new PrivateMessageHeader(id, g, timestamp, local, read, - s.isSent(), s.isSeen())); + headers.add(new PrivateMessageHeader(id, g, timestamp, local, + read, s.isSent(), s.isSeen())); } catch (FormatException e) { throw new DbException(e); } diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/CreatorProtocolEngine.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/CreatorProtocolEngine.java index d043fbad2..4ca049b42 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/CreatorProtocolEngine.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/CreatorProtocolEngine.java @@ -68,8 +68,7 @@ class CreatorProtocolEngine extends AbstractProtocolEngine { } @Override - public CreatorSession onJoinAction(Transaction txn, CreatorSession s) - throws DbException { + public CreatorSession onJoinAction(Transaction txn, CreatorSession s) { throw new UnsupportedOperationException(); // Invalid in this role } @@ -91,8 +90,8 @@ class CreatorProtocolEngine extends AbstractProtocolEngine { } @Override - public CreatorSession onMemberAddedAction(Transaction txn, CreatorSession s) - throws DbException { + public CreatorSession onMemberAddedAction(Transaction txn, + CreatorSession s) { return s; // Ignored in this role } @@ -193,8 +192,8 @@ class CreatorProtocolEngine extends AbstractProtocolEngine { setPrivateGroupVisibility(txn, s, SHARED); // Broadcast an event ContactId contactId = getContactId(txn, m.getContactGroupId()); - txn.attach(new GroupInvitationResponseReceivedEvent(contactId, - createInvitationResponse(m, contactId, true))); + txn.attach(new GroupInvitationResponseReceivedEvent( + createInvitationResponse(m, true), contactId)); // Move to the JOINED state return new CreatorSession(s.getContactGroupId(), s.getPrivateGroupId(), sent.getId(), m.getId(), sent.getTimestamp(), @@ -215,8 +214,8 @@ class CreatorProtocolEngine extends AbstractProtocolEngine { m.getTimestamp(), false); // Broadcast an event ContactId contactId = getContactId(txn, m.getContactGroupId()); - txn.attach(new GroupInvitationResponseReceivedEvent(contactId, - createInvitationResponse(m, contactId, false))); + txn.attach(new GroupInvitationResponseReceivedEvent( + createInvitationResponse(m, false), contactId)); // Move to the START state return new CreatorSession(s.getContactGroupId(), s.getPrivateGroupId(), s.getLastLocalMessageId(), m.getId(), s.getLocalTimestamp(), @@ -254,10 +253,10 @@ class CreatorProtocolEngine extends AbstractProtocolEngine { } private GroupInvitationResponse createInvitationResponse( - GroupInvitationMessage m, ContactId c, boolean accept) { + GroupInvitationMessage m, boolean accept) { SessionId sessionId = new SessionId(m.getPrivateGroupId().getBytes()); return new GroupInvitationResponse(m.getId(), m.getContactGroupId(), - m.getTimestamp(), false, false, true, false, sessionId, - m.getPrivateGroupId(), c, accept); + m.getTimestamp(), false, false, false, false, sessionId, + accept, m.getPrivateGroupId()); } } diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java index a4aef1eca..1082ec2cf 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java @@ -26,6 +26,7 @@ import org.briarproject.bramble.api.versioning.ClientVersioningManager; import org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVersioningHook; import org.briarproject.briar.api.client.MessageTracker; import org.briarproject.briar.api.client.SessionId; +import org.briarproject.briar.api.messaging.PrivateMessageHeader; import org.briarproject.briar.api.privategroup.PrivateGroup; import org.briarproject.briar.api.privategroup.PrivateGroupFactory; import org.briarproject.briar.api.privategroup.PrivateGroupManager; @@ -34,7 +35,6 @@ import org.briarproject.briar.api.privategroup.invitation.GroupInvitationItem; import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager; import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest; import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse; -import org.briarproject.briar.api.sharing.InvitationMessage; import org.briarproject.briar.client.ConversationClientImpl; import java.util.ArrayList; @@ -353,7 +353,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl private S handleAction(Transaction txn, LocalAction type, S session, ProtocolEngine engine) - throws DbException, FormatException { + throws DbException { if (type == LocalAction.INVITE) { throw new IllegalArgumentException(); } else if (type == LocalAction.JOIN) { @@ -368,17 +368,16 @@ class GroupInvitationManagerImpl extends ConversationClientImpl } @Override - public Collection getInvitationMessages(ContactId c) - throws DbException { - List messages; - Transaction txn = db.startTransaction(true); + public Collection getMessageHeaders(Transaction txn, + ContactId c) throws DbException { try { Contact contact = db.getContact(txn, c); GroupId contactGroupId = getContactGroup(contact).getId(); BdfDictionary query = messageParser.getMessagesVisibleInUiQuery(); Map results = clientHelper .getMessageMetadataAsDictionary(txn, contactGroupId, query); - messages = new ArrayList<>(results.size()); + List messages = + new ArrayList<>(results.size()); for (Entry e : results.entrySet()) { MessageId m = e.getKey(); MessageMetadata meta = @@ -386,31 +385,25 @@ class GroupInvitationManagerImpl extends ConversationClientImpl MessageStatus status = db.getMessageStatus(txn, c, m); MessageType type = meta.getMessageType(); if (type == INVITE) { - messages.add(parseInvitationRequest(txn, c, contactGroupId, - m, meta, status)); + messages.add(parseInvitationRequest(txn, contactGroupId, m, + meta, status)); } else if (type == JOIN) { - messages.add( - parseInvitationResponse(c, contactGroupId, m, meta, - status, true)); + messages.add(parseInvitationResponse(contactGroupId, m, + meta, status, true)); } else if (type == LEAVE) { - messages.add( - parseInvitationResponse(c, contactGroupId, m, meta, - status, false)); + messages.add(parseInvitationResponse(contactGroupId, m, + meta, status, false)); } } - db.commitTransaction(txn); + return messages; } catch (FormatException e) { throw new DbException(e); - } finally { - db.endTransaction(txn); } - return messages; } private GroupInvitationRequest parseInvitationRequest(Transaction txn, - ContactId c, GroupId contactGroupId, MessageId m, - MessageMetadata meta, MessageStatus status) - throws DbException, FormatException { + GroupId contactGroupId, MessageId m, MessageMetadata meta, + MessageStatus status) throws DbException, FormatException { SessionId sessionId = getSessionId(meta.getPrivateGroupId()); // Look up the invite message to get the details of the private group InviteMessage invite = messageParser.getInviteMessage(txn, m); @@ -422,19 +415,19 @@ class GroupInvitationManagerImpl extends ConversationClientImpl db.containsGroup(txn, invite.getPrivateGroupId()); return new GroupInvitationRequest(m, contactGroupId, meta.getTimestamp(), meta.isLocal(), status.isSent(), - status.isSeen(), meta.isRead(), sessionId, pg, c, + status.isSeen(), meta.isRead(), sessionId, pg, invite.getMessage(), meta.isAvailableToAnswer(), canBeOpened); } - private GroupInvitationResponse parseInvitationResponse(ContactId c, + private GroupInvitationResponse parseInvitationResponse( GroupId contactGroupId, MessageId m, MessageMetadata meta, - MessageStatus status, boolean accept) - throws DbException, FormatException { + MessageStatus status, boolean accept) { SessionId sessionId = getSessionId(meta.getPrivateGroupId()); return new GroupInvitationResponse(m, contactGroupId, meta.getTimestamp(), meta.isLocal(), status.isSent(), - status.isSeen(), meta.isRead(), sessionId, - meta.getPrivateGroupId(), c, accept); + status.isSeen(), meta.isRead(), sessionId, accept, + meta.getPrivateGroupId() + ); } @Override diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngine.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngine.java index a0e73d9b0..722b562b8 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngine.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngine.java @@ -56,8 +56,7 @@ class InviteeProtocolEngine extends AbstractProtocolEngine { @Override public InviteeSession onInviteAction(Transaction txn, InviteeSession s, - @Nullable String message, long timestamp, byte[] signature) - throws DbException { + @Nullable String message, long timestamp, byte[] signature) { throw new UnsupportedOperationException(); // Invalid in this role } @@ -99,8 +98,8 @@ class InviteeProtocolEngine extends AbstractProtocolEngine { } @Override - public InviteeSession onMemberAddedAction(Transaction txn, InviteeSession s) - throws DbException { + public InviteeSession onMemberAddedAction(Transaction txn, + InviteeSession s) { return s; // Ignored in this role } @@ -244,9 +243,8 @@ class InviteeProtocolEngine extends AbstractProtocolEngine { // Broadcast an event PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup( m.getGroupName(), m.getCreator(), m.getSalt()); - txn.attach( - new GroupInvitationRequestReceivedEvent(privateGroup, contactId, - createInvitationRequest(m, privateGroup, contactId))); + txn.attach(new GroupInvitationRequestReceivedEvent( + createInvitationRequest(m, privateGroup), contactId)); // Move to the INVITED state return new InviteeSession(s.getContactGroupId(), s.getPrivateGroupId(), s.getLastLocalMessageId(), m.getId(), s.getLocalTimestamp(), @@ -328,10 +326,10 @@ class InviteeProtocolEngine extends AbstractProtocolEngine { } private GroupInvitationRequest createInvitationRequest(InviteMessage m, - PrivateGroup pg, ContactId c) { + PrivateGroup pg) { SessionId sessionId = new SessionId(m.getPrivateGroupId().getBytes()); return new GroupInvitationRequest(m.getId(), m.getContactGroupId(), - m.getTimestamp(), false, false, true, false, sessionId, pg, c, + m.getTimestamp(), false, false, true, false, sessionId, pg, m.getMessage(), true, false); } 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 0162f08de..780f2b7a1 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 @@ -24,17 +24,16 @@ public class BlogInvitationFactoryImpl SessionId sessionId = new SessionId(m.getShareableId().getBytes()); return new BlogInvitationRequest(m.getId(), m.getContactGroupId(), m.getTimestamp(), local, sent, seen, read, sessionId, - m.getShareable(), c, m.getMessage(), available, canBeOpened); + m.getShareable(), m.getMessage(), available, canBeOpened); } @Override public BlogInvitationResponse createInvitationResponse(MessageId id, GroupId contactGroupId, long time, boolean local, boolean sent, - boolean seen, boolean read, GroupId shareableId, - ContactId contactId, boolean accept) { + boolean seen, boolean read, boolean accept, GroupId shareableId) { SessionId sessionId = new SessionId(shareableId.getBytes()); - return new BlogInvitationResponse(id, contactGroupId, time, local, - sent, seen, read, sessionId, shareableId, contactId, accept); + return new BlogInvitationResponse(id, contactGroupId, time, local, sent, + seen, read, sessionId, accept, shareableId); } } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogMessageParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogMessageParserImpl.java index a2fc9d95d..9bb080bb2 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogMessageParserImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogMessageParserImpl.java @@ -30,7 +30,7 @@ class BlogMessageParserImpl extends MessageParserImpl { } @Override - protected Blog createShareable(BdfList descriptor) throws FormatException { + public Blog createShareable(BdfList descriptor) throws FormatException { // Author, RSS BdfList authorList = descriptor.getList(0); boolean rssFeed = descriptor.getBoolean(1); 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 25e0d0e8e..2ebaf2a10 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 @@ -18,7 +18,7 @@ import org.briarproject.briar.api.blog.BlogManager; import org.briarproject.briar.api.blog.event.BlogInvitationRequestReceivedEvent; import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent; import org.briarproject.briar.api.client.MessageTracker; -import org.briarproject.briar.api.sharing.InvitationRequest; +import org.briarproject.briar.api.messaging.PrivateRequest; import javax.annotation.concurrent.Immutable; import javax.inject.Inject; @@ -50,11 +50,10 @@ class BlogProtocolEngineImpl extends ProtocolEngineImpl { @Override Event getInvitationRequestReceivedEvent(InviteMessage m, ContactId contactId, boolean available, boolean canBeOpened) { - InvitationRequest request = invitationFactory + PrivateRequest request = invitationFactory .createInvitationRequest(false, false, true, false, m, contactId, available, canBeOpened); - return new BlogInvitationRequestReceivedEvent(m.getShareable(), - contactId, request); + return new BlogInvitationRequestReceivedEvent(request, contactId); } @Override @@ -62,9 +61,9 @@ class BlogProtocolEngineImpl extends ProtocolEngineImpl { ContactId contactId) { BlogInvitationResponse response = invitationFactory .createInvitationResponse(m.getId(), m.getContactGroupId(), - m.getTimestamp(), false, false, true, false, - m.getShareableId(), contactId, true); - return new BlogInvitationResponseReceivedEvent(contactId, response); + m.getTimestamp(), false, false, false, false, + true, m.getShareableId()); + return new BlogInvitationResponseReceivedEvent(response, contactId); } @Override @@ -72,9 +71,9 @@ class BlogProtocolEngineImpl extends ProtocolEngineImpl { ContactId contactId) { BlogInvitationResponse response = invitationFactory .createInvitationResponse(m.getId(), m.getContactGroupId(), - m.getTimestamp(), false, false, true, false, - m.getShareableId(), contactId, true); - return new BlogInvitationResponseReceivedEvent(contactId, response); + m.getTimestamp(), false, false, false, false, + false, m.getShareableId()); + return new BlogInvitationResponseReceivedEvent(response, contactId); } @Override diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java index 5c77c7be9..26852845d 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java @@ -80,8 +80,8 @@ class BlogSharingManagerImpl extends SharingManagerImpl // Pre-share both blogs, if they have not been shared already try { - preShareShareable(txn, c, ourBlog); - preShareShareable(txn, c, theirBlog); + preShareGroup(txn, c, ourBlog.getGroup()); + preShareGroup(txn, c, theirBlog.getGroup()); } catch (FormatException e) { throw new DbException(e); } 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 c59acfd00..4259c5cb2 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 @@ -24,17 +24,16 @@ public class ForumInvitationFactoryImpl SessionId sessionId = new SessionId(m.getShareableId().getBytes()); return new ForumInvitationRequest(m.getId(), m.getContactGroupId(), m.getTimestamp(), local, sent, seen, read, sessionId, - m.getShareable(), c, m.getMessage(), available, canBeOpened); + m.getShareable(), m.getMessage(), available, canBeOpened); } @Override public ForumInvitationResponse createInvitationResponse(MessageId id, GroupId contactGroupId, long time, boolean local, boolean sent, - boolean seen, boolean read, GroupId shareableId, - ContactId contactId, boolean accept) { + boolean seen, boolean read, boolean accept, GroupId shareableId) { SessionId sessionId = new SessionId(shareableId.getBytes()); return new ForumInvitationResponse(id, contactGroupId, time, local, - sent, seen, read, sessionId, shareableId, contactId, accept); + sent, seen, read, sessionId, accept, shareableId); } } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/ForumMessageParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/ForumMessageParserImpl.java index 44ef0d821..76e5569ba 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/ForumMessageParserImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/ForumMessageParserImpl.java @@ -24,7 +24,7 @@ class ForumMessageParserImpl extends MessageParserImpl { } @Override - protected Forum createShareable(BdfList descriptor) throws FormatException { + public Forum createShareable(BdfList descriptor) throws FormatException { // Name, salt String name = descriptor.getString(0); byte[] salt = descriptor.getRaw(1); 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 7b2a1c785..f4b5b627f 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 @@ -18,7 +18,7 @@ import org.briarproject.briar.api.forum.ForumInvitationResponse; import org.briarproject.briar.api.forum.ForumManager; import org.briarproject.briar.api.forum.event.ForumInvitationRequestReceivedEvent; import org.briarproject.briar.api.forum.event.ForumInvitationResponseReceivedEvent; -import org.briarproject.briar.api.sharing.InvitationRequest; +import org.briarproject.briar.api.messaging.PrivateRequest; import javax.annotation.concurrent.Immutable; import javax.inject.Inject; @@ -31,8 +31,7 @@ import static org.briarproject.briar.api.forum.ForumManager.MAJOR_VERSION; class ForumProtocolEngineImpl extends ProtocolEngineImpl { private final ForumManager forumManager; - private final InvitationFactory - invitationFactory; + private final InvitationFactory invitationFactory; @Inject ForumProtocolEngineImpl(DatabaseComponent db, @@ -52,11 +51,10 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl { @Override Event getInvitationRequestReceivedEvent(InviteMessage m, ContactId contactId, boolean available, boolean canBeOpened) { - InvitationRequest request = invitationFactory + PrivateRequest request = invitationFactory .createInvitationRequest(false, false, true, false, m, contactId, available, canBeOpened); - return new ForumInvitationRequestReceivedEvent(m.getShareable(), - contactId, request); + return new ForumInvitationRequestReceivedEvent(request, contactId); } @Override @@ -65,8 +63,8 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl { ForumInvitationResponse response = invitationFactory .createInvitationResponse(m.getId(), m.getContactGroupId(), m.getTimestamp(), false, false, true, false, - m.getShareableId(), contactId, true); - return new ForumInvitationResponseReceivedEvent(contactId, response); + true, m.getShareableId()); + return new ForumInvitationResponseReceivedEvent(response, contactId); } @Override @@ -75,8 +73,8 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl { ForumInvitationResponse response = invitationFactory .createInvitationResponse(m.getId(), m.getContactGroupId(), m.getTimestamp(), false, false, true, false, - m.getShareableId(), contactId, true); - return new ForumInvitationResponseReceivedEvent(contactId, response); + false, m.getShareableId()); + return new ForumInvitationResponseReceivedEvent(response, contactId); } @Override 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 ef473ca7b..086f44ae3 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 @@ -3,19 +3,18 @@ package org.briarproject.briar.sharing; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; -import org.briarproject.briar.api.sharing.InvitationRequest; +import org.briarproject.briar.api.messaging.PrivateRequest; import org.briarproject.briar.api.sharing.InvitationResponse; import org.briarproject.briar.api.sharing.Shareable; -public interface InvitationFactory { +public interface InvitationFactory { - InvitationRequest createInvitationRequest(boolean local, boolean sent, + PrivateRequest createInvitationRequest(boolean local, boolean sent, boolean seen, boolean read, InviteMessage m, ContactId c, boolean available, boolean canBeOpened); - I createInvitationResponse(MessageId id, - GroupId contactGroupId, long time, boolean local, boolean sent, - boolean seen, boolean read, GroupId shareableId, - ContactId contactId, boolean accept); + R createInvitationResponse(MessageId id, GroupId contactGroupId, long time, + boolean local, boolean sent, boolean seen, boolean read, + boolean accept, GroupId shareableId); } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParser.java b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParser.java index 869d017ad..e164dfdd8 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParser.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParser.java @@ -22,6 +22,8 @@ interface MessageParser { MessageMetadata parseMetadata(BdfDictionary meta) throws FormatException; + S createShareable(BdfList descriptor) throws FormatException; + InviteMessage getInviteMessage(Transaction txn, MessageId m) throws DbException, FormatException; 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 32659fe4f..4eaa98114 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 @@ -94,9 +94,6 @@ abstract class MessageParserImpl m.getGroupId(), shareable, message, m.getTimestamp()); } - protected abstract S createShareable(BdfList descriptor) - throws FormatException; - @Override public AcceptMessage parseAcceptMessage(Message m, BdfList body) throws FormatException { 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 0a672f578..8b20cdb10 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 @@ -293,7 +293,7 @@ abstract class ProtocolEngineImpl if (m.getTimestamp() <= s.getInviteTimestamp()) return abortWithMessage(txn, s); // The dependency, if any, must be the last remote message - if (!isValidDependency(s, m.getPreviousMessageId())) + if (isInvalidDependency(s, m.getPreviousMessageId())) return abortWithMessage(txn, s); // Mark the invite message visible in the UI and (un)available to answer markMessageVisibleInUi(txn, m.getId()); @@ -317,7 +317,7 @@ abstract class ProtocolEngineImpl if (m.getTimestamp() <= s.getInviteTimestamp()) return abortWithMessage(txn, s); // The dependency, if any, must be the last remote message - if (!isValidDependency(s, m.getPreviousMessageId())) + if (isInvalidDependency(s, m.getPreviousMessageId())) return abortWithMessage(txn, s); // Mark the invite message visible in the UI and unavailable to answer markMessageVisibleInUi(txn, m.getId()); @@ -364,7 +364,7 @@ abstract class ProtocolEngineImpl if (m.getTimestamp() <= s.getInviteTimestamp()) return abortWithMessage(txn, s); // The dependency, if any, must be the last remote message - if (!isValidDependency(s, m.getPreviousMessageId())) + if (isInvalidDependency(s, m.getPreviousMessageId())) return abortWithMessage(txn, s); // Mark the response visible in the UI markMessageVisibleInUi(txn, m.getId()); @@ -416,7 +416,7 @@ abstract class ProtocolEngineImpl if (m.getTimestamp() <= s.getInviteTimestamp()) return abortWithMessage(txn, s); // The dependency, if any, must be the last remote message - if (!isValidDependency(s, m.getPreviousMessageId())) + if (isInvalidDependency(s, m.getPreviousMessageId())) return abortWithMessage(txn, s); // Mark the response visible in the UI markMessageVisibleInUi(txn, m.getId()); @@ -463,7 +463,7 @@ abstract class ProtocolEngineImpl private Session onRemoteLeaveWhenInvited(Transaction txn, Session s, LeaveMessage m) throws DbException, FormatException { // The dependency, if any, must be the last remote message - if (!isValidDependency(s, m.getPreviousMessageId())) + if (isInvalidDependency(s, m.getPreviousMessageId())) return abortWithMessage(txn, s); // Mark any invite messages in the session unavailable to answer markInvitesUnavailableToAnswer(txn, s); @@ -476,7 +476,7 @@ abstract class ProtocolEngineImpl private Session onRemoteLeaveWhenLocalLeft(Transaction txn, Session s, LeaveMessage m) throws DbException, FormatException { // The dependency, if any, must be the last remote message - if (!isValidDependency(s, m.getPreviousMessageId())) + if (isInvalidDependency(s, m.getPreviousMessageId())) return abortWithMessage(txn, s); // Move to the next state return new Session(START, s.getContactGroupId(), s.getShareableId(), @@ -487,7 +487,7 @@ abstract class ProtocolEngineImpl private Session onRemoteLeaveWhenSharing(Transaction txn, Session s, LeaveMessage m) throws DbException, FormatException { // The dependency, if any, must be the last remote message - if (!isValidDependency(s, m.getPreviousMessageId())) + if (isInvalidDependency(s, m.getPreviousMessageId())) return abortWithMessage(txn, s); // Broadcast event informing that contact left ContactId contactId = getContactId(txn, s.getContactGroupId()); @@ -623,11 +623,11 @@ abstract class ProtocolEngineImpl return new ContactId(meta.getLong(GROUP_KEY_CONTACT_ID).intValue()); } - private boolean isValidDependency(Session session, + private boolean isInvalidDependency(Session session, @Nullable MessageId dependency) { MessageId expected = session.getLastRemoteMessageId(); - if (dependency == null) return expected == null; - return expected != null && dependency.equals(expected); + if (dependency == null) return expected != null; + return expected == null || !dependency.equals(expected); } private long getLocalTimestamp(Session session) { 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 fc57a6daa..d37807953 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 @@ -26,8 +26,8 @@ import org.briarproject.bramble.api.versioning.ClientVersioningManager; import org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVersioningHook; import org.briarproject.briar.api.client.MessageTracker; import org.briarproject.briar.api.client.SessionId; -import org.briarproject.briar.api.sharing.InvitationMessage; -import org.briarproject.briar.api.sharing.InvitationRequest; +import org.briarproject.briar.api.messaging.PrivateMessageHeader; +import org.briarproject.briar.api.messaging.PrivateRequest; import org.briarproject.briar.api.sharing.InvitationResponse; import org.briarproject.briar.api.sharing.Shareable; import org.briarproject.briar.api.sharing.SharingInvitationItem; @@ -156,29 +156,29 @@ abstract class SharingManagerImpl } /** - * Adds the given Shareable and initializes a session between us + * Adds the given Group and initializes a session between us * and the Contact c in state SHARING. * If a session already exists, this does nothing. */ - void preShareShareable(Transaction txn, Contact c, S shareable) + void preShareGroup(Transaction txn, Contact c, Group g) throws DbException, FormatException { // Return if a session already exists with the contact GroupId contactGroupId = getContactGroup(c).getId(); StoredSession existingSession = getSession(txn, contactGroupId, - getSessionId(shareable.getId())); + getSessionId(g.getId())); if (existingSession != null) return; - // Add the shareable - db.addGroup(txn, shareable.getGroup()); + // Add the shareable's group + db.addGroup(txn, g); // Apply the client's visibility Visibility client = clientVersioningManager.getClientVisibility(txn, c.getId(), getShareableClientId(), getShareableMajorVersion()); - db.setGroupVisibility(txn, c.getId(), shareable.getId(), client); + db.setGroupVisibility(txn, c.getId(), g.getId(), client); // Initialize session in sharing state - Session session = new Session(SHARING, contactGroupId, - shareable.getId(), null, null, 0, 0); + Session session = new Session(SHARING, contactGroupId, g.getId(), + null, null, 0, 0); MessageId storageId = createStorageId(txn, contactGroupId); storeSession(txn, storageId, session); } @@ -321,17 +321,16 @@ abstract class SharingManagerImpl } @Override - public Collection getInvitationMessages(ContactId c) - throws DbException { - List messages; - Transaction txn = db.startTransaction(true); + public Collection getMessageHeaders(Transaction txn, + ContactId c) throws DbException { try { Contact contact = db.getContact(txn, c); GroupId contactGroupId = getContactGroup(contact).getId(); BdfDictionary query = messageParser.getMessagesVisibleInUiQuery(); Map results = clientHelper .getMessageMetadataAsDictionary(txn, contactGroupId, query); - messages = new ArrayList<>(results.size()); + Collection messages = + new ArrayList<>(results.size()); for (Entry e : results.entrySet()) { MessageId m = e.getKey(); MessageMetadata meta = @@ -339,28 +338,23 @@ abstract class SharingManagerImpl MessageStatus status = db.getMessageStatus(txn, c, m); MessageType type = meta.getMessageType(); if (type == INVITE) { - messages.add( - parseInvitationRequest(txn, c, m, meta, status)); + messages.add(parseInvitationRequest(txn, c, m, + meta, status)); } else if (type == ACCEPT) { - messages.add( - parseInvitationResponse(c, contactGroupId, m, meta, - status, true)); + messages.add(parseInvitationResponse(contactGroupId, m, + meta, status, true)); } else if (type == DECLINE) { - messages.add( - parseInvitationResponse(c, contactGroupId, m, meta, - status, false)); + messages.add(parseInvitationResponse(contactGroupId, m, + meta, status, false)); } } - db.commitTransaction(txn); + return messages; } catch (FormatException e) { throw new DbException(e); - } finally { - db.endTransaction(txn); } - return messages; } - private InvitationRequest parseInvitationRequest(Transaction txn, + private PrivateRequest parseInvitationRequest(Transaction txn, ContactId c, MessageId m, MessageMetadata meta, MessageStatus status) throws DbException, FormatException { // Look up the invite message to get the details of the private group @@ -374,14 +368,12 @@ abstract class SharingManagerImpl meta.isAvailableToAnswer(), canBeOpened); } - private InvitationResponse parseInvitationResponse(ContactId c, - GroupId contactGroupId, MessageId m, MessageMetadata meta, - MessageStatus status, boolean accept) - throws DbException, FormatException { + private InvitationResponse parseInvitationResponse(GroupId contactGroupId, + MessageId m, MessageMetadata meta, MessageStatus status, + boolean accept) { return invitationFactory.createInvitationResponse(m, contactGroupId, meta.getTimestamp(), meta.isLocal(), status.isSent(), - status.isSeen(), meta.isRead(), meta.getShareableId(), c, - accept); + status.isSeen(), meta.isRead(), accept, meta.getShareableId()); } @Override diff --git a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java index a089eb0e0..49bba71d1 100644 --- a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java @@ -1,6 +1,5 @@ package org.briarproject.briar.blog; -import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.sync.MessageId; @@ -63,10 +62,7 @@ public class BlogManagerIntegrationTest blog1 = blogFactory.createBlog(author1); rssBlog = blogFactory.createFeedBlog(rssAuthor); - Transaction txn = db0.startTransaction(false); - blogManager0.addBlog(txn, rssBlog); - db0.commitTransaction(txn); - db0.endTransaction(txn); + withinTransaction(db0, txn -> blogManager0.addBlog(txn, rssBlog)); } @Override diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java index b3161af64..e366a627b 100644 --- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java @@ -9,8 +9,8 @@ import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfEntry; import org.briarproject.bramble.api.data.BdfList; +import org.briarproject.bramble.api.db.DatabaseComponent; 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.event.EventListener; import org.briarproject.bramble.api.identity.Author; @@ -25,13 +25,13 @@ import org.briarproject.bramble.test.TestDatabaseModule; import org.briarproject.briar.api.client.ProtocolStateException; import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.introduction.IntroductionManager; -import org.briarproject.briar.api.introduction.IntroductionMessage; import org.briarproject.briar.api.introduction.IntroductionRequest; import org.briarproject.briar.api.introduction.IntroductionResponse; import org.briarproject.briar.api.introduction.event.IntroductionAbortedEvent; import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent; import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent; import org.briarproject.briar.api.introduction.event.IntroductionSucceededEvent; +import org.briarproject.briar.api.messaging.PrivateMessageHeader; import org.briarproject.briar.test.BriarIntegrationTest; import org.junit.Before; import org.junit.Test; @@ -159,7 +159,7 @@ public class IntroductionIntegrationTest eventWaiter.await(TIMEOUT, 1); assertTrue(listener0.response1Received); assertEquals(introducee2.getAuthor().getName(), - listener0.getResponse().getName()); + listener0.getResponse().getIntroducedAuthor().getName()); assertGroupCount(messageTracker0, g1.getId(), 2, 1); // sync second ACCEPT message @@ -167,7 +167,7 @@ public class IntroductionIntegrationTest eventWaiter.await(TIMEOUT, 1); assertTrue(listener0.response2Received); assertEquals(introducee1.getAuthor().getName(), - listener0.getResponse().getName()); + listener0.getResponse().getIntroducedAuthor().getName()); assertGroupCount(messageTracker0, g2.getId(), 2, 1); // sync forwarded ACCEPT messages to introducees @@ -265,7 +265,7 @@ public class IntroductionIntegrationTest // assert that the name on the decline event is correct assertEquals(introducee2.getAuthor().getName(), - listener0.getResponse().getName()); + listener0.getResponse().getIntroducedAuthor().getName()); // sync second response sync2To0(1, true); @@ -282,7 +282,7 @@ public class IntroductionIntegrationTest // assert that the name on the decline event is correct eventWaiter.await(TIMEOUT, 1); assertEquals(introducee1.getAuthor().getName(), - listener2.getResponse().getName()); + listener2.getResponse().getIntroducedAuthor().getName()); // note how the introducer does not forward the second response, // because after the first decline the protocol finished @@ -297,22 +297,23 @@ public class IntroductionIntegrationTest Group g1 = introductionManager0.getContactGroup(introducee1); Group g2 = introductionManager0.getContactGroup(introducee2); - assertEquals(2, - introductionManager0.getIntroductionMessages(contactId1From0) - .size()); + Collection messages = + withinTransactionReturns(db0, txn -> introductionManager0 + .getMessageHeaders(txn, contactId1From0)); + assertEquals(2, messages.size()); assertGroupCount(messageTracker0, g1.getId(), 2, 1); - assertEquals(2, - introductionManager0.getIntroductionMessages(contactId2From0) - .size()); + messages = withinTransactionReturns(db0, + txn -> introductionManager0.getMessageHeaders(txn, contactId2From0)); + assertEquals(2, messages.size()); assertGroupCount(messageTracker0, g2.getId(), 2, 1); - assertEquals(2, - introductionManager1.getIntroductionMessages(contactId0From1) - .size()); + messages = withinTransactionReturns(db1, + txn -> introductionManager1.getMessageHeaders(txn, contactId0From1)); + assertEquals(2, messages.size()); assertGroupCount(messageTracker1, g1.getId(), 2, 1); // introducee2 should also have the decline response of introducee1 - assertEquals(3, - introductionManager2.getIntroductionMessages(contactId0From2) - .size()); + messages = withinTransactionReturns(db2, + txn -> introductionManager2.getMessageHeaders(txn, contactId0From2)); + assertEquals(3, messages.size()); assertGroupCount(messageTracker2, g2.getId(), 3, 2); assertFalse(listener0.aborted); @@ -355,25 +356,29 @@ public class IntroductionIntegrationTest // assert that the name on the decline event is correct eventWaiter.await(TIMEOUT, 1); assertEquals(contact2From0.getAuthor().getName(), - listener1.getResponse().getName()); + listener1.getResponse().getIntroducedAuthor().getName()); assertFalse(contactManager1 .contactExists(author2.getId(), author1.getId())); assertFalse(contactManager2 .contactExists(author1.getId(), author2.getId())); - assertEquals(2, - introductionManager0.getIntroductionMessages(contactId1From0) - .size()); - assertEquals(2, - introductionManager0.getIntroductionMessages(contactId2From0) - .size()); - assertEquals(3, - introductionManager1.getIntroductionMessages(contactId0From1) - .size()); - assertEquals(3, - introductionManager2.getIntroductionMessages(contactId0From2) - .size()); + Collection messages = + withinTransactionReturns(db0, txn -> introductionManager0 + .getMessageHeaders(txn, contactId1From0)); + assertEquals(2, messages.size()); + messages = withinTransactionReturns(db0, + txn -> introductionManager0 + .getMessageHeaders(txn, contactId2From0)); + assertEquals(2, messages.size()); + messages = withinTransactionReturns(db1, + txn -> introductionManager1 + .getMessageHeaders(txn, contactId0From1)); + assertEquals(3, messages.size()); + messages = withinTransactionReturns(db2, + txn -> introductionManager2 + .getMessageHeaders(txn, contactId0From2)); + assertEquals(3, messages.size()); assertFalse(listener0.aborted); assertFalse(listener1.aborted); assertFalse(listener2.aborted); @@ -482,7 +487,7 @@ public class IntroductionIntegrationTest // assert that the name on the decline event is correct eventWaiter.await(TIMEOUT, 1); assertEquals(introducee1.getAuthor().getName(), - listener2.getResponse().getName()); + listener2.getResponse().getIntroducedAuthor().getName()); // assert that introducee2 is in correct state introduceeSession = getIntroduceeSession(c2); @@ -519,21 +524,21 @@ public class IntroductionIntegrationTest Group g1 = introductionManager0.getContactGroup(introducee1); Group g2 = introductionManager0.getContactGroup(introducee2); - assertEquals(2, - introductionManager0.getIntroductionMessages(contactId1From0) - .size()); + assertEquals(2, withinTransactionReturns(db0, + txn -> introductionManager0.getMessageHeaders(txn, contactId1From0)) + .size()); assertGroupCount(messageTracker0, g1.getId(), 2, 1); - assertEquals(2, - introductionManager0.getIntroductionMessages(contactId2From0) - .size()); + assertEquals(2, withinTransactionReturns(db0, + txn -> introductionManager0.getMessageHeaders(txn, contactId2From0)) + .size()); assertGroupCount(messageTracker0, g2.getId(), 2, 1); - assertEquals(3, - introductionManager1.getIntroductionMessages(contactId0From1) - .size()); + assertEquals(3, withinTransactionReturns(db1, + txn -> introductionManager1.getMessageHeaders(txn, contactId0From1)) + .size()); assertGroupCount(messageTracker1, g1.getId(), 3, 2); - assertEquals(3, - introductionManager2.getIntroductionMessages(contactId0From2) - .size()); + assertEquals(3, withinTransactionReturns(db2, + txn -> introductionManager2.getMessageHeaders(txn, contactId0From2)) + .size()); assertGroupCount(messageTracker2, g2.getId(), 3, 2); assertFalse(listener0.aborted); @@ -557,7 +562,8 @@ public class IntroductionIntegrationTest assertFalse(listener1.requestReceived); // make really sure we don't have that request - assertTrue(introductionManager1.getIntroductionMessages(contactId0From1) + assertTrue(withinTransactionReturns(db1, + txn -> introductionManager1.getMessageHeaders(txn, contactId0From1)) .isEmpty()); // The message was invalid, so no abort message was sent @@ -606,12 +612,12 @@ public class IntroductionIntegrationTest sync0To2(1, true); // assert that introducees get notified about the existing contact - IntroductionRequest ir1 = - getIntroductionRequest(introductionManager1, contactId0From1); - assertTrue(ir1.contactExists()); - IntroductionRequest ir2 = - getIntroductionRequest(introductionManager2, contactId0From2); - assertTrue(ir2.contactExists()); + IntroductionRequest ir1 = getIntroductionRequest(db1, + introductionManager1, contactId0From1); + assertTrue(ir1.isContact()); + IntroductionRequest ir2 = getIntroductionRequest(db2, + introductionManager2, contactId0From2); + assertTrue(ir2.isContact()); // sync ACCEPT messages back to introducer sync1To0(1, true); @@ -991,8 +997,7 @@ public class IntroductionIntegrationTest AcceptMessage m = visitor.visit(message); // replace original response with modified one - Transaction txn = db0.startTransaction(false); - try { + withinTransaction(db0, txn -> { db0.removeMessage(txn, message.getMessageId()); Message msg = c0.getMessageEncoder() .encodeAcceptMessage(m.getGroupId(), m.getTimestamp(), @@ -1012,10 +1017,7 @@ public class IntroductionIntegrationTest session.getValue(), msg.getId()); c0.getClientHelper().mergeMessageMetadata(txn, session.getKey(), session.getValue()); - db0.commitTransaction(txn); - } finally { - db0.endTransaction(txn); - } + }); // sync second response sync2To0(1, true); @@ -1100,30 +1102,31 @@ public class IntroductionIntegrationTest } private void assertDefaultUiMessages() throws DbException { - Collection messages = - introductionManager0.getIntroductionMessages(contactId1From0); + Collection messages = + withinTransactionReturns(db0, txn -> introductionManager0 + .getMessageHeaders(txn, contactId1From0)); assertEquals(2, messages.size()); assertMessagesAreAcked(messages); - messages = introductionManager0.getIntroductionMessages( - contactId2From0); + messages = withinTransactionReturns(db0, + txn -> introductionManager0.getMessageHeaders(txn, contactId2From0)); assertEquals(2, messages.size()); assertMessagesAreAcked(messages); - messages = introductionManager1.getIntroductionMessages( - contactId0From1); + messages = withinTransactionReturns(db1, + txn -> introductionManager1.getMessageHeaders(txn, contactId0From1)); assertEquals(2, messages.size()); assertMessagesAreAcked(messages); - messages = introductionManager2.getIntroductionMessages( - contactId0From2); + messages = withinTransactionReturns(db2, + txn -> introductionManager2.getMessageHeaders(txn, contactId0From2)); assertEquals(2, messages.size()); assertMessagesAreAcked(messages); } private void assertMessagesAreAcked( - Collection messages) { - for (IntroductionMessage msg : messages) { + Collection messages) { + for (PrivateMessageHeader msg : messages) { if (msg.isLocal()) assertTrue(msg.isSeen()); } } @@ -1150,7 +1153,7 @@ public class IntroductionIntegrationTest assertTrue( latestEvent instanceof IntroductionResponseReceivedEvent); return ((IntroductionResponseReceivedEvent) latestEvent) - .getIntroductionResponse(); + .getMessageHeader(); } } @@ -1178,7 +1181,7 @@ public class IntroductionIntegrationTest IntroductionRequestReceivedEvent introEvent = ((IntroductionRequestReceivedEvent) e); requestReceived = true; - IntroductionRequest ir = introEvent.getIntroductionRequest(); + IntroductionRequest ir = introEvent.getMessageHeader(); ContactId contactId = introEvent.getContactId(); sessionId = ir.getSessionId(); long time = clock.currentTimeMillis(); @@ -1219,7 +1222,7 @@ public class IntroductionIntegrationTest assertTrue( latestEvent instanceof IntroductionRequestReceivedEvent); return ((IntroductionRequestReceivedEvent) latestEvent) - .getIntroductionRequest(); + .getMessageHeader(); } } @@ -1296,11 +1299,12 @@ public class IntroductionIntegrationTest } else throw new AssertionError("Not implemented"); } - private IntroductionRequest getIntroductionRequest( + private IntroductionRequest getIntroductionRequest(DatabaseComponent db, IntroductionManager manager, ContactId contactId) throws DbException { - for (IntroductionMessage im : manager - .getIntroductionMessages(contactId)) { + Collection messages = withinTransactionReturns(db, + txn -> manager.getMessageHeaders(txn, contactId)); + for (PrivateMessageHeader im : messages) { if (im instanceof IntroductionRequest) { return (IntroductionRequest) im; } diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/PrivateGroupManagerIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/PrivateGroupManagerIntegrationTest.java index 943c4dabe..c376c30e1 100644 --- a/briar-core/src/test/java/org/briarproject/briar/privategroup/PrivateGroupManagerIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/PrivateGroupManagerIntegrationTest.java @@ -2,7 +2,6 @@ package org.briarproject.briar.privategroup; import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.data.BdfList; -import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.test.TestDatabaseModule; @@ -245,11 +244,8 @@ public class PrivateGroupManagerIntegrationTest groupManager0.getPreviousMsgId(groupId0)); // share the group with 1 - Transaction txn0 = db0.startTransaction(false); - db0.setGroupVisibility(txn0, contactId1From0, privateGroup0.getId(), - SHARED); - db0.commitTransaction(txn0); - db0.endTransaction(txn0); + withinTransaction(db0, txn -> db0.setGroupVisibility(txn, + contactId1From0, privateGroup0.getId(), SHARED)); // author1 joins privateGroup0 with wrong timestamp joinTime = clock.currentTimeMillis(); @@ -266,11 +262,8 @@ public class PrivateGroupManagerIntegrationTest groupManager1.getPreviousMsgId(groupId0)); // share the group with 0 - Transaction txn1 = db1.startTransaction(false); - db1.setGroupVisibility(txn1, contactId0From1, privateGroup0.getId(), - SHARED); - db1.commitTransaction(txn1); - db1.endTransaction(txn1); + withinTransaction(db1, txn -> db1.setGroupVisibility(txn, + contactId0From1, privateGroup0.getId(), SHARED)); // sync join messages sync0To1(1, false); @@ -303,11 +296,8 @@ public class PrivateGroupManagerIntegrationTest groupManager0.getPreviousMsgId(groupId0)); // share the group with 1 - Transaction txn0 = db0.startTransaction(false); - db0.setGroupVisibility(txn0, contactId1From0, privateGroup0.getId(), - SHARED); - db0.commitTransaction(txn0); - db0.endTransaction(txn0); + withinTransaction(db0, txn -> db0.setGroupVisibility(txn, + contactId1From0, privateGroup0.getId(), SHARED)); // author1 joins privateGroup0 with wrong signature in join message joinTime = clock.currentTimeMillis(); @@ -325,11 +315,8 @@ public class PrivateGroupManagerIntegrationTest groupManager1.getPreviousMsgId(groupId0)); // share the group with 0 - Transaction txn1 = db1.startTransaction(false); - db1.setGroupVisibility(txn1, contactId0From1, privateGroup0.getId(), - SHARED); - db1.commitTransaction(txn1); - db1.endTransaction(txn1); + withinTransaction(db1, txn -> db1.setGroupVisibility(txn, + contactId0From1, privateGroup0.getId(), SHARED)); // sync join messages sync0To1(1, false); @@ -404,11 +391,8 @@ public class PrivateGroupManagerIntegrationTest addGroup(); // share the group with 2 - Transaction txn0 = db0.startTransaction(false); - db0.setGroupVisibility(txn0, contactId2From0, privateGroup0.getId(), - SHARED); - db0.commitTransaction(txn0); - db0.endTransaction(txn0); + withinTransaction(db0, txn -> db0.setGroupVisibility(txn, + contactId2From0, privateGroup0.getId(), SHARED)); // author2 joins privateGroup0 long joinTime = clock.currentTimeMillis(); @@ -420,14 +404,12 @@ public class PrivateGroupManagerIntegrationTest GroupMessage joinMsg2 = groupMessageFactory .createJoinMessage(privateGroup0.getId(), joinTime, author2, inviteTime, creatorSignature); - Transaction txn2 = db2.startTransaction(false); - groupManager2.addPrivateGroup(txn2, privateGroup0, joinMsg2, false); - - // share the group with 0 - db2.setGroupVisibility(txn2, contactId0From1, privateGroup0.getId(), - SHARED); - db2.commitTransaction(txn2); - db2.endTransaction(txn2); + withinTransaction(db2, txn -> { + groupManager2.addPrivateGroup(txn, privateGroup0, joinMsg2, false); + // share the group with 0 + db2.setGroupVisibility(txn, + contactId0From2, privateGroup0.getId(), SHARED); + }); // sync join messages sync2To0(1, true); @@ -458,16 +440,10 @@ public class PrivateGroupManagerIntegrationTest } // reveal contact relationship - Transaction txn1 = db1.startTransaction(false); - groupManager1 - .relationshipRevealed(txn1, groupId0, author2.getId(), false); - db1.commitTransaction(txn1); - db1.endTransaction(txn1); - txn2 = db2.startTransaction(false); - groupManager2 - .relationshipRevealed(txn2, groupId0, author1.getId(), true); - db2.commitTransaction(txn2); - db2.endTransaction(txn2); + withinTransaction(db1, txn -> groupManager1.relationshipRevealed(txn, + groupId0, author2.getId(), false)); + withinTransaction(db2, txn -> groupManager2.relationshipRevealed(txn, + groupId0, author1.getId(), true)); // assert that contact relationship is now revealed properly members1 = groupManager1.getMembers(groupId0); @@ -520,10 +496,8 @@ public class PrivateGroupManagerIntegrationTest assertFalse(groupManager1.isDissolved(groupId0)); // creator dissolves group - Transaction txn1 = db1.startTransaction(false); - groupManager1.markGroupDissolved(txn1, groupId0); - db1.commitTransaction(txn1); - db1.endTransaction(txn1); + withinTransaction(db1, + txn -> groupManager1.markGroupDissolved(txn, groupId0)); // group is dissolved now assertTrue(groupManager1.isDissolved(groupId0)); @@ -539,11 +513,8 @@ public class PrivateGroupManagerIntegrationTest groupManager0.getPreviousMsgId(groupId0)); // share the group with 1 - Transaction txn0 = db0.startTransaction(false); - db0.setGroupVisibility(txn0, contactId1From0, privateGroup0.getId(), - SHARED); - db0.commitTransaction(txn0); - db0.endTransaction(txn0); + withinTransaction(db0, txn -> db0.setGroupVisibility(txn, + contactId1From0, privateGroup0.getId(), SHARED)); // author1 joins privateGroup0 joinTime = clock.currentTimeMillis(); @@ -558,11 +529,8 @@ public class PrivateGroupManagerIntegrationTest groupManager1.addPrivateGroup(privateGroup0, joinMsg1, false); // share the group with 0 - Transaction txn1 = db1.startTransaction(false); - db1.setGroupVisibility(txn1, contactId0From1, privateGroup0.getId(), - SHARED); - db1.commitTransaction(txn1); - db1.endTransaction(txn1); + withinTransaction(db1, txn -> db1.setGroupVisibility(txn, + contactId0From1, privateGroup0.getId(), SHARED)); assertEquals(joinMsg1.getMessage().getId(), groupManager1.getPreviousMsgId(groupId0)); diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationIntegrationTest.java index 66a0bdb03..5ae80caf5 100644 --- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationIntegrationTest.java @@ -4,6 +4,7 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.test.TestDatabaseModule; import org.briarproject.briar.api.client.ProtocolStateException; +import org.briarproject.briar.api.messaging.PrivateMessageHeader; import org.briarproject.briar.api.privategroup.GroupMessage; import org.briarproject.briar.api.privategroup.PrivateGroup; import org.briarproject.briar.api.privategroup.PrivateGroupManager; @@ -11,8 +12,6 @@ import org.briarproject.briar.api.privategroup.invitation.GroupInvitationItem; import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager; import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest; import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse; -import org.briarproject.briar.api.sharing.InvitationMessage; -import org.briarproject.briar.api.sharing.InvitationResponse; import org.briarproject.briar.test.BriarIntegrationTest; import org.briarproject.briar.test.BriarIntegrationTestComponent; import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent; @@ -92,19 +91,20 @@ public class GroupInvitationIntegrationTest assertEquals(privateGroup0.getName(), item.getName()); assertFalse(item.isSubscribed()); - Collection messages = - groupInvitationManager1.getInvitationMessages(contactId0From1); + Collection messages = + withinTransactionReturns(db1, txn -> groupInvitationManager1 + .getMessageHeaders(txn, contactId0From1)); assertEquals(1, messages.size()); GroupInvitationRequest request = (GroupInvitationRequest) messages.iterator().next(); assertEquals(msg, request.getMessage()); - assertEquals(author0, request.getShareable().getCreator()); + assertEquals(author0, request.getNameable().getCreator()); assertEquals(timestamp, request.getTimestamp()); - assertEquals(contactId0From1, request.getContactId()); - assertEquals(privateGroup0.getName(), request.getShareable().getName()); + assertEquals(privateGroup0.getName(), request.getNameable().getName()); assertFalse(request.isLocal()); assertFalse(request.isRead()); assertFalse(request.canBeOpened()); + assertFalse(request.wasAnswered()); } @Test @@ -118,15 +118,16 @@ public class GroupInvitationIntegrationTest groupInvitationManager1 .respondToInvitation(contactId0From1, privateGroup0, false); - Collection messages = - groupInvitationManager1.getInvitationMessages(contactId0From1); + Collection messages = + withinTransactionReturns(db1, txn -> groupInvitationManager1 + .getMessageHeaders(txn, contactId0From1)); assertEquals(2, messages.size()); boolean foundResponse = false; - for (InvitationMessage m : messages) { + for (PrivateMessageHeader m : messages) { if (m instanceof GroupInvitationResponse) { foundResponse = true; - InvitationResponse response = (GroupInvitationResponse) m; - assertEquals(contactId0From1, response.getContactId()); + GroupInvitationResponse response = (GroupInvitationResponse) m; + assertEquals(privateGroup0.getId(), response.getShareableId()); assertTrue(response.isLocal()); assertFalse(response.wasAccepted()); } @@ -135,15 +136,15 @@ public class GroupInvitationIntegrationTest sync1To0(1, true); - messages = - groupInvitationManager0.getInvitationMessages(contactId1From0); + messages = withinTransactionReturns(db0, txn -> groupInvitationManager0 + .getMessageHeaders(txn, contactId1From0)); assertEquals(2, messages.size()); foundResponse = false; - for (InvitationMessage m : messages) { + for (PrivateMessageHeader m : messages) { if (m instanceof GroupInvitationResponse) { foundResponse = true; - InvitationResponse response = (GroupInvitationResponse) m; - assertEquals(contactId0From1, response.getContactId()); + GroupInvitationResponse response = (GroupInvitationResponse) m; + assertEquals(privateGroup0.getId(), response.getShareableId()); assertFalse(response.isLocal()); assertFalse(response.wasAccepted()); } @@ -167,31 +168,37 @@ public class GroupInvitationIntegrationTest groupInvitationManager1 .respondToInvitation(contactId0From1, privateGroup0, true); - Collection messages = - groupInvitationManager1.getInvitationMessages(contactId0From1); + Collection messages = + withinTransactionReturns(db1, txn -> groupInvitationManager1 + .getMessageHeaders(txn, contactId0From1)); assertEquals(2, messages.size()); boolean foundResponse = false; - for (InvitationMessage m : messages) { + for (PrivateMessageHeader m : messages) { if (m instanceof GroupInvitationResponse) { foundResponse = true; - InvitationResponse response = (GroupInvitationResponse) m; + GroupInvitationResponse response = (GroupInvitationResponse) m; + assertEquals(privateGroup0.getId(), response.getShareableId()); assertTrue(response.wasAccepted()); } else { - assertTrue(((GroupInvitationRequest) m).canBeOpened()); + GroupInvitationRequest request = (GroupInvitationRequest) m; + assertEquals(privateGroup0, request.getNameable()); + assertTrue(request.wasAnswered()); + assertTrue(request.canBeOpened()); } } assertTrue(foundResponse); sync1To0(1, true); - messages = - groupInvitationManager0.getInvitationMessages(contactId1From0); + messages = withinTransactionReturns(db1, txn -> groupInvitationManager0 + .getMessageHeaders(txn, contactId1From0)); assertEquals(2, messages.size()); foundResponse = false; - for (InvitationMessage m : messages) { + for (PrivateMessageHeader m : messages) { if (m instanceof GroupInvitationResponse) { foundResponse = true; - InvitationResponse response = (GroupInvitationResponse) m; + GroupInvitationResponse response = (GroupInvitationResponse) m; + assertEquals(privateGroup0.getId(), response.getShareableId()); assertTrue(response.wasAccepted()); } } @@ -219,9 +226,9 @@ public class GroupInvitationIntegrationTest // 1 has one unread message Group g0 = groupInvitationManager1.getContactGroup(contact0From1); assertGroupCount(messageTracker1, g0.getId(), 1, 1, timestamp); - InvitationMessage m = - groupInvitationManager1.getInvitationMessages(contactId0From1) - .iterator().next(); + PrivateMessageHeader m = withinTransactionReturns(db1, + txn -> groupInvitationManager1.getMessageHeaders(txn, contactId0From1) + .iterator().next()); groupInvitationManager1 .respondToInvitation(contactId0From1, privateGroup0, true); diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java index 328347b4d..e9a19ae7f 100644 --- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java @@ -24,13 +24,13 @@ import org.briarproject.bramble.test.BrambleMockTestCase; import org.briarproject.bramble.test.TestUtils; import org.briarproject.briar.api.client.MessageTracker; import org.briarproject.briar.api.client.SessionId; +import org.briarproject.briar.api.messaging.PrivateMessageHeader; import org.briarproject.briar.api.privategroup.PrivateGroup; import org.briarproject.briar.api.privategroup.PrivateGroupFactory; import org.briarproject.briar.api.privategroup.PrivateGroupManager; import org.briarproject.briar.api.privategroup.invitation.GroupInvitationItem; import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest; import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse; -import org.briarproject.briar.api.sharing.InvitationMessage; import org.jmock.AbstractExpectations; import org.jmock.Expectations; import org.jmock.lib.legacy.ClassImposteriser; @@ -669,8 +669,6 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase { invite.getCreator(), invite.getSalt()); context.checking(new Expectations() {{ - oneOf(db).startTransaction(true); - will(returnValue(txn)); oneOf(db).getContact(txn, contactId); will(returnValue(contact)); oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, @@ -696,23 +694,22 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase { oneOf(messageParser).parseMetadata(meta2); will(returnValue(messageMetadata2)); oneOf(db).getMessageStatus(txn, contactId, messageId2); - // end transaction - oneOf(db).commitTransaction(txn); - oneOf(db).endTransaction(txn); }}); - Collection messages = - groupInvitationManager.getInvitationMessages(contactId); + Collection messages = + groupInvitationManager.getMessageHeaders(txn, contactId); assertEquals(2, messages.size()); - for (InvitationMessage m : messages) { + for (PrivateMessageHeader m : messages) { assertEquals(contactGroup.getId(), m.getGroupId()); - assertEquals(contactId, m.getContactId()); if (m.getId().equals(message.getId())) { assertTrue(m instanceof GroupInvitationRequest); assertEquals(time1, m.getTimestamp()); + assertEquals(pg, ((GroupInvitationRequest) m).getNameable()); } else if (m.getId().equals(messageId2)) { assertTrue(m instanceof GroupInvitationResponse); assertEquals(time2, m.getTimestamp()); + assertEquals(pg.getId(), + ((GroupInvitationResponse) m).getShareableId()); } else { throw new AssertionError(); } diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingIntegrationTest.java index 1fbc64387..44a1d3995 100644 --- a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingIntegrationTest.java @@ -18,7 +18,7 @@ import org.briarproject.briar.api.blog.BlogManager; import org.briarproject.briar.api.blog.BlogSharingManager; import org.briarproject.briar.api.blog.event.BlogInvitationRequestReceivedEvent; import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent; -import org.briarproject.briar.api.sharing.InvitationMessage; +import org.briarproject.briar.api.messaging.PrivateMessageHeader; import org.briarproject.briar.test.BriarIntegrationTest; import org.briarproject.briar.test.BriarIntegrationTestComponent; import org.briarproject.briar.test.DaggerBriarIntegrationTestComponent; @@ -27,9 +27,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; import static org.briarproject.briar.api.blog.BlogSharingManager.CLIENT_ID; import static org.briarproject.briar.api.blog.BlogSharingManager.MAJOR_VERSION; @@ -147,32 +145,30 @@ public class BlogSharingIntegrationTest assertTrue(blogManager1.getBlogs().contains(blog2)); // invitee has one invitation message from sharer - List list = new ArrayList<>( - blogSharingManager1.getInvitationMessages(contactId0From1)); + Collection list = withinTransactionReturns(db1, + txn -> blogSharingManager1.getMessageHeaders(txn, contactId0From1)); assertEquals(2, list.size()); // check other things are alright with the message - for (InvitationMessage m : list) { + for (PrivateMessageHeader m : list) { if (m instanceof BlogInvitationRequest) { - BlogInvitationRequest invitation = - (BlogInvitationRequest) m; - assertFalse(invitation.isAvailable()); + BlogInvitationRequest invitation = (BlogInvitationRequest) m; + assertEquals(blog2, invitation.getNameable()); + assertTrue(invitation.wasAnswered()); assertEquals(blog2.getAuthor().getName(), - invitation.getBlogAuthorName()); - assertFalse(invitation.getShareable().isRssFeed()); - assertEquals(contactId1From0, invitation.getContactId()); + invitation.getName()); + assertFalse(invitation.getNameable().isRssFeed()); assertEquals("Hi!", invitation.getMessage()); } else { - BlogInvitationResponse response = - (BlogInvitationResponse) m; - assertEquals(contactId0From1, response.getContactId()); + BlogInvitationResponse response = (BlogInvitationResponse) m; + assertEquals(blog2.getId(), response.getShareableId()); assertTrue(response.wasAccepted()); assertTrue(response.isLocal()); } } // sharer has own invitation message and response - assertEquals(2, - blogSharingManager0.getInvitationMessages(contactId1From0) - .size()); + assertEquals(2, withinTransactionReturns(db0, + txn -> blogSharingManager0.getMessageHeaders(txn, contactId1From0)) + .size()); // blog can not be shared again assertFalse(blogSharingManager0.canBeShared(blog2.getId(), contact1From0)); @@ -222,31 +218,30 @@ public class BlogSharingIntegrationTest assertTrue(blogManager1.getBlogs().contains(rssBlog)); // invitee has one invitation message from sharer - List list = new ArrayList<>( - blogSharingManager1.getInvitationMessages(contactId0From1)); + Collection list = withinTransactionReturns(db1, + txn -> blogSharingManager1.getMessageHeaders(txn, contactId0From1)); assertEquals(2, list.size()); // check other things are alright with the message - for (InvitationMessage m : list) { + for (PrivateMessageHeader m : list) { if (m instanceof BlogInvitationRequest) { - BlogInvitationRequest invitation = - (BlogInvitationRequest) m; - assertFalse(invitation.isAvailable()); + BlogInvitationRequest invitation = (BlogInvitationRequest) m; + assertEquals(rssBlog, invitation.getNameable()); + assertTrue(invitation.wasAnswered()); assertEquals(rssBlog.getAuthor().getName(), - invitation.getBlogAuthorName()); - assertTrue(invitation.getShareable().isRssFeed()); - assertEquals(contactId1From0, invitation.getContactId()); + invitation.getName()); + assertTrue(invitation.getNameable().isRssFeed()); assertEquals("Hi!", invitation.getMessage()); } else { - BlogInvitationResponse response = - (BlogInvitationResponse) m; - assertEquals(contactId0From1, response.getContactId()); + BlogInvitationResponse response = (BlogInvitationResponse) m; + assertEquals(rssBlog.getId(), response.getShareableId()); assertTrue(response.wasAccepted()); assertTrue(response.isLocal()); } } // sharer has own invitation message and response - assertEquals(2, blogSharingManager0.getInvitationMessages( - contactId1From0).size()); + assertEquals(2, withinTransactionReturns(db0, + txn -> blogSharingManager0.getMessageHeaders(txn, contactId1From0)) + .size()); // blog can not be shared again assertFalse(blogSharingManager0.canBeShared(rssBlog.getId(), contact1From0)); @@ -285,31 +280,29 @@ public class BlogSharingIntegrationTest assertEquals(0, blogSharingManager1.getInvitations().size()); // invitee has one invitation message from sharer and one response - List list = new ArrayList<>( - blogSharingManager1.getInvitationMessages(contactId0From1)); + Collection list = withinTransactionReturns(db1, + txn -> blogSharingManager1.getMessageHeaders(txn, contactId0From1)); assertEquals(2, list.size()); // check things are alright with the message - for (InvitationMessage m : list) { + for (PrivateMessageHeader m : list) { if (m instanceof BlogInvitationRequest) { - BlogInvitationRequest invitation = - (BlogInvitationRequest) m; - assertFalse(invitation.isAvailable()); + BlogInvitationRequest invitation = (BlogInvitationRequest) m; + assertEquals(blog2, invitation.getNameable()); + assertTrue(invitation.wasAnswered()); assertEquals(blog2.getAuthor().getName(), - invitation.getBlogAuthorName()); - assertEquals(contactId1From0, invitation.getContactId()); + invitation.getName()); assertEquals(null, invitation.getMessage()); } else { - BlogInvitationResponse response = - (BlogInvitationResponse) m; - assertEquals(contactId0From1, response.getContactId()); + BlogInvitationResponse response = (BlogInvitationResponse) m; + assertEquals(blog2.getId(), response.getShareableId()); assertFalse(response.wasAccepted()); assertTrue(response.isLocal()); } } // sharer has own invitation message and response - assertEquals(2, - blogSharingManager0.getInvitationMessages(contactId1From0) - .size()); + assertEquals(2, withinTransactionReturns(db0, + txn -> blogSharingManager0.getMessageHeaders(txn, contactId1From0)) + .size()); // blog can be shared again assertTrue( blogSharingManager0.canBeShared(blog2.getId(), contact1From0)); @@ -394,8 +387,9 @@ public class BlogSharingIntegrationTest assertTrue(contacts.contains(contact0From1)); // make sure 1 knows that they have blog2 already - Collection messages = - blogSharingManager1.getInvitationMessages(contactId0From1); + Collection messages = + withinTransactionReturns(db1, txn -> blogSharingManager1 + .getMessageHeaders(txn, contactId0From1)); assertEquals(2, messages.size()); assertEquals(blog2, blogManager1.getBlog(blog2.getId())); @@ -565,7 +559,7 @@ public class BlogSharingIntegrationTest BlogInvitationRequestReceivedEvent event = (BlogInvitationRequestReceivedEvent) e; eventWaiter.assertEquals(contactId1From0, event.getContactId()); - Blog b = event.getShareable(); + Blog b = event.getMessageHeader().getNameable(); try { Contact c = contactManager0.getContact(contactId1From0); blogSharingManager0.respondToInvitation(b, c, true); @@ -601,7 +595,7 @@ public class BlogSharingIntegrationTest (BlogInvitationRequestReceivedEvent) e; requestReceived = true; if (!answer) return; - Blog b = event.getShareable(); + Blog b = event.getMessageHeader().getNameable(); try { eventWaiter.assertEquals(1, blogSharingManager1.getInvitations().size()); @@ -624,7 +618,7 @@ public class BlogSharingIntegrationTest } } - private void listenToEvents(boolean accept) throws DbException { + private void listenToEvents(boolean accept) { listener0 = new SharerListener(); c0.getEventBus().addListener(listener0); listener1 = new InviteeListener(accept); diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingIntegrationTest.java index 2683ea715..4e87aaa73 100644 --- a/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingIntegrationTest.java @@ -5,7 +5,6 @@ import net.jodah.concurrentunit.Waiter; import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.data.BdfDictionary; 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.event.EventListener; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; @@ -22,7 +21,7 @@ import org.briarproject.briar.api.forum.ForumPostHeader; import org.briarproject.briar.api.forum.ForumSharingManager; import org.briarproject.briar.api.forum.event.ForumInvitationRequestReceivedEvent; import org.briarproject.briar.api.forum.event.ForumInvitationResponseReceivedEvent; -import org.briarproject.briar.api.sharing.InvitationMessage; +import org.briarproject.briar.api.messaging.PrivateMessageHeader; import org.briarproject.briar.api.sharing.SharingInvitationItem; import org.briarproject.briar.test.BriarIntegrationTest; import org.briarproject.briar.test.BriarIntegrationTestComponent; @@ -32,9 +31,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; import static junit.framework.Assert.assertNotNull; import static org.briarproject.bramble.util.StringUtils.getRandomString; @@ -131,31 +128,28 @@ public class ForumSharingIntegrationTest assertEquals(1, forumManager1.getForums().size()); // invitee has one invitation message from sharer - List list = new ArrayList<>( - forumSharingManager1.getInvitationMessages(contactId0From1)); + Collection list = withinTransactionReturns(db1, + txn -> forumSharingManager1.getMessageHeaders(txn, contactId0From1)); assertEquals(2, list.size()); // check other things are alright with the forum message - for (InvitationMessage m : list) { + for (PrivateMessageHeader m : list) { if (m instanceof ForumInvitationRequest) { - ForumInvitationRequest invitation = - (ForumInvitationRequest) m; - assertFalse(invitation.isAvailable()); - assertEquals(forum0.getName(), invitation.getForumName()); - assertEquals(contactId1From0, invitation.getContactId()); + ForumInvitationRequest invitation = (ForumInvitationRequest) m; + assertTrue(invitation.wasAnswered()); + assertEquals(forum0.getName(), invitation.getName()); + assertEquals(forum0, invitation.getNameable()); assertEquals("Hi!", invitation.getMessage()); assertTrue(invitation.canBeOpened()); } else { - ForumInvitationResponse response = - (ForumInvitationResponse) m; - assertEquals(contactId0From1, response.getContactId()); + ForumInvitationResponse response = (ForumInvitationResponse) m; + assertEquals(forum0.getId(), response.getShareableId()); assertTrue(response.wasAccepted()); assertTrue(response.isLocal()); } } // sharer has own invitation message and response - assertEquals(2, - forumSharingManager0.getInvitationMessages(contactId1From0) - .size()); + assertEquals(2, withinTransactionReturns(db0, txn -> + forumSharingManager0.getMessageHeaders(txn, contactId1From0)).size()); // forum can not be shared again Contact c1 = contactManager0.getContact(contactId1From0); assertFalse(forumSharingManager0.canBeShared(forum0.getId(), c1)); @@ -190,31 +184,28 @@ public class ForumSharingIntegrationTest assertEquals(0, forumSharingManager1.getInvitations().size()); // invitee has one invitation message from sharer and one response - List list = new ArrayList<>( - forumSharingManager1.getInvitationMessages(contactId0From1)); + Collection list = withinTransactionReturns(db1, + txn -> forumSharingManager1.getMessageHeaders(txn, contactId0From1)); assertEquals(2, list.size()); // check things are alright with the forum message - for (InvitationMessage m : list) { + for (PrivateMessageHeader m : list) { if (m instanceof ForumInvitationRequest) { - ForumInvitationRequest invitation = - (ForumInvitationRequest) m; - assertFalse(invitation.isAvailable()); - assertEquals(forum0.getName(), invitation.getForumName()); - assertEquals(contactId1From0, invitation.getContactId()); + ForumInvitationRequest invitation = (ForumInvitationRequest) m; + assertEquals(forum0, invitation.getNameable()); + assertTrue(invitation.wasAnswered()); + assertEquals(forum0.getName(), invitation.getName()); assertEquals(null, invitation.getMessage()); assertFalse(invitation.canBeOpened()); } else { - ForumInvitationResponse response = - (ForumInvitationResponse) m; - assertEquals(contactId0From1, response.getContactId()); + ForumInvitationResponse response = (ForumInvitationResponse) m; + assertEquals(forum0.getId(), response.getShareableId()); assertFalse(response.wasAccepted()); assertTrue(response.isLocal()); } } // sharer has own invitation message and response - assertEquals(2, - forumSharingManager0.getInvitationMessages(contactId1From0) - .size()); + assertEquals(2, withinTransactionReturns(db0, txn -> + forumSharingManager0.getMessageHeaders(txn, contactId1From0)).size()); // forum can be shared again Contact c1 = contactManager0.getContact(contactId1From0); assertTrue(forumSharingManager0.canBeShared(forum0.getId(), c1)); @@ -455,10 +446,7 @@ public class ForumSharingIntegrationTest listenToEvents(true); // invitee adds the same forum - Transaction txn = db1.startTransaction(false); - forumManager1.addForum(txn, forum0); - db1.commitTransaction(txn); - db1.endTransaction(txn); + withinTransaction(db1, txn -> forumManager1.addForum(txn, forum0)); // send invitation forumSharingManager0 @@ -490,10 +478,12 @@ public class ForumSharingIntegrationTest .contains(contact0From1)); // and both have each other's invitations (and no response) - assertEquals(2, forumSharingManager0 - .getInvitationMessages(contactId1From0).size()); - assertEquals(2, forumSharingManager1 - .getInvitationMessages(contactId0From1).size()); + assertEquals(2, withinTransactionReturns(db0, txn -> + forumSharingManager0.getMessageHeaders(txn, contactId1From0)) + .size()); + assertEquals(2, withinTransactionReturns(db1, txn -> + forumSharingManager1.getMessageHeaders(txn, contactId0From1)) + .size()); // there are no more open invitations assertTrue(forumSharingManager0.getInvitations().isEmpty()); @@ -568,17 +558,14 @@ public class ForumSharingIntegrationTest @Test public void testTwoContactsShareSameForum() throws Exception { // second sharer adds the same forum - Transaction txn = db2.startTransaction(false); - db2.addGroup(txn, forum0.getGroup()); - db2.commitTransaction(txn); - db2.endTransaction(txn); + withinTransaction(db2, txn -> db2.addGroup(txn, forum0.getGroup())); // add listeners - listener0 = new SharerListener(); + listener0 = new SharerListener(true); c0.getEventBus().addListener(listener0); listener1 = new InviteeListener(true, false); c1.getEventBus().addListener(listener1); - listener2 = new SharerListener(); + listener2 = new SharerListener(true); c2.getEventBus().addListener(listener2); // send invitation @@ -748,8 +735,9 @@ public class ForumSharingIntegrationTest // get invitation MessageId for later MessageId invitationId = null; - for (InvitationMessage m : forumSharingManager1 - .getInvitationMessages(contactId0From1)) { + Collection list = withinTransactionReturns(db1, + txn -> forumSharingManager1.getMessageHeaders(txn, contactId0From1)); + for (PrivateMessageHeader m : list) { if (m instanceof ForumInvitationRequest) { invitationId = m.getId(); } @@ -802,13 +790,22 @@ public class ForumSharingIntegrationTest @NotNullByDefault private class SharerListener implements EventListener { + private final boolean accept; private volatile boolean requestReceived = false; private volatile boolean responseReceived = false; + private SharerListener(boolean accept) { + this.accept = accept; + } + @Override public void eventOccurred(Event e) { if (e instanceof ForumInvitationResponseReceivedEvent) { + ForumInvitationResponseReceivedEvent event = + (ForumInvitationResponseReceivedEvent) e; responseReceived = true; + eventWaiter.assertEquals(accept, + event.getMessageHeader().wasAccepted()); eventWaiter.resume(); } // this is only needed for tests where a forum is re-shared @@ -817,7 +814,7 @@ public class ForumSharingIntegrationTest (ForumInvitationRequestReceivedEvent) e; eventWaiter.assertEquals(contactId1From0, event.getContactId()); requestReceived = true; - Forum f = event.getShareable(); + Forum f = event.getMessageHeader().getNameable(); try { if (respond) { Contact c = contactManager0.getContact(contactId1From0); @@ -855,7 +852,7 @@ public class ForumSharingIntegrationTest (ForumInvitationRequestReceivedEvent) e; requestReceived = true; if (!answer) return; - Forum f = event.getShareable(); + Forum f = event.getMessageHeader().getNameable(); try { if (respond) { eventWaiter.assertEquals(1, @@ -880,17 +877,19 @@ public class ForumSharingIntegrationTest ForumInvitationResponseReceivedEvent event = (ForumInvitationResponseReceivedEvent) e; eventWaiter.assertEquals(contactId0From1, event.getContactId()); + eventWaiter.assertEquals(accept, + event.getMessageHeader().wasAccepted()); eventWaiter.resume(); } } } - private void listenToEvents(boolean accept) throws DbException { - listener0 = new SharerListener(); + private void listenToEvents(boolean accept) { + listener0 = new SharerListener(accept); c0.getEventBus().addListener(listener0); listener1 = new InviteeListener(accept); c1.getEventBus().addListener(listener1); - listener2 = new SharerListener(); + listener2 = new SharerListener(accept); c2.getEventBus().addListener(listener2); } diff --git a/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java index f10d94183..1d74f72e9 100644 --- a/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java @@ -2,6 +2,7 @@ package org.briarproject.briar.test; import net.jodah.concurrentunit.Waiter; +import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ContactGroupFactory; import org.briarproject.bramble.api.contact.Contact; @@ -10,6 +11,7 @@ import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.db.DatabaseComponent; 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.event.EventListener; import org.briarproject.bramble.api.identity.AuthorFactory; @@ -376,4 +378,41 @@ public abstract class BriarIntegrationTest { + R execute(Transaction txn) throws DbException; + } + + protected R withinTransactionReturns(DatabaseComponent db, + TransactionResultScope scope) throws DbException { + Transaction txn = db.startTransaction(false); + R r; + try { + r = scope.execute(txn); + db.commitTransaction(txn); + } finally { + db.endTransaction(txn); + } + return r; + } + }