mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 22:29:53 +01:00
Improve handling of missing and invalid attachments.
This commit is contained in:
@@ -55,7 +55,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||||
InputStream is = getUrlInputStream(smallKitten);
|
InputStream is = getUrlInputStream(smallKitten);
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, true);
|
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||||
assertEquals(msgId, item.getMessageId());
|
assertEquals(msgId, item.getMessageId());
|
||||||
assertEquals(160, item.getWidth());
|
assertEquals(160, item.getWidth());
|
||||||
assertEquals(240, item.getHeight());
|
assertEquals(240, item.getHeight());
|
||||||
@@ -71,7 +71,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||||
InputStream is = getUrlInputStream(originalKitten);
|
InputStream is = getUrlInputStream(originalKitten);
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, true);
|
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||||
assertEquals(msgId, item.getMessageId());
|
assertEquals(msgId, item.getMessageId());
|
||||||
assertEquals(1728, item.getWidth());
|
assertEquals(1728, item.getWidth());
|
||||||
assertEquals(2592, item.getHeight());
|
assertEquals(2592, item.getHeight());
|
||||||
@@ -87,7 +87,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/png");
|
AttachmentHeader h = new AttachmentHeader(msgId, "image/png");
|
||||||
InputStream is = getUrlInputStream(pngKitten);
|
InputStream is = getUrlInputStream(pngKitten);
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, true);
|
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||||
assertEquals(msgId, item.getMessageId());
|
assertEquals(msgId, item.getMessageId());
|
||||||
assertEquals(737, item.getWidth());
|
assertEquals(737, item.getWidth());
|
||||||
assertEquals(510, item.getHeight());
|
assertEquals(510, item.getHeight());
|
||||||
@@ -103,7 +103,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||||
InputStream is = getUrlInputStream(uberGif);
|
InputStream is = getUrlInputStream(uberGif);
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, true);
|
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||||
assertEquals(1, item.getWidth());
|
assertEquals(1, item.getWidth());
|
||||||
assertEquals(1, item.getHeight());
|
assertEquals(1, item.getHeight());
|
||||||
assertEquals(dimensions.minHeight, item.getThumbnailWidth());
|
assertEquals(dimensions.minHeight, item.getThumbnailWidth());
|
||||||
@@ -118,7 +118,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||||
InputStream is = getUrlInputStream(lottaPixel);
|
InputStream is = getUrlInputStream(lottaPixel);
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, true);
|
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||||
assertEquals(64250, item.getWidth());
|
assertEquals(64250, item.getWidth());
|
||||||
assertEquals(64250, item.getHeight());
|
assertEquals(64250, item.getHeight());
|
||||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||||
@@ -133,7 +133,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||||
InputStream is = getUrlInputStream(imageIoCrash);
|
InputStream is = getUrlInputStream(imageIoCrash);
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, true);
|
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||||
assertEquals(1184, item.getWidth());
|
assertEquals(1184, item.getWidth());
|
||||||
assertEquals(448, item.getHeight());
|
assertEquals(448, item.getHeight());
|
||||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||||
@@ -148,7 +148,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||||
InputStream is = getUrlInputStream(gimpCrash);
|
InputStream is = getUrlInputStream(gimpCrash);
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, true);
|
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||||
assertEquals(1, item.getWidth());
|
assertEquals(1, item.getWidth());
|
||||||
assertEquals(1, item.getHeight());
|
assertEquals(1, item.getHeight());
|
||||||
assertEquals(dimensions.minHeight, item.getThumbnailWidth());
|
assertEquals(dimensions.minHeight, item.getThumbnailWidth());
|
||||||
@@ -163,7 +163,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||||
InputStream is = getUrlInputStream(optiPngAfl);
|
InputStream is = getUrlInputStream(optiPngAfl);
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, true);
|
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||||
assertEquals(32, item.getWidth());
|
assertEquals(32, item.getWidth());
|
||||||
assertEquals(32, item.getHeight());
|
assertEquals(32, item.getHeight());
|
||||||
assertEquals(dimensions.minHeight, item.getThumbnailWidth());
|
assertEquals(dimensions.minHeight, item.getThumbnailWidth());
|
||||||
@@ -178,7 +178,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||||
InputStream is = getUrlInputStream(librawError);
|
InputStream is = getUrlInputStream(librawError);
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, true);
|
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||||
assertTrue(item.hasError());
|
assertTrue(item.hasError());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
||||||
InputStream is = getAssetInputStream("animated.gif");
|
InputStream is = getAssetInputStream("animated.gif");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, true);
|
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||||
assertEquals(65535, item.getWidth());
|
assertEquals(65535, item.getWidth());
|
||||||
assertEquals(65535, item.getHeight());
|
assertEquals(65535, item.getHeight());
|
||||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||||
@@ -202,7 +202,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
||||||
InputStream is = getAssetInputStream("animated2.gif");
|
InputStream is = getAssetInputStream("animated2.gif");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, true);
|
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||||
assertEquals(10000, item.getWidth());
|
assertEquals(10000, item.getWidth());
|
||||||
assertEquals(10000, item.getHeight());
|
assertEquals(10000, item.getHeight());
|
||||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||||
@@ -217,7 +217,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
||||||
InputStream is = getAssetInputStream("error_large.gif");
|
InputStream is = getAssetInputStream("error_large.gif");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, true);
|
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||||
assertEquals(16384, item.getWidth());
|
assertEquals(16384, item.getWidth());
|
||||||
assertEquals(16384, item.getHeight());
|
assertEquals(16384, item.getHeight());
|
||||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||||
@@ -232,7 +232,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||||
InputStream is = getAssetInputStream("error_high.jpg");
|
InputStream is = getAssetInputStream("error_high.jpg");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, true);
|
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||||
assertEquals(1, item.getWidth());
|
assertEquals(1, item.getWidth());
|
||||||
assertEquals(10000, item.getHeight());
|
assertEquals(10000, item.getHeight());
|
||||||
assertEquals(dimensions.minWidth, item.getThumbnailWidth());
|
assertEquals(dimensions.minWidth, item.getThumbnailWidth());
|
||||||
@@ -247,7 +247,7 @@ public class AttachmentRetrieverIntegrationTest {
|
|||||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||||
InputStream is = getAssetInputStream("error_wide.jpg");
|
InputStream is = getAssetInputStream("error_wide.jpg");
|
||||||
Attachment a = new Attachment(h, is);
|
Attachment a = new Attachment(h, is);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, true);
|
AttachmentItem item = retriever.getAttachmentItem(a, true);
|
||||||
assertEquals(1920, item.getWidth());
|
assertEquals(1920, item.getWidth());
|
||||||
assertEquals(1, item.getHeight());
|
assertEquals(1, item.getHeight());
|
||||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ public class AttachmentCreator {
|
|||||||
// get and cache AttachmentItem for ImagePreview
|
// get and cache AttachmentItem for ImagePreview
|
||||||
try {
|
try {
|
||||||
Attachment a = retriever.getMessageAttachment(h);
|
Attachment a = retriever.getMessageAttachment(h);
|
||||||
AttachmentItem item = retriever.getAttachmentItem(h, a, needsSize);
|
AttachmentItem item = retriever.getAttachmentItem(a, needsSize);
|
||||||
if (item.hasError()) throw new IOException();
|
if (item.hasError()) throw new IOException();
|
||||||
AttachmentItemResult itemResult =
|
AttachmentItemResult itemResult =
|
||||||
new AttachmentItemResult(uri, item);
|
new AttachmentItemResult(uri, item);
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ import android.webkit.MimeTypeMap;
|
|||||||
|
|
||||||
import com.bumptech.glide.util.MarkEnforcingInputStream;
|
import com.bumptech.glide.util.MarkEnforcingInputStream;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.Pair;
|
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
@@ -22,7 +20,6 @@ import org.briarproject.briar.api.messaging.MessagingManager;
|
|||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@@ -38,9 +35,7 @@ import static android.support.media.ExifInterface.TAG_ORIENTATION;
|
|||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class AttachmentRetriever {
|
public class AttachmentRetriever {
|
||||||
@@ -93,7 +88,8 @@ public class AttachmentRetriever {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cachePut(MessageId messageId, List<AttachmentItem> attachments) {
|
public void cachePut(MessageId messageId,
|
||||||
|
List<AttachmentItem> attachments) {
|
||||||
attachmentCache.put(messageId, attachments);
|
attachmentCache.put(messageId, attachments);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,47 +98,17 @@ public class AttachmentRetriever {
|
|||||||
return attachmentCache.get(messageId);
|
return attachmentCache.get(messageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DatabaseExecutor
|
public Attachment getMessageAttachment(AttachmentHeader h)
|
||||||
public List<Pair<AttachmentHeader, Attachment>> getMessageAttachments(
|
throws DbException {
|
||||||
List<AttachmentHeader> headers) throws DbException {
|
|
||||||
long start = now();
|
|
||||||
List<Pair<AttachmentHeader, Attachment>> attachments =
|
|
||||||
new ArrayList<>(headers.size());
|
|
||||||
for (AttachmentHeader h : headers) {
|
|
||||||
Attachment a = messagingManager.getAttachment(h);
|
|
||||||
attachments.add(new Pair<>(h, a));
|
|
||||||
}
|
|
||||||
logDuration(LOG, "Loading attachments", start);
|
|
||||||
return attachments;
|
|
||||||
}
|
|
||||||
|
|
||||||
Attachment getMessageAttachment(AttachmentHeader h) throws DbException {
|
|
||||||
return messagingManager.getAttachment(h);
|
return messagingManager.getAttachment(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates {@link AttachmentItem}s from the passed headers and Attachments.
|
|
||||||
* <p>
|
|
||||||
* Note: This closes the {@link Attachment}'s {@link InputStream}.
|
|
||||||
*/
|
|
||||||
public List<AttachmentItem> getAttachmentItems(
|
|
||||||
List<Pair<AttachmentHeader, Attachment>> attachments) {
|
|
||||||
boolean needsSize = attachments.size() == 1;
|
|
||||||
List<AttachmentItem> items = new ArrayList<>(attachments.size());
|
|
||||||
for (Pair<AttachmentHeader, Attachment> a : attachments) {
|
|
||||||
AttachmentItem item =
|
|
||||||
getAttachmentItem(a.getFirst(), a.getSecond(), needsSize);
|
|
||||||
items.add(item);
|
|
||||||
}
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an {@link AttachmentItem} from the {@link Attachment}'s
|
* Creates an {@link AttachmentItem} from the {@link Attachment}'s
|
||||||
* {@link InputStream} which will be closed when this method returns.
|
* {@link InputStream} which will be closed when this method returns.
|
||||||
*/
|
*/
|
||||||
AttachmentItem getAttachmentItem(AttachmentHeader h, Attachment a,
|
public AttachmentItem getAttachmentItem(Attachment a, boolean needsSize) {
|
||||||
boolean needsSize) {
|
AttachmentHeader h = a.getHeader();
|
||||||
if (!needsSize) {
|
if (!needsSize) {
|
||||||
String extension =
|
String extension =
|
||||||
imageHelper.getExtensionFromMimeType(h.getContentType());
|
imageHelper.getExtensionFromMimeType(h.getContentType());
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
|
|||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchContactException;
|
import org.briarproject.bramble.api.db.NoSuchContactException;
|
||||||
|
import org.briarproject.bramble.api.db.NoSuchMessageException;
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.event.EventListener;
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
@@ -107,6 +108,7 @@ import static android.support.v7.util.SortedList.INVALID_POSITION;
|
|||||||
import static android.view.Gravity.RIGHT;
|
import static android.view.Gravity.RIGHT;
|
||||||
import static android.widget.Toast.LENGTH_SHORT;
|
import static android.widget.Toast.LENGTH_SHORT;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Collections.sort;
|
import static java.util.Collections.sort;
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
@@ -434,29 +436,36 @@ public class ConversationActivity extends BriarActivity
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void eagerlyLoadMessageSize(PrivateMessageHeader h)
|
private void eagerlyLoadMessageSize(PrivateMessageHeader h) {
|
||||||
throws DbException {
|
try {
|
||||||
MessageId id = h.getId();
|
MessageId id = h.getId();
|
||||||
// If the message has text, load it
|
// If the message has text, load it
|
||||||
if (h.hasText()) {
|
if (h.hasText()) {
|
||||||
String text = textCache.get(id);
|
String text = textCache.get(id);
|
||||||
if (text == null) {
|
if (text == null) {
|
||||||
LOG.info("Eagerly loading text for latest message");
|
LOG.info("Eagerly loading text for latest message");
|
||||||
text = messagingManager.getMessageText(id);
|
text = messagingManager.getMessageText(id);
|
||||||
textCache.put(id, requireNonNull(text));
|
textCache.put(id, requireNonNull(text));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
// If the message has a single image, load its size - for multiple
|
||||||
// If the message has a single image, load its size - for multiple
|
// images we use a grid so the size is fixed
|
||||||
// images we use a grid so the size is fixed
|
List<AttachmentHeader> headers = h.getAttachmentHeaders();
|
||||||
if (h.getAttachmentHeaders().size() == 1) {
|
if (headers.size() == 1) {
|
||||||
List<AttachmentItem> items = attachmentRetriever.cacheGet(id);
|
List<AttachmentItem> items = attachmentRetriever.cacheGet(id);
|
||||||
if (items == null) {
|
if (items == null) {
|
||||||
LOG.info("Eagerly loading image size for latest message");
|
LOG.info("Eagerly loading image size for latest message");
|
||||||
items = attachmentRetriever.getAttachmentItems(
|
Attachment a = attachmentRetriever
|
||||||
attachmentRetriever.getMessageAttachments(
|
.getMessageAttachment(headers.get(0));
|
||||||
h.getAttachmentHeaders()));
|
AttachmentItem item =
|
||||||
attachmentRetriever.cachePut(id, items);
|
attachmentRetriever.getAttachmentItem(a, true);
|
||||||
|
attachmentRetriever.cachePut(id, singletonList(item));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchMessageException e) {
|
||||||
|
LOG.info("Attachment not received yet");
|
||||||
|
} catch (DbException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,14 +545,23 @@ public class ConversationActivity extends BriarActivity
|
|||||||
|
|
||||||
private void loadMessageAttachments(MessageId messageId,
|
private void loadMessageAttachments(MessageId messageId,
|
||||||
List<AttachmentHeader> headers) {
|
List<AttachmentHeader> headers) {
|
||||||
|
// TODO: Use placeholders for missing/invalid attachments
|
||||||
runOnDbThread(() -> {
|
runOnDbThread(() -> {
|
||||||
try {
|
try {
|
||||||
List<Pair<AttachmentHeader, Attachment>> attachments =
|
|
||||||
attachmentRetriever.getMessageAttachments(headers);
|
|
||||||
// TODO move getting the items off to IoExecutor, if size == 1
|
// TODO move getting the items off to IoExecutor, if size == 1
|
||||||
List<AttachmentItem> items =
|
boolean needsSize = headers.size() == 1;
|
||||||
attachmentRetriever.getAttachmentItems(attachments);
|
List<AttachmentItem> items = new ArrayList<>(headers.size());
|
||||||
|
for (AttachmentHeader h : headers) {
|
||||||
|
Attachment a = attachmentRetriever.getMessageAttachment(h);
|
||||||
|
AttachmentItem item =
|
||||||
|
attachmentRetriever.getAttachmentItem(a, needsSize);
|
||||||
|
items.add(item);
|
||||||
|
}
|
||||||
|
// TODO: Don't cache items unless all are present and valid
|
||||||
|
attachmentRetriever.cachePut(messageId, items);
|
||||||
displayMessageAttachments(messageId, items);
|
displayMessageAttachments(messageId, items);
|
||||||
|
} catch (NoSuchMessageException e) {
|
||||||
|
LOG.info("Attachment not received yet");
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
}
|
}
|
||||||
@@ -553,7 +571,6 @@ public class ConversationActivity extends BriarActivity
|
|||||||
private void displayMessageAttachments(MessageId m,
|
private void displayMessageAttachments(MessageId m,
|
||||||
List<AttachmentItem> items) {
|
List<AttachmentItem> items) {
|
||||||
runOnUiThreadUnlessDestroyed(() -> {
|
runOnUiThreadUnlessDestroyed(() -> {
|
||||||
attachmentRetriever.cachePut(m, items);
|
|
||||||
Pair<Integer, ConversationMessageItem> pair =
|
Pair<Integer, ConversationMessageItem> pair =
|
||||||
adapter.getMessageItem(m);
|
adapter.getMessageItem(m);
|
||||||
if (pair != null) {
|
if (pair != null) {
|
||||||
@@ -567,6 +584,7 @@ public class ConversationActivity extends BriarActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
|
// TODO: Load missing attachments when they arrive
|
||||||
if (e instanceof ContactRemovedEvent) {
|
if (e instanceof ContactRemovedEvent) {
|
||||||
ContactRemovedEvent c = (ContactRemovedEvent) e;
|
ContactRemovedEvent c = (ContactRemovedEvent) e;
|
||||||
if (c.getContactId().equals(contactId)) {
|
if (c.getContactId().equals(contactId)) {
|
||||||
|
|||||||
@@ -9,14 +9,11 @@ import org.briarproject.briar.api.messaging.MessagingManager;
|
|||||||
import org.jmock.Expectations;
|
import org.jmock.Expectations;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
|
||||||
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_CONTENT_TYPE_BYTES;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@@ -27,35 +24,26 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
|||||||
100, 50, 200, 75, 300
|
100, 50, 200, 75, 300
|
||||||
);
|
);
|
||||||
private final MessageId msgId = new MessageId(getRandomId());
|
private final MessageId msgId = new MessageId(getRandomId());
|
||||||
private final String mimeType = getRandomString(MAX_CONTENT_TYPE_BYTES);
|
|
||||||
private final AttachmentHeader header =
|
|
||||||
new AttachmentHeader(msgId, mimeType);
|
|
||||||
private final Attachment attachment = new Attachment(header,
|
|
||||||
new BufferedInputStream(
|
|
||||||
new ByteArrayInputStream(getRandomBytes(42))));
|
|
||||||
|
|
||||||
private final MessagingManager messagingManager =
|
private final MessagingManager messagingManager =
|
||||||
context.mock(MessagingManager.class);
|
context.mock(MessagingManager.class);
|
||||||
private final ImageHelper imageHelper = context.mock(ImageHelper.class);
|
private final ImageHelper imageHelper = context.mock(ImageHelper.class);
|
||||||
private final AttachmentRetriever controller =
|
private final AttachmentRetriever retriever = new AttachmentRetriever(
|
||||||
new AttachmentRetriever(
|
messagingManager,
|
||||||
messagingManager,
|
dimensions,
|
||||||
dimensions,
|
imageHelper
|
||||||
imageHelper
|
);
|
||||||
);
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoSize() {
|
public void testNoSize() {
|
||||||
String mimeType = "image/jpeg";
|
String mimeType = "image/jpeg";
|
||||||
AttachmentHeader h = getAttachmentHeader(mimeType);
|
Attachment attachment = getAttachment(mimeType);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(imageHelper).getExtensionFromMimeType(mimeType);
|
oneOf(imageHelper).getExtensionFromMimeType(mimeType);
|
||||||
will(returnValue("jpg"));
|
will(returnValue("jpg"));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
AttachmentItem item =
|
AttachmentItem item = retriever.getAttachmentItem(attachment, false);
|
||||||
controller.getAttachmentItem(h, attachment, false);
|
|
||||||
assertEquals(mimeType, item.getMimeType());
|
assertEquals(mimeType, item.getMimeType());
|
||||||
assertEquals("jpg", item.getExtension());
|
assertEquals("jpg", item.getExtension());
|
||||||
assertFalse(item.hasError());
|
assertFalse(item.hasError());
|
||||||
@@ -64,22 +52,21 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testNoSizeWrongMimeTypeProducesError() {
|
public void testNoSizeWrongMimeTypeProducesError() {
|
||||||
String mimeType = "application/octet-stream";
|
String mimeType = "application/octet-stream";
|
||||||
AttachmentHeader h = getAttachmentHeader(mimeType);
|
Attachment attachment = getAttachment(mimeType);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(imageHelper).getExtensionFromMimeType(mimeType);
|
oneOf(imageHelper).getExtensionFromMimeType(mimeType);
|
||||||
will(returnValue(null));
|
will(returnValue(null));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
AttachmentItem item =
|
AttachmentItem item = retriever.getAttachmentItem(attachment, false);
|
||||||
controller.getAttachmentItem(h, attachment, false);
|
|
||||||
assertTrue(item.hasError());
|
assertTrue(item.hasError());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSmallJpegImage() {
|
public void testSmallJpegImage() {
|
||||||
String mimeType = "image/jpeg";
|
String mimeType = "image/jpeg";
|
||||||
AttachmentHeader h = getAttachmentHeader(mimeType);
|
Attachment attachment = getAttachment(mimeType);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(imageHelper).decodeStream(with(any(InputStream.class)));
|
oneOf(imageHelper).decodeStream(with(any(InputStream.class)));
|
||||||
@@ -88,7 +75,7 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
|||||||
will(returnValue("jpg"));
|
will(returnValue("jpg"));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
AttachmentItem item = controller.getAttachmentItem(h, attachment, true);
|
AttachmentItem item = retriever.getAttachmentItem(attachment, true);
|
||||||
assertEquals(msgId, item.getMessageId());
|
assertEquals(msgId, item.getMessageId());
|
||||||
assertEquals(160, item.getWidth());
|
assertEquals(160, item.getWidth());
|
||||||
assertEquals(240, item.getHeight());
|
assertEquals(240, item.getHeight());
|
||||||
@@ -102,7 +89,7 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testBigJpegImage() {
|
public void testBigJpegImage() {
|
||||||
String mimeType = "image/jpeg";
|
String mimeType = "image/jpeg";
|
||||||
AttachmentHeader h = getAttachmentHeader(mimeType);
|
Attachment attachment = getAttachment(mimeType);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(imageHelper).decodeStream(with(any(InputStream.class)));
|
oneOf(imageHelper).decodeStream(with(any(InputStream.class)));
|
||||||
@@ -111,7 +98,7 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
|||||||
will(returnValue("jpg"));
|
will(returnValue("jpg"));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
AttachmentItem item = controller.getAttachmentItem(h, attachment, true);
|
AttachmentItem item = retriever.getAttachmentItem(attachment, true);
|
||||||
assertEquals(1728, item.getWidth());
|
assertEquals(1728, item.getWidth());
|
||||||
assertEquals(2592, item.getHeight());
|
assertEquals(2592, item.getHeight());
|
||||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||||
@@ -121,7 +108,7 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMalformedError() {
|
public void testMalformedError() {
|
||||||
AttachmentHeader h = getAttachmentHeader("image/jpeg");
|
Attachment attachment = getAttachment("image/jpeg");
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(imageHelper).decodeStream(with(any(InputStream.class)));
|
oneOf(imageHelper).decodeStream(with(any(InputStream.class)));
|
||||||
@@ -130,12 +117,13 @@ public class AttachmentRetrieverTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(null));
|
will(returnValue(null));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
AttachmentItem item = controller.getAttachmentItem(h, attachment, true);
|
AttachmentItem item = retriever.getAttachmentItem(attachment, true);
|
||||||
assertTrue(item.hasError());
|
assertTrue(item.hasError());
|
||||||
}
|
}
|
||||||
|
|
||||||
private AttachmentHeader getAttachmentHeader(String contentType) {
|
private Attachment getAttachment(String contentType) {
|
||||||
return new AttachmentHeader(msgId, contentType);
|
AttachmentHeader header = new AttachmentHeader(msgId, contentType);
|
||||||
|
InputStream in = new ByteArrayInputStream(getRandomBytes(42));
|
||||||
|
return new Attachment(header, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.briarproject.briar.api.messaging;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An exception that is thrown when an {@link AttachmentHeader} is used to
|
||||||
|
* load an {@link Attachment}, and the header refers to a message that is not
|
||||||
|
* an attachment, or to an attachment that does not have the expected content
|
||||||
|
* type.
|
||||||
|
*/
|
||||||
|
@NotNullByDefault
|
||||||
|
public class InvalidAttachmentException extends DbException {
|
||||||
|
}
|
||||||
@@ -69,6 +69,10 @@ public interface MessagingManager extends ConversationClient {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the attachment with the given message ID and content type.
|
* Returns the attachment with the given message ID and content type.
|
||||||
|
*
|
||||||
|
* @throws InvalidAttachmentException If the header refers to a message
|
||||||
|
* that is not an attachment, or to an attachment that does not have the
|
||||||
|
* expected content type
|
||||||
*/
|
*/
|
||||||
Attachment getAttachment(AttachmentHeader h) throws DbException;
|
Attachment getAttachment(AttachmentHeader h) throws DbException;
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.briarproject.briar.api.conversation.ConversationMessageHeader;
|
|||||||
import org.briarproject.briar.api.messaging.Attachment;
|
import org.briarproject.briar.api.messaging.Attachment;
|
||||||
import org.briarproject.briar.api.messaging.AttachmentHeader;
|
import org.briarproject.briar.api.messaging.AttachmentHeader;
|
||||||
import org.briarproject.briar.api.messaging.FileTooBigException;
|
import org.briarproject.briar.api.messaging.FileTooBigException;
|
||||||
|
import org.briarproject.briar.api.messaging.InvalidAttachmentException;
|
||||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessage;
|
import org.briarproject.briar.api.messaging.PrivateMessage;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||||
@@ -380,6 +381,12 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
byte[] body = clientHelper.getMessage(m).getBody();
|
byte[] body = clientHelper.getMessage(m).getBody();
|
||||||
try {
|
try {
|
||||||
BdfDictionary meta = clientHelper.getMessageMetadataAsDictionary(m);
|
BdfDictionary meta = clientHelper.getMessageMetadataAsDictionary(m);
|
||||||
|
Long messageType = meta.getOptionalLong(MSG_KEY_MSG_TYPE);
|
||||||
|
if (messageType == null || messageType != ATTACHMENT)
|
||||||
|
throw new InvalidAttachmentException();
|
||||||
|
String contentType = meta.getString(MSG_KEY_CONTENT_TYPE);
|
||||||
|
if (!contentType.equals(h.getContentType()))
|
||||||
|
throw new InvalidAttachmentException();
|
||||||
int offset = meta.getLong(MSG_KEY_DESCRIPTOR_LENGTH).intValue();
|
int offset = meta.getLong(MSG_KEY_DESCRIPTOR_LENGTH).intValue();
|
||||||
return new Attachment(h, new ByteArrayInputStream(body, offset,
|
return new Attachment(h, new ByteArrayInputStream(body, offset,
|
||||||
body.length - offset));
|
body.length - offset));
|
||||||
|
|||||||
Reference in New Issue
Block a user