Search in sources :

Example 6 with Pair

use of org.whispersystems.libsignal.util.Pair in project Signal-Android by WhisperSystems.

the class SmsDatabase method insertCallLog.

@NonNull
private Pair<Long, Long> insertCallLog(@NonNull RecipientId recipientId, long type, boolean unread, long timestamp) {
    Recipient recipient = Recipient.resolved(recipientId);
    long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient);
    ContentValues values = new ContentValues(6);
    values.put(RECIPIENT_ID, recipientId.serialize());
    values.put(ADDRESS_DEVICE_ID, 1);
    values.put(DATE_RECEIVED, System.currentTimeMillis());
    values.put(DATE_SENT, timestamp);
    values.put(READ, unread ? 0 : 1);
    values.put(TYPE, type);
    values.put(THREAD_ID, threadId);
    SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
    long messageId = db.insert(TABLE_NAME, null, values);
    if (unread) {
        SignalDatabase.threads().incrementUnread(threadId, 1);
    }
    SignalDatabase.threads().update(threadId, true);
    notifyConversationListeners(threadId);
    TrimThreadJob.enqueueAsync(threadId);
    return new Pair<>(messageId, threadId);
}
Also used : ContentValues(android.content.ContentValues) Recipient(org.thoughtcrime.securesms.recipients.Recipient) Pair(org.whispersystems.libsignal.util.Pair) NonNull(androidx.annotation.NonNull)

Example 7 with Pair

use of org.whispersystems.libsignal.util.Pair in project Signal-Android by WhisperSystems.

the class CdshService method createTlsSocketFactory.

private static Pair<SSLSocketFactory, X509TrustManager> createTlsSocketFactory(TrustStore trustStore) {
    try {
        SSLContext context = SSLContext.getInstance("TLS");
        TrustManager[] trustManagers = BlacklistingTrustManager.createFor(trustStore);
        context.init(null, trustManagers, null);
        return new Pair<>(context.getSocketFactory(), (X509TrustManager) trustManagers[0]);
    } catch (NoSuchAlgorithmException | KeyManagementException e) {
        throw new AssertionError(e);
    }
}
Also used : SSLContext(javax.net.ssl.SSLContext) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) KeyManagementException(java.security.KeyManagementException) TrustManager(javax.net.ssl.TrustManager) X509TrustManager(javax.net.ssl.X509TrustManager) BlacklistingTrustManager(org.whispersystems.signalservice.internal.util.BlacklistingTrustManager) Pair(org.whispersystems.libsignal.util.Pair)

Example 8 with Pair

use of org.whispersystems.libsignal.util.Pair in project Signal-Android by WhisperSystems.

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();
    }
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) NonNull(androidx.annotation.NonNull) Data(org.thoughtcrime.securesms.jobmanager.Data) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) RecipientUtil(org.thoughtcrime.securesms.recipients.RecipientUtil) ProfileKey(org.signal.zkgroup.profiles.ProfileKey) ProfileCipher(org.whispersystems.signalservice.api.crypto.ProfileCipher) ProfileAndCredential(org.whispersystems.signalservice.api.profiles.ProfileAndCredential) Badges(org.thoughtcrime.securesms.badges.Badges) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Locale(java.util.Locale) Map(java.util.Map) Badge(org.thoughtcrime.securesms.badges.models.Badge) Recipient(org.thoughtcrime.securesms.recipients.Recipient) InvalidCiphertextException(org.whispersystems.signalservice.api.crypto.InvalidCiphertextException) SignalExecutors(org.signal.core.util.concurrent.SignalExecutors) UnidentifiedAccessMode(org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode) Base64(org.thoughtcrime.securesms.util.Base64) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) ProfileKeyUtil(org.thoughtcrime.securesms.crypto.ProfileKeyUtil) Set(java.util.Set) SetUtil(org.thoughtcrime.securesms.util.SetUtil) GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) IdentityKey(org.whispersystems.libsignal.IdentityKey) Log(org.signal.core.util.logging.Log) List(java.util.List) Nullable(androidx.annotation.Nullable) ProfileService(org.whispersystems.signalservice.api.services.ProfileService) Application(android.app.Application) Job(org.thoughtcrime.securesms.jobmanager.Job) Context(android.content.Context) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) RetryLaterException(org.thoughtcrime.securesms.transport.RetryLaterException) Stream(com.annimon.stream.Stream) Util(org.thoughtcrime.securesms.util.Util) ProfileName(org.thoughtcrime.securesms.profiles.ProfileName) WorkerThread(androidx.annotation.WorkerThread) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) SignalServiceProfile(org.whispersystems.signalservice.api.profiles.SignalServiceProfile) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Schedulers(io.reactivex.rxjava3.schedulers.Schedulers) Pair(org.whispersystems.libsignal.util.Pair) ProfileUtil(org.thoughtcrime.securesms.util.ProfileUtil) Observable(io.reactivex.rxjava3.core.Observable) IdentityUtil(org.thoughtcrime.securesms.util.IdentityUtil) Collectors(com.annimon.stream.Collectors) ProfileKeyCredential(org.signal.zkgroup.profiles.ProfileKeyCredential) TextUtils(android.text.TextUtils) NetworkConstraint(org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint) IOException(java.io.IOException) ServiceResponse(org.whispersystems.signalservice.internal.ServiceResponse) Optional(org.whispersystems.libsignal.util.guava.Optional) TimeUnit(java.util.concurrent.TimeUnit) Stopwatch(org.thoughtcrime.securesms.util.Stopwatch) ServiceId(org.whispersystems.signalservice.api.push.ServiceId) Collections(java.util.Collections) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Stopwatch(org.thoughtcrime.securesms.util.Stopwatch) ProfileAndCredential(org.whispersystems.signalservice.api.profiles.ProfileAndCredential) Recipient(org.thoughtcrime.securesms.recipients.Recipient) Observable(io.reactivex.rxjava3.core.Observable) ServiceId(org.whispersystems.signalservice.api.push.ServiceId) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) ServiceResponse(org.whispersystems.signalservice.internal.ServiceResponse) ProfileService(org.whispersystems.signalservice.api.services.ProfileService) RetryLaterException(org.thoughtcrime.securesms.transport.RetryLaterException) Pair(org.whispersystems.libsignal.util.Pair)

Example 9 with Pair

use of org.whispersystems.libsignal.util.Pair in project Signal-Android by WhisperSystems.

the class SearchUtil method getHighlightedSpan.

public static Spannable getHighlightedSpan(@NonNull Locale locale, @NonNull StyleFactory styleFactory, @Nullable Spannable text, @Nullable String highlight, int matchMode) {
    if (TextUtils.isEmpty(text)) {
        return new SpannableString("");
    }
    if (TextUtils.isEmpty(highlight)) {
        return text;
    }
    SpannableString spanned = new SpannableString(text);
    List<Pair<Integer, Integer>> ranges;
    switch(matchMode) {
        case STRICT:
            ranges = getStrictHighlightRanges(locale, text.toString(), highlight);
            break;
        case MATCH_ALL:
            ranges = getHighlightRanges(locale, text.toString(), highlight);
            break;
        default:
            throw new InvalidParameterException("match mode must be STRICT or MATCH_ALL: " + matchMode);
    }
    if (matchMode == STRICT) {
        ranges = getStrictHighlightRanges(locale, text.toString(), highlight);
    } else {
        ranges = getHighlightRanges(locale, text.toString(), highlight);
    }
    for (Pair<Integer, Integer> range : ranges) {
        spanned.setSpan(styleFactory.create(), range.first(), range.second(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    }
    return spanned;
}
Also used : SpannableString(android.text.SpannableString) InvalidParameterException(java.security.InvalidParameterException) Pair(org.whispersystems.libsignal.util.Pair)

Example 10 with Pair

use of org.whispersystems.libsignal.util.Pair in project Signal-Android by WhisperSystems.

the class MarkReadReceiverTest method givenMultipleThreadsWithMultipleMessagesEach_whenIProcess_thenIProperlyGroupByThreadAndRecipient.

@Test
public void givenMultipleThreadsWithMultipleMessagesEach_whenIProcess_thenIProperlyGroupByThreadAndRecipient() {
    // GIVEN
    List<RecipientId> recipients = Stream.range(1L, 4L).map(RecipientId::from).toList();
    List<Long> threads = Stream.range(4L, 7L).toList();
    int expected = recipients.size() * threads.size() + 1;
    List<MessageDatabase.MarkedMessageInfo> infoList = Stream.of(threads).flatMap(threadId -> Stream.of(recipients).map(recipientId -> createMarkedMessageInfo(threadId, recipientId))).toList();
    List<MessageDatabase.MarkedMessageInfo> duplicatedList = Util.concatenatedList(infoList, infoList);
    // WHEN
    MarkReadReceiver.process(mockContext, duplicatedList);
    // THEN
    assertEquals("Should have 10 total jobs, including MultiDeviceReadUpdateJob", expected, jobs.size());
    Set<Pair<Long, String>> threadRecipientPairs = new HashSet<>();
    Stream.of(jobs).forEach(job -> {
        if (job instanceof MultiDeviceReadUpdateJob) {
            return;
        }
        Data data = job.serialize();
        long threadId = data.getLong("thread");
        String recipientId = data.getString("recipient");
        long[] messageIds = data.getLongArray("message_ids");
        assertEquals("Each job should contain two messages.", 2, messageIds.length);
        assertTrue("Each thread recipient pair should only exist once.", threadRecipientPairs.add(new Pair<>(threadId, recipientId)));
    });
    assertEquals("Should have 9 total combinations.", 9, threadRecipientPairs.size());
}
Also used : Context(android.content.Context) Stream(com.annimon.stream.Stream) Util(org.thoughtcrime.securesms.util.Util) PowerMockito.mockStatic(org.powermock.api.mockito.PowerMockito.mockStatic) NonNull(androidx.annotation.NonNull) Data(org.thoughtcrime.securesms.jobmanager.Data) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) RunWith(org.junit.runner.RunWith) HashSet(java.util.HashSet) Answer(org.mockito.stubbing.Answer) Pair(org.whispersystems.libsignal.util.Pair) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Recipient(org.thoughtcrime.securesms.recipients.Recipient) PowerMockRunner(org.powermock.modules.junit4.PowerMockRunner) LinkedList(java.util.LinkedList) Before(org.junit.Before) MessageId(org.thoughtcrime.securesms.database.model.MessageId) PowerMockito.when(org.powermock.api.mockito.PowerMockito.when) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) Set(java.util.Set) Assert.assertTrue(org.junit.Assert.assertTrue) Test(org.junit.Test) Matchers.any(org.mockito.Matchers.any) List(java.util.List) PowerMockito.mock(org.powermock.api.mockito.PowerMockito.mock) MultiDeviceReadUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob) PowerMockito.doAnswer(org.powermock.api.mockito.PowerMockito.doAnswer) Job(org.thoughtcrime.securesms.jobmanager.Job) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) Assert.assertEquals(org.junit.Assert.assertEquals) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Data(org.thoughtcrime.securesms.jobmanager.Data) MultiDeviceReadUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob) Pair(org.whispersystems.libsignal.util.Pair) HashSet(java.util.HashSet) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) Test(org.junit.Test)

Aggregations

Pair (org.whispersystems.libsignal.util.Pair)49 NonNull (androidx.annotation.NonNull)26 List (java.util.List)18 LinkedList (java.util.LinkedList)15 Context (android.content.Context)14 Stream (com.annimon.stream.Stream)14 IOException (java.io.IOException)14 Recipient (org.thoughtcrime.securesms.recipients.Recipient)14 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)14 Nullable (androidx.annotation.Nullable)12 SpannableString (android.text.SpannableString)10 TextUtils (android.text.TextUtils)10 ArrayList (java.util.ArrayList)10 Collections (java.util.Collections)10 Cursor (android.database.Cursor)9 ContentValues (android.content.ContentValues)8 HashSet (java.util.HashSet)8 Locale (java.util.Locale)8 Set (java.util.Set)8 Log (org.signal.core.util.logging.Log)8