Search in sources :

Example 56 with WorkerThread

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

the class RemoteDeleteSendJob method create.

@WorkerThread
@NonNull
public static RemoteDeleteSendJob create(@NonNull Context context, long messageId, boolean isMms) throws NoSuchMessageException {
    MessageRecord message = isMms ? SignalDatabase.mms().getMessageRecord(messageId) : SignalDatabase.sms().getSmsMessage(messageId);
    Recipient conversationRecipient = SignalDatabase.threads().getRecipientForThreadId(message.getThreadId());
    if (conversationRecipient == null) {
        throw new AssertionError("We have a message, but couldn't find the thread!");
    }
    List<RecipientId> recipients = conversationRecipient.isGroup() ? Stream.of(RecipientUtil.getEligibleForSending(conversationRecipient.getParticipants())).map(Recipient::getId).toList() : Stream.of(conversationRecipient.getId()).toList();
    recipients.remove(Recipient.self().getId());
    return new RemoteDeleteSendJob(messageId, isMms, recipients, recipients.size(), new Parameters.Builder().setQueue(conversationRecipient.getId().toQueueKey()).setLifespan(TimeUnit.DAYS.toMillis(1)).setMaxAttempts(Parameters.UNLIMITED).build());
}
Also used : RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) Recipient(org.thoughtcrime.securesms.recipients.Recipient) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Example 57 with WorkerThread

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

the class RetrieveProfileJob method forRecipients.

/**
 * Works for any RecipientId, whether it's an individual, group, or yourself.
 *
 * @return A list of length 2 or less. Two iff you are in the recipients.
 */
@WorkerThread
@NonNull
public static List<Job> forRecipients(@NonNull Set<RecipientId> recipientIds) {
    Context context = ApplicationDependencies.getApplication();
    Set<RecipientId> combined = new HashSet<>(recipientIds.size());
    boolean includeSelf = false;
    for (RecipientId recipientId : recipientIds) {
        Recipient recipient = Recipient.resolved(recipientId);
        if (recipient.isSelf()) {
            includeSelf = true;
        } else if (recipient.isGroup()) {
            List<Recipient> recipients = SignalDatabase.groups().getGroupMembers(recipient.requireGroupId(), GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF);
            combined.addAll(Stream.of(recipients).map(Recipient::getId).toList());
        } else {
            combined.add(recipientId);
        }
    }
    List<Job> jobs = new ArrayList<>(2);
    if (includeSelf) {
        jobs.add(new RefreshOwnProfileJob());
    }
    if (combined.size() > 0) {
        jobs.add(new RetrieveProfileJob(combined));
    }
    return jobs;
}
Also used : Context(android.content.Context) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) ArrayList(java.util.ArrayList) Recipient(org.thoughtcrime.securesms.recipients.Recipient) List(java.util.List) ArrayList(java.util.ArrayList) Job(org.thoughtcrime.securesms.jobmanager.Job) HashSet(java.util.HashSet) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Example 58 with WorkerThread

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

the class MmsSendJob method enqueue.

/**
 * Enqueues compression jobs for attachments and finally the MMS send job.
 */
@WorkerThread
public static void enqueue(@NonNull Context context, @NonNull JobManager jobManager, long messageId) {
    MessageDatabase database = SignalDatabase.mms();
    OutgoingMediaMessage message;
    try {
        message = database.getOutgoingMessage(messageId);
    } catch (MmsException | NoSuchMessageException e) {
        throw new AssertionError(e);
    }
    List<Job> compressionJobs = Stream.of(message.getAttachments()).map(a -> (Job) AttachmentCompressionJob.fromAttachment((DatabaseAttachment) a, true, message.getSubscriptionId())).toList();
    MmsSendJob sendJob = new MmsSendJob(messageId);
    jobManager.startChain(compressionJobs).then(sendJob).enqueue();
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) NumberUtil(org.thoughtcrime.securesms.phonenumbers.NumberUtil) Arrays(java.util.Arrays) NonNull(androidx.annotation.NonNull) Data(org.thoughtcrime.securesms.jobmanager.Data) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) PduPart(com.google.android.mms.pdu_alt.PduPart) InsecureFallbackApprovalException(org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException) Utils(com.klinker.android.send_message.Utils) SecureRandom(java.security.SecureRandom) SmilXmlSerializer(com.android.mms.dom.smil.parser.SmilXmlSerializer) Recipient(org.thoughtcrime.securesms.recipients.Recipient) PartAuthority(org.thoughtcrime.securesms.mms.PartAuthority) SendReq(com.google.android.mms.pdu_alt.SendReq) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) UndeliverableMessageException(org.thoughtcrime.securesms.transport.UndeliverableMessageException) ThreadDatabase(org.thoughtcrime.securesms.database.ThreadDatabase) Log(org.signal.core.util.logging.Log) List(java.util.List) ContentType(com.google.android.mms.ContentType) SmilHelper(com.google.android.mms.smil.SmilHelper) Job(org.thoughtcrime.securesms.jobmanager.Job) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) NoSuchMessageException(org.thoughtcrime.securesms.database.NoSuchMessageException) Attachment(org.thoughtcrime.securesms.attachments.Attachment) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) Context(android.content.Context) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) Stream(com.annimon.stream.Stream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Util(org.thoughtcrime.securesms.util.Util) JobLogger(org.thoughtcrime.securesms.jobmanager.JobLogger) WorkerThread(androidx.annotation.WorkerThread) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) InvalidHeaderValueException(com.google.android.mms.InvalidHeaderValueException) PduHeaders(com.google.android.mms.pdu_alt.PduHeaders) StreamUtil(org.signal.core.util.StreamUtil) MmsException(org.thoughtcrime.securesms.mms.MmsException) EncodedStringValue(com.google.android.mms.pdu_alt.EncodedStringValue) TextUtils(android.text.TextUtils) NetworkConstraint(org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint) Hex(org.thoughtcrime.securesms.util.Hex) IOException(java.io.IOException) SendConf(com.google.android.mms.pdu_alt.SendConf) MediaConstraints(org.thoughtcrime.securesms.mms.MediaConstraints) CharacterSets(com.google.android.mms.pdu_alt.CharacterSets) PduComposer(com.google.android.mms.pdu_alt.PduComposer) CompatMmsConnection(org.thoughtcrime.securesms.mms.CompatMmsConnection) MmsSendResult(org.thoughtcrime.securesms.mms.MmsSendResult) MimeTypeMap(android.webkit.MimeTypeMap) PduBody(com.google.android.mms.pdu_alt.PduBody) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) MmsException(org.thoughtcrime.securesms.mms.MmsException) NoSuchMessageException(org.thoughtcrime.securesms.database.NoSuchMessageException) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) Job(org.thoughtcrime.securesms.jobmanager.Job) WorkerThread(androidx.annotation.WorkerThread)

Example 59 with WorkerThread

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

the class ProfileKeySendJob method create.

/**
 * Suitable for a 1:1 conversation or a GV1 group only.
 *
 * @param queueLimits True if you only want one of these to be run per person after decryptions
 *                    are drained, otherwise false.
 */
@WorkerThread
public static ProfileKeySendJob create(@NonNull Context context, long threadId, boolean queueLimits) {
    Recipient conversationRecipient = SignalDatabase.threads().getRecipientForThreadId(threadId);
    if (conversationRecipient == null) {
        throw new AssertionError("We have a thread but no recipient!");
    }
    if (conversationRecipient.isPushV2Group()) {
        throw new AssertionError("Do not send profile keys directly for GV2");
    }
    List<RecipientId> recipients = conversationRecipient.isGroup() ? Stream.of(RecipientUtil.getEligibleForSending(conversationRecipient.getParticipants())).map(Recipient::getId).toList() : Stream.of(conversationRecipient.getId()).toList();
    recipients.remove(Recipient.self().getId());
    if (queueLimits) {
        return new ProfileKeySendJob(new Parameters.Builder().setQueue("ProfileKeySendJob_" + conversationRecipient.getId().toQueueKey()).setMaxInstancesForQueue(1).addConstraint(NetworkConstraint.KEY).addConstraint(DecryptionsDrainedConstraint.KEY).setLifespan(TimeUnit.DAYS.toMillis(1)).setMaxAttempts(Parameters.UNLIMITED).build(), threadId, recipients);
    } else {
        return new ProfileKeySendJob(new Parameters.Builder().setQueue(conversationRecipient.getId().toQueueKey()).addConstraint(NetworkConstraint.KEY).setLifespan(TimeUnit.DAYS.toMillis(1)).setMaxAttempts(Parameters.UNLIMITED).build(), threadId, recipients);
    }
}
Also used : RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Recipient(org.thoughtcrime.securesms.recipients.Recipient) WorkerThread(androidx.annotation.WorkerThread)

Example 60 with WorkerThread

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

the class ProfileUtil method getAddressForRecipient.

@WorkerThread
@NonNull
public static MobileCoinPublicAddress getAddressForRecipient(@NonNull Recipient recipient) throws IOException, PaymentsAddressException {
    ProfileKey profileKey;
    try {
        profileKey = getProfileKey(recipient);
    } catch (IOException e) {
        Log.w(TAG, "Profile key not available for " + recipient.getId());
        throw new PaymentsAddressException(PaymentsAddressException.Code.NO_PROFILE_KEY);
    }
    ProfileAndCredential profileAndCredential = ProfileUtil.retrieveProfileSync(ApplicationDependencies.getApplication(), recipient, SignalServiceProfile.RequestType.PROFILE);
    SignalServiceProfile profile = profileAndCredential.getProfile();
    byte[] encryptedPaymentsAddress = profile.getPaymentAddress();
    if (encryptedPaymentsAddress == null) {
        Log.w(TAG, "Payments not enabled for " + recipient.getId());
        throw new PaymentsAddressException(PaymentsAddressException.Code.NOT_ENABLED);
    }
    try {
        IdentityKey identityKey = new IdentityKey(Base64.decode(profileAndCredential.getProfile().getIdentityKey()), 0);
        ProfileCipher profileCipher = new ProfileCipher(profileKey);
        byte[] decrypted = profileCipher.decryptWithLength(encryptedPaymentsAddress);
        SignalServiceProtos.PaymentAddress paymentAddress = SignalServiceProtos.PaymentAddress.parseFrom(decrypted);
        byte[] bytes = MobileCoinPublicAddressProfileUtil.verifyPaymentsAddress(paymentAddress, identityKey);
        MobileCoinPublicAddress mobileCoinPublicAddress = MobileCoinPublicAddress.fromBytes(bytes);
        if (mobileCoinPublicAddress == null) {
            throw new PaymentsAddressException(PaymentsAddressException.Code.INVALID_ADDRESS);
        }
        return mobileCoinPublicAddress;
    } catch (InvalidCiphertextException | IOException e) {
        Log.w(TAG, "Could not decrypt payments address, ProfileKey may be outdated for " + recipient.getId(), e);
        throw new PaymentsAddressException(PaymentsAddressException.Code.COULD_NOT_DECRYPT);
    } catch (InvalidKeyException e) {
        Log.w(TAG, "Could not verify payments address due to bad identity key " + recipient.getId(), e);
        throw new PaymentsAddressException(PaymentsAddressException.Code.INVALID_ADDRESS_SIGNATURE);
    }
}
Also used : IdentityKey(org.whispersystems.libsignal.IdentityKey) InvalidCiphertextException(org.whispersystems.signalservice.api.crypto.InvalidCiphertextException) ProfileCipher(org.whispersystems.signalservice.api.crypto.ProfileCipher) ProfileAndCredential(org.whispersystems.signalservice.api.profiles.ProfileAndCredential) IOException(java.io.IOException) PaymentsAddressException(org.thoughtcrime.securesms.payments.PaymentsAddressException) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) ProfileKey(org.signal.zkgroup.profiles.ProfileKey) SignalServiceProfile(org.whispersystems.signalservice.api.profiles.SignalServiceProfile) SignalServiceProtos(org.whispersystems.signalservice.internal.push.SignalServiceProtos) MobileCoinPublicAddress(org.thoughtcrime.securesms.payments.MobileCoinPublicAddress) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Aggregations

WorkerThread (androidx.annotation.WorkerThread)365 NonNull (androidx.annotation.NonNull)151 IOException (java.io.IOException)83 Recipient (org.thoughtcrime.securesms.recipients.Recipient)82 Nullable (androidx.annotation.Nullable)51 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)46 Cursor (android.database.Cursor)41 ArrayList (java.util.ArrayList)41 Context (android.content.Context)39 Uri (android.net.Uri)32 LinkedList (java.util.LinkedList)30 List (java.util.List)30 RecipientDatabase (org.thoughtcrime.securesms.database.RecipientDatabase)28 Stream (com.annimon.stream.Stream)26 HashMap (java.util.HashMap)26 Log (org.signal.core.util.logging.Log)26 HashSet (java.util.HashSet)24 Map (java.util.Map)21 Collections (java.util.Collections)20 ApplicationDependencies (org.thoughtcrime.securesms.dependencies.ApplicationDependencies)20