mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Merge branch '1468-image-size-tests' into 'master'
Add tests for parsing image sizes See merge request briar/briar!1026
This commit is contained in:
BIN
briar-android/src/androidTestOfficial/assets/animated.gif
Normal file
BIN
briar-android/src/androidTestOfficial/assets/animated.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 B |
BIN
briar-android/src/androidTestOfficial/assets/animated2.gif
Normal file
BIN
briar-android/src/androidTestOfficial/assets/animated2.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 317 B |
BIN
briar-android/src/androidTestOfficial/assets/error_high.jpg
Normal file
BIN
briar-android/src/androidTestOfficial/assets/error_high.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
BIN
briar-android/src/androidTestOfficial/assets/error_large.gif
Normal file
BIN
briar-android/src/androidTestOfficial/assets/error_large.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 B |
BIN
briar-android/src/androidTestOfficial/assets/error_wide.jpg
Normal file
BIN
briar-android/src/androidTestOfficial/assets/error_wide.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,279 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.briarproject.bramble.api.UniqueId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.api.messaging.Attachment;
|
||||
import org.briarproject.briar.api.messaging.AttachmentHeader;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class AttachmentControllerIntegrationTest {
|
||||
|
||||
private static final String smallKitten =
|
||||
"https://upload.wikimedia.org/wikipedia/commons/thumb/0/06/Kitten_in_Rizal_Park%2C_Manila.jpg/160px-Kitten_in_Rizal_Park%2C_Manila.jpg";
|
||||
private static final String originalKitten =
|
||||
"https://upload.wikimedia.org/wikipedia/commons/0/06/Kitten_in_Rizal_Park%2C_Manila.jpg";
|
||||
private static final String pngKitten =
|
||||
"https://upload.wikimedia.org/wikipedia/commons/c/c8/Young_cat.png";
|
||||
private static final String uberGif =
|
||||
"https://raw.githubusercontent.com/fuzzdb-project/fuzzdb/master/attack/file-upload/malicious-images/uber.gif";
|
||||
private static final String lottaPixel =
|
||||
"https://raw.githubusercontent.com/fuzzdb-project/fuzzdb/master/attack/file-upload/malicious-images/lottapixel.jpg";
|
||||
private static final String imageIoCrash =
|
||||
"https://www.landaire.net/img/crasher.png";
|
||||
private static final String gimpCrash =
|
||||
"https://gitlab.gnome.org/GNOME/gimp/uploads/75f5b7ed3b09b3f1c13f1f65bffe784f/31153c919d3aa634e8e6cff82219fe7352dd8a37.png";
|
||||
private static final String optiPngAfl =
|
||||
"https://sourceforge.net/p/optipng/bugs/64/attachment/test.gif";
|
||||
private static final String librawError =
|
||||
"https://www.libraw.org/sites/libraw.org/files/P1010671.JPG";
|
||||
|
||||
private final AttachmentDimensions dimensions = new AttachmentDimensions(
|
||||
100, 50, 200, 75, 300
|
||||
);
|
||||
private final MessageId msgId = new MessageId(getRandomId());
|
||||
|
||||
private final AttachmentController controller =
|
||||
new AttachmentController(null, dimensions);
|
||||
|
||||
@Test
|
||||
public void testSmallJpegImage() throws Exception {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getUrlInputStream(smallKitten);
|
||||
Attachment a = new Attachment(is);
|
||||
AttachmentItem item = controller.getAttachmentItem(h, a, true);
|
||||
assertEquals(msgId, item.getMessageId());
|
||||
assertEquals(160, item.getWidth());
|
||||
assertEquals(240, item.getHeight());
|
||||
assertEquals(160, item.getThumbnailWidth());
|
||||
assertEquals(240, item.getThumbnailHeight());
|
||||
assertEquals("image/jpeg", item.getMimeType());
|
||||
assertEquals("jpg", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBigJpegImage() throws Exception {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getUrlInputStream(originalKitten);
|
||||
Attachment a = new Attachment(is);
|
||||
AttachmentItem item = controller.getAttachmentItem(h, a, true);
|
||||
assertEquals(msgId, item.getMessageId());
|
||||
assertEquals(1728, item.getWidth());
|
||||
assertEquals(2592, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.maxHeight, item.getThumbnailHeight());
|
||||
assertEquals("image/jpeg", item.getMimeType());
|
||||
assertEquals("jpg", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSmallPngImage() throws Exception {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/png");
|
||||
InputStream is = getUrlInputStream(pngKitten);
|
||||
Attachment a = new Attachment(is);
|
||||
AttachmentItem item = controller.getAttachmentItem(h, a, true);
|
||||
assertEquals(msgId, item.getMessageId());
|
||||
assertEquals(737, item.getWidth());
|
||||
assertEquals(510, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(138, item.getThumbnailHeight());
|
||||
assertEquals("image/png", item.getMimeType());
|
||||
assertEquals("png", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUberGif() throws Exception {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getUrlInputStream(uberGif);
|
||||
Attachment a = new Attachment(is);
|
||||
AttachmentItem item = controller.getAttachmentItem(h, a, true);
|
||||
assertEquals(1, item.getWidth());
|
||||
assertEquals(1, item.getHeight());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailHeight());
|
||||
assertEquals("image/gif", item.getMimeType());
|
||||
assertEquals("gif", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLottaPixels() throws Exception {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getUrlInputStream(lottaPixel);
|
||||
Attachment a = new Attachment(is);
|
||||
AttachmentItem item = controller.getAttachmentItem(h, a, true);
|
||||
assertEquals(64250, item.getWidth());
|
||||
assertEquals(64250, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailHeight());
|
||||
assertEquals("image/jpeg", item.getMimeType());
|
||||
assertEquals("jpg", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageIoCrash() throws Exception {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getUrlInputStream(imageIoCrash);
|
||||
Attachment a = new Attachment(is);
|
||||
AttachmentItem item = controller.getAttachmentItem(h, a, true);
|
||||
assertEquals(1184, item.getWidth());
|
||||
assertEquals(448, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailHeight());
|
||||
assertEquals("image/png", item.getMimeType());
|
||||
assertEquals("png", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGimpCrash() throws Exception {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getUrlInputStream(gimpCrash);
|
||||
Attachment a = new Attachment(is);
|
||||
AttachmentItem item = controller.getAttachmentItem(h, a, true);
|
||||
assertEquals(1, item.getWidth());
|
||||
assertEquals(1, item.getHeight());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailHeight());
|
||||
assertEquals("image/gif", item.getMimeType());
|
||||
assertEquals("gif", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptiPngAfl() throws Exception {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getUrlInputStream(optiPngAfl);
|
||||
Attachment a = new Attachment(is);
|
||||
AttachmentItem item = controller.getAttachmentItem(h, a, true);
|
||||
assertEquals(32, item.getWidth());
|
||||
assertEquals(32, item.getHeight());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailHeight());
|
||||
assertEquals("image/gif", item.getMimeType());
|
||||
assertEquals("gif", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLibrawError() throws Exception {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getUrlInputStream(librawError);
|
||||
Attachment a = new Attachment(is);
|
||||
AttachmentItem item = controller.getAttachmentItem(h, a, true);
|
||||
assertTrue(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSmallAnimatedGifMaxDimensions() throws Exception {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
||||
InputStream is = getAssetInputStream("animated.gif");
|
||||
Attachment a = new Attachment(is);
|
||||
AttachmentItem item = controller.getAttachmentItem(h, a, true);
|
||||
assertEquals(65535, item.getWidth());
|
||||
assertEquals(65535, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailHeight());
|
||||
assertEquals("image/gif", item.getMimeType());
|
||||
assertEquals("gif", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSmallAnimatedGifHugeDimensions() throws Exception {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
||||
InputStream is = getAssetInputStream("animated2.gif");
|
||||
Attachment a = new Attachment(is);
|
||||
AttachmentItem item = controller.getAttachmentItem(h, a, true);
|
||||
assertEquals(10000, item.getWidth());
|
||||
assertEquals(10000, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailHeight());
|
||||
assertEquals("image/gif", item.getMimeType());
|
||||
assertEquals("gif", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSmallGifLargeDimensions() throws Exception {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/gif");
|
||||
InputStream is = getAssetInputStream("error_large.gif");
|
||||
Attachment a = new Attachment(is);
|
||||
AttachmentItem item = controller.getAttachmentItem(h, a, true);
|
||||
assertEquals(16384, item.getWidth());
|
||||
assertEquals(16384, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailHeight());
|
||||
assertEquals("image/gif", item.getMimeType());
|
||||
assertEquals("gif", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHighError() throws Exception {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getAssetInputStream("error_high.jpg");
|
||||
Attachment a = new Attachment(is);
|
||||
AttachmentItem item = controller.getAttachmentItem(h, a, true);
|
||||
assertEquals(1, item.getWidth());
|
||||
assertEquals(10000, item.getHeight());
|
||||
assertEquals(dimensions.minWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.maxHeight, item.getThumbnailHeight());
|
||||
assertEquals("image/jpeg", item.getMimeType());
|
||||
assertEquals("jpg", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWideError() throws Exception {
|
||||
AttachmentHeader h = new AttachmentHeader(msgId, "image/jpeg");
|
||||
InputStream is = getAssetInputStream("error_wide.jpg");
|
||||
Attachment a = new Attachment(is);
|
||||
AttachmentItem item = controller.getAttachmentItem(h, a, true);
|
||||
assertEquals(1920, item.getWidth());
|
||||
assertEquals(1, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.minHeight, item.getThumbnailHeight());
|
||||
assertEquals("image/jpeg", item.getMimeType());
|
||||
assertEquals("jpg", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
private InputStream getUrlInputStream(String url) throws IOException {
|
||||
return new URL(url).openStream();
|
||||
}
|
||||
|
||||
private InputStream getAssetInputStream(String name) throws IOException {
|
||||
AssetManager assets = InstrumentationRegistry.getContext().getAssets();
|
||||
return assets.open(name);
|
||||
}
|
||||
|
||||
public static byte[] getRandomBytes(int length) {
|
||||
byte[] b = new byte[length];
|
||||
new Random().nextBytes(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
public static byte[] getRandomId() {
|
||||
return getRandomBytes(UniqueId.LENGTH);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.BitmapFactory.Options;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.media.ExifInterface;
|
||||
import android.webkit.MimeTypeMap;
|
||||
@@ -13,7 +13,7 @@ import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.conversation.ImageHelper.DecodeResult;
|
||||
import org.briarproject.briar.api.messaging.Attachment;
|
||||
import org.briarproject.briar.api.messaging.AttachmentHeader;
|
||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||
@@ -49,6 +49,7 @@ class AttachmentController {
|
||||
private static final int READ_LIMIT = 1024 * 8192;
|
||||
|
||||
private final MessagingManager messagingManager;
|
||||
private final ImageHelper imageHelper;
|
||||
private final int defaultSize;
|
||||
private final int minWidth, maxWidth;
|
||||
private final int minHeight, maxHeight;
|
||||
@@ -56,18 +57,38 @@ class AttachmentController {
|
||||
private final Map<MessageId, List<AttachmentItem>> attachmentCache =
|
||||
new ConcurrentHashMap<>();
|
||||
|
||||
AttachmentController(MessagingManager messagingManager, Resources res) {
|
||||
AttachmentController(MessagingManager messagingManager,
|
||||
AttachmentDimensions dimensions, ImageHelper imageHelper) {
|
||||
this.messagingManager = messagingManager;
|
||||
defaultSize =
|
||||
res.getDimensionPixelSize(R.dimen.message_bubble_image_default);
|
||||
minWidth = res.getDimensionPixelSize(
|
||||
R.dimen.message_bubble_image_min_width);
|
||||
maxWidth = res.getDimensionPixelSize(
|
||||
R.dimen.message_bubble_image_max_width);
|
||||
minHeight = res.getDimensionPixelSize(
|
||||
R.dimen.message_bubble_image_min_height);
|
||||
maxHeight = res.getDimensionPixelSize(
|
||||
R.dimen.message_bubble_image_max_height);
|
||||
this.imageHelper = imageHelper;
|
||||
defaultSize = dimensions.defaultSize;
|
||||
minWidth = dimensions.minWidth;
|
||||
maxWidth = dimensions.maxWidth;
|
||||
minHeight = dimensions.minHeight;
|
||||
maxHeight = dimensions.maxHeight;
|
||||
}
|
||||
|
||||
AttachmentController(MessagingManager messagingManager,
|
||||
AttachmentDimensions dimensions) {
|
||||
this(messagingManager, dimensions, new ImageHelper() {
|
||||
@Override
|
||||
public DecodeResult decodeStream(InputStream is) {
|
||||
Options options = new Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeStream(is, null, options);
|
||||
String mimeType = options.outMimeType;
|
||||
if (mimeType == null) mimeType = "";
|
||||
return new DecodeResult(options.outWidth, options.outHeight,
|
||||
mimeType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getExtensionFromMimeType(String mimeType) {
|
||||
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
|
||||
return mimeTypeMap.getExtensionFromMimeType(mimeType);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void put(MessageId messageId, List<AttachmentItem> attachments) {
|
||||
@@ -119,7 +140,7 @@ class AttachmentController {
|
||||
MessageId messageId = h.getMessageId();
|
||||
if (!needsSize) {
|
||||
String mimeType = h.getContentType();
|
||||
String extension = getExtensionFromMimeType(mimeType);
|
||||
String extension = imageHelper.getExtensionFromMimeType(mimeType);
|
||||
boolean hasError = false;
|
||||
if (extension == null) {
|
||||
extension = "";
|
||||
@@ -162,7 +183,7 @@ class AttachmentController {
|
||||
getThumbnailSize(size.width, size.height, size.mimeType);
|
||||
}
|
||||
// get file extension
|
||||
String extension = getExtensionFromMimeType(size.mimeType);
|
||||
String extension = imageHelper.getExtensionFromMimeType(size.mimeType);
|
||||
boolean hasError = extension == null || size.error;
|
||||
if (extension == null) extension = "";
|
||||
return new AttachmentItem(messageId, size.width, size.height,
|
||||
@@ -170,17 +191,10 @@ class AttachmentController {
|
||||
thumbnailSize.height, hasError);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getExtensionFromMimeType(String mimeType) {
|
||||
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
|
||||
return mimeTypeMap.getExtensionFromMimeType(mimeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of a JPEG {@link InputStream} if EXIF info is available.
|
||||
*/
|
||||
private static Size getSizeFromExif(InputStream is)
|
||||
throws IOException {
|
||||
private Size getSizeFromExif(InputStream is) throws IOException {
|
||||
ExifInterface exif = new ExifInterface(is);
|
||||
// these can return 0 independent of default value
|
||||
int width = exif.getAttributeInt(TAG_IMAGE_WIDTH, 0);
|
||||
@@ -200,14 +214,10 @@ class AttachmentController {
|
||||
/**
|
||||
* Gets the size of any image {@link InputStream}.
|
||||
*/
|
||||
private static Size getSizeFromBitmap(InputStream is) {
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeStream(is, null, options);
|
||||
if (options.outWidth < 1 || options.outHeight < 1)
|
||||
return new Size();
|
||||
return new Size(options.outWidth, options.outHeight,
|
||||
options.outMimeType);
|
||||
private Size getSizeFromBitmap(InputStream is) {
|
||||
DecodeResult result = imageHelper.decodeStream(is);
|
||||
if (result.width < 1 || result.height < 1) return new Size();
|
||||
return new Size(result.width, result.height, result.mimeType);
|
||||
}
|
||||
|
||||
private Size getThumbnailSize(int width, int height, String mimeType) {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
|
||||
import org.briarproject.briar.R;
|
||||
|
||||
class AttachmentDimensions {
|
||||
|
||||
final int defaultSize;
|
||||
final int minWidth, maxWidth;
|
||||
final int minHeight, maxHeight;
|
||||
|
||||
@VisibleForTesting
|
||||
AttachmentDimensions(int defaultSize, int minWidth, int maxWidth,
|
||||
int minHeight, int maxHeight) {
|
||||
this.defaultSize = defaultSize;
|
||||
this.minWidth = minWidth;
|
||||
this.maxWidth = maxWidth;
|
||||
this.minHeight = minHeight;
|
||||
this.maxHeight = maxHeight;
|
||||
}
|
||||
|
||||
static AttachmentDimensions getAttachmentDimensions(Resources res) {
|
||||
int defaultSize =
|
||||
res.getDimensionPixelSize(R.dimen.message_bubble_image_default);
|
||||
int minWidth = res.getDimensionPixelSize(
|
||||
R.dimen.message_bubble_image_min_width);
|
||||
int maxWidth = res.getDimensionPixelSize(
|
||||
R.dimen.message_bubble_image_max_width);
|
||||
int minHeight = res.getDimensionPixelSize(
|
||||
R.dimen.message_bubble_image_min_height);
|
||||
int maxHeight = res.getDimensionPixelSize(
|
||||
R.dimen.message_bubble_image_max_height);
|
||||
return new AttachmentDimensions(defaultSize, minWidth, maxWidth,
|
||||
minHeight, minHeight);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -51,6 +51,7 @@ 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.now;
|
||||
import static org.briarproject.briar.android.conversation.AttachmentDimensions.getAttachmentDimensions;
|
||||
import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
|
||||
import static org.briarproject.briar.android.util.UiUtils.observeForeverOnce;
|
||||
|
||||
@@ -114,7 +115,7 @@ public class ConversationViewModel extends AndroidViewModel {
|
||||
this.settingsManager = settingsManager;
|
||||
this.privateMessageFactory = privateMessageFactory;
|
||||
this.attachmentController = new AttachmentController(messagingManager,
|
||||
application.getResources());
|
||||
getAttachmentDimensions(application.getResources()));
|
||||
contactDeleted.setValue(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
@NotNullByDefault
|
||||
interface ImageHelper {
|
||||
|
||||
DecodeResult decodeStream(InputStream is);
|
||||
|
||||
@Nullable
|
||||
String getExtensionFromMimeType(String mimeType);
|
||||
|
||||
class DecodeResult {
|
||||
|
||||
final int width;
|
||||
final int height;
|
||||
final String mimeType;
|
||||
|
||||
DecodeResult(int width, int height, String mimeType) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.mimeType = mimeType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.briar.android.conversation.ImageHelper.DecodeResult;
|
||||
import org.briarproject.briar.api.messaging.Attachment;
|
||||
import org.briarproject.briar.api.messaging.AttachmentHeader;
|
||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class AttachmentControllerTest extends BrambleMockTestCase {
|
||||
|
||||
private final AttachmentDimensions dimensions = new AttachmentDimensions(
|
||||
100, 50, 200, 75, 300
|
||||
);
|
||||
private final MessageId msgId = new MessageId(getRandomId());
|
||||
private final Attachment attachment = new Attachment(
|
||||
new BufferedInputStream(
|
||||
new ByteArrayInputStream(getRandomBytes(42))));
|
||||
|
||||
private final MessagingManager messagingManager =
|
||||
context.mock(MessagingManager.class);
|
||||
private final ImageHelper imageHelper = context.mock(ImageHelper.class);
|
||||
private final AttachmentController controller =
|
||||
new AttachmentController(
|
||||
messagingManager,
|
||||
dimensions,
|
||||
imageHelper
|
||||
);
|
||||
|
||||
@Test
|
||||
public void testNoSize() {
|
||||
String mimeType = "image/jpeg";
|
||||
AttachmentHeader h = getAttachmentHeader(mimeType);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(imageHelper).getExtensionFromMimeType(mimeType);
|
||||
will(returnValue("jpg"));
|
||||
}});
|
||||
|
||||
AttachmentItem item =
|
||||
controller.getAttachmentItem(h, attachment, false);
|
||||
assertEquals(mimeType, item.getMimeType());
|
||||
assertEquals("jpg", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoSizeWrongMimeTypeProducesError() {
|
||||
String mimeType = "application/octet-stream";
|
||||
AttachmentHeader h = getAttachmentHeader(mimeType);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(imageHelper).getExtensionFromMimeType(mimeType);
|
||||
will(returnValue(null));
|
||||
}});
|
||||
|
||||
AttachmentItem item =
|
||||
controller.getAttachmentItem(h, attachment, false);
|
||||
assertTrue(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSmallJpegImage() {
|
||||
String mimeType = "image/jpeg";
|
||||
AttachmentHeader h = getAttachmentHeader(mimeType);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(imageHelper).decodeStream(with(any(InputStream.class)));
|
||||
will(returnValue(new DecodeResult(160, 240, mimeType)));
|
||||
oneOf(imageHelper).getExtensionFromMimeType(mimeType);
|
||||
will(returnValue("jpg"));
|
||||
}});
|
||||
|
||||
AttachmentItem item = controller.getAttachmentItem(h, attachment, true);
|
||||
assertEquals(msgId, item.getMessageId());
|
||||
assertEquals(160, item.getWidth());
|
||||
assertEquals(240, item.getHeight());
|
||||
assertEquals(160, item.getThumbnailWidth());
|
||||
assertEquals(240, item.getThumbnailHeight());
|
||||
assertEquals(mimeType, item.getMimeType());
|
||||
assertEquals("jpg", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageHealsWrongMimeType() {
|
||||
AttachmentHeader h = getAttachmentHeader("image/png");
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(imageHelper).decodeStream(with(any(InputStream.class)));
|
||||
will(returnValue(new DecodeResult(160, 240, "image/jpeg")));
|
||||
oneOf(imageHelper).getExtensionFromMimeType("image/jpeg");
|
||||
will(returnValue("jpg"));
|
||||
}});
|
||||
|
||||
AttachmentItem item = controller.getAttachmentItem(h, attachment, true);
|
||||
assertEquals("image/jpeg", item.getMimeType());
|
||||
assertEquals("jpg", item.getExtension());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBigJpegImage() {
|
||||
String mimeType = "image/jpeg";
|
||||
AttachmentHeader h = getAttachmentHeader(mimeType);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(imageHelper).decodeStream(with(any(InputStream.class)));
|
||||
will(returnValue(new DecodeResult(1728, 2592, mimeType)));
|
||||
oneOf(imageHelper).getExtensionFromMimeType(mimeType);
|
||||
will(returnValue("jpg"));
|
||||
}});
|
||||
|
||||
AttachmentItem item = controller.getAttachmentItem(h, attachment, true);
|
||||
assertEquals(1728, item.getWidth());
|
||||
assertEquals(2592, item.getHeight());
|
||||
assertEquals(dimensions.maxWidth, item.getThumbnailWidth());
|
||||
assertEquals(dimensions.maxHeight, item.getThumbnailHeight());
|
||||
assertFalse(item.hasError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedError() {
|
||||
AttachmentHeader h = getAttachmentHeader("image/jpeg");
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(imageHelper).decodeStream(with(any(InputStream.class)));
|
||||
will(returnValue(new DecodeResult(0, 0, "")));
|
||||
oneOf(imageHelper).getExtensionFromMimeType("");
|
||||
will(returnValue(null));
|
||||
}});
|
||||
|
||||
AttachmentItem item = controller.getAttachmentItem(h, attachment, true);
|
||||
assertTrue(item.hasError());
|
||||
}
|
||||
|
||||
private AttachmentHeader getAttachmentHeader(String contentType) {
|
||||
return new AttachmentHeader(msgId, contentType);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package org.briarproject.briar.android.conversation;
|
||||
|
||||
import com.bumptech.glide.util.MarkEnforcingInputStream;
|
||||
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
public class MarkEnforcingInputStreamTest extends BrambleTestCase {
|
||||
|
||||
private final int readLimit = 4;
|
||||
private final byte[] bytes = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6};
|
||||
|
||||
@Test
|
||||
public void testPlainStreamReadsAllBytes() throws Exception {
|
||||
InputStream is = getStream();
|
||||
is.mark(readLimit);
|
||||
for (byte ignored : bytes) {
|
||||
assertNotEquals(-1, is.read());
|
||||
}
|
||||
assertEquals(0, is.available());
|
||||
is.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMarkEnforcingStreamReadsUntilMarkLimit() throws Exception {
|
||||
InputStream is = new MarkEnforcingInputStream(getStream());
|
||||
is.mark(readLimit);
|
||||
assertEquals(readLimit, is.available());
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
if (i < readLimit) {
|
||||
assertEquals(readLimit - i, is.available());
|
||||
assertNotEquals(-1, is.read());
|
||||
} else {
|
||||
assertEquals(0, is.available());
|
||||
assertEquals(-1, is.read());
|
||||
}
|
||||
}
|
||||
assertEquals(0, is.available());
|
||||
is.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMarkEnforcingStreamCanBeReset() throws Exception {
|
||||
InputStream is = new MarkEnforcingInputStream(getStream());
|
||||
is.mark(readLimit);
|
||||
assertEquals(readLimit, is.available());
|
||||
for (int i = 0; i < readLimit; i++) {
|
||||
assertNotEquals(-1, is.read());
|
||||
}
|
||||
assertEquals(0, is.available());
|
||||
is.reset();
|
||||
is.mark(readLimit);
|
||||
assertEquals(readLimit, is.available());
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
if (i < readLimit) {
|
||||
assertEquals(readLimit - i, is.available());
|
||||
assertNotEquals(-1, is.read());
|
||||
} else {
|
||||
assertEquals(0, is.available());
|
||||
assertEquals(-1, is.read());
|
||||
}
|
||||
}
|
||||
is.close();
|
||||
}
|
||||
|
||||
private InputStream getStream() {
|
||||
return new BufferedInputStream(new ByteArrayInputStream(bytes));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user