import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.NotFoundException;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
-import org.whispersystems.signalservice.internal.util.concurrent.CascadingFuture;
-import org.whispersystems.signalservice.internal.util.concurrent.ListenableFuture;
+import org.whispersystems.signalservice.api.services.ProfileService;
+import org.whispersystems.signalservice.internal.ServiceResponse;
import java.io.IOException;
-import java.util.Arrays;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
+
+import io.reactivex.rxjava3.core.Single;
public final class ProfileHelper {
private final UnidentifiedAccessProvider unidentifiedAccessProvider;
- private final MessagePipeProvider messagePipeProvider;
+ private final ProfileServiceProvider profileServiceProvider;
private final MessageReceiverProvider messageReceiverProvider;
public ProfileHelper(
final ProfileKeyProvider profileKeyProvider,
final UnidentifiedAccessProvider unidentifiedAccessProvider,
- final MessagePipeProvider messagePipeProvider,
+ final ProfileServiceProvider profileServiceProvider,
final MessageReceiverProvider messageReceiverProvider,
final SignalServiceAddressResolver addressResolver
) {
this.profileKeyProvider = profileKeyProvider;
this.unidentifiedAccessProvider = unidentifiedAccessProvider;
- this.messagePipeProvider = messagePipeProvider;
+ this.profileServiceProvider = profileServiceProvider;
this.messageReceiverProvider = messageReceiverProvider;
this.addressResolver = addressResolver;
}
RecipientId recipientId, SignalServiceProfile.RequestType requestType
) throws IOException {
try {
- return retrieveProfile(recipientId, requestType).get(10, TimeUnit.SECONDS);
- } catch (ExecutionException e) {
+ return retrieveProfile(recipientId, requestType).blockingGet();
+ } catch (RuntimeException e) {
if (e.getCause() instanceof PushNetworkException) {
throw (PushNetworkException) e.getCause();
} else if (e.getCause() instanceof NotFoundException) {
} else {
throw new IOException(e);
}
- } catch (InterruptedException | TimeoutException e) {
- throw new PushNetworkException(e);
}
}
- public ListenableFuture<ProfileAndCredential> retrieveProfile(
+ public SignalServiceProfile retrieveProfileSync(String username) throws IOException {
+ return messageReceiverProvider.getMessageReceiver().retrieveProfileByUsername(username, Optional.absent());
+ }
+
+ public Single<ProfileAndCredential> retrieveProfile(
RecipientId recipientId, SignalServiceProfile.RequestType requestType
- ) {
+ ) throws IOException {
var unidentifiedAccess = getUnidentifiedAccess(recipientId);
var profileKey = Optional.fromNullable(profileKeyProvider.getProfileKey(recipientId));
final var address = addressResolver.resolveSignalServiceAddress(recipientId);
- if (unidentifiedAccess.isPresent()) {
- return new CascadingFuture<>(Arrays.asList(() -> getPipeRetrievalFuture(address,
- profileKey,
- unidentifiedAccess,
- requestType),
- () -> getSocketRetrievalFuture(address, profileKey, unidentifiedAccess, requestType),
- () -> getPipeRetrievalFuture(address, profileKey, Optional.absent(), requestType),
- () -> getSocketRetrievalFuture(address, profileKey, Optional.absent(), requestType)),
- e -> !(e instanceof NotFoundException));
- } else {
- return new CascadingFuture<>(Arrays.asList(() -> getPipeRetrievalFuture(address,
- profileKey,
- Optional.absent(),
- requestType), () -> getSocketRetrievalFuture(address, profileKey, Optional.absent(), requestType)),
- e -> !(e instanceof NotFoundException));
- }
+ return retrieveProfile(address, profileKey, unidentifiedAccess, requestType);
}
- private ListenableFuture<ProfileAndCredential> getPipeRetrievalFuture(
+ private Single<ProfileAndCredential> retrieveProfile(
SignalServiceAddress address,
Optional<ProfileKey> profileKey,
Optional<UnidentifiedAccess> unidentifiedAccess,
SignalServiceProfile.RequestType requestType
) throws IOException {
- var unidentifiedPipe = messagePipeProvider.getMessagePipe(true);
- var pipe = unidentifiedPipe != null && unidentifiedAccess.isPresent()
- ? unidentifiedPipe
- : messagePipeProvider.getMessagePipe(false);
- if (pipe != null) {
- try {
- return pipe.getProfile(address, profileKey, unidentifiedAccess, requestType);
- } catch (NoClassDefFoundError e) {
- // Native zkgroup lib not available for ProfileKey
- if (!address.getNumber().isPresent()) {
- throw new NotFoundException("Can't request profile without number");
- }
- var addressWithoutUuid = new SignalServiceAddress(Optional.absent(), address.getNumber());
- return pipe.getProfile(addressWithoutUuid, profileKey, unidentifiedAccess, requestType);
- }
- }
+ var profileService = profileServiceProvider.getProfileService();
- throw new IOException("No pipe available!");
- }
-
- private ListenableFuture<ProfileAndCredential> getSocketRetrievalFuture(
- SignalServiceAddress address,
- Optional<ProfileKey> profileKey,
- Optional<UnidentifiedAccess> unidentifiedAccess,
- SignalServiceProfile.RequestType requestType
- ) throws NotFoundException {
- var receiver = messageReceiverProvider.getMessageReceiver();
+ Single<ServiceResponse<ProfileAndCredential>> responseSingle;
try {
- return receiver.retrieveProfile(address, profileKey, unidentifiedAccess, requestType);
+ responseSingle = profileService.getProfile(address, profileKey, unidentifiedAccess, requestType);
} catch (NoClassDefFoundError e) {
// Native zkgroup lib not available for ProfileKey
if (!address.getNumber().isPresent()) {
throw new NotFoundException("Can't request profile without number");
}
var addressWithoutUuid = new SignalServiceAddress(Optional.absent(), address.getNumber());
- return receiver.retrieveProfile(addressWithoutUuid, profileKey, unidentifiedAccess, requestType);
+ responseSingle = profileService.getProfile(addressWithoutUuid, profileKey, unidentifiedAccess, requestType);
}
+
+ return responseSingle.map(pair -> {
+ var processor = new ProfileService.ProfileResponseProcessor(pair);
+ if (processor.hasResult()) {
+ return processor.getResult();
+ } else if (processor.notFound()) {
+ throw new NotFoundException("Profile not found");
+ } else {
+ throw pair.getExecutionError()
+ .or(pair.getApplicationError())
+ .or(new IOException("Unknown error while retrieving profile"));
+ }
+ });
}
private Optional<UnidentifiedAccess> getUnidentifiedAccess(RecipientId recipientId) {