Search in sources :

Example 21 with GroupId

use of org.thoughtcrime.securesms.groups.GroupId in project Signal-Android by WhisperSystems.

the class IncomingGroupCallActionProcessor method handleDenyCall.

@Override
@NonNull
protected WebRtcServiceState handleDenyCall(@NonNull WebRtcServiceState currentState) {
    Recipient recipient = currentState.getCallInfoState().getCallRecipient();
    Optional<GroupId> groupId = recipient.getGroupId();
    long ringId = currentState.getCallSetupState(RemotePeer.GROUP_CALL_ID).getRingId();
    SignalDatabase.groupCallRings().insertOrUpdateGroupRing(ringId, System.currentTimeMillis(), CallManager.RingUpdate.DECLINED_ON_ANOTHER_DEVICE);
    try {
        webRtcInteractor.getCallManager().cancelGroupRing(groupId.get().getDecodedId(), ringId, CallManager.RingCancelReason.DeclinedByUser);
    } catch (CallException e) {
        Log.w(TAG, "Error while trying to cancel ring " + ringId, e);
    }
    webRtcInteractor.updatePhoneState(LockManager.PhoneState.PROCESSING);
    webRtcInteractor.stopAudio(false);
    webRtcInteractor.updatePhoneState(LockManager.PhoneState.IDLE);
    webRtcInteractor.stopForegroundService();
    currentState = WebRtcVideoUtil.deinitializeVideo(currentState);
    EglBaseWrapper.releaseEglBase(RemotePeer.GROUP_CALL_ID.longValue());
    return currentState.builder().actionProcessor(new IdleActionProcessor(webRtcInteractor)).terminate(RemotePeer.GROUP_CALL_ID).build();
}
Also used : CallException(org.signal.ringrtc.CallException) Recipient(org.thoughtcrime.securesms.recipients.Recipient) GroupId(org.thoughtcrime.securesms.groups.GroupId) NonNull(androidx.annotation.NonNull)

Example 22 with GroupId

use of org.thoughtcrime.securesms.groups.GroupId in project Signal-Android by WhisperSystems.

the class ReactionSendJob method deliver.

@NonNull
private List<Recipient> deliver(@NonNull Recipient conversationRecipient, @NonNull List<Recipient> destinations, @NonNull Recipient targetAuthor, long targetSentTimestamp) throws IOException, UntrustedIdentityException {
    SignalServiceDataMessage.Builder dataMessageBuilder = SignalServiceDataMessage.newBuilder().withTimestamp(System.currentTimeMillis()).withReaction(buildReaction(context, reaction, remove, targetAuthor, targetSentTimestamp));
    if (conversationRecipient.isGroup()) {
        GroupUtil.setDataMessageGroupContext(context, dataMessageBuilder, conversationRecipient.requireGroupId().requirePush());
    }
    SignalServiceDataMessage dataMessage = dataMessageBuilder.build();
    List<Recipient> nonSelfDestinations = destinations.stream().filter(r -> !r.isSelf()).collect(Collectors.toList());
    boolean includesSelf = nonSelfDestinations.size() != destinations.size();
    List<SendMessageResult> results = GroupSendUtil.sendResendableDataMessage(context, conversationRecipient.getGroupId().transform(GroupId::requireV2).orNull(), nonSelfDestinations, false, ContentHint.RESENDABLE, messageId, dataMessage);
    if (includesSelf) {
        results.add(ApplicationDependencies.getSignalServiceMessageSender().sendSyncMessage(dataMessage));
    }
    return GroupSendJobHelper.getCompletedSends(destinations, results);
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) ServerRejectedException(org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException) Context(android.content.Context) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) RetryLaterException(org.thoughtcrime.securesms.transport.RetryLaterException) ContentHint(org.whispersystems.signalservice.api.crypto.ContentHint) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) NonNull(androidx.annotation.NonNull) Data(org.thoughtcrime.securesms.jobmanager.Data) RecipientUtil(org.thoughtcrime.securesms.recipients.RecipientUtil) WorkerThread(androidx.annotation.WorkerThread) NotPushRegisteredException(org.thoughtcrime.securesms.net.NotPushRegisteredException) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Recipient(org.thoughtcrime.securesms.recipients.Recipient) GroupSendUtil(org.thoughtcrime.securesms.messages.GroupSendUtil) ReactionDatabase(org.thoughtcrime.securesms.database.ReactionDatabase) MessageId(org.thoughtcrime.securesms.database.model.MessageId) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) NetworkConstraint(org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint) IOException(java.io.IOException) ReactionRecord(org.thoughtcrime.securesms.database.model.ReactionRecord) Collectors(java.util.stream.Collectors) TimeUnit(java.util.concurrent.TimeUnit) Log(org.signal.core.util.logging.Log) List(java.util.List) UntrustedIdentityException(org.whispersystems.signalservice.api.crypto.UntrustedIdentityException) GroupId(org.thoughtcrime.securesms.groups.GroupId) Job(org.thoughtcrime.securesms.jobmanager.Job) GroupUtil(org.thoughtcrime.securesms.util.GroupUtil) NoSuchMessageException(org.thoughtcrime.securesms.database.NoSuchMessageException) Collections(java.util.Collections) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) Recipient(org.thoughtcrime.securesms.recipients.Recipient) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) GroupId(org.thoughtcrime.securesms.groups.GroupId) NonNull(androidx.annotation.NonNull)

Example 23 with GroupId

use of org.thoughtcrime.securesms.groups.GroupId in project Signal-Android by WhisperSystems.

the class PushGroupSendJob method deliver.

private List<SendMessageResult> deliver(OutgoingMediaMessage message, @NonNull Recipient groupRecipient, @NonNull List<Recipient> destinations) throws IOException, UntrustedIdentityException, UndeliverableMessageException {
    try {
        rotateSenderCertificateIfNecessary();
        GroupId.Push groupId = groupRecipient.requireGroupId().requirePush();
        Optional<byte[]> profileKey = getProfileKey(groupRecipient);
        Optional<Quote> quote = getQuoteFor(message);
        Optional<SignalServiceDataMessage.Sticker> sticker = getStickerFor(message);
        List<SharedContact> sharedContacts = getSharedContactsFor(message);
        List<Preview> previews = getPreviewsFor(message);
        List<SignalServiceDataMessage.Mention> mentions = getMentionsFor(message.getMentions());
        List<Attachment> attachments = Stream.of(message.getAttachments()).filterNot(Attachment::isSticker).toList();
        List<SignalServiceAttachment> attachmentPointers = getAttachmentPointersFor(attachments);
        boolean isRecipientUpdate = Stream.of(SignalDatabase.groupReceipts().getGroupReceiptInfo(messageId)).anyMatch(info -> info.getStatus() > GroupReceiptDatabase.STATUS_UNDELIVERED);
        if (message.isGroup()) {
            OutgoingGroupUpdateMessage groupMessage = (OutgoingGroupUpdateMessage) message;
            if (groupMessage.isV2Group()) {
                MessageGroupContext.GroupV2Properties properties = groupMessage.requireGroupV2Properties();
                GroupContextV2 groupContext = properties.getGroupContext();
                SignalServiceGroupV2.Builder builder = SignalServiceGroupV2.newBuilder(properties.getGroupMasterKey()).withRevision(groupContext.getRevision());
                ByteString groupChange = groupContext.getGroupChange();
                if (groupChange != null) {
                    builder.withSignedGroupChange(groupChange.toByteArray());
                }
                SignalServiceGroupV2 group = builder.build();
                SignalServiceDataMessage groupDataMessage = SignalServiceDataMessage.newBuilder().withTimestamp(message.getSentTimeMillis()).withExpiration(groupRecipient.getExpiresInSeconds()).asGroupMessage(group).build();
                return GroupSendUtil.sendResendableDataMessage(context, groupRecipient.requireGroupId().requireV2(), destinations, isRecipientUpdate, ContentHint.IMPLICIT, new MessageId(messageId, true), groupDataMessage);
            } else {
                throw new UndeliverableMessageException("Messages can no longer be sent to V1 groups!");
            }
        } else {
            Optional<GroupDatabase.GroupRecord> groupRecord = SignalDatabase.groups().getGroup(groupRecipient.requireGroupId());
            if (groupRecord.isPresent() && groupRecord.get().isAnnouncementGroup() && !groupRecord.get().isAdmin(Recipient.self())) {
                throw new UndeliverableMessageException("Non-admins cannot send messages in announcement groups!");
            }
            SignalServiceDataMessage.Builder builder = SignalServiceDataMessage.newBuilder().withTimestamp(message.getSentTimeMillis());
            GroupUtil.setDataMessageGroupContext(context, builder, groupId);
            SignalServiceDataMessage groupMessage = builder.withAttachments(attachmentPointers).withBody(message.getBody()).withExpiration((int) (message.getExpiresIn() / 1000)).withViewOnce(message.isViewOnce()).asExpirationUpdate(message.isExpirationUpdate()).withProfileKey(profileKey.orNull()).withQuote(quote.orNull()).withSticker(sticker.orNull()).withSharedContacts(sharedContacts).withPreviews(previews).withMentions(mentions).build();
            Log.i(TAG, JobLogger.format(this, "Beginning message send."));
            return GroupSendUtil.sendResendableDataMessage(context, groupRecipient.getGroupId().transform(GroupId::requireV2).orNull(), destinations, isRecipientUpdate, ContentHint.RESENDABLE, new MessageId(messageId, true), groupMessage);
        }
    } catch (ServerRejectedException e) {
        throw new UndeliverableMessageException(e);
    }
}
Also used : ByteString(com.google.protobuf.ByteString) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) OutgoingGroupUpdateMessage(org.thoughtcrime.securesms.mms.OutgoingGroupUpdateMessage) GroupContextV2(org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContextV2) MessageGroupContext(org.thoughtcrime.securesms.mms.MessageGroupContext) UndeliverableMessageException(org.thoughtcrime.securesms.transport.UndeliverableMessageException) Preview(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage.Preview) ServerRejectedException(org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException) SignalServiceGroupV2(org.whispersystems.signalservice.api.messages.SignalServiceGroupV2) GroupId(org.thoughtcrime.securesms.groups.GroupId) Quote(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage.Quote) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SharedContact(org.whispersystems.signalservice.api.messages.shared.SharedContact) MessageId(org.thoughtcrime.securesms.database.model.MessageId)

Example 24 with GroupId

use of org.thoughtcrime.securesms.groups.GroupId in project Signal-Android by WhisperSystems.

the class MmsDownloadJob method storeRetrievedMms.

private void storeRetrievedMms(String contentLocation, long messageId, long threadId, RetrieveConf retrieved, int subscriptionId, @Nullable RecipientId notificationFrom) throws MmsException {
    MessageDatabase database = SignalDatabase.mms();
    Optional<GroupId> group = Optional.absent();
    Set<RecipientId> members = new HashSet<>();
    String body = null;
    List<Attachment> attachments = new LinkedList<>();
    List<Contact> sharedContacts = new LinkedList<>();
    RecipientId from = null;
    if (retrieved.getFrom() != null) {
        from = Recipient.external(context, Util.toIsoString(retrieved.getFrom().getTextString())).getId();
    } else if (notificationFrom != null) {
        from = notificationFrom;
    }
    if (retrieved.getTo() != null) {
        for (EncodedStringValue toValue : retrieved.getTo()) {
            members.add(Recipient.external(context, Util.toIsoString(toValue.getTextString())).getId());
        }
    }
    if (retrieved.getCc() != null) {
        for (EncodedStringValue ccValue : retrieved.getCc()) {
            members.add(Recipient.external(context, Util.toIsoString(ccValue.getTextString())).getId());
        }
    }
    if (from != null) {
        members.add(from);
    }
    members.add(Recipient.self().getId());
    if (retrieved.getBody() != null) {
        body = PartParser.getMessageText(retrieved.getBody());
        PduBody media = PartParser.getSupportedMediaParts(retrieved.getBody());
        for (int i = 0; i < media.getPartsNum(); i++) {
            PduPart part = media.getPart(i);
            if (part.getData() != null) {
                if (Util.toIsoString(part.getContentType()).toLowerCase().equals(MediaUtil.VCARD)) {
                    sharedContacts.addAll(VCardUtil.parseContacts(new String(part.getData())));
                } else {
                    Uri uri = BlobProvider.getInstance().forData(part.getData()).createForSingleUseInMemory();
                    String name = null;
                    if (part.getName() != null)
                        name = Util.toIsoString(part.getName());
                    attachments.add(new UriAttachment(uri, Util.toIsoString(part.getContentType()), AttachmentDatabase.TRANSFER_PROGRESS_DONE, part.getData().length, name, false, false, false, false, null, null, null, null, null));
                }
            }
        }
    }
    if (members.size() > 2) {
        List<RecipientId> recipients = new ArrayList<>(members);
        group = Optional.of(SignalDatabase.groups().getOrCreateMmsGroupForMembers(recipients));
    }
    IncomingMediaMessage message = new IncomingMediaMessage(from, group, body, TimeUnit.SECONDS.toMillis(retrieved.getDate()), -1, System.currentTimeMillis(), attachments, subscriptionId, 0, false, false, false, Optional.of(sharedContacts));
    Optional<InsertResult> insertResult = database.insertMessageInbox(message, contentLocation, threadId);
    if (insertResult.isPresent()) {
        database.deleteMessage(messageId);
        ApplicationDependencies.getMessageNotifier().updateNotification(context, insertResult.get().getThreadId());
    }
}
Also used : InsertResult(org.thoughtcrime.securesms.database.MessageDatabase.InsertResult) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) EncodedStringValue(com.google.android.mms.pdu_alt.EncodedStringValue) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) PduBody(com.google.android.mms.pdu_alt.PduBody) IncomingMediaMessage(org.thoughtcrime.securesms.mms.IncomingMediaMessage) ArrayList(java.util.ArrayList) UriAttachment(org.thoughtcrime.securesms.attachments.UriAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) Uri(android.net.Uri) LinkedList(java.util.LinkedList) GroupId(org.thoughtcrime.securesms.groups.GroupId) Contact(org.thoughtcrime.securesms.contactshare.Contact) PduPart(com.google.android.mms.pdu_alt.PduPart) UriAttachment(org.thoughtcrime.securesms.attachments.UriAttachment) HashSet(java.util.HashSet)

