Change batch identity check timing behavior.

fork-5.53.8
Cody Henthorne 2022-08-01 13:18:20 -04:00 zatwierdzone przez Greyson Parrelli
rodzic dc04c8ed98
commit c2b5407911
9 zmienionych plików z 38 dodań i 18 usunięć

Wyświetl plik

@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.contacts.paged
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.core.Single
import org.signal.core.util.concurrent.SignalExecutors import org.signal.core.util.concurrent.SignalExecutors
import org.signal.core.util.concurrent.safeBlockingGet
import org.signal.core.util.logging.Log import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.crypto.storage.SignalIdentityKeyStore import org.thoughtcrime.securesms.crypto.storage.SignalIdentityKeyStore
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
@ -26,11 +27,18 @@ class SafetyNumberRepository(
private val recentlyFetched: MutableMap<RecipientId, Long> = HashMap() private val recentlyFetched: MutableMap<RecipientId, Long> = HashMap()
fun batchSafetyNumberCheck(newSelectionEntries: List<ContactSearchKey>) { fun batchSafetyNumberCheck(newSelectionEntries: List<ContactSearchKey>) {
SignalExecutors.UNBOUNDED.execute { batchSafetyNumberCheckSync(newSelectionEntries) } SignalExecutors.UNBOUNDED.execute {
try {
batchSafetyNumberCheckSync(newSelectionEntries)
} catch (e: InterruptedException) {
Log.w(TAG, "Unable to fetch safety number change", e)
}
}
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@VisibleForTesting @VisibleForTesting
@Throws(InterruptedException::class)
fun batchSafetyNumberCheckSync(newSelectionEntries: List<ContactSearchKey>, now: Long = System.currentTimeMillis(), batchSize: Int = MAX_BATCH_SIZE) { fun batchSafetyNumberCheckSync(newSelectionEntries: List<ContactSearchKey>, now: Long = System.currentTimeMillis(), batchSize: Int = MAX_BATCH_SIZE) {
val stopwatch = Stopwatch("batch-snc") val stopwatch = Stopwatch("batch-snc")
val recipientIds: Set<RecipientId> = newSelectionEntries.flattenToRecipientIds() val recipientIds: Set<RecipientId> = newSelectionEntries.flattenToRecipientIds()
@ -49,7 +57,7 @@ class SafetyNumberRepository(
responses responses
.map { it as List<IdentityCheckResponse.AciIdentityPair> } .map { it as List<IdentityCheckResponse.AciIdentityPair> }
.flatten() .flatten()
}.blockingGet() }.safeBlockingGet()
stopwatch.split("batch-fetches") stopwatch.split("batch-fetches")

Wyświetl plik

@ -16,7 +16,8 @@ class MultiselectForwardViewModel(
private val storySendRequirements: Stories.MediaTransform.SendRequirements, private val storySendRequirements: Stories.MediaTransform.SendRequirements,
private val records: List<MultiShareArgs>, private val records: List<MultiShareArgs>,
private val isSelectionOnly: Boolean, private val isSelectionOnly: Boolean,
private val repository: MultiselectForwardRepository private val repository: MultiselectForwardRepository,
private val identityChangesSince: Long = System.currentTimeMillis()
) : ViewModel() { ) : ViewModel() {
private val store = Store( private val store = Store(
@ -48,7 +49,7 @@ class MultiselectForwardViewModel(
store.update { it.copy(stage = MultiselectForwardState.Stage.FirstConfirmation) } store.update { it.copy(stage = MultiselectForwardState.Stage.FirstConfirmation) }
} else { } else {
store.update { it.copy(stage = MultiselectForwardState.Stage.LoadingIdentities) } store.update { it.copy(stage = MultiselectForwardState.Stage.LoadingIdentities) }
UntrustedRecords.checkForBadIdentityRecords(selectedContacts.filterIsInstance(ContactSearchKey.RecipientSearchKey::class.java).toSet()) { identityRecords -> UntrustedRecords.checkForBadIdentityRecords(selectedContacts.filterIsInstance(ContactSearchKey.RecipientSearchKey::class.java).toSet(), identityChangesSince) { identityRecords ->
if (identityRecords.isEmpty()) { if (identityRecords.isEmpty()) {
performSend(additionalMessage, selectedContacts) performSend(additionalMessage, selectedContacts)
} else { } else {

Wyświetl plik

@ -16,7 +16,7 @@ public final class IdentityRecordList {
public static final IdentityRecordList EMPTY = new IdentityRecordList(Collections.emptyList()); public static final IdentityRecordList EMPTY = new IdentityRecordList(Collections.emptyList());
private static final long DEFAULT_UNTRUSTED_WINDOW = TimeUnit.SECONDS.toMillis(5); public static final long DEFAULT_UNTRUSTED_WINDOW = TimeUnit.SECONDS.toMillis(5);
private final List<IdentityRecord> identityRecords; private final List<IdentityRecord> identityRecords;
private final boolean isVerified; private final boolean isVerified;

Wyświetl plik

@ -40,7 +40,8 @@ class MediaSelectionViewModel(
initialMessage: CharSequence?, initialMessage: CharSequence?,
val isReply: Boolean, val isReply: Boolean,
isStory: Boolean, isStory: Boolean,
private val repository: MediaSelectionRepository private val repository: MediaSelectionRepository,
private val identityChangesSince: Long = System.currentTimeMillis()
) : ViewModel() { ) : ViewModel() {
private val selectedMediaSubject: Subject<List<Media>> = BehaviorSubject.create() private val selectedMediaSubject: Subject<List<Media>> = BehaviorSubject.create()
@ -308,7 +309,7 @@ class MediaSelectionViewModel(
fun send( fun send(
selectedContacts: List<ContactSearchKey.RecipientSearchKey> = emptyList() selectedContacts: List<ContactSearchKey.RecipientSearchKey> = emptyList()
): Maybe<MediaSendActivityResult> { ): Maybe<MediaSendActivityResult> {
return UntrustedRecords.checkForBadIdentityRecords(selectedContacts.toSet()).andThen( return UntrustedRecords.checkForBadIdentityRecords(selectedContacts.toSet(), identityChangesSince).andThen(
repository.send( repository.send(
store.state.selectedMedia, store.state.selectedMedia,
store.state.editorStateMap, store.state.editorStateMap,

Wyświetl plik

@ -14,23 +14,23 @@ import java.util.concurrent.TimeUnit
object UntrustedRecords { object UntrustedRecords {
fun checkForBadIdentityRecords(contactSearchKeys: Set<ContactSearchKey.RecipientSearchKey>): Completable { fun checkForBadIdentityRecords(contactSearchKeys: Set<ContactSearchKey.RecipientSearchKey>, changedSince: Long): Completable {
return Completable.fromAction { return Completable.fromAction {
val untrustedRecords: List<IdentityRecord> = checkForBadIdentityRecordsSync(contactSearchKeys) val untrustedRecords: List<IdentityRecord> = checkForBadIdentityRecordsSync(contactSearchKeys, changedSince)
if (untrustedRecords.isNotEmpty()) { if (untrustedRecords.isNotEmpty()) {
throw UntrustedRecordsException(untrustedRecords, contactSearchKeys) throw UntrustedRecordsException(untrustedRecords, contactSearchKeys)
} }
}.subscribeOn(Schedulers.io()) }.subscribeOn(Schedulers.io())
} }
fun checkForBadIdentityRecords(contactSearchKeys: Set<ContactSearchKey.RecipientSearchKey>, consumer: Consumer<List<IdentityRecord>>) { fun checkForBadIdentityRecords(contactSearchKeys: Set<ContactSearchKey.RecipientSearchKey>, changedSince: Long, consumer: Consumer<List<IdentityRecord>>) {
SignalExecutors.BOUNDED.execute { SignalExecutors.BOUNDED.execute {
consumer.accept(checkForBadIdentityRecordsSync(contactSearchKeys)) consumer.accept(checkForBadIdentityRecordsSync(contactSearchKeys, changedSince))
} }
} }
@WorkerThread @WorkerThread
private fun checkForBadIdentityRecordsSync(contactSearchKeys: Set<ContactSearchKey.RecipientSearchKey>): List<IdentityRecord> { private fun checkForBadIdentityRecordsSync(contactSearchKeys: Set<ContactSearchKey.RecipientSearchKey>, changedSince: Long): List<IdentityRecord> {
val recipients: List<Recipient> = contactSearchKeys val recipients: List<Recipient> = contactSearchKeys
.map { Recipient.resolved(it.recipientId) } .map { Recipient.resolved(it.recipientId) }
.map { recipient -> .map { recipient ->
@ -42,7 +42,13 @@ object UntrustedRecords {
} }
.flatten() .flatten()
return ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecords(recipients).getUntrustedRecords(TimeUnit.SECONDS.toMillis(30)) val calculatedUntrustedWindow = System.currentTimeMillis() - changedSince
return ApplicationDependencies
.getProtocolStore()
.aci()
.identities()
.getIdentityRecords(recipients)
.getUntrustedRecords(calculatedUntrustedWindow.coerceIn(TimeUnit.SECONDS.toMillis(5)..TimeUnit.HOURS.toMillis(1)))
} }
class UntrustedRecordsException(val untrustedRecords: List<IdentityRecord>, val destinations: Set<ContactSearchKey.RecipientSearchKey>) : Throwable() class UntrustedRecordsException(val untrustedRecords: List<IdentityRecord>, val destinations: Set<ContactSearchKey.RecipientSearchKey>) : Throwable()

Wyświetl plik

@ -26,7 +26,7 @@ import org.thoughtcrime.securesms.mediasend.v2.text.send.TextStoryPostSendReposi
import org.thoughtcrime.securesms.mediasend.v2.text.send.TextStoryPostSendResult import org.thoughtcrime.securesms.mediasend.v2.text.send.TextStoryPostSendResult
import org.thoughtcrime.securesms.util.livedata.Store import org.thoughtcrime.securesms.util.livedata.Store
class TextStoryPostCreationViewModel(private val repository: TextStoryPostSendRepository) : ViewModel() { class TextStoryPostCreationViewModel(private val repository: TextStoryPostSendRepository, private val identityChangesSince: Long = System.currentTimeMillis()) : ViewModel() {
private val store = Store(TextStoryPostCreationState()) private val store = Store(TextStoryPostCreationState())
private val textFontSubject: Subject<TextFont> = BehaviorSubject.create() private val textFontSubject: Subject<TextFont> = BehaviorSubject.create()
@ -123,7 +123,8 @@ class TextStoryPostCreationViewModel(private val repository: TextStoryPostSendRe
return repository.send( return repository.send(
contacts, contacts,
store.state, store.state,
linkPreview linkPreview,
identityChangesSince
) )
} }

Wyświetl plik

@ -38,9 +38,9 @@ class TextStoryPostSendRepository {
}.subscribeOn(Schedulers.computation()) }.subscribeOn(Schedulers.computation())
} }
fun send(contactSearchKey: Set<ContactSearchKey>, textStoryPostCreationState: TextStoryPostCreationState, linkPreview: LinkPreview?): Single<TextStoryPostSendResult> { fun send(contactSearchKey: Set<ContactSearchKey>, textStoryPostCreationState: TextStoryPostCreationState, linkPreview: LinkPreview?, identityChangesSince: Long): Single<TextStoryPostSendResult> {
return UntrustedRecords return UntrustedRecords
.checkForBadIdentityRecords(contactSearchKey.filterIsInstance(ContactSearchKey.RecipientSearchKey::class.java).toSet()) .checkForBadIdentityRecords(contactSearchKey.filterIsInstance(ContactSearchKey.RecipientSearchKey::class.java).toSet(), identityChangesSince)
.toSingleDefault<TextStoryPostSendResult>(TextStoryPostSendResult.Success) .toSingleDefault<TextStoryPostSendResult>(TextStoryPostSendResult.Success)
.onErrorReturn { .onErrorReturn {
if (it is UntrustedRecords.UntrustedRecordsException) { if (it is UntrustedRecords.UntrustedRecordsException) {

Wyświetl plik

@ -6,6 +6,7 @@ import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.schedulers.Schedulers
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey
import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.identity.IdentityRecordList
import org.thoughtcrime.securesms.database.model.Mention import org.thoughtcrime.securesms.database.model.Mention
import org.thoughtcrime.securesms.database.model.ParentStoryId import org.thoughtcrime.securesms.database.model.ParentStoryId
import org.thoughtcrime.securesms.database.model.StoryType import org.thoughtcrime.securesms.database.model.StoryType
@ -36,7 +37,7 @@ object StoryGroupReplySender {
} }
return messageAndRecipient.flatMapCompletable { (message, recipient) -> return messageAndRecipient.flatMapCompletable { (message, recipient) ->
UntrustedRecords.checkForBadIdentityRecords(setOf(ContactSearchKey.RecipientSearchKey.KnownRecipient(recipient.id))) UntrustedRecords.checkForBadIdentityRecords(setOf(ContactSearchKey.RecipientSearchKey.KnownRecipient(recipient.id)), System.currentTimeMillis() - IdentityRecordList.DEFAULT_UNTRUSTED_WINDOW)
.andThen( .andThen(
Completable.create { Completable.create {
MessageSender.send( MessageSender.send(

Wyświetl plik

@ -2,6 +2,7 @@
package org.signal.core.util.concurrent package org.signal.core.util.concurrent
import android.annotation.SuppressLint
import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.core.Single
import java.lang.RuntimeException import java.lang.RuntimeException
@ -11,6 +12,7 @@ import java.lang.RuntimeException
* *
* [Single.blockingGet] is considered harmful and should not be used. * [Single.blockingGet] is considered harmful and should not be used.
*/ */
@SuppressLint("UnsafeBlockingGet")
@Throws(InterruptedException::class) @Throws(InterruptedException::class)
fun <T : Any> Single<T>.safeBlockingGet(): T { fun <T : Any> Single<T>.safeBlockingGet(): T {
try { try {