Use ConversationManager to retrieve messages

This removes the public method for retrieving messages
from individual conversation clients
and just leaves methods that require a transaction
to be used by the ConversationManager only.
parent 29758b17
......@@ -62,8 +62,8 @@ 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.IntroductionRequest;
import org.briarproject.briar.api.introduction.IntroductionResponse;
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;
......@@ -159,6 +159,8 @@ public class ConversationActivity extends BriarActivity
@Inject
volatile MessagingManager messagingManager;
@Inject
volatile ConversationManager conversationManager;
@Inject
volatile EventBus eventBus;
@Inject
volatile SettingsManager settingsManager;
......@@ -337,23 +339,9 @@ public class ConversationActivity extends BriarActivity
try {
long start = now();
Collection<PrivateMessageHeader> headers =
messagingManager.getMessages(contactId);
Collection<PrivateMessageHeader> introductions =
introductionManager.getMessages(contactId);
Collection<PrivateMessageHeader> forumInvitations =
forumSharingManager.getMessages(contactId);
Collection<PrivateMessageHeader> blogInvitations =
blogSharingManager.getMessages(contactId);
Collection<PrivateMessageHeader> groupInvitations =
groupInvitationManager.getMessages(contactId);
List<PrivateMessageHeader> 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) {
......@@ -363,15 +351,12 @@ public class ConversationActivity extends BriarActivity
}
private void displayMessages(int revision,
Collection<PrivateMessageHeader> headers,
Collection<PrivateMessageHeader> introductions,
Collection<PrivateMessageHeader> invitations) {
Collection<PrivateMessageHeader> headers) {
runOnUiThreadUnlessDestroyed(() -> {
if (revision == adapter.getRevision()) {
adapter.incrementRevision();
textInputView.setSendButtonEnabled(true);
List<ConversationItem> items = createItems(headers,
introductions, invitations);
List<ConversationItem> items = createItems(headers);
adapter.addAll(items);
list.showData();
// Scroll to the bottom
......@@ -390,38 +375,24 @@ public class ConversationActivity extends BriarActivity
*/
@SuppressWarnings("ConstantConditions")
private List<ConversationItem> createItems(
Collection<PrivateMessageHeader> headers,
Collection<PrivateMessageHeader> introductions,
Collection<PrivateMessageHeader> invitations) {
int size =
headers.size() + introductions.size() + invitations.size();
List<ConversationItem> items = new ArrayList<>(size);
Collection<PrivateMessageHeader> headers) {
List<ConversationItem> 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 (PrivateMessageHeader m : introductions) {
ConversationItem item;
if (m instanceof IntroductionRequest) {
IntroductionRequest i = (IntroductionRequest) m;
if (h instanceof IntroductionResponse) {
IntroductionResponse i = (IntroductionResponse) h;
item = ConversationItem.from(this, contactName, i);
} else {
IntroductionResponse i = (IntroductionResponse) m;
item = ConversationItem.from(this, contactName, i);
}
items.add(item);
}
for (PrivateMessageHeader i : invitations) {
ConversationItem item;
if (i instanceof PrivateRequest) {
item = ConversationItem
.from(this, contactName, (PrivateRequest) i);
} else {
PrivateResponse r = (PrivateResponse) i;
} else if (h instanceof PrivateRequest) {
PrivateRequest r = (PrivateRequest) h;
item = ConversationItem.from(this, contactName, r);
} else if (h instanceof PrivateResponse) {
PrivateResponse r = (PrivateResponse) h;
item = ConversationItem.from(this, contactName, r);
} else {
item = ConversationItem.from(h);
String body = bodyCache.get(h.getId());
if (body == null) loadMessageBody(h.getId());
else item.setBody(body);
}
items.add(item);
}
......@@ -513,9 +484,9 @@ public class ConversationActivity extends BriarActivity
getContactNameTask().addListener(new FutureTaskListener<String>() {
@Override
public void onSuccess(String contactName) {
runOnUiThreadUnlessDestroyed(() -> {
handlePrivateRequestAndResponse(h, contactName);
});
runOnUiThreadUnlessDestroyed(
() -> handlePrivateRequestAndResponse(h,
contactName));
}
@Override
......
......@@ -34,7 +34,8 @@ import static org.briarproject.briar.android.contact.ConversationRequestItem.Req
@NotNullByDefault
abstract class ConversationItem {
protected @Nullable String body;
@Nullable
protected String body;
private final MessageId id;
private final GroupId groupId;
private final long time;
......@@ -105,7 +106,7 @@ abstract class ConversationItem {
R.string.groups_invitations_invitation_sent,
contactName, ir.getName());
} else {
throw new IllegalArgumentException("Unknown InvitationRequest");
throw new IllegalArgumentException("Unknown PrivateRequest");
}
return new ConversationNoticeOutItem(ir.getId(), ir.getGroupId(),
text, ir.getMessage(), ir.getTimestamp(), ir.isSent(),
......@@ -145,7 +146,7 @@ abstract class ConversationItem {
contactName, ir.getName());
type = GROUP;
} else {
throw new IllegalArgumentException("Unknown InvitationRequest");
throw new IllegalArgumentException("Unknown PrivateRequest");
}
return new ConversationRequestItem(ir.getId(),
ir.getGroupId(), type, ir.getSessionId(), text,
......@@ -229,22 +230,24 @@ abstract class ConversationItem {
} 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;
res =
R.string.groups_invitations_response_accepted_received;
} else {
throw new IllegalArgumentException(
"Unknown PrivateResponse");
}
} 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 PrivateResponse");
}
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 PrivateResponse");
}
}
String text = ctx.getString(res, contactName);
return new ConversationNoticeInItem(ir.getId(), ir.getGroupId(),
......@@ -258,11 +261,11 @@ abstract class ConversationItem {
* PrivateMessageHeader.
**/
static ConversationItem from(Context ctx, PrivateMessageHeader h) {
if(h instanceof IntroductionResponse) {
if (h instanceof IntroductionResponse) {
return from(ctx, "", (IntroductionResponse) h);
} else if(h instanceof PrivateRequest) {
} else if (h instanceof PrivateRequest) {
return from(ctx, "", (PrivateRequest) h);
} else if(h instanceof PrivateResponse) {
} else if (h instanceof PrivateResponse) {
return from(ctx, "", (PrivateResponse) h);
} else {
return from(h);
......
......@@ -7,9 +7,6 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.messaging.ConversationManager.ConversationClient;
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
import java.util.Collection;
import javax.annotation.Nullable;
......@@ -48,11 +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.
*/
@Deprecated
Collection<PrivateMessageHeader> getMessages(ContactId contactId)
throws DbException;
}
......@@ -22,12 +22,12 @@ public interface ConversationManager {
void registerConversationClient(ConversationClient client);
/**
* Returns (the headers) of all messages in the given private conversation.
* 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<PrivateMessageHeader> getMessages(ContactId c)
Collection<PrivateMessageHeader> getMessageHeaders(ContactId c)
throws DbException;
/**
......@@ -40,7 +40,7 @@ public interface ConversationManager {
Group getContactGroup(Contact c);
Collection<PrivateMessageHeader> getMessages(Transaction txn,
Collection<PrivateMessageHeader> getMessageHeaders(Transaction txn,
ContactId contactId) throws DbException;
GroupCount getGroupCount(Transaction txn, ContactId c)
......
......@@ -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,13 +41,6 @@ public interface MessagingManager extends ConversationClient {
*/
GroupId getConversationId(ContactId c) throws DbException;
/**
* Returns the headers of all messages in the given private conversation.
*/
@Deprecated
Collection<PrivateMessageHeader> getMessages(ContactId c)
throws DbException;
/**
* Returns the body of the private message with the given ID.
*/
......
......@@ -9,7 +9,6 @@ import org.briarproject.bramble.api.sync.GroupId;
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.messaging.PrivateMessageHeader;
import org.briarproject.briar.api.privategroup.PrivateGroup;
import java.util.Collection;
......@@ -73,14 +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.
*/
@Deprecated
Collection<PrivateMessageHeader> getMessages(ContactId c)
throws DbException;
/**
* Returns all private groups to which the user has been invited.
*/
......
......@@ -7,7 +7,6 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.messaging.ConversationManager.ConversationClient;
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
import java.util.Collection;
......@@ -36,14 +35,6 @@ public interface SharingManager<S extends Shareable>
void respondToInvitation(ContactId c, SessionId id, boolean accept)
throws DbException;
/**
* Returns all group sharing messages sent by the Contact
* identified by contactId.
*/
@Deprecated
Collection<PrivateMessageHeader> getMessages(ContactId contactId)
throws DbException;
/**
* Returns all invitations to groups.
*/
......
......@@ -399,21 +399,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
}
@Override
public Collection<PrivateMessageHeader> getMessages(ContactId c)
throws DbException {
Collection<PrivateMessageHeader> messages;
Transaction txn = db.startTransaction(true);
try {
messages = getMessages(txn, c);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return messages;
}
@Override
public Collection<PrivateMessageHeader> getMessages(Transaction txn,
public Collection<PrivateMessageHeader> getMessageHeaders(Transaction txn,
ContactId c) throws DbException {
try {
Contact contact = db.getContact(txn, c);
......
......@@ -38,13 +38,13 @@ class ConversationManagerImpl implements ConversationManager {
}
@Override
public Collection<PrivateMessageHeader> getMessages(ContactId c)
public Collection<PrivateMessageHeader> getMessageHeaders(ContactId c)
throws DbException {
List<PrivateMessageHeader> messages = new ArrayList<>();
Transaction txn = db.startTransaction(true);
try {
for (ConversationClient client : clients) {
messages.addAll(client.getMessages(txn, c));
messages.addAll(client.getMessageHeaders(txn, c));
}
db.commitTransaction(txn);
} finally {
......
......@@ -178,21 +178,7 @@ class MessagingManagerImpl extends ConversationClientImpl
}
@Override
public Collection<PrivateMessageHeader> getMessages(ContactId c)
throws DbException {
Collection<PrivateMessageHeader> headers;
Transaction txn = db.startTransaction(true);
try {
headers = getMessages(txn, c);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return headers;
}
@Override
public Collection<PrivateMessageHeader> getMessages(Transaction txn,
public Collection<PrivateMessageHeader> getMessageHeaders(Transaction txn,
ContactId c) throws DbException {
Map<MessageId, BdfDictionary> metadata;
Collection<MessageStatus> statuses;
......
......@@ -368,21 +368,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
}
@Override
public Collection<PrivateMessageHeader> getMessages(ContactId c)
throws DbException {
Collection<PrivateMessageHeader> messages;
Transaction txn = db.startTransaction(true);
try {
messages = getMessages(txn, c);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return messages;
}
@Override
public Collection<PrivateMessageHeader> getMessages(Transaction txn,
public Collection<PrivateMessageHeader> getMessageHeaders(Transaction txn,
ContactId c) throws DbException {
try {
Contact contact = db.getContact(txn, c);
......
......@@ -321,21 +321,7 @@ abstract class SharingManagerImpl<S extends Shareable>
}
@Override
public Collection<PrivateMessageHeader> getMessages(ContactId c)
throws DbException {
Collection<PrivateMessageHeader> messages;
Transaction txn = db.startTransaction(true);
try {
messages = getMessages(txn, c);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
}
return messages;
}
@Override
public Collection<PrivateMessageHeader> getMessages(Transaction txn,
public Collection<PrivateMessageHeader> getMessageHeaders(Transaction txn,
ContactId c) throws DbException {
try {
Contact contact = db.getContact(txn, c);
......
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
......
......@@ -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;
......@@ -299,18 +299,23 @@ public class IntroductionIntegrationTest
Group g1 = introductionManager0.getContactGroup(introducee1);
Group g2 = introductionManager0.getContactGroup(introducee2);
assertEquals(2,
introductionManager0.getMessages(contactId1From0).size());
Collection<PrivateMessageHeader> messages =
withinTransactionReturns(db0, txn -> introductionManager0
.getMessageHeaders(txn, contactId1From0));
assertEquals(2, messages.size());
assertGroupCount(messageTracker0, g1.getId(), 2, 1);
assertEquals(2,
introductionManager0.getMessages(contactId2From0).size());
messages = withinTransactionReturns(db0,
txn -> introductionManager0.getMessageHeaders(txn, contactId2From0));
assertEquals(2, messages.size());
assertGroupCount(messageTracker0, g2.getId(), 2, 1);
assertEquals(2,
introductionManager1.getMessages(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.getMessages(contactId0From2).size());
messages = withinTransactionReturns(db2,
txn -> introductionManager2.getMessageHeaders(txn, contactId0From2));
assertEquals(3, messages.size());
assertGroupCount(messageTracker2, g2.getId(), 3, 2);
assertFalse(listener0.aborted);
......@@ -360,15 +365,19 @@ public class IntroductionIntegrationTest
assertFalse(contactManager2
.contactExists(author1.getId(), author2.getId()));
assertEquals(2,
introductionManager0.getMessages(contactId1From0).size());
assertEquals(2,
introductionManager0.getMessages(contactId2From0).size());
assertEquals(3,
introductionManager1.getMessages(contactId0From1).size());
assertEquals(3,
introductionManager2.getMessages(contactId0From2)
.size());
Collection<PrivateMessageHeader> 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);
......@@ -514,17 +523,21 @@ public class IntroductionIntegrationTest
Group g1 = introductionManager0.getContactGroup(introducee1);
Group g2 = introductionManager0.getContactGroup(introducee2);
assertEquals(2,
introductionManager0.getMessages(contactId1From0).size());
assertEquals(2, withinTransactionReturns(db0,
txn -> introductionManager0.getMessageHeaders(txn, contactId1From0))
.size());
assertGroupCount(messageTracker0, g1.getId(), 2, 1);
assertEquals(2,
introductionManager0.getMessages(contactId2From0).size());
assertEquals(2, withinTransactionReturns(db0,
txn -> introductionManager0.getMessageHeaders(txn, contactId2From0))
.size());
assertGroupCount(messageTracker0, g2.getId(), 2, 1);
assertEquals(3,
introductionManager1.getMessages(contactId0From1).size());
assertEquals(3, withinTransactionReturns(db1,
txn -> introductionManager1.getMessageHeaders(txn, contactId0From1))
.size());
assertGroupCount(messageTracker1, g1.getId(), 3, 2);
assertEquals(3,
introductionManager2.getMessages(contactId0From2).size());
assertEquals(3, withinTransactionReturns(db2,
txn -> introductionManager2.getMessageHeaders(txn, contactId0From2))
.size());
assertGroupCount(messageTracker2, g2.getId(), 3, 2);
assertFalse(listener0.aborted);
......@@ -548,7 +561,9 @@ public class IntroductionIntegrationTest
assertFalse(listener1.requestReceived);
// make really sure we don't have that request
assertTrue(introductionManager1.getMessages(contactId0From1).isEmpty());
assertTrue(withinTransactionReturns(db1,
txn -> introductionManager1.getMessageHeaders(txn, contactId0From1))
.isEmpty());
// The message was invalid, so no abort message was sent
assertFalse(listener0.aborted);
......@@ -596,11 +611,11 @@ public class IntroductionIntegrationTest
sync0To2(1, true);
// assert that introducees get notified about the existing contact
IntroductionRequest ir1 =
getIntroductionRequest(introductionManager1, contactId0From1);
IntroductionRequest ir1 = getIntroductionRequest(db1,
introductionManager1, contactId0From1);
assertTrue(ir1.doesExist());
IntroductionRequest ir2 =
getIntroductionRequest(introductionManager2, contactId0From2);
IntroductionRequest ir2 = getIntroductionRequest(db2,
introductionManager2, contactId0From2);
assertTrue(ir2.doesExist());
// sync ACCEPT messages back to introducer
......@@ -981,8 +996,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(),
......@@ -1002,10 +1016,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);
......@@ -1091,19 +1102,23 @@ public class IntroductionIntegrationTest
private void assertDefaultUiMessages() throws DbException {
Collection<PrivateMessageHeader> messages =
introductionManager0.getMessages(contactId1From0);
withinTransactionReturns(db0, txn -> introductionManager0
.getMessageHeaders(txn, contactId1From0));
assertEquals(2, messages.size());
assertMessagesAreAcked(messages);
messages = introductionManager0.getMessages(contactId2From0);
messages = withinTransactionReturns(db0,
txn -> introductionManager0.getMessageHeaders(txn, contactId2From0));
assertEquals(2, messages.size());
assertMessagesAreAcked(messages);
messages = introductionManager1.getMessages(contactId0From1);
messages = withinTransactionReturns(db1,
txn -> introductionManager1.getMessageHeaders(txn, contactId0From1));
assertEquals(2, messages.size());
assertMessagesAreAcked(messages);