diff --git a/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/AbstractAttachmentCreationTaskTest.java b/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/AbstractAttachmentCreationTaskTest.java deleted file mode 100644 index 6b112fa55..000000000 --- a/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/AbstractAttachmentCreationTaskTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.briarproject.briar.android.attachment; - -import android.content.res.AssetManager; - -import org.junit.Before; - -import java.io.IOException; -import java.io.InputStream; - -import static androidx.test.InstrumentationRegistry.getContext; -import static androidx.test.core.app.ApplicationProvider.getApplicationContext; - -abstract class AbstractAttachmentCreationTaskTest { - - private final ImageHelper imageHelper = new ImageHelperImpl(); - private final ImageSizeCalculator imageSizeCalculator = - new ImageSizeCalculator(imageHelper); - - private AttachmentCreationTask task; - - @Before - @SuppressWarnings("ConstantConditions") // add real objects when needed - public void setUp() { - task = new AttachmentCreationTask(null, - getApplicationContext().getContentResolver(), null, - imageSizeCalculator, null, null, true); - } - - void testCompress(String filename, String contentType) - throws IOException { - InputStream is = getAssetManager().open(filename); - task.compressImage(is, contentType); - } - - static AssetManager getAssetManager() { - // pm.getResourcesForApplication(packageName).getAssets() did not work - //noinspection deprecation - return getContext().getAssets(); - } - -} diff --git a/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/AbstractImageCompressorComponent.java b/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/AbstractImageCompressorComponent.java new file mode 100644 index 000000000..aecaf71fa --- /dev/null +++ b/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/AbstractImageCompressorComponent.java @@ -0,0 +1,15 @@ +package org.briarproject.briar.android.attachment; + +import javax.inject.Singleton; + +import dagger.Component; + +@Singleton +@Component(modules = { + AttachmentModule.class +}) +interface AbstractImageCompressorComponent { + + void inject(AbstractImageCompressorTest test); + +} diff --git a/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/AbstractImageCompressorTest.java b/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/AbstractImageCompressorTest.java new file mode 100644 index 000000000..ca1ed70e8 --- /dev/null +++ b/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/AbstractImageCompressorTest.java @@ -0,0 +1,38 @@ +package org.briarproject.briar.android.attachment; + +import android.content.res.AssetManager; + +import java.io.IOException; +import java.io.InputStream; + +import javax.inject.Inject; + +import static androidx.test.InstrumentationRegistry.getContext; + +public abstract class AbstractImageCompressorTest { + + @Inject + ImageCompressor imageCompressor; + + public AbstractImageCompressorTest() { + AbstractImageCompressorComponent component = + DaggerAbstractImageCompressorComponent.builder().build(); + component.inject(this); + } + + protected abstract void inject( + AbstractImageCompressorComponent component); + + void testCompress(String filename, String contentType) + throws IOException { + InputStream is = getAssetManager().open(filename); + imageCompressor.compressImage(is, contentType); + } + + static AssetManager getAssetManager() { + // pm.getResourcesForApplication(packageName).getAssets() did not work + //noinspection deprecation + return getContext().getAssets(); + } + +} diff --git a/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/AttachmentCreationTaskTest.java b/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/ImageCompressorTest.java similarity index 89% rename from briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/AttachmentCreationTaskTest.java rename to briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/ImageCompressorTest.java index 59b6ebf0a..b3cf1f1e9 100644 --- a/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/AttachmentCreationTaskTest.java +++ b/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/ImageCompressorTest.java @@ -9,8 +9,13 @@ import static android.os.Build.VERSION.SDK_INT; import static org.junit.Assume.assumeTrue; @RunWith(AndroidJUnit4.class) -public class AttachmentCreationTaskTest - extends AbstractAttachmentCreationTaskTest { +public class ImageCompressorTest + extends AbstractImageCompressorTest { + + @Override + protected void inject(AbstractImageCompressorComponent component) { + component.inject(this); + } @Test public void testCompressSmallPng() throws Exception { diff --git a/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/PngSuiteAttachmentCreationTaskTest.java b/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/PngSuiteImageCompressorTest.java similarity index 80% rename from briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/PngSuiteAttachmentCreationTaskTest.java rename to briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/PngSuiteImageCompressorTest.java index d3c2b80b8..7891fb6b6 100644 --- a/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/PngSuiteAttachmentCreationTaskTest.java +++ b/briar-android/src/androidTestOfficial/java/org/briarproject/briar/android/attachment/PngSuiteImageCompressorTest.java @@ -17,11 +17,16 @@ import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; @RunWith(Parameterized.class) -public class PngSuiteAttachmentCreationTaskTest - extends AbstractAttachmentCreationTaskTest { +public class PngSuiteImageCompressorTest + extends AbstractImageCompressorTest { private static final Logger LOG = - getLogger(PngSuiteAttachmentCreationTaskTest.class.getName()); + getLogger(PngSuiteImageCompressorTest.class.getName()); + + @Override + protected void inject(AbstractImageCompressorComponent component) { + component.inject(this); + } @Parameters public static Iterable data() throws IOException { @@ -34,14 +39,14 @@ public class PngSuiteAttachmentCreationTaskTest private final String filename; - public PngSuiteAttachmentCreationTaskTest(String filename) { + public PngSuiteImageCompressorTest(String filename) { this.filename = filename; } @Test public void testPngSuiteCompress() throws Exception { assumeTrue(isOptionalTestEnabled( - PngSuiteAttachmentCreationTaskTest.class)); + PngSuiteImageCompressorTest.class)); LOG.info("Testing " + filename); if (filename.startsWith("x")) { try { diff --git a/briar-android/src/debug/java/org/briarproject/briar/android/test/TestAvatarCreatorImpl.java b/briar-android/src/debug/java/org/briarproject/briar/android/test/TestAvatarCreatorImpl.java index edcc1ad28..06f775bed 100644 --- a/briar-android/src/debug/java/org/briarproject/briar/android/test/TestAvatarCreatorImpl.java +++ b/briar-android/src/debug/java/org/briarproject/briar/android/test/TestAvatarCreatorImpl.java @@ -14,17 +14,15 @@ import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; +import org.briarproject.briar.android.attachment.ImageCompressor; import org.briarproject.briar.api.test.TestAvatarCreator; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.io.InputStream; import java.util.Random; import javax.annotation.Nullable; - -import static android.graphics.Bitmap.CompressFormat.JPEG; -import static org.briarproject.briar.api.media.MediaConstants.MAX_IMAGE_SIZE; +import javax.inject.Inject; public class TestAvatarCreatorImpl implements TestAvatarCreator { private final int WIDTH = 800; @@ -34,20 +32,18 @@ public class TestAvatarCreatorImpl implements TestAvatarCreator { private final float[] hsv = new float[3]; private final Random random = new Random(); + private final ImageCompressor imageCompressor; + + @Inject + TestAvatarCreatorImpl(ImageCompressor imageCompressor) { + this.imageCompressor = imageCompressor; + } + @Nullable @Override - public InputStream getAvatarInputStream() { + public InputStream getAvatarInputStream() throws IOException { Bitmap bitmap = generateBitmap(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - // TODO maybe use ImageCompressor once available standalone - for (int quality = 100; quality >= 0; quality -= 10) { - if (!bitmap.compress(JPEG, quality, out)) return null; - if (out.size() <= MAX_IMAGE_SIZE) { - return new ByteArrayInputStream(out.toByteArray()); - } - out.reset(); - } - return new ByteArrayInputStream(out.toByteArray()); + return imageCompressor.compressImage(bitmap); } private Bitmap generateBitmap() { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java index 0ebb6d789..45c90381e 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java @@ -187,8 +187,9 @@ public class AppModule { } @Provides - TestAvatarCreator provideTestAvatarCreator() { - return new TestAvatarCreatorImpl(); + TestAvatarCreator provideTestAvatarCreator( + TestAvatarCreatorImpl testAvatarCreator) { + return testAvatarCreator; } @Provides diff --git a/briar-android/src/main/java/org/briarproject/briar/android/attachment/AttachmentCreationTask.java b/briar-android/src/main/java/org/briarproject/briar/android/attachment/AttachmentCreationTask.java index 77c8ae8de..031480b38 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/attachment/AttachmentCreationTask.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/attachment/AttachmentCreationTask.java @@ -1,8 +1,6 @@ package org.briarproject.briar.android.attachment; import android.content.ContentResolver; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory.Options; import android.net.Uri; import org.briarproject.bramble.api.db.DbException; @@ -13,21 +11,14 @@ import org.briarproject.briar.api.media.AttachmentHeader; import org.briarproject.briar.api.messaging.MessagingManager; import org.jsoup.UnsupportedMimeTypeException; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.logging.Logger; import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; -import static android.graphics.Bitmap.CompressFormat.JPEG; -import static android.graphics.BitmapFactory.decodeStream; import static java.util.Arrays.asList; -import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.util.AndroidUtils.getSupportedImageContentTypes; @@ -35,19 +26,16 @@ 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.api.media.MediaConstants.MAX_IMAGE_SIZE; @NotNullByDefault class AttachmentCreationTask { - private static Logger LOG = + private static final Logger LOG = getLogger(AttachmentCreationTask.class.getName()); - private static final int MAX_ATTACHMENT_DIMENSION = 1000; - private final MessagingManager messagingManager; private final ContentResolver contentResolver; - private final ImageSizeCalculator imageSizeCalculator; + private final ImageCompressor imageCompressor; private final GroupId groupId; private final Collection uris; private final boolean needsSize; @@ -59,11 +47,11 @@ class AttachmentCreationTask { AttachmentCreationTask(MessagingManager messagingManager, ContentResolver contentResolver, AttachmentCreator attachmentCreator, - ImageSizeCalculator imageSizeCalculator, + ImageCompressor imageCompressor, GroupId groupId, Collection uris, boolean needsSize) { this.messagingManager = messagingManager; this.contentResolver = contentResolver; - this.imageSizeCalculator = imageSizeCalculator; + this.imageCompressor = imageCompressor; this.groupId = groupId; this.uris = uris; this.needsSize = needsSize; @@ -115,7 +103,8 @@ class AttachmentCreationTask { } InputStream is = contentResolver.openInputStream(uri); if (is == null) throw new IOException(); - is = compressImage(is, contentType); + is = imageCompressor + .compressImage(is, contentType); contentType = "image/jpeg"; long timestamp = System.currentTimeMillis(); AttachmentHeader h = messagingManager @@ -125,51 +114,4 @@ class AttachmentCreationTask { return h; } - @VisibleForTesting - InputStream compressImage(InputStream is, String contentType) - throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try { - Bitmap bitmap = createBitmap(is, contentType); - for (int quality = 100; quality >= 0; quality -= 10) { - if (!bitmap.compress(JPEG, quality, out)) - throw new IOException(); - if (out.size() <= MAX_IMAGE_SIZE) { - if (LOG.isLoggable(INFO)) { - LOG.info("Compressed image to " - + out.size() + " bytes, quality " + quality); - } - return new ByteArrayInputStream(out.toByteArray()); - } - out.reset(); - } - throw new IOException(); - } finally { - tryToClose(is, LOG, WARNING); - } - } - - private Bitmap createBitmap(InputStream is, String contentType) - throws IOException { - is = new BufferedInputStream(is); - Size size = imageSizeCalculator.getSize(is, contentType); - if (size.error) throw new IOException(); - if (LOG.isLoggable(INFO)) - LOG.info("Original image size: " + size.width + "x" + size.height); - int dimension = Math.max(size.width, size.height); - int inSampleSize = 1; - while (dimension > MAX_ATTACHMENT_DIMENSION) { - inSampleSize *= 2; - dimension /= 2; - } - if (LOG.isLoggable(INFO)) - LOG.info("Scaling attachment by factor of " + inSampleSize); - Options options = new Options(); - options.inSampleSize = inSampleSize; - if (contentType.equals("image/png")) - options.inPreferredConfig = Bitmap.Config.RGB_565; - Bitmap bitmap = decodeStream(is, null, options); - if (bitmap == null) throw new IOException(); - return bitmap; - } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/attachment/AttachmentCreatorImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/attachment/AttachmentCreatorImpl.java index 941c5e4f6..fdc27c690 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/attachment/AttachmentCreatorImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/attachment/AttachmentCreatorImpl.java @@ -41,7 +41,7 @@ import static org.briarproject.briar.api.media.MediaConstants.MAX_IMAGE_SIZE; @NotNullByDefault class AttachmentCreatorImpl implements AttachmentCreator { - private static Logger LOG = + private static final Logger LOG = getLogger(AttachmentCreatorImpl.class.getName()); private final Application app; @@ -49,7 +49,7 @@ class AttachmentCreatorImpl implements AttachmentCreator { private final Executor ioExecutor; private final MessagingManager messagingManager; private final AttachmentRetriever retriever; - private final ImageSizeCalculator imageSizeCalculator; + private final ImageCompressor imageCompressor; private final CopyOnWriteArrayList uris = new CopyOnWriteArrayList<>(); private final CopyOnWriteArrayList itemResults = @@ -64,12 +64,12 @@ class AttachmentCreatorImpl implements AttachmentCreator { @Inject AttachmentCreatorImpl(Application app, @IoExecutor Executor ioExecutor, MessagingManager messagingManager, AttachmentRetriever retriever, - ImageSizeCalculator imageSizeCalculator) { + ImageCompressor imageCompressor) { this.app = app; this.ioExecutor = ioExecutor; this.messagingManager = messagingManager; this.retriever = retriever; - this.imageSizeCalculator = imageSizeCalculator; + this.imageCompressor = imageCompressor; } @Override @@ -89,7 +89,7 @@ class AttachmentCreatorImpl implements AttachmentCreator { if (id == null) throw new IllegalStateException(); boolean needsSize = uris.size() == 1; task = new AttachmentCreationTask(messagingManager, - app.getContentResolver(), this, imageSizeCalculator, id, + app.getContentResolver(), this, imageCompressor, id, uris, needsSize); ioExecutor.execute(() -> task.storeAttachments()); }); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/attachment/AttachmentModule.java b/briar-android/src/main/java/org/briarproject/briar/android/attachment/AttachmentModule.java index 57ae44f56..0f121d95a 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/attachment/AttachmentModule.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/attachment/AttachmentModule.java @@ -22,6 +22,12 @@ public class AttachmentModule { return new ImageSizeCalculator(imageHelper); } + @Provides + ImageCompressor provideImageCompressor( + ImageCompressorImpl imageCompressor) { + return imageCompressor; + } + @Provides AttachmentDimensions provideAttachmentDimensions(Application app) { return getAttachmentDimensions(app.getResources()); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/attachment/ImageCompressor.java b/briar-android/src/main/java/org/briarproject/briar/android/attachment/ImageCompressor.java new file mode 100644 index 000000000..8c1e99ad9 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/attachment/ImageCompressor.java @@ -0,0 +1,34 @@ +package org.briarproject.briar.android.attachment; + +import android.graphics.Bitmap; +import android.net.Uri; + +import java.io.IOException; +import java.io.InputStream; + +public interface ImageCompressor { + + /** + * Load an image from {@code is}, compress it and return an InputStream + * from which the resulting image can be read. The image will be compressed + * such that it fits into a message. + * + * @param is the stream to read the source image from + * @param contentType the mimetype of the source image such as "image/jpeg" + * as obtained by {@link android.content.ContentResolver#getType(Uri)} + * @return a stream from which the resulting image can be read + */ + InputStream compressImage(InputStream is, String contentType) + throws IOException; + + /** + * Compress an image and return an InputStream from which the resulting + * image can be read. The image will be compressed such that it fits into + * a message. + * + * @param bitmap the source image + * @return a stream from which the resulting image can be read + */ + InputStream compressImage(Bitmap bitmap) throws IOException; + +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/attachment/ImageCompressorImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/attachment/ImageCompressorImpl.java new file mode 100644 index 000000000..3c5249ac5 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/attachment/ImageCompressorImpl.java @@ -0,0 +1,91 @@ +package org.briarproject.briar.android.attachment; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.logging.Logger; + +import javax.inject.Inject; + +import static android.graphics.Bitmap.CompressFormat.JPEG; +import static android.graphics.BitmapFactory.decodeStream; +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.util.IoUtils.tryToClose; +import static org.briarproject.briar.api.media.MediaConstants.MAX_IMAGE_SIZE; + +class ImageCompressorImpl implements ImageCompressor { + + private static final Logger LOG = + getLogger(ImageCompressorImpl.class.getName()); + + private static final int MAX_ATTACHMENT_DIMENSION = 1000; + + private final ImageSizeCalculator imageSizeCalculator; + + @Inject + ImageCompressorImpl(ImageSizeCalculator imageSizeCalculator) { + this.imageSizeCalculator = imageSizeCalculator; + } + + @Override + public InputStream compressImage(InputStream is, String contentType) + throws IOException { + try { + Bitmap bitmap = + createBitmap(is, contentType, MAX_ATTACHMENT_DIMENSION); + return compressImage(bitmap); + } finally { + tryToClose(is, LOG, WARNING); + } + } + + @Override + public InputStream compressImage(Bitmap bitmap) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + for (int quality = 100; quality >= 0; quality -= 10) { + if (!bitmap.compress(JPEG, quality, out)) + throw new IOException(); + if (out.size() <= MAX_IMAGE_SIZE) { + if (LOG.isLoggable(INFO)) { + LOG.info("Compressed image to " + + out.size() + " bytes, quality " + quality); + } + return new ByteArrayInputStream(out.toByteArray()); + } + out.reset(); + } + throw new IOException(); + } + + private Bitmap createBitmap(InputStream is, String contentType, int maxSize) + throws IOException { + is = new BufferedInputStream(is); + Size size = imageSizeCalculator.getSize(is, contentType); + if (size.error) throw new IOException(); + if (LOG.isLoggable(INFO)) + LOG.info("Original image size: " + size.width + "x" + size.height); + int dimension = Math.max(size.width, size.height); + int inSampleSize = 1; + while (dimension > maxSize) { + inSampleSize *= 2; + dimension /= 2; + } + if (LOG.isLoggable(INFO)) + LOG.info("Scaling attachment by factor of " + inSampleSize); + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inSampleSize = inSampleSize; + if (contentType.equals("image/png")) + options.inPreferredConfig = Bitmap.Config.RGB_565; + Bitmap bitmap = decodeStream(is, null, options); + if (bitmap == null) throw new IOException(); + return bitmap; + } + +} diff --git a/briar-android/src/release/java/org/briarproject/briar/android/test/TestAvatarCreatorImpl.java b/briar-android/src/release/java/org/briarproject/briar/android/test/TestAvatarCreatorImpl.java index f3299e209..3d235fcc4 100644 --- a/briar-android/src/release/java/org/briarproject/briar/android/test/TestAvatarCreatorImpl.java +++ b/briar-android/src/release/java/org/briarproject/briar/android/test/TestAvatarCreatorImpl.java @@ -1,14 +1,18 @@ package org.briarproject.briar.android.test; -import android.util.Log; - import org.briarproject.briar.api.test.TestAvatarCreator; import java.io.InputStream; import javax.annotation.Nullable; +import javax.inject.Inject; public class TestAvatarCreatorImpl implements TestAvatarCreator { + + @Inject + TestAvatarCreatorImpl() { + } + @Nullable @Override public InputStream getAvatarInputStream() { diff --git a/briar-api/src/main/java/org/briarproject/briar/api/test/TestAvatarCreator.java b/briar-api/src/main/java/org/briarproject/briar/api/test/TestAvatarCreator.java index 534a25ce1..d2d322c92 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/test/TestAvatarCreator.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/test/TestAvatarCreator.java @@ -1,10 +1,11 @@ package org.briarproject.briar.api.test; +import java.io.IOException; import java.io.InputStream; import javax.annotation.Nullable; public interface TestAvatarCreator { @Nullable - InputStream getAvatarInputStream(); + InputStream getAvatarInputStream() throws IOException; } diff --git a/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java b/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java index ccdd4dd0b..e773d3195 100644 --- a/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java @@ -302,7 +302,13 @@ public class TestDataCreatorImpl implements TestDataCreator { AuthorId authorId = c.getAuthor().getId(); GroupId groupId = groupFactory.createGroup(AvatarManager.CLIENT_ID, AvatarManager.MAJOR_VERSION, authorId.getBytes()).getId(); - InputStream is = testAvatarCreator.getAvatarInputStream(); + InputStream is; + try { + is = testAvatarCreator.getAvatarInputStream(); + } catch (IOException e) { + logException(LOG, WARNING, e); + return; + } if (is == null) return; Message m; try {