mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 00:59:49 +01:00
Fix story send issues due to insertion of story sends to database.
This commit is contained in:
committed by
Greyson Parrelli
parent
38b6362b25
commit
5d16d1cd23
@@ -47,6 +47,7 @@ import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -78,6 +79,7 @@ public final class MultiShareSender {
|
||||
boolean isMmsEnabled = Util.isMmsCapable(context);
|
||||
String message = multiShareArgs.getDraftText();
|
||||
SlideDeck slideDeck;
|
||||
List<OutgoingMediaMessage> storiesBatch = new LinkedList<>();
|
||||
|
||||
try {
|
||||
slideDeck = buildSlideDeck(context, multiShareArgs);
|
||||
@@ -118,7 +120,7 @@ public final class MultiShareSender {
|
||||
if ((recipient.isMmsGroup() || recipient.getEmail().isPresent()) && !isMmsEnabled) {
|
||||
results.add(new MultiShareSendResult(recipientSearchKey, MultiShareSendResult.Type.MMS_NOT_ENABLED));
|
||||
} else if (hasMmsMedia && transport.isSms() || hasPushMedia && !transport.isSms() || canSendAsTextStory) {
|
||||
sendMediaMessage(context, multiShareArgs, recipient, slideDeck, transport, threadId, forceSms, expiresIn, multiShareArgs.isViewOnce(), subscriptionId, mentions, recipientSearchKey.isStory(), sentTimestamp, canSendAsTextStory);
|
||||
sendMediaMessageOrCollectStoryToBatch(context, multiShareArgs, recipient, slideDeck, transport, threadId, forceSms, expiresIn, multiShareArgs.isViewOnce(), subscriptionId, mentions, recipientSearchKey.isStory(), sentTimestamp, canSendAsTextStory, storiesBatch);
|
||||
results.add(new MultiShareSendResult(recipientSearchKey, MultiShareSendResult.Type.SUCCESS));
|
||||
} else if (recipientSearchKey.isStory()) {
|
||||
results.add(new MultiShareSendResult(recipientSearchKey, MultiShareSendResult.Type.INVALID_SHARE_TO_STORY));
|
||||
@@ -132,6 +134,15 @@ public final class MultiShareSender {
|
||||
ThreadUtil.sleep(5);
|
||||
}
|
||||
|
||||
if (!storiesBatch.isEmpty()) {
|
||||
MessageSender.sendStories(context,
|
||||
storiesBatch.stream()
|
||||
.map(OutgoingSecureMediaMessage::new)
|
||||
.collect(Collectors.toList()),
|
||||
null,
|
||||
null);
|
||||
}
|
||||
|
||||
return new MultiShareSendResultCollection(results);
|
||||
}
|
||||
|
||||
@@ -160,20 +171,21 @@ public final class MultiShareSender {
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendMediaMessage(@NonNull Context context,
|
||||
@NonNull MultiShareArgs multiShareArgs,
|
||||
@NonNull Recipient recipient,
|
||||
@NonNull SlideDeck slideDeck,
|
||||
@NonNull TransportOption transportOption,
|
||||
long threadId,
|
||||
boolean forceSms,
|
||||
long expiresIn,
|
||||
boolean isViewOnce,
|
||||
int subscriptionId,
|
||||
@NonNull List<Mention> validatedMentions,
|
||||
boolean isStory,
|
||||
long sentTimestamp,
|
||||
boolean canSendAsTextStory)
|
||||
private static void sendMediaMessageOrCollectStoryToBatch(@NonNull Context context,
|
||||
@NonNull MultiShareArgs multiShareArgs,
|
||||
@NonNull Recipient recipient,
|
||||
@NonNull SlideDeck slideDeck,
|
||||
@NonNull TransportOption transportOption,
|
||||
long threadId,
|
||||
boolean forceSms,
|
||||
long expiresIn,
|
||||
boolean isViewOnce,
|
||||
int subscriptionId,
|
||||
@NonNull List<Mention> validatedMentions,
|
||||
boolean isStory,
|
||||
long sentTimestamp,
|
||||
boolean canSendAsTextStory,
|
||||
@NonNull List<OutgoingMediaMessage> storiesToBatchSend)
|
||||
{
|
||||
String body = multiShareArgs.getDraftText();
|
||||
if (transportOption.isType(TransportOption.Type.TEXTSECURE) && !forceSms && body != null) {
|
||||
@@ -270,8 +282,9 @@ public final class MultiShareSender {
|
||||
outgoingMessages.add(outgoingMediaMessage);
|
||||
}
|
||||
|
||||
if (shouldSendAsPush(recipient, forceSms))
|
||||
{
|
||||
if (isStory) {
|
||||
storiesToBatchSend.addAll(outgoingMessages);
|
||||
} else if (shouldSendAsPush(recipient, forceSms)) {
|
||||
for (final OutgoingMediaMessage outgoingMessage : outgoingMessages) {
|
||||
MessageSender.send(context, new OutgoingSecureMediaMessage(outgoingMessage), threadId, false, null, null);
|
||||
}
|
||||
|
||||
@@ -130,6 +130,67 @@ public class MessageSender {
|
||||
return allocatedThreadId;
|
||||
}
|
||||
|
||||
public static void sendStories(@NonNull final Context context,
|
||||
@NonNull final List<OutgoingSecureMediaMessage> messages,
|
||||
@Nullable final String metricId,
|
||||
@Nullable final SmsDatabase.InsertListener insertListener)
|
||||
{
|
||||
Log.i(TAG, "Sending story messages to " + messages.size() + " targets.");
|
||||
ThreadDatabase threadDatabase = SignalDatabase.threads();
|
||||
MessageDatabase database = SignalDatabase.mms();
|
||||
List<Long> messageIds = new ArrayList<>(messages.size());
|
||||
List<Long> threads = new ArrayList<>(messages.size());
|
||||
|
||||
try {
|
||||
database.beginTransaction();
|
||||
for (OutgoingMediaMessage message : messages) {
|
||||
long allocatedThreadId = threadDatabase.getOrCreateValidThreadId(message.getRecipient(), -1L, message.getDistributionType());
|
||||
Recipient recipient = message.getRecipient();
|
||||
long messageId = database.insertMessageOutbox(applyUniversalExpireTimerIfNecessary(context, recipient, message, allocatedThreadId), allocatedThreadId, false, insertListener);
|
||||
|
||||
messageIds.add(messageId);
|
||||
threads.add(allocatedThreadId);
|
||||
|
||||
if (message.getRecipient().isGroup() && message.getAttachments().isEmpty() && message.getLinkPreviews().isEmpty() && message.getSharedContacts().isEmpty()) {
|
||||
SignalLocalMetrics.GroupMessageSend.onInsertedIntoDatabase(messageId, metricId);
|
||||
} else {
|
||||
SignalLocalMetrics.GroupMessageSend.cancel(metricId);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < messageIds.size(); i++) {
|
||||
long messageId = messageIds.get(i);
|
||||
OutgoingSecureMediaMessage message = messages.get(i);
|
||||
Recipient recipient = message.getRecipient();
|
||||
|
||||
if (recipient.isDistributionList()) {
|
||||
List<RecipientId> members = SignalDatabase.distributionLists().getMembers(recipient.requireDistributionListId());
|
||||
SignalDatabase.storySends().insert(messageId, members, message.getSentTimeMillis(), message.getStoryType().isStoryWithReplies());
|
||||
}
|
||||
}
|
||||
|
||||
database.setTransactionSuccessful();
|
||||
} catch (MmsException e) {
|
||||
Log.w(TAG, e);
|
||||
} finally {
|
||||
database.endTransaction();
|
||||
}
|
||||
|
||||
for (int i = 0; i < messageIds.size(); i++) {
|
||||
long messageId = messageIds.get(i);
|
||||
OutgoingSecureMediaMessage message = messages.get(i);
|
||||
Recipient recipient = message.getRecipient();
|
||||
|
||||
sendMediaMessage(context, recipient, false, messageId, Collections.emptyList());
|
||||
}
|
||||
|
||||
onMessageSent();
|
||||
|
||||
for (long threadId : threads) {
|
||||
threadDatabase.update(threadId, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static long send(final Context context,
|
||||
final OutgoingMediaMessage message,
|
||||
final long threadId,
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.stories
|
||||
import androidx.annotation.WorkerThread
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import io.reactivex.rxjava3.core.Completable
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.contacts.HeaderAction
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase
|
||||
@@ -21,6 +22,7 @@ import org.thoughtcrime.securesms.sms.MessageSender
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper
|
||||
import org.thoughtcrime.securesms.util.BottomSheetUtil
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags
|
||||
import org.thoughtcrime.securesms.util.hasLinkPreview
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object Stories {
|
||||
@@ -49,10 +51,9 @@ object Stories {
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun sendTextStories(messages: List<OutgoingSecureMediaMessage>): Completable {
|
||||
return Completable.create { emitter ->
|
||||
MessageSender.sendMediaBroadcast(ApplicationDependencies.getApplication(), messages, listOf(), listOf())
|
||||
MessageSender.sendStories(ApplicationDependencies.getApplication(), messages, null, null)
|
||||
emitter.onComplete()
|
||||
}
|
||||
}
|
||||
@@ -87,12 +88,29 @@ object Stories {
|
||||
val unreadStoriesReader = SignalDatabase.mms.getUnreadStories(recipientId, FeatureFlags.storiesAutoDownloadMaximum())
|
||||
while (unreadStoriesReader.next != null) {
|
||||
val record = unreadStoriesReader.current as MmsMessageRecord
|
||||
SignalDatabase.attachments.getAttachmentsForMessage(record.id).filterNot { it.isSticker }.forEach {
|
||||
if (it.transferState == AttachmentDatabase.TRANSFER_PROGRESS_PENDING) {
|
||||
val job = AttachmentDownloadJob(record.id, it.attachmentId, ignoreAutoDownloadConstraints)
|
||||
ApplicationDependencies.getJobManager().add(job)
|
||||
}
|
||||
enqueueAttachmentsFromStoryForDownloadSync(record, ignoreAutoDownloadConstraints)
|
||||
}
|
||||
}
|
||||
|
||||
fun enqueueAttachmentsFromStoryForDownload(record: MmsMessageRecord, ignoreAutoDownloadConstraints: Boolean): Completable {
|
||||
return Completable.fromAction {
|
||||
enqueueAttachmentsFromStoryForDownloadSync(record, ignoreAutoDownloadConstraints)
|
||||
}.subscribeOn(Schedulers.io())
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private fun enqueueAttachmentsFromStoryForDownloadSync(record: MmsMessageRecord, ignoreAutoDownloadConstraints: Boolean) {
|
||||
SignalDatabase.attachments.getAttachmentsForMessage(record.id).filterNot { it.isSticker }.forEach {
|
||||
if (it.transferState == AttachmentDatabase.TRANSFER_PROGRESS_PENDING) {
|
||||
val job = AttachmentDownloadJob(record.id, it.attachmentId, ignoreAutoDownloadConstraints)
|
||||
ApplicationDependencies.getJobManager().add(job)
|
||||
}
|
||||
}
|
||||
|
||||
if (record.hasLinkPreview()) {
|
||||
ApplicationDependencies.getJobManager().add(
|
||||
AttachmentDownloadJob(record.id, record.linkPreviews[0].attachmentId, true)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import org.signal.core.util.BreakIteratorCompat
|
||||
import org.signal.core.util.concurrent.SignalExecutors
|
||||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment
|
||||
import org.thoughtcrime.securesms.conversation.ConversationMessage
|
||||
import org.thoughtcrime.securesms.database.DatabaseObserver
|
||||
import org.thoughtcrime.securesms.database.NoSuchMessageException
|
||||
@@ -17,7 +16,6 @@ import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.StoryTextPost
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceViewedUpdateJob
|
||||
import org.thoughtcrime.securesms.jobs.SendViewedReceiptJob
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
@@ -133,12 +131,8 @@ open class StoryViewerPageRepository(context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
fun forceDownload(post: StoryPost) {
|
||||
if (post.content is StoryPost.Content.AttachmentContent) {
|
||||
ApplicationDependencies.getJobManager().add(
|
||||
AttachmentDownloadJob(post.id, (post.content.attachment as DatabaseAttachment).attachmentId, true)
|
||||
)
|
||||
}
|
||||
fun forceDownload(post: StoryPost): Completable {
|
||||
return Stories.enqueueAttachmentsFromStoryForDownload(post.conversationMessage.messageRecord as MmsMessageRecord, true)
|
||||
}
|
||||
|
||||
fun getStoryPostsFor(recipientId: RecipientId): Observable<List<StoryPost>> {
|
||||
|
||||
@@ -85,7 +85,7 @@ class StoryViewerPageViewModel(
|
||||
val selectedPost = getPostAt(index)
|
||||
|
||||
if (selectedPost != null && selectedPost.content.transferState != AttachmentDatabase.TRANSFER_PROGRESS_DONE) {
|
||||
repository.forceDownload(selectedPost)
|
||||
disposables += repository.forceDownload(selectedPost).subscribe()
|
||||
}
|
||||
|
||||
store.update {
|
||||
@@ -136,7 +136,7 @@ class StoryViewerPageViewModel(
|
||||
}
|
||||
|
||||
fun forceDownloadSelectedPost() {
|
||||
repository.forceDownload(getPost())
|
||||
disposables += repository.forceDownload(getPost()).subscribe()
|
||||
}
|
||||
|
||||
fun startDirectReply(storyId: Long, recipientId: RecipientId) {
|
||||
|
||||
Reference in New Issue
Block a user