diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/io/BlockSource.java b/bramble-api/src/main/java/org/briarproject/bramble/api/io/BlockSource.java index 83a88a29f..926c5bbc6 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/io/BlockSource.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/io/BlockSource.java @@ -1,11 +1,21 @@ package org.briarproject.bramble.api.io; import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.db.NoSuchBlockException; import org.briarproject.bramble.api.sync.MessageId; public interface BlockSource { + /** + * Returns the number of blocks in the given message. + */ int getBlockCount(MessageId m) throws DbException; + /** + * Returns the given block of the given message. + * + * @throws NoSuchBlockException if 'blockNumber' is greater than or equal + * to the number of blocks in the message + */ byte[] getBlock(MessageId m, int blockNumber) throws DbException; } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/client/ThreadedMessage.java b/briar-api/src/main/java/org/briarproject/briar/api/client/ThreadedMessage.java index 37b0dc86f..d53223103 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/client/ThreadedMessage.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/client/ThreadedMessage.java @@ -9,6 +9,8 @@ import org.briarproject.briar.api.messaging.PrivateMessage; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; +import static java.util.Collections.emptyList; + @Immutable @NotNullByDefault public abstract class ThreadedMessage extends PrivateMessage { @@ -19,7 +21,7 @@ public abstract class ThreadedMessage extends PrivateMessage { public ThreadedMessage(Message message, @Nullable MessageId parent, Author author) { - super(message); + super(message, emptyList()); this.parent = parent; this.author = author; } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessage.java b/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessage.java index 2fe86deab..0c5a90b8d 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessage.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/messaging/PrivateMessage.java @@ -3,6 +3,8 @@ package org.briarproject.briar.api.messaging; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.Message; +import java.util.List; + import javax.annotation.concurrent.Immutable; @Immutable @@ -10,13 +12,18 @@ import javax.annotation.concurrent.Immutable; public class PrivateMessage { private final Message message; + private final List attachments; - public PrivateMessage(Message message) { + public PrivateMessage(Message message, List attachments) { this.message = message; + this.attachments = attachments; } public Message getMessage() { return message; } + public List getAttachmentHeaders() { + return attachments; + } } 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 bc92e6952..a0518a7a7 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 @@ -11,13 +11,16 @@ import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.MetadataParser; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Transaction; +import org.briarproject.bramble.api.io.MessageInputStreamFactory; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.Client; import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group.Visibility; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.Message; +import org.briarproject.bramble.api.sync.MessageFactory; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageStatus; import org.briarproject.bramble.api.versioning.ClientVersioningManager; @@ -32,16 +35,17 @@ import org.briarproject.briar.api.messaging.PrivateMessageHeader; import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent; import org.briarproject.briar.client.ConversationClientImpl; +import java.io.InputStream; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collection; import java.util.Map; -import java.util.Random; import javax.annotation.concurrent.Immutable; import javax.inject.Inject; import static java.util.Collections.emptyList; +import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_LENGTH; import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ; @Immutable @@ -51,15 +55,21 @@ class MessagingManagerImpl extends ConversationClientImpl private final ClientVersioningManager clientVersioningManager; private final ContactGroupFactory contactGroupFactory; + private final MessageFactory messageFactory; + private final MessageInputStreamFactory messageInputStreamFactory; @Inject MessagingManagerImpl(DatabaseComponent db, ClientHelper clientHelper, ClientVersioningManager clientVersioningManager, MetadataParser metadataParser, MessageTracker messageTracker, - ContactGroupFactory contactGroupFactory) { + ContactGroupFactory contactGroupFactory, + MessageFactory messageFactory, + MessageInputStreamFactory messageInputStreamFactory) { super(db, clientHelper, metadataParser, messageTracker); this.clientVersioningManager = clientVersioningManager; this.contactGroupFactory = contactGroupFactory; + this.messageFactory = messageFactory; + this.messageInputStreamFactory = messageInputStreamFactory; } @Override @@ -142,9 +152,11 @@ class MessagingManagerImpl extends ConversationClientImpl meta.put("read", true); clientHelper.addLocalMessage(txn, m.getMessage(), meta, true); messageTracker.trackOutgoingMessage(txn, m.getMessage()); + for (AttachmentHeader h : m.getAttachmentHeaders()) + db.setMessageShared(txn, h.getMessageId()); db.commitTransaction(txn); } catch (FormatException e) { - throw new RuntimeException(e); + throw new AssertionError(e); } finally { db.endTransaction(txn); } @@ -152,11 +164,16 @@ class MessagingManagerImpl extends ConversationClientImpl @Override public AttachmentHeader addLocalAttachment(GroupId groupId, long timestamp, - String contentType, ByteBuffer data) { - // TODO add real implementation - byte[] b = new byte[MessageId.LENGTH]; - new Random().nextBytes(b); - return new AttachmentHeader(new MessageId(b), "image/png"); + String contentType, ByteBuffer data) throws DbException { + // TODO: Remove this restriction when large messages are supported + byte[] body = data.array(); + if (body.length > MAX_MESSAGE_LENGTH) throw new DbException(); + // TODO: Store message type and content type + Message m = messageFactory.createMessage(groupId, timestamp, body); + Metadata meta = new Metadata(); + // Attachment will be shared when private message is added + db.transaction(false, txn -> db.addLocalMessage(txn, m, meta, false)); + return new AttachmentHeader(m.getId(), contentType); } private ContactId getContactId(Transaction txn, GroupId g) @@ -236,8 +253,9 @@ class MessagingManagerImpl extends ConversationClientImpl @Override public Attachment getAttachment(MessageId m) { - // TODO add real implementation - throw new IllegalStateException("Not yet implemented"); + InputStream in = messageInputStreamFactory.getMessageInputStream(m); + // TODO: Read message type and content type + return new Attachment(in); } } diff --git a/briar-core/src/main/java/org/briarproject/briar/messaging/PrivateMessageFactoryImpl.java b/briar-core/src/main/java/org/briarproject/briar/messaging/PrivateMessageFactoryImpl.java index d2c592787..bc250d57d 100644 --- a/briar-core/src/main/java/org/briarproject/briar/messaging/PrivateMessageFactoryImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/messaging/PrivateMessageFactoryImpl.java @@ -39,6 +39,6 @@ class PrivateMessageFactoryImpl implements PrivateMessageFactory { // Serialise the message BdfList message = BdfList.of(text); Message m = clientHelper.createMessage(groupId, timestamp, message); - return new PrivateMessage(m); + return new PrivateMessage(m, attachments); } } diff --git a/briar-headless/src/test/java/org/briarproject/briar/headless/messaging/MessagingControllerImplTest.kt b/briar-headless/src/test/java/org/briarproject/briar/headless/messaging/MessagingControllerImplTest.kt index c438a768b..fb6251548 100644 --- a/briar-headless/src/test/java/org/briarproject/briar/headless/messaging/MessagingControllerImplTest.kt +++ b/briar-headless/src/test/java/org/briarproject/briar/headless/messaging/MessagingControllerImplTest.kt @@ -62,7 +62,7 @@ internal class MessagingControllerImplTest : ControllerTest() { emptyList() ) private val sessionId = SessionId(getRandomId()) - private val privateMessage = PrivateMessage(message) + private val privateMessage = PrivateMessage(message, emptyList()) @Test fun list() {