mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 05:09:53 +01:00
Establish some rules for handling InputStreams
* Methods shouldn't place any special requirements on the streams passed into them * This implies that if a stream's going to be marked and reset, that should all happen within one method * This also implies that if a method needs to mark and reset a stream, it should wrap the stream in a BufferedInputStream before doing so, rather than requiring a markable stream to be passed in
This commit is contained in:
@@ -16,6 +16,7 @@ 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.MessagingManager;
|
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||||
|
|
||||||
|
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.ArrayList;
|
||||||
@@ -92,14 +93,13 @@ class AttachmentController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates {@link AttachmentItem}s from the passed headers and Attachments.
|
* Creates {@link AttachmentItem}s from the passed headers and Attachments.
|
||||||
* Note: This marks the {@link Attachment}'s {@link InputStream}
|
*
|
||||||
* and closes the streams.
|
* Note: This closes the {@link Attachment}'s {@link InputStream}.
|
||||||
*/
|
*/
|
||||||
List<AttachmentItem> getAttachmentItems(
|
List<AttachmentItem> getAttachmentItems(
|
||||||
List<Pair<AttachmentHeader, Attachment>> attachments) {
|
List<Pair<AttachmentHeader, Attachment>> attachments) {
|
||||||
List<AttachmentItem> items = new ArrayList<>(attachments.size());
|
List<AttachmentItem> items = new ArrayList<>(attachments.size());
|
||||||
for (Pair<AttachmentHeader, Attachment> a : attachments) {
|
for (Pair<AttachmentHeader, Attachment> a : attachments) {
|
||||||
a.getSecond().getStream().mark(Integer.MAX_VALUE);
|
|
||||||
AttachmentItem item =
|
AttachmentItem item =
|
||||||
getAttachmentItem(a.getFirst(), a.getSecond());
|
getAttachmentItem(a.getFirst(), a.getSecond());
|
||||||
items.add(item);
|
items.add(item);
|
||||||
@@ -109,16 +109,14 @@ class AttachmentController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an {@link AttachmentItem} from the {@link Attachment}'s
|
* Creates an {@link AttachmentItem} from the {@link Attachment}'s
|
||||||
* {@link InputStream}.
|
* {@link InputStream} which will be closed when this method returns.
|
||||||
* Note: Requires a resettable InputStream
|
|
||||||
* with the beginning already marked.
|
|
||||||
* The stream will be closed when this method returns.
|
|
||||||
*/
|
*/
|
||||||
AttachmentItem getAttachmentItem(AttachmentHeader h, Attachment a) {
|
AttachmentItem getAttachmentItem(AttachmentHeader h, Attachment a) {
|
||||||
MessageId messageId = h.getMessageId();
|
MessageId messageId = h.getMessageId();
|
||||||
Size size = new Size();
|
Size size = new Size();
|
||||||
|
|
||||||
InputStream is = a.getStream();
|
InputStream is = new BufferedInputStream(a.getStream());
|
||||||
|
is.mark(Integer.MAX_VALUE);
|
||||||
try {
|
try {
|
||||||
// use exif to get size
|
// use exif to get size
|
||||||
if (h.getContentType().equals("image/jpeg")) {
|
if (h.getContentType().equals("image/jpeg")) {
|
||||||
@@ -190,13 +188,6 @@ class AttachmentController {
|
|||||||
options.outMimeType);
|
options.outMimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
static String getContentTypeFromBitmap(InputStream is) {
|
|
||||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
|
||||||
options.inJustDecodeBounds = true;
|
|
||||||
BitmapFactory.decodeStream(is, null, options);
|
|
||||||
return options.outMimeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Size getThumbnailSize(int width, int height, String mimeType) {
|
private Size getThumbnailSize(int width, int height, String mimeType) {
|
||||||
float widthPercentage = maxWidth / (float) width;
|
float widthPercentage = maxWidth / (float) width;
|
||||||
float heightPercentage = maxHeight / (float) height;
|
float heightPercentage = maxHeight / (float) height;
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import org.briarproject.briar.api.messaging.PrivateMessage;
|
|||||||
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||||
|
|
||||||
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.ArrayList;
|
||||||
@@ -48,7 +47,6 @@ import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
|||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
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;
|
import static org.briarproject.bramble.util.LogUtils.now;
|
||||||
import static org.briarproject.briar.android.conversation.AttachmentController.getContentTypeFromBitmap;
|
|
||||||
import static org.briarproject.briar.android.util.UiUtils.observeForeverOnce;
|
import static org.briarproject.briar.android.util.UiUtils.observeForeverOnce;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -140,7 +138,6 @@ public class ConversationViewModel extends AndroidViewModel {
|
|||||||
observeForeverOnce(messagingGroupId, groupId -> {
|
observeForeverOnce(messagingGroupId, groupId -> {
|
||||||
if (groupId == null) return;
|
if (groupId == null) return;
|
||||||
// calls through to creating and storing the message
|
// calls through to creating and storing the message
|
||||||
// (wouldn't Kotlin's co-routines be nice here?)
|
|
||||||
storeAttachments(groupId, text, uris, timestamp);
|
storeAttachments(groupId, text, uris, timestamp);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -185,12 +182,14 @@ public class ConversationViewModel extends AndroidViewModel {
|
|||||||
getApplication().getContentResolver();
|
getApplication().getContentResolver();
|
||||||
is = contentResolver.openInputStream(uri);
|
is = contentResolver.openInputStream(uri);
|
||||||
if (is == null) throw new IOException();
|
if (is == null) throw new IOException();
|
||||||
is = new BufferedInputStream(is); // adds support for reset()
|
|
||||||
is.mark(Integer.MAX_VALUE);
|
|
||||||
String contentType = contentResolver.getType(uri);
|
String contentType = contentResolver.getType(uri);
|
||||||
if (contentType == null) contentType = getContentTypeFromBitmap(is);
|
if (contentType == null) throw new IOException("null content type");
|
||||||
AttachmentHeader h = messagingManager
|
AttachmentHeader h = messagingManager
|
||||||
.addLocalAttachment(groupId, timestamp, contentType, is);
|
.addLocalAttachment(groupId, timestamp, contentType, is);
|
||||||
|
is.close();
|
||||||
|
// re-open stream to get AttachmentItem
|
||||||
|
is = contentResolver.openInputStream(uri);
|
||||||
|
if (is == null) throw new IOException();
|
||||||
AttachmentItem item = attachmentController
|
AttachmentItem item = attachmentController
|
||||||
.getAttachmentItem(h, new Attachment(is));
|
.getAttachmentItem(h, new Attachment(is));
|
||||||
return new Pair<>(h, item);
|
return new Pair<>(h, item);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.sync.GroupId;
|
|||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.briar.api.conversation.ConversationManager.ConversationClient;
|
import org.briarproject.briar.api.conversation.ConversationManager.ConversationClient;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -37,7 +38,7 @@ public interface MessagingManager extends ConversationClient {
|
|||||||
* Stores a local attachment message.
|
* Stores a local attachment message.
|
||||||
*/
|
*/
|
||||||
AttachmentHeader addLocalAttachment(GroupId groupId, long timestamp,
|
AttachmentHeader addLocalAttachment(GroupId groupId, long timestamp,
|
||||||
String contentType, InputStream is) throws DbException;
|
String contentType, InputStream is) throws DbException, IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ID of the contact with the given private conversation.
|
* Returns the ID of the contact with the given private conversation.
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
|||||||
import org.briarproject.briar.client.ConversationClientImpl;
|
import org.briarproject.briar.client.ConversationClientImpl;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -154,8 +155,9 @@ class MessagingManagerImpl extends ConversationClientImpl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AttachmentHeader addLocalAttachment(GroupId groupId, long timestamp,
|
public AttachmentHeader addLocalAttachment(GroupId groupId, long timestamp,
|
||||||
String contentType, InputStream is) {
|
String contentType, InputStream is) throws IOException {
|
||||||
// TODO add real implementation
|
// TODO add real implementation
|
||||||
|
if (is.available() == 0) throw new IOException();
|
||||||
byte[] b = new byte[MessageId.LENGTH];
|
byte[] b = new byte[MessageId.LENGTH];
|
||||||
new Random().nextBytes(b);
|
new Random().nextBytes(b);
|
||||||
return new AttachmentHeader(new MessageId(b), "image/png");
|
return new AttachmentHeader(new MessageId(b), "image/png");
|
||||||
|
|||||||
Reference in New Issue
Block a user