Search in sources :

Example 21 with Contact

use of org.thoughtcrime.securesms.contactshare.Contact in project Signal-Android by signalapp.

the class MmsDatabase method getOutgoingMessage.

@Override
public OutgoingMediaMessage getOutgoingMessage(long messageId) throws MmsException, NoSuchMessageException {
    AttachmentDatabase attachmentDatabase = SignalDatabase.attachments();
    MentionDatabase mentionDatabase = SignalDatabase.mentions();
    Cursor cursor = null;
    try {
        cursor = rawQuery(RAW_ID_WHERE, new String[] { String.valueOf(messageId) });
        if (cursor != null && cursor.moveToNext()) {
            List<DatabaseAttachment> associatedAttachments = attachmentDatabase.getAttachmentsForMessage(messageId);
            List<Mention> mentions = mentionDatabase.getMentionsForMessage(messageId);
            long outboxType = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_BOX));
            String body = cursor.getString(cursor.getColumnIndexOrThrow(BODY));
            long timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(NORMALIZED_DATE_SENT));
            int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(SUBSCRIPTION_ID));
            long expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(EXPIRES_IN));
            boolean viewOnce = cursor.getLong(cursor.getColumnIndexOrThrow(VIEW_ONCE)) == 1;
            long recipientId = cursor.getLong(cursor.getColumnIndexOrThrow(RECIPIENT_ID));
            long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID));
            int distributionType = SignalDatabase.threads().getDistributionType(threadId);
            String mismatchDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.MISMATCHED_IDENTITIES));
            String networkDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.NETWORK_FAILURE));
            long quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_ID));
            long quoteAuthor = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_AUTHOR));
            String quoteText = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_BODY));
            boolean quoteMissing = cursor.getInt(cursor.getColumnIndexOrThrow(QUOTE_MISSING)) == 1;
            List<Attachment> quoteAttachments = Stream.of(associatedAttachments).filter(Attachment::isQuote).map(a -> (Attachment) a).toList();
            List<Mention> quoteMentions = parseQuoteMentions(context, cursor);
            List<Contact> contacts = getSharedContacts(cursor, associatedAttachments);
            Set<Attachment> contactAttachments = new HashSet<>(Stream.of(contacts).map(Contact::getAvatarAttachment).filter(a -> a != null).toList());
            List<LinkPreview> previews = getLinkPreviews(cursor, associatedAttachments);
            Set<Attachment> previewAttachments = Stream.of(previews).filter(lp -> lp.getThumbnail().isPresent()).map(lp -> lp.getThumbnail().get()).collect(Collectors.toSet());
            List<Attachment> attachments = Stream.of(associatedAttachments).filterNot(Attachment::isQuote).filterNot(contactAttachments::contains).filterNot(previewAttachments::contains).sorted(new DatabaseAttachment.DisplayOrderComparator()).map(a -> (Attachment) a).toList();
            Recipient recipient = Recipient.resolved(RecipientId.from(recipientId));
            Set<NetworkFailure> networkFailures = new HashSet<>();
            Set<IdentityKeyMismatch> mismatches = new HashSet<>();
            QuoteModel quote = null;
            if (quoteId > 0 && quoteAuthor > 0 && (!TextUtils.isEmpty(quoteText) || !quoteAttachments.isEmpty())) {
                quote = new QuoteModel(quoteId, RecipientId.from(quoteAuthor), quoteText, quoteMissing, quoteAttachments, quoteMentions);
            }
            if (!TextUtils.isEmpty(mismatchDocument)) {
                try {
                    mismatches = JsonUtils.fromJson(mismatchDocument, IdentityKeyMismatchSet.class).getItems();
                } catch (IOException e) {
                    Log.w(TAG, e);
                }
            }
            if (!TextUtils.isEmpty(networkDocument)) {
                try {
                    networkFailures = JsonUtils.fromJson(networkDocument, NetworkFailureSet.class).getItems();
                } catch (IOException e) {
                    Log.w(TAG, e);
                }
            }
            if (body != null && (Types.isGroupQuit(outboxType) || Types.isGroupUpdate(outboxType))) {
                return new OutgoingGroupUpdateMessage(recipient, new MessageGroupContext(body, Types.isGroupV2(outboxType)), attachments, timestamp, 0, false, quote, contacts, previews, mentions);
            } else if (Types.isExpirationTimerUpdate(outboxType)) {
                return new OutgoingExpirationUpdateMessage(recipient, timestamp, expiresIn);
            }
            OutgoingMediaMessage message = new OutgoingMediaMessage(recipient, body, attachments, timestamp, subscriptionId, expiresIn, viewOnce, distributionType, quote, contacts, previews, mentions, networkFailures, mismatches);
            if (Types.isSecureType(outboxType)) {
                return new OutgoingSecureMediaMessage(message);
            }
            return message;
        }
        throw new NoSuchMessageException("No record found for id: " + messageId);
    } catch (IOException e) {
        throw new MmsException(e);
    } finally {
        if (cursor != null)
            cursor.close();
    }
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) SlideDeck(org.thoughtcrime.securesms.mms.SlideDeck) GroupMigrationMembershipChange(org.thoughtcrime.securesms.groups.GroupMigrationMembershipChange) LinkPreview(org.thoughtcrime.securesms.linkpreview.LinkPreview) NonNull(androidx.annotation.NonNull) Avatar(org.thoughtcrime.securesms.contactshare.Contact.Avatar) MessageGroupContext(org.thoughtcrime.securesms.mms.MessageGroupContext) Mention(org.thoughtcrime.securesms.database.model.Mention) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) SecureRandom(java.security.SecureRandom) JSONException(org.json.JSONException) JsonUtils(org.thoughtcrime.securesms.util.JsonUtils) JSONObject(org.json.JSONObject) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) BodyRangeList(org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList) SqlUtil(org.thoughtcrime.securesms.util.SqlUtil) IdentityKeyMismatchSet(org.thoughtcrime.securesms.database.documents.IdentityKeyMismatchSet) Map(java.util.Map) ViewOnceUtil(org.thoughtcrime.securesms.revealable.ViewOnceUtil) Recipient(org.thoughtcrime.securesms.recipients.Recipient) OutgoingTextMessage(org.thoughtcrime.securesms.sms.OutgoingTextMessage) OutgoingGroupUpdateMessage(org.thoughtcrime.securesms.mms.OutgoingGroupUpdateMessage) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) NotificationInd(com.google.android.mms.pdu_alt.NotificationInd) ACI(org.whispersystems.signalservice.api.push.ACI) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) Collection(java.util.Collection) OutgoingSecureMediaMessage(org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage) Set(java.util.Set) UUID(java.util.UUID) OutgoingExpirationUpdateMessage(org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage) Log(org.signal.core.util.logging.Log) NetworkFailureSet(org.thoughtcrime.securesms.database.documents.NetworkFailureSet) List(java.util.List) Nullable(androidx.annotation.Nullable) ContentValues(android.content.ContentValues) IncomingTextMessage(org.thoughtcrime.securesms.sms.IncomingTextMessage) Attachment(org.thoughtcrime.securesms.attachments.Attachment) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) MediaUtil(org.thoughtcrime.securesms.util.MediaUtil) Context(android.content.Context) Stream(com.annimon.stream.Stream) Util(org.thoughtcrime.securesms.util.Util) HashMap(java.util.HashMap) SQLiteStatement(net.zetetic.database.sqlcipher.SQLiteStatement) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) ArrayList(java.util.ArrayList) TextSecurePreferences(org.thoughtcrime.securesms.util.TextSecurePreferences) HashSet(java.util.HashSet) Pair(org.whispersystems.libsignal.util.Pair) MmsNotificationAttachment(org.thoughtcrime.securesms.attachments.MmsNotificationAttachment) NotificationMmsMessageRecord(org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord) QuoteModel(org.thoughtcrime.securesms.mms.QuoteModel) MediaMmsMessageRecord(org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord) LinkedList(java.util.LinkedList) PduHeaders(com.google.android.mms.pdu_alt.PduHeaders) Cursor(android.database.Cursor) MessageId(org.thoughtcrime.securesms.database.model.MessageId) Collectors(com.annimon.stream.Collectors) Contact(org.thoughtcrime.securesms.contactshare.Contact) IdentityKeyMismatch(org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch) MmsException(org.thoughtcrime.securesms.mms.MmsException) TextUtils(android.text.TextUtils) IOException(java.io.IOException) Quote(org.thoughtcrime.securesms.database.model.Quote) Optional(org.whispersystems.libsignal.util.guava.Optional) CursorUtil(org.thoughtcrime.securesms.util.CursorUtil) ViewOnceExpirationInfo(org.thoughtcrime.securesms.revealable.ViewOnceExpirationInfo) AttachmentId(org.thoughtcrime.securesms.attachments.AttachmentId) NetworkFailure(org.thoughtcrime.securesms.database.documents.NetworkFailure) TrimThreadJob(org.thoughtcrime.securesms.jobs.TrimThreadJob) SmsMessageRecord(org.thoughtcrime.securesms.database.model.SmsMessageRecord) Collections(java.util.Collections) JSONArray(org.json.JSONArray) IncomingMediaMessage(org.thoughtcrime.securesms.mms.IncomingMediaMessage) LinkPreview(org.thoughtcrime.securesms.linkpreview.LinkPreview) Attachment(org.thoughtcrime.securesms.attachments.Attachment) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) MmsNotificationAttachment(org.thoughtcrime.securesms.attachments.MmsNotificationAttachment) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) Cursor(android.database.Cursor) OutgoingGroupUpdateMessage(org.thoughtcrime.securesms.mms.OutgoingGroupUpdateMessage) MmsException(org.thoughtcrime.securesms.mms.MmsException) MessageGroupContext(org.thoughtcrime.securesms.mms.MessageGroupContext) Mention(org.thoughtcrime.securesms.database.model.Mention) HashSet(java.util.HashSet) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) Recipient(org.thoughtcrime.securesms.recipients.Recipient) NetworkFailure(org.thoughtcrime.securesms.database.documents.NetworkFailure) IdentityKeyMismatch(org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch) IOException(java.io.IOException) QuoteModel(org.thoughtcrime.securesms.mms.QuoteModel) Contact(org.thoughtcrime.securesms.contactshare.Contact) OutgoingSecureMediaMessage(org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage) OutgoingExpirationUpdateMessage(org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage)

Example 22 with Contact

use of org.thoughtcrime.securesms.contactshare.Contact in project Signal-Android by signalapp.

the class MmsDatabase method getSerializedSharedContacts.

@Nullable
private String getSerializedSharedContacts(@NonNull Map<Attachment, AttachmentId> insertedAttachmentIds, @NonNull List<Contact> contacts) {
    if (contacts.isEmpty())
        return null;
    JSONArray sharedContactJson = new JSONArray();
    for (Contact contact : contacts) {
        try {
            AttachmentId attachmentId = null;
            if (contact.getAvatarAttachment() != null) {
                attachmentId = insertedAttachmentIds.get(contact.getAvatarAttachment());
            }
            Avatar updatedAvatar = new Avatar(attachmentId, contact.getAvatarAttachment(), contact.getAvatar() != null && contact.getAvatar().isProfile());
            Contact updatedContact = new Contact(contact, updatedAvatar);
            sharedContactJson.put(new JSONObject(updatedContact.serialize()));
        } catch (JSONException | IOException e) {
            Log.w(TAG, "Failed to serialize shared contact. Skipping it.", e);
        }
    }
    return sharedContactJson.toString();
}
Also used : JSONObject(org.json.JSONObject) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) IOException(java.io.IOException) AttachmentId(org.thoughtcrime.securesms.attachments.AttachmentId) Avatar(org.thoughtcrime.securesms.contactshare.Contact.Avatar) Contact(org.thoughtcrime.securesms.contactshare.Contact) Nullable(androidx.annotation.Nullable)

Example 23 with Contact

use of org.thoughtcrime.securesms.contactshare.Contact in project Signal-Android by signalapp.

the class PushSendJob method getSharedContactsFor.

List<SharedContact> getSharedContactsFor(OutgoingMediaMessage mediaMessage) {
    List<SharedContact> sharedContacts = new LinkedList<>();
    for (Contact contact : mediaMessage.getSharedContacts()) {
        SharedContact.Builder builder = ContactModelMapper.localToRemoteBuilder(contact);
        SharedContact.Avatar avatar = null;
        if (contact.getAvatar() != null && contact.getAvatar().getAttachment() != null) {
            avatar = SharedContact.Avatar.newBuilder().withAttachment(getAttachmentFor(contact.getAvatarAttachment())).withProfileFlag(contact.getAvatar().isProfile()).build();
        }
        builder.setAvatar(avatar);
        sharedContacts.add(builder.build());
    }
    return sharedContacts;
}
Also used : SharedContact(org.whispersystems.signalservice.api.messages.shared.SharedContact) LinkedList(java.util.LinkedList) SharedContact(org.whispersystems.signalservice.api.messages.shared.SharedContact) Contact(org.thoughtcrime.securesms.contactshare.Contact)

Example 24 with Contact

use of org.thoughtcrime.securesms.contactshare.Contact in project Signal-Android by signalapp.

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)

Aggregations

Contact (org.thoughtcrime.securesms.contactshare.Contact)24 NonNull (androidx.annotation.NonNull)14 LinkedList (java.util.LinkedList)14 Attachment (org.thoughtcrime.securesms.attachments.Attachment)14 Nullable (androidx.annotation.Nullable)12 List (java.util.List)12 AttachmentId (org.thoughtcrime.securesms.attachments.AttachmentId)12 DatabaseAttachment (org.thoughtcrime.securesms.attachments.DatabaseAttachment)12 Context (android.content.Context)10 Stream (com.annimon.stream.Stream)10 IOException (java.io.IOException)10 ArrayList (java.util.ArrayList)10 HashMap (java.util.HashMap)10 Log (org.signal.core.util.logging.Log)10 Recipient (org.thoughtcrime.securesms.recipients.Recipient)10 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)10 Collections (java.util.Collections)8 Map (java.util.Map)8 LinkPreview (org.thoughtcrime.securesms.linkpreview.LinkPreview)8 Collection (java.util.Collection)6