Fix contact discovery refresh crash.
This commit is contained in:
parent
8cb4034c80
commit
9f4d8ac12c
3 changed files with 54 additions and 16 deletions
|
@ -9,6 +9,7 @@ import com.annimon.stream.Collectors;
|
|||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.signal.contacts.SystemContactsRepository;
|
||||
import org.signal.core.util.concurrent.RxExtensions;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.libsignal.protocol.InvalidKeyException;
|
||||
import org.signal.libsignal.protocol.util.Pair;
|
||||
|
@ -190,23 +191,33 @@ class ContactDiscoveryRefreshV1 {
|
|||
.onErrorReturn(t -> new Pair<>(r, ServiceResponse.forUnknownError(t))))
|
||||
.toList();
|
||||
|
||||
return Observable.mergeDelayError(requests)
|
||||
.observeOn(Schedulers.io(), true)
|
||||
.scan(new UnlistedResult.Builder(), (builder, pair) -> {
|
||||
Recipient recipient = pair.first();
|
||||
ProfileService.ProfileResponseProcessor processor = new ProfileService.ProfileResponseProcessor(pair.second());
|
||||
if (processor.hasResult()) {
|
||||
builder.potentiallyActiveIds.add(recipient.getId());
|
||||
} else if (processor.genericIoError() || !processor.notFound()) {
|
||||
builder.retries.add(recipient.getId());
|
||||
builder.potentiallyActiveIds.add(recipient.getId());
|
||||
}
|
||||
try {
|
||||
return RxExtensions.safeBlockingGet(
|
||||
Observable.mergeDelayError(requests)
|
||||
.observeOn(Schedulers.io(), true)
|
||||
.scan(new UnlistedResult.Builder(), (builder, pair) -> {
|
||||
Recipient recipient = pair.first();
|
||||
ProfileService.ProfileResponseProcessor processor = new ProfileService.ProfileResponseProcessor(pair.second());
|
||||
if (processor.hasResult()) {
|
||||
builder.potentiallyActiveIds.add(recipient.getId());
|
||||
} else if (processor.genericIoError() || !processor.notFound()) {
|
||||
builder.retries.add(recipient.getId());
|
||||
builder.potentiallyActiveIds.add(recipient.getId());
|
||||
}
|
||||
|
||||
return builder;
|
||||
})
|
||||
.lastOrError()
|
||||
.map(UnlistedResult.Builder::build)
|
||||
.blockingGet();
|
||||
return builder;
|
||||
})
|
||||
.lastOrError()
|
||||
.map(UnlistedResult.Builder::build)
|
||||
);
|
||||
} catch (InterruptedException e) {
|
||||
Log.i(TAG, "Filter for unlisted profile fetches interrupted, fetch via job instead");
|
||||
UnlistedResult.Builder builder = new UnlistedResult.Builder();
|
||||
for (Recipient recipient : possiblyUnlisted) {
|
||||
builder.retries.add(recipient.getId());
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasCommunicatedWith(@NonNull Recipient recipient) {
|
||||
|
|
|
@ -50,6 +50,7 @@ dependencies {
|
|||
implementation libs.androidx.core.ktx
|
||||
implementation libs.google.protobuf.javalite
|
||||
implementation libs.androidx.sqlite
|
||||
implementation libs.rxjava3.rxjava
|
||||
|
||||
testImplementation testLibs.junit.junit
|
||||
testImplementation testLibs.mockito.core
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
@file:JvmName("RxExtensions")
|
||||
|
||||
package org.signal.core.util.concurrent
|
||||
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import java.lang.RuntimeException
|
||||
|
||||
/**
|
||||
* Throw an [InterruptedException] if a [Single.blockingGet] call is interrupted. This can
|
||||
* happen when being called by code already within an Rx chain that is disposed.
|
||||
*
|
||||
* [Single.blockingGet] is considered harmful and should not be used.
|
||||
*/
|
||||
@Throws(InterruptedException::class)
|
||||
fun <T : Any> Single<T>.safeBlockingGet(): T {
|
||||
try {
|
||||
return blockingGet()
|
||||
} catch (e: RuntimeException) {
|
||||
val cause = e.cause
|
||||
if (cause is InterruptedException) {
|
||||
throw cause
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue