Search in sources :

Example 26 with WorkerThread

use of androidx.annotation.WorkerThread in project Signal-Android by WhisperSystems.

the class GroupDatabase method getGroupMembers.

@WorkerThread
@NonNull
public List<Recipient> getGroupMembers(@NonNull GroupId groupId, @NonNull MemberSet memberSet) {
    if (groupId.isV2()) {
        return getGroup(groupId).transform(g -> g.requireV2GroupProperties().getMemberRecipients(memberSet)).or(Collections.emptyList());
    } else {
        List<RecipientId> currentMembers = getCurrentMembers(groupId);
        List<Recipient> recipients = new ArrayList<>(currentMembers.size());
        for (RecipientId member : currentMembers) {
            Recipient resolved = Recipient.resolved(member);
            if (memberSet.includeSelf || !resolved.isSelf()) {
                recipients.add(resolved);
            }
        }
        return recipients;
    }
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) GroupMigrationMembershipChange(org.thoughtcrime.securesms.groups.GroupMigrationMembershipChange) NonNull(androidx.annotation.NonNull) RequestGroupV2InfoJob(org.thoughtcrime.securesms.jobs.RequestGroupV2InfoJob) GroupAccessControl(org.thoughtcrime.securesms.groups.GroupAccessControl) GroupMasterKey(org.signal.zkgroup.groups.GroupMasterKey) SecureRandom(java.security.SecureRandom) Member(org.signal.storageservice.protos.groups.Member) SenderKeyUtil(org.thoughtcrime.securesms.crypto.SenderKeyUtil) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) SqlUtil(org.thoughtcrime.securesms.util.SqlUtil) Locale(java.util.Locale) Map(java.util.Map) DecryptedGroupChange(org.signal.storageservice.protos.groups.local.DecryptedGroupChange) Recipient(org.thoughtcrime.securesms.recipients.Recipient) GroupsV2StateProcessor(org.thoughtcrime.securesms.groups.v2.processing.GroupsV2StateProcessor) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) ACI(org.whispersystems.signalservice.api.push.ACI) DecryptedGroupUtil(org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) Collection(java.util.Collection) EnabledState(org.signal.storageservice.protos.groups.local.EnabledState) Set(java.util.Set) SetUtil(org.thoughtcrime.securesms.util.SetUtil) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) InvalidInputException(org.signal.zkgroup.InvalidInputException) Objects(java.util.Objects) Log(org.signal.core.util.logging.Log) DecryptedGroup(org.signal.storageservice.protos.groups.local.DecryptedGroup) List(java.util.List) Nullable(androidx.annotation.Nullable) GroupId(org.thoughtcrime.securesms.groups.GroupId) ContentValues(android.content.ContentValues) Context(android.content.Context) Stream(com.annimon.stream.Stream) Util(org.thoughtcrime.securesms.util.Util) WorkerThread(androidx.annotation.WorkerThread) HashMap(java.util.HashMap) AccessControl(org.signal.storageservice.protos.groups.AccessControl) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) SuppressLint(android.annotation.SuppressLint) LinkedList(java.util.LinkedList) DistributionId(org.whispersystems.signalservice.api.push.DistributionId) Cursor(android.database.Cursor) GroupChangeReconstruct(org.whispersystems.signalservice.api.groupsv2.GroupChangeReconstruct) SignalServiceAttachmentPointer(org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer) UuidUtil(org.whispersystems.signalservice.api.util.UuidUtil) TextUtils(android.text.TextUtils) Optional(org.whispersystems.libsignal.util.guava.Optional) CursorUtil(org.thoughtcrime.securesms.util.CursorUtil) Closeable(java.io.Closeable) ServiceId(org.whispersystems.signalservice.api.push.ServiceId) Collections(java.util.Collections) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) ArrayList(java.util.ArrayList) Recipient(org.thoughtcrime.securesms.recipients.Recipient) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Example 27 with WorkerThread

use of androidx.annotation.WorkerThread in project Signal-Android by WhisperSystems.

the class UnidentifiedAccessUtil method getAccessFor.

@WorkerThread
public static List<Optional<UnidentifiedAccessPair>> getAccessFor(@NonNull Context context, @NonNull List<Recipient> recipients, boolean log) {
    byte[] ourUnidentifiedAccessKey = UnidentifiedAccess.deriveAccessKeyFrom(ProfileKeyUtil.getSelfProfileKey());
    if (TextSecurePreferences.isUniversalUnidentifiedAccess(context)) {
        ourUnidentifiedAccessKey = UNRESTRICTED_KEY;
    }
    List<Optional<UnidentifiedAccessPair>> access = new ArrayList<>(recipients.size());
    Map<CertificateType, Integer> typeCounts = new HashMap<>();
    for (Recipient recipient : recipients) {
        byte[] theirUnidentifiedAccessKey = getTargetUnidentifiedAccessKey(recipient);
        CertificateType certificateType = getUnidentifiedAccessCertificateType(recipient);
        byte[] ourUnidentifiedAccessCertificate = SignalStore.certificateValues().getUnidentifiedAccessCertificate(certificateType);
        int typeCount = Util.getOrDefault(typeCounts, certificateType, 0);
        typeCount++;
        typeCounts.put(certificateType, typeCount);
        if (theirUnidentifiedAccessKey != null && ourUnidentifiedAccessCertificate != null) {
            try {
                access.add(Optional.of(new UnidentifiedAccessPair(new UnidentifiedAccess(theirUnidentifiedAccessKey, ourUnidentifiedAccessCertificate), new UnidentifiedAccess(ourUnidentifiedAccessKey, ourUnidentifiedAccessCertificate))));
            } catch (InvalidCertificateException e) {
                Log.w(TAG, e);
                access.add(Optional.absent());
            }
        } else {
            access.add(Optional.absent());
        }
    }
    int unidentifiedCount = Stream.of(access).filter(Optional::isPresent).toList().size();
    int otherCount = access.size() - unidentifiedCount;
    if (log) {
        Log.i(TAG, "Unidentified: " + unidentifiedCount + ", Other: " + otherCount + ". Types: " + typeCounts);
    }
    return access;
}
Also used : Optional(org.whispersystems.libsignal.util.guava.Optional) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Recipient(org.thoughtcrime.securesms.recipients.Recipient) UnidentifiedAccessPair(org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair) UnidentifiedAccess(org.whispersystems.signalservice.api.crypto.UnidentifiedAccess) CertificateType(org.thoughtcrime.securesms.keyvalue.CertificateType) InvalidCertificateException(org.signal.libsignal.metadata.certificate.InvalidCertificateException) WorkerThread(androidx.annotation.WorkerThread)

Example 28 with WorkerThread

use of androidx.annotation.WorkerThread in project Signal-Android by WhisperSystems.

the class Wallet method sendPayment.

@WorkerThread
private void sendPayment(@NonNull MobileCoinPublicAddress to, @NonNull Money.MobileCoin amount, @NonNull Money.MobileCoin totalFee, boolean defragmentFirst, @NonNull List<TransactionSubmissionResult> results) {
    Money.MobileCoin defragmentFees = Money.MobileCoin.ZERO;
    if (defragmentFirst) {
        try {
            defragmentFees = defragment(amount, results);
        } catch (InsufficientFundsException e) {
            Log.w(TAG, "Insufficient funds", e);
            results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.INSUFFICIENT_FUNDS, true));
            return;
        } catch (TimeoutException | InvalidTransactionException | InvalidFogResponse | AttestationException | TransactionBuilderException | NetworkException | FogReportException e) {
            Log.w(TAG, "Defragment failed", e);
            results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, true));
            return;
        }
    }
    Money.MobileCoin feeMobileCoin = totalFee.subtract(defragmentFees).requireMobileCoin();
    BigInteger picoMob = amount.requireMobileCoin().toPicoMobBigInteger();
    PendingTransaction pendingTransaction = null;
    Log.i(TAG, String.format("Total fee advised: %s\nDefrag fees: %s\nTransaction fee: %s", totalFee, defragmentFees, feeMobileCoin));
    if (!feeMobileCoin.isPositive()) {
        Log.i(TAG, "No fee left after defrag");
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
        return;
    }
    try {
        pendingTransaction = mobileCoinClient.prepareTransaction(to.getAddress(), picoMob, feeMobileCoin.toPicoMobBigInteger());
    } catch (InsufficientFundsException e) {
        Log.w(TAG, "Insufficient funds", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.INSUFFICIENT_FUNDS, false));
    } catch (FeeRejectedException e) {
        Log.w(TAG, "Fee rejected " + totalFee, e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    } catch (InvalidFogResponse | FogReportException e) {
        Log.w(TAG, "Invalid fog response", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    } catch (FragmentedAccountException e) {
        if (defragmentFirst) {
            Log.w(TAG, "Account is fragmented, but already tried to defragment", e);
            results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
        } else {
            Log.i(TAG, "Account is fragmented, defragmenting and retrying");
            sendPayment(to, amount, totalFee, true, results);
        }
    } catch (AttestationException e) {
        Log.w(TAG, "Attestation problem", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    } catch (NetworkException e) {
        Log.w(TAG, "Network problem", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    } catch (TransactionBuilderException e) {
        Log.w(TAG, "Builder problem", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    }
    if (pendingTransaction == null) {
        Log.w(TAG, "Failed to create pending transaction");
        return;
    }
    try {
        Log.i(TAG, "Submitting transaction");
        mobileCoinClient.submitTransaction(pendingTransaction.getTransaction());
        Log.i(TAG, "Transaction submitted");
        results.add(TransactionSubmissionResult.successfullySubmitted(new PaymentTransactionId.MobileCoin(pendingTransaction.getTransaction().toByteArray(), pendingTransaction.getReceipt().toByteArray(), feeMobileCoin)));
    } catch (NetworkException e) {
        Log.w(TAG, "Network problem", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.NETWORK_FAILURE, false));
    } catch (InvalidTransactionException e) {
        Log.w(TAG, "Invalid transaction", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    } catch (AttestationException e) {
        Log.w(TAG, "Attestation problem", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    } catch (SerializationException e) {
        Log.w(TAG, "Serialization problem", e);
        results.add(TransactionSubmissionResult.failure(TransactionSubmissionResult.ErrorCode.GENERIC_FAILURE, false));
    }
}
Also used : PendingTransaction(com.mobilecoin.lib.PendingTransaction) AttestationException(com.mobilecoin.lib.exceptions.AttestationException) FogReportException(com.mobilecoin.lib.exceptions.FogReportException) SerializationException(com.mobilecoin.lib.exceptions.SerializationException) FeeRejectedException(com.mobilecoin.lib.exceptions.FeeRejectedException) InvalidTransactionException(com.mobilecoin.lib.exceptions.InvalidTransactionException) InvalidFogResponse(com.mobilecoin.lib.exceptions.InvalidFogResponse) TransactionBuilderException(com.mobilecoin.lib.exceptions.TransactionBuilderException) Money(org.whispersystems.signalservice.api.payments.Money) FragmentedAccountException(com.mobilecoin.lib.exceptions.FragmentedAccountException) InsufficientFundsException(com.mobilecoin.lib.exceptions.InsufficientFundsException) BigInteger(java.math.BigInteger) NetworkException(com.mobilecoin.lib.exceptions.NetworkException) TimeoutException(java.util.concurrent.TimeoutException) WorkerThread(androidx.annotation.WorkerThread)

Example 29 with WorkerThread

use of androidx.annotation.WorkerThread in project Signal-Android by WhisperSystems.

the class Wallet method getFullLedger.

@WorkerThread
@NonNull
private MobileCoinLedgerWrapper getFullLedger(boolean retryOnAuthFailure) {
    PaymentsValues paymentsValues = SignalStore.paymentsValues();
    try {
        MobileCoinLedgerWrapper ledger = tryGetFullLedger(null);
        paymentsValues.setMobileCoinFullLedger(Objects.requireNonNull(ledger));
    } catch (IOException e) {
        if ((retryOnAuthFailure && e.getCause() instanceof NetworkException) && (((NetworkException) e.getCause()).statusCode == 401)) {
            Log.w(TAG, "Failed to get up to date ledger, due to temp auth failure, retrying", e);
            return getFullLedger(false);
        } else {
            Log.w(TAG, "Failed to get up to date ledger", e);
        }
    }
    return getCachedLedger();
}
Also used : PaymentsValues(org.thoughtcrime.securesms.keyvalue.PaymentsValues) IOException(java.io.IOException) NetworkException(com.mobilecoin.lib.exceptions.NetworkException) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Example 30 with WorkerThread

use of androidx.annotation.WorkerThread in project Signal-Android by WhisperSystems.

the class NotificationChannels method updateMessagesLedColor.

/**
 * Updates the LED color for message notifications and all contact-specific message notification
 * channels. Performs database operations and should therefore be invoked on a background thread.
 */
@WorkerThread
public static synchronized void updateMessagesLedColor(@NonNull Context context, @NonNull String color) {
    if (!supported()) {
        return;
    }
    Log.i(TAG, "Updating LED color.");
    NotificationManager notificationManager = ServiceUtil.getNotificationManager(context);
    updateMessageChannel(context, channel -> setLedPreference(channel, color));
    updateAllRecipientChannelLedColors(context, notificationManager, color);
    ensureCustomChannelConsistency(context);
}
Also used : NotificationManager(android.app.NotificationManager) WorkerThread(androidx.annotation.WorkerThread)

Aggregations

WorkerThread (androidx.annotation.WorkerThread)204 NonNull (androidx.annotation.NonNull)77 IOException (java.io.IOException)45 Recipient (org.thoughtcrime.securesms.recipients.Recipient)41 Nullable (androidx.annotation.Nullable)26 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)23 Cursor (android.database.Cursor)22 ArrayList (java.util.ArrayList)22 Context (android.content.Context)20 Uri (android.net.Uri)18 LinkedList (java.util.LinkedList)15 List (java.util.List)15 HashMap (java.util.HashMap)14 RecipientDatabase (org.thoughtcrime.securesms.database.RecipientDatabase)14 Stream (com.annimon.stream.Stream)13 Log (org.signal.core.util.logging.Log)13 HashSet (java.util.HashSet)12 InputStream (java.io.InputStream)11 Bitmap (android.graphics.Bitmap)10 Collections (java.util.Collections)10