[android] support attachments arriving *before* the message containing them

This commit is contained in:
Torsten Grote
2019-10-17 13:25:04 -03:00
parent 4122e0852a
commit b7d3cd7990
3 changed files with 27 additions and 6 deletions

View File

@@ -12,6 +12,9 @@ import org.briarproject.briar.api.messaging.PrivateMessageHeader;
import java.io.InputStream; import java.io.InputStream;
import java.util.List; import java.util.List;
import androidx.annotation.Nullable;
@NotNullByDefault @NotNullByDefault
public interface AttachmentRetriever { public interface AttachmentRetriever {
@@ -33,6 +36,14 @@ public interface AttachmentRetriever {
*/ */
AttachmentItem createAttachmentItem(Attachment a, boolean needsSize); AttachmentItem createAttachmentItem(Attachment a, boolean needsSize);
/**
* Load an {@link AttachmentItem} from the database.
*
* @return a pair of the {@link MessageId} of the conversation message
* and the {@link AttachmentItem}
* or {@code null} when the conversation message did not yet arrive.
*/
@Nullable
@DatabaseExecutor @DatabaseExecutor
Pair<MessageId, AttachmentItem> loadAttachmentItem(MessageId attachmentId) Pair<MessageId, AttachmentItem> loadAttachmentItem(MessageId attachmentId)
throws DbException; throws DbException;

View File

@@ -22,6 +22,8 @@ import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.annotation.Nullable;
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.briar.android.attachment.AttachmentItem.State.AVAILABLE; import static org.briarproject.briar.android.attachment.AttachmentItem.State.AVAILABLE;
@@ -103,11 +105,12 @@ class AttachmentRetrieverImpl implements AttachmentRetriever {
} }
@Override @Override
@Nullable
@DatabaseExecutor @DatabaseExecutor
public Pair<MessageId, AttachmentItem> loadAttachmentItem( public Pair<MessageId, AttachmentItem> loadAttachmentItem(
MessageId attachmentId) throws DbException { MessageId attachmentId) throws DbException {
UnavailableItem unavailableItem = unavailableItems.get(attachmentId); UnavailableItem unavailableItem = unavailableItems.get(attachmentId);
if (unavailableItem == null) throw new AssertionError(); if (unavailableItem == null) return null;
MessageId conversationMessageId = MessageId conversationMessageId =
unavailableItem.getConversationMessageId(); unavailableItem.getConversationMessageId();

View File

@@ -643,16 +643,21 @@ public class ConversationActivity extends BriarActivity
runOnDbThread(() -> { runOnDbThread(() -> {
for (AttachmentItem item : items) { for (AttachmentItem item : items) {
if (item.getState() == LOADING) if (item.getState() == LOADING)
loadMessageAttachment(item.getMessageId()); loadMessageAttachment(item.getMessageId(), false);
} }
}); });
} }
@DatabaseExecutor @DatabaseExecutor
private void loadMessageAttachment(MessageId attachmentId) { private void loadMessageAttachment(MessageId attachmentId,
boolean allowedToFail) {
try { try {
Pair<MessageId, AttachmentItem> pair = Pair<MessageId, AttachmentItem> pair = attachmentRetriever
attachmentRetriever.loadAttachmentItem(attachmentId); .loadAttachmentItem(attachmentId);
if (pair == null && allowedToFail) {
LOG.warning("Attachment arrived before message");
return;
} else if (pair == null) throw new AssertionError();
MessageId conversationMessageId = pair.getFirst(); MessageId conversationMessageId = pair.getFirst();
AttachmentItem item = pair.getSecond(); AttachmentItem item = pair.getSecond();
updateMessageAttachment(conversationMessageId, item); updateMessageAttachment(conversationMessageId, item);
@@ -743,7 +748,9 @@ public class ConversationActivity extends BriarActivity
@UiThread @UiThread
private void onAttachmentReceived(MessageId attachmentId) { private void onAttachmentReceived(MessageId attachmentId) {
runOnDbThread(() -> loadMessageAttachment(attachmentId)); // This is allowed to fail, because the conversation message
// might arrive *after* the attachment.
runOnDbThread(() -> loadMessageAttachment(attachmentId, true));
} }
@UiThread @UiThread