use of org.whispersystems.libsignal.util.Pair in project Signal-Android by signalapp.
the class ConversationParentFragment method initializeIdentityRecords.
private ListenableFuture<Boolean> initializeIdentityRecords() {
final SettableFuture<Boolean> future = new SettableFuture<>();
final Context context = requireContext().getApplicationContext();
if (SignalStore.account().getAci() == null || SignalStore.account().getPni() == null) {
Log.w(TAG, "Not registered! Skipping initializeIdentityRecords()");
future.set(false);
return future;
}
new AsyncTask<Recipient, Void, Pair<IdentityRecordList, String>>() {
@Override
@NonNull
protected Pair<IdentityRecordList, String> doInBackground(Recipient... params) {
List<Recipient> recipients;
if (params[0].isGroup()) {
recipients = SignalDatabase.groups().getGroupMembers(params[0].requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF);
} else {
recipients = Collections.singletonList(params[0]);
}
long startTime = System.currentTimeMillis();
IdentityRecordList identityRecordList = ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecords(recipients);
Log.i(TAG, String.format(Locale.US, "Loaded %d identities in %d ms", recipients.size(), System.currentTimeMillis() - startTime));
String message = null;
if (identityRecordList.isUnverified()) {
message = IdentityUtil.getUnverifiedBannerDescription(context, identityRecordList.getUnverifiedRecipients());
}
return new Pair<>(identityRecordList, message);
}
@Override
protected void onPostExecute(@NonNull Pair<IdentityRecordList, String> result) {
Log.i(TAG, "Got identity records: " + result.first().isUnverified());
identityRecords = result.first();
if (result.second() != null) {
Log.d(TAG, "Replacing banner...");
unverifiedBannerView.get().display(result.second(), result.first().getUnverifiedRecords(), new UnverifiedClickedListener(), new UnverifiedDismissedListener());
} else if (unverifiedBannerView.resolved()) {
Log.d(TAG, "Clearing banner...");
unverifiedBannerView.get().hide();
}
titleView.setVerified(isSecureText && identityRecords.isVerified());
future.set(true);
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, recipient.get());
return future;
}
use of org.whispersystems.libsignal.util.Pair in project Signal-Android by signalapp.
the class SignalCallManager method onSendHttpRequest.
@Override
public void onSendHttpRequest(long requestId, @NonNull String url, @NonNull CallManager.HttpMethod httpMethod, @Nullable List<HttpHeader> headers, @Nullable byte[] body) {
if (callManager == null) {
Log.w(TAG, "Unable to send http request, call manager is not initialized");
return;
}
Log.i(TAG, "onSendHttpRequest(): request_id: " + requestId);
networkExecutor.execute(() -> {
List<Pair<String, String>> headerPairs;
if (headers != null) {
headerPairs = Stream.of(headers).map(header -> new Pair<>(header.getName(), header.getValue())).toList();
} else {
headerPairs = Collections.emptyList();
}
CallingResponse response = messageSender.makeCallingRequest(requestId, url, httpMethod.name(), headerPairs, body);
try {
if (response instanceof CallingResponse.Success) {
CallingResponse.Success success = (CallingResponse.Success) response;
callManager.receivedHttpResponse(requestId, success.getResponseStatus(), success.getResponseBody());
} else {
callManager.httpRequestFailed(requestId);
}
} catch (CallException e) {
Log.i(TAG, "Failed to process HTTP response/failure", e);
}
});
}
use of org.whispersystems.libsignal.util.Pair in project Signal-Android by signalapp.
the class RetrieveProfileJob method onRun.
@Override
public void onRun() throws IOException, RetryLaterException {
if (!SignalStore.account().isRegistered()) {
Log.w(TAG, "Unregistered. Skipping.");
return;
}
Stopwatch stopwatch = new Stopwatch("RetrieveProfile");
RecipientDatabase recipientDatabase = SignalDatabase.recipients();
RecipientUtil.ensureUuidsAreAvailable(context, Stream.of(Recipient.resolvedList(recipientIds)).filter(r -> r.getRegistered() != RecipientDatabase.RegisteredState.NOT_REGISTERED).toList());
List<Recipient> recipients = Recipient.resolvedList(recipientIds);
stopwatch.split("resolve-ensure");
ProfileService profileService = new ProfileService(ApplicationDependencies.getGroupsV2Operations().getProfileOperations(), ApplicationDependencies.getSignalServiceMessageReceiver(), ApplicationDependencies.getSignalWebSocket());
List<Observable<Pair<Recipient, ServiceResponse<ProfileAndCredential>>>> requests = Stream.of(recipients).filter(Recipient::hasServiceId).map(r -> ProfileUtil.retrieveProfile(context, r, getRequestType(r), profileService).toObservable()).toList();
stopwatch.split("requests");
OperationState operationState = Observable.mergeDelayError(requests).observeOn(Schedulers.io(), true).scan(new OperationState(), (state, pair) -> {
Recipient recipient = pair.first();
ProfileService.ProfileResponseProcessor processor = new ProfileService.ProfileResponseProcessor(pair.second());
if (processor.hasResult()) {
state.profiles.add(processor.getResult(recipient));
} else if (processor.notFound()) {
Log.w(TAG, "Failed to find a profile for " + recipient.getId());
if (recipient.isRegistered()) {
state.unregistered.add(recipient.getId());
}
} else if (processor.genericIoError()) {
state.retries.add(recipient.getId());
} else {
Log.w(TAG, "Failed to retrieve profile for " + recipient.getId());
}
return state;
}).lastOrError().blockingGet();
stopwatch.split("responses");
Set<RecipientId> success = SetUtil.difference(recipientIds, operationState.retries);
Map<RecipientId, ServiceId> newlyRegistered = Stream.of(operationState.profiles).map(Pair::first).filterNot(Recipient::isRegistered).collect(Collectors.toMap(Recipient::getId, r -> r.getServiceId().orNull()));
// noinspection SimplifyStreamApiCallChains
Util.chunk(operationState.profiles, 150).stream().forEach(list -> {
SignalDatabase.runInTransaction(() -> {
for (Pair<Recipient, ProfileAndCredential> profile : list) {
process(profile.first(), profile.second());
}
});
});
recipientDatabase.markProfilesFetched(success, System.currentTimeMillis());
if (operationState.unregistered.size() > 0 || newlyRegistered.size() > 0) {
Log.i(TAG, "Marking " + newlyRegistered.size() + " users as registered and " + operationState.unregistered.size() + " users as unregistered.");
recipientDatabase.bulkUpdatedRegisteredStatus(newlyRegistered, operationState.unregistered);
}
stopwatch.split("process");
for (Pair<Recipient, ProfileAndCredential> profile : operationState.profiles) {
setIdentityKey(profile.first(), profile.second().getProfile().getIdentityKey());
}
stopwatch.split("identityKeys");
long keyCount = Stream.of(operationState.profiles).map(Pair::first).map(Recipient::getProfileKey).withoutNulls().count();
Log.d(TAG, String.format(Locale.US, "Started with %d recipient(s). Found %d profile(s), and had keys for %d of them. Will retry %d.", recipients.size(), operationState.profiles.size(), keyCount, operationState.retries.size()));
stopwatch.stop(TAG);
recipientIds.clear();
recipientIds.addAll(operationState.retries);
if (recipientIds.size() > 0) {
throw new RetryLaterException();
}
}
use of org.whispersystems.libsignal.util.Pair in project Signal-Android by signalapp.
the class SaveAttachmentTask method doInBackground.
@Override
protected Pair<Integer, String> doInBackground(SaveAttachmentTask.Attachment... attachments) {
if (attachments == null || attachments.length == 0) {
throw new AssertionError("must pass in at least one attachment");
}
try {
Context context = contextReference.get();
String directory = null;
if (!StorageUtil.canWriteToMediaStore()) {
return new Pair<>(WRITE_ACCESS_FAILURE, null);
}
if (context == null) {
return new Pair<>(FAILURE, null);
}
for (Attachment attachment : attachments) {
if (attachment != null) {
directory = saveAttachment(context, attachment);
if (directory == null) {
return new Pair<>(FAILURE, null);
}
}
}
if (attachments.length > 1) {
return new Pair<>(SUCCESS, null);
} else {
return new Pair<>(SUCCESS, directory);
}
} catch (IOException ioe) {
Log.w(TAG, ioe);
return new Pair<>(FAILURE, null);
}
}
Aggregations