mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 13:49:53 +01:00
[android] Let AttachmentCreator return same LiveData after configuration changes
This commit is contained in:
@@ -29,7 +29,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static java.util.Objects.requireNonNull;
|
|
||||||
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.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
@@ -46,6 +45,7 @@ public class AttachmentCreator {
|
|||||||
private final MessagingManager messagingManager;
|
private final MessagingManager messagingManager;
|
||||||
private final AttachmentRetriever retriever;
|
private final AttachmentRetriever retriever;
|
||||||
|
|
||||||
|
// store unsent items separately, as LiveData might not return latest value
|
||||||
private final Map<Uri, AttachmentItem> unsentItems =
|
private final Map<Uri, AttachmentItem> unsentItems =
|
||||||
new ConcurrentHashMap<>();
|
new ConcurrentHashMap<>();
|
||||||
private final Map<Uri, MutableLiveData<AttachmentItemResult>>
|
private final Map<Uri, MutableLiveData<AttachmentItemResult>>
|
||||||
@@ -66,32 +66,38 @@ public class AttachmentCreator {
|
|||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
public AttachmentResult storeAttachments(GroupId groupId,
|
public AttachmentResult storeAttachments(GroupId groupId,
|
||||||
Collection<Uri> uris) {
|
Collection<Uri> uris, boolean restart) {
|
||||||
if (task != null && !isStoring()) throw new AssertionError();
|
|
||||||
List<LiveData<AttachmentItemResult>> itemResults = new ArrayList<>();
|
List<LiveData<AttachmentItemResult>> itemResults = new ArrayList<>();
|
||||||
List<Uri> urisToStore = new ArrayList<>();
|
if (restart) {
|
||||||
for (Uri uri : uris) {
|
// This can happen due to configuration changes.
|
||||||
MutableLiveData<AttachmentItemResult> liveData =
|
// So don't create new attachments, if we have (or creating) them.
|
||||||
new MutableLiveData<>();
|
// Instead, re-subscribe to the existing LiveData.
|
||||||
itemResults.add(liveData);
|
if (task == null || isNotStoring()) throw new AssertionError();
|
||||||
liveDataResult.put(uri, liveData);
|
for (Uri uri : uris) {
|
||||||
if (unsentItems.containsKey(uri)) {
|
// We don't want to expose mutable(!) LiveData
|
||||||
// This can happen due to configuration changes.
|
LiveData<AttachmentItemResult> liveData =
|
||||||
// So don't create a new attachment, if we have one already.
|
liveDataResult.get(uri);
|
||||||
AttachmentItem item = requireNonNull(unsentItems.get(uri));
|
if (liveData == null) throw new IllegalStateException();
|
||||||
AttachmentItemResult result =
|
itemResults.add(liveData);
|
||||||
new AttachmentItemResult(uri, item);
|
|
||||||
liveData.setValue(result);
|
|
||||||
} else {
|
|
||||||
urisToStore.add(uri);
|
|
||||||
}
|
}
|
||||||
|
if (liveDataFinished == null) throw new IllegalStateException();
|
||||||
|
} else {
|
||||||
|
if (task != null && isNotStoring()) throw new AssertionError();
|
||||||
|
List<Uri> urisToStore = new ArrayList<>();
|
||||||
|
for (Uri uri : uris) {
|
||||||
|
urisToStore.add(uri);
|
||||||
|
MutableLiveData<AttachmentItemResult> liveData =
|
||||||
|
new MutableLiveData<>();
|
||||||
|
liveDataResult.put(uri, liveData);
|
||||||
|
itemResults.add(liveData);
|
||||||
|
}
|
||||||
|
boolean needsSize = uris.size() == 1;
|
||||||
|
task = new AttachmentCreationTask(messagingManager,
|
||||||
|
app.getContentResolver(), this, groupId, urisToStore,
|
||||||
|
needsSize);
|
||||||
|
ioExecutor.execute(() -> task.storeAttachments());
|
||||||
|
liveDataFinished = new MutableLiveData<>();
|
||||||
}
|
}
|
||||||
boolean needsSize = uris.size() == 1;
|
|
||||||
task = new AttachmentCreationTask(messagingManager,
|
|
||||||
app.getContentResolver(), this, groupId, urisToStore,
|
|
||||||
needsSize);
|
|
||||||
ioExecutor.execute(() -> task.storeAttachments());
|
|
||||||
liveDataFinished = new MutableLiveData<>();
|
|
||||||
return new AttachmentResult(itemResults, liveDataFinished);
|
return new AttachmentResult(itemResults, liveDataFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,6 +191,7 @@ public class AttachmentCreator {
|
|||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
public void deleteUnsentAttachments() {
|
public void deleteUnsentAttachments() {
|
||||||
|
// Make a copy for the IoExecutor as we clear the unsentItems soon
|
||||||
List<AttachmentItem> itemsToDelete =
|
List<AttachmentItem> itemsToDelete =
|
||||||
new ArrayList<>(unsentItems.values());
|
new ArrayList<>(unsentItems.values());
|
||||||
ioExecutor.execute(() -> {
|
ioExecutor.execute(() -> {
|
||||||
@@ -198,8 +205,8 @@ public class AttachmentCreator {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isStoring() {
|
private boolean isNotStoring() {
|
||||||
return liveDataFinished != null;
|
return liveDataFinished == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import java.util.List;
|
|||||||
@UiThread
|
@UiThread
|
||||||
public interface AttachmentManager {
|
public interface AttachmentManager {
|
||||||
|
|
||||||
AttachmentResult storeAttachments(Collection<Uri> uri);
|
AttachmentResult storeAttachments(Collection<Uri> uri, boolean restart);
|
||||||
|
|
||||||
List<AttachmentHeader> getAttachmentHeadersForSending();
|
List<AttachmentHeader> getAttachmentHeadersForSending();
|
||||||
|
|
||||||
|
|||||||
@@ -150,8 +150,7 @@ public class ConversationViewModel extends AndroidViewModel
|
|||||||
contact.postValue(c);
|
contact.postValue(c);
|
||||||
logDuration(LOG, "Loading contact", start);
|
logDuration(LOG, "Loading contact", start);
|
||||||
start = now();
|
start = now();
|
||||||
messagingGroupId =
|
messagingGroupId = messagingManager.getContactGroup(c).getId();
|
||||||
messagingManager.getConversationId(contactId);
|
|
||||||
logDuration(LOG, "Load conversation GroupId", start);
|
logDuration(LOG, "Load conversation GroupId", start);
|
||||||
start = now();
|
start = now();
|
||||||
checkFeaturesAndOnboarding(contactId);
|
checkFeaturesAndOnboarding(contactId);
|
||||||
@@ -197,10 +196,11 @@ public class ConversationViewModel extends AndroidViewModel
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@UiThread
|
@UiThread
|
||||||
public AttachmentResult storeAttachments(Collection<Uri> uris) {
|
public AttachmentResult storeAttachments(Collection<Uri> uris,
|
||||||
|
boolean restart) {
|
||||||
GroupId groupId = messagingGroupId;
|
GroupId groupId = messagingGroupId;
|
||||||
if (groupId == null) throw new IllegalStateException();
|
if (groupId == null) throw new IllegalStateException();
|
||||||
return attachmentCreator.storeAttachments(groupId, uris);
|
return attachmentCreator.storeAttachments(groupId, uris, restart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -153,17 +153,17 @@ public class TextAttachmentController extends TextSendController
|
|||||||
if (loadingUris || !imageUris.isEmpty()) throw new AssertionError();
|
if (loadingUris || !imageUris.isEmpty()) throw new AssertionError();
|
||||||
if (resultData.getData() != null) {
|
if (resultData.getData() != null) {
|
||||||
imageUris.add(resultData.getData());
|
imageUris.add(resultData.getData());
|
||||||
onNewUris();
|
onNewUris(false);
|
||||||
} else if (SDK_INT >= 18 && resultData.getClipData() != null) {
|
} else if (SDK_INT >= 18 && resultData.getClipData() != null) {
|
||||||
ClipData clipData = resultData.getClipData();
|
ClipData clipData = resultData.getClipData();
|
||||||
for (int i = 0; i < clipData.getItemCount(); i++) {
|
for (int i = 0; i < clipData.getItemCount(); i++) {
|
||||||
imageUris.add(clipData.getItemAt(i).getUri());
|
imageUris.add(clipData.getItemAt(i).getUri());
|
||||||
}
|
}
|
||||||
onNewUris();
|
onNewUris(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onNewUris() {
|
private void onNewUris(boolean restart) {
|
||||||
if (imageUris.isEmpty()) return;
|
if (imageUris.isEmpty()) return;
|
||||||
if (loadingUris) throw new AssertionError();
|
if (loadingUris) throw new AssertionError();
|
||||||
loadingUris = true;
|
loadingUris = true;
|
||||||
@@ -172,7 +172,8 @@ public class TextAttachmentController extends TextSendController
|
|||||||
List<ImagePreviewItem> items = ImagePreviewItem.fromUris(imageUris);
|
List<ImagePreviewItem> items = ImagePreviewItem.fromUris(imageUris);
|
||||||
imagePreview.showPreview(items);
|
imagePreview.showPreview(items);
|
||||||
// store attachments and show preview when successful
|
// store attachments and show preview when successful
|
||||||
AttachmentResult result = attachmentManager.storeAttachments(imageUris);
|
AttachmentResult result =
|
||||||
|
attachmentManager.storeAttachments(imageUris, restart);
|
||||||
for (LiveData<AttachmentItemResult> liveData : result
|
for (LiveData<AttachmentItemResult> liveData : result
|
||||||
.getItemResults()) {
|
.getItemResults()) {
|
||||||
onLiveDataReturned(liveData);
|
onLiveDataReturned(liveData);
|
||||||
@@ -240,7 +241,7 @@ public class TextAttachmentController extends TextSendController
|
|||||||
SavedState state = (SavedState) inState;
|
SavedState state = (SavedState) inState;
|
||||||
if (!imageUris.isEmpty()) throw new AssertionError();
|
if (!imageUris.isEmpty()) throw new AssertionError();
|
||||||
if (state.imageUris != null) imageUris.addAll(state.imageUris);
|
if (state.imageUris != null) imageUris.addAll(state.imageUris);
|
||||||
onNewUris();
|
onNewUris(true);
|
||||||
return state.getSuperState();
|
return state.getSuperState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user