Example 25 with GroupId

use of org.thoughtcrime.securesms.groups.GroupId in project Signal-Android by WhisperSystems.

the class PushGroupSilentUpdateSendJob method onRun.

@Override
protected void onRun() throws Exception {
    if (!Recipient.self().isRegistered()) {
        throw new NotPushRegisteredException();
    }
    GroupId.V2 groupId = GroupId.v2(GroupUtil.requireMasterKey(groupContextV2.getMasterKey().toByteArray()));
    if (Recipient.externalGroupExact(context, groupId).isBlocked()) {
        Log.i(TAG, "Not updating group state for blocked group " + groupId);
        return;
    }
    List<Recipient> destinations = Stream.of(recipients).map(Recipient::resolved).toList();
    List<Recipient> completions = deliver(destinations, groupId);
    for (Recipient completion : completions) {
        recipients.remove(completion.getId());
    }
    Log.i(TAG, "Completed now: " + completions.size() + ", Remaining: " + recipients.size());
    if (!recipients.isEmpty()) {
        Log.w(TAG, "Still need to send to " + recipients.size() + " recipients. Retrying.");
        throw new RetryLaterException();
    }
}
Also used : NotPushRegisteredException(org.thoughtcrime.securesms.net.NotPushRegisteredException) Recipient(org.thoughtcrime.securesms.recipients.Recipient) RetryLaterException(org.thoughtcrime.securesms.transport.RetryLaterException) GroupId(org.thoughtcrime.securesms.groups.GroupId)

Aggregations

GroupId (org.thoughtcrime.securesms.groups.GroupId)41 Recipient (org.thoughtcrime.securesms.recipients.Recipient)26 NonNull (androidx.annotation.NonNull)22 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)13 Context (android.content.Context)12 List (java.util.List)11 Log (org.signal.core.util.logging.Log)11 GroupDatabase (org.thoughtcrime.securesms.database.GroupDatabase)11 Collections (java.util.Collections)10 SignalDatabase (org.thoughtcrime.securesms.database.SignalDatabase)10 ApplicationDependencies (org.thoughtcrime.securesms.dependencies.ApplicationDependencies)10 Optional (org.whispersystems.libsignal.util.guava.Optional)10 Nullable (androidx.annotation.Nullable)9 IOException (java.io.IOException)9 LinkedList (java.util.LinkedList)8 Collectors (java.util.stream.Collectors)8 SignalStore (org.thoughtcrime.securesms.keyvalue.SignalStore)8 SendMessageResult (org.whispersystems.signalservice.api.messages.SendMessageResult)8 Intent (android.content.Intent)7 Stream (com.annimon.stream.Stream)7