org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptMessage Java Examples

The following examples show how to use org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptMessage. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
private long handleSynchronizeSentEndSessionMessage(@NonNull SentTranscriptMessage message)
    throws BadGroupIdException
{
  SmsDatabase               database                  = DatabaseFactory.getSmsDatabase(context);
  Recipient                 recipient                 = getSyncMessageDestination(message);
  OutgoingTextMessage       outgoingTextMessage       = new OutgoingTextMessage(recipient, "", -1);
  OutgoingEndSessionMessage outgoingEndSessionMessage = new OutgoingEndSessionMessage(outgoingTextMessage);

  long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient);

  if (!recipient.isGroup()) {
    SessionStore sessionStore = new TextSecureSessionStore(context);
    sessionStore.deleteAllSessions(recipient.requireServiceId());

    SecurityEvent.broadcastSecurityUpdateEvent(context);

    long messageId = database.insertMessageOutbox(threadId, outgoingEndSessionMessage,
                                                  false, message.getTimestamp(),
                                                  null);
    database.markAsSent(messageId, true);
  }

  return threadId;
}
 
Example #2
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
private long handleSynchronizeSentExpirationUpdate(@NonNull SentTranscriptMessage message)
    throws MmsException, BadGroupIdException
{
  MmsDatabase database   = DatabaseFactory.getMmsDatabase(context);
  Recipient   recipient  = getSyncMessageDestination(message);

  OutgoingExpirationUpdateMessage expirationUpdateMessage = new OutgoingExpirationUpdateMessage(recipient,
                                                                                                message.getTimestamp(),
                                                                                                message.getMessage().getExpiresInSeconds() * 1000L);

  long threadId  = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient);
  long messageId = database.insertMessageOutbox(expirationUpdateMessage, threadId, false, null);

  database.markAsSent(messageId, true);

  DatabaseFactory.getRecipientDatabase(context).setExpireMessages(recipient.getId(), message.getMessage().getExpiresInSeconds());

  return threadId;
}
 
Example #3
Source File: Manager.java    From signal-cli with GNU General Public License v3.0 6 votes vote down vote up
private SendMessageResult sendSelfMessage(SignalServiceDataMessage message) throws IOException {
    SignalServiceMessageSender messageSender = getMessageSender();

    SignalServiceAddress recipient = account.getSelfAddress();

    final Optional<UnidentifiedAccessPair> unidentifiedAccess = getAccessFor(recipient);
    SentTranscriptMessage transcript = new SentTranscriptMessage(Optional.of(recipient),
            message.getTimestamp(),
            message,
            message.getExpiresInSeconds(),
            Collections.singletonMap(recipient, unidentifiedAccess.isPresent()),
            false);
    SignalServiceSyncMessage syncMessage = SignalServiceSyncMessage.forSentTranscript(transcript);

    try {
        messageSender.sendMessage(syncMessage, unidentifiedAccess);
        return SendMessageResult.success(recipient, unidentifiedAccess.isPresent(), false);
    } catch (UntrustedIdentityException e) {
        account.getSignalProtocolStore().saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), e.getIdentityKey(), TrustLevel.UNTRUSTED);
        return SendMessageResult.identityFailure(recipient, e.getIdentityKey());
    }
}
 
Example #4
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
private void handleGroupRecipientUpdate(@NonNull SentTranscriptMessage message)
    throws BadGroupIdException
{
  Recipient recipient = getSyncMessageDestination(message);

  if (!recipient.isGroup()) {
    Log.w(TAG, "Got recipient update for a non-group message! Skipping.");
    return;
  }

  MmsSmsDatabase database = DatabaseFactory.getMmsSmsDatabase(context);
  MessageRecord  record   = database.getMessageFor(message.getTimestamp(), Recipient.self().getId());

  if (record == null) {
    Log.w(TAG, "Got recipient update for non-existing message! Skipping.");
    return;
  }

  if (!record.isMms()) {
    Log.w(TAG, "Recipient update matched a non-MMS message! Skipping.");
    return;
  }

  updateGroupReceiptStatus(message, record.getId(), recipient.requireGroupId());
}
 
Example #5
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
private void updateGroupReceiptStatus(@NonNull SentTranscriptMessage message, long messageId, @NonNull GroupId groupString) {
  GroupReceiptDatabase      receiptDatabase   = DatabaseFactory.getGroupReceiptDatabase(context);
  List<Recipient>           messageRecipients = Stream.of(message.getRecipients()).map(address -> Recipient.externalPush(context, address)).toList();
  List<Recipient>           members           = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupString, GroupDatabase.MemberSet.FULL_MEMBERS_EXCLUDING_SELF);
  Map<RecipientId, Integer> localReceipts     = Stream.of(receiptDatabase.getGroupReceiptInfo(messageId))
                                                      .collect(Collectors.toMap(GroupReceiptInfo::getRecipientId, GroupReceiptInfo::getStatus));

  for (Recipient messageRecipient : messageRecipients) {
    //noinspection ConstantConditions
    if (localReceipts.containsKey(messageRecipient.getId()) && localReceipts.get(messageRecipient.getId()) < GroupReceiptDatabase.STATUS_UNDELIVERED) {
      receiptDatabase.update(messageRecipient.getId(), messageId, GroupReceiptDatabase.STATUS_UNDELIVERED, message.getTimestamp());
    } else if (!localReceipts.containsKey(messageRecipient.getId())) {
      receiptDatabase.insert(Collections.singletonList(messageRecipient.getId()), messageId, GroupReceiptDatabase.STATUS_UNDELIVERED, message.getTimestamp());
    }
  }

  List<org.whispersystems.libsignal.util.Pair<RecipientId, Boolean>> unidentifiedStatus = Stream.of(members)
                                                                                                .map(m -> new org.whispersystems.libsignal.util.Pair<>(m.getId(), message.isUnidentified(m.requireServiceId())))
                                                                                                .toList();
  receiptDatabase.setUnidentified(unidentifiedStatus, messageId);
}
 
Example #6
Source File: PushDecryptJob.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
private long handleSynchronizeSentEndSessionMessage(@NonNull SentTranscriptMessage message) {
    ALog.i(TAG, "handleSynchronizeSentEndSessionMessage");
    PrivateChatRepo chatRepo = repository.getChatRepo();
    Recipient recipient = getSyncMessageDestination(message);
    OutgoingTextMessage outgoingTextMessage = new OutgoingTextMessage(recipient, "", -1);
    OutgoingEndSessionMessage outgoingEndSessionMessage = new OutgoingEndSessionMessage(outgoingTextMessage);

    long threadId = repository.getThreadRepo().getThreadIdFor(recipient);

    if (!recipient.isGroupRecipient()) {
        SessionStore sessionStore = new TextSecureSessionStore(context, accountContext);
        sessionStore.deleteAllSessions(recipient.getAddress().serialize());

        SecurityEvent.broadcastSecurityUpdateEvent(context);

        chatRepo.insertOutgoingTextMessage(threadId, outgoingEndSessionMessage, message.getTimestamp(), null);
        chatRepo.setMessageSendSuccess(messageId);
    }

    return threadId;
}
 
Example #7
Source File: PushDecryptJob.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
private long handleSynchronizeSentExpirationUpdate(@NonNull MasterSecretUnion masterSecret,
                                                   @NonNull SentTranscriptMessage message) {
    ALog.i(TAG, "handleSynchronizeSentExpirationUpdate");

    PrivateChatRepo chatRepo = repository.getChatRepo();
    Recipient recipient = getSyncMessageDestination(message);

    OutgoingExpirationUpdateMessage expirationUpdateMessage = new OutgoingExpirationUpdateMessage(recipient,
            message.getTimestamp(),
            message.getMessage().getExpiresInSeconds() * 1000);

    long threadId = repository.getThreadRepo().getThreadIdFor(recipient);
    long messageId = chatRepo.insertOutgoingMediaMessage(threadId, masterSecret.getMasterSecret().get(), expirationUpdateMessage, null);

    chatRepo.setMessageSendSuccess(messageId);

    RecipientRepo recipientRepo = Repository.getRecipientRepo(accountContext);
    if (recipientRepo != null) {
        recipientRepo.setExpireTime(recipient, message.getMessage().getExpiresInSeconds());
    }
    return threadId;
}
 
Example #8
Source File: PushSendJob.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
protected SignalServiceSyncMessage buildSelfSendSyncMessage(@NonNull Context context, @NonNull SignalServiceDataMessage message, Optional<UnidentifiedAccessPair> syncAccess) {
  SignalServiceAddress  localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalUuid(context), TextSecurePreferences.getLocalNumber(context));
  SentTranscriptMessage transcript   = new SentTranscriptMessage(Optional.of(localAddress),
                                                                 message.getTimestamp(),
                                                                 message,
                                                                 message.getExpiresInSeconds(),
                                                                 Collections.singletonMap(localAddress, syncAccess.isPresent()),
                                                                 false);
  return SignalServiceSyncMessage.forSentTranscript(transcript);
}
 
Example #9
Source File: SignalServiceMessageSender.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
private byte[] createMultiDeviceSentTranscriptContent(SentTranscriptMessage transcript, Optional<UnidentifiedAccessPair> unidentifiedAccess) throws IOException {
  SignalServiceAddress address = transcript.getDestination().get();
  SendMessageResult    result  = SendMessageResult.success(address, unidentifiedAccess.isPresent(), true);

  return createMultiDeviceSentTranscriptContent(createMessageContent(transcript.getMessage()),
                                                Optional.of(address),
                                                transcript.getTimestamp(),
                                                Collections.singletonList(result),
                                                false);
}
 
Example #10
Source File: SignalServiceMessageSender.java    From libsignal-service-java with GNU General Public License v3.0 5 votes vote down vote up
private byte[] createMultiDeviceSentTranscriptContent(SentTranscriptMessage transcript, Optional<UnidentifiedAccessPair> unidentifiedAccess) throws IOException {
  SignalServiceAddress address = transcript.getDestination().get();
  SendMessageResult    result  = SendMessageResult.success(address, unidentifiedAccess.isPresent(), true);

  return createMultiDeviceSentTranscriptContent(createMessageContent(transcript.getMessage()),
                                                Optional.of(address),
                                                transcript.getTimestamp(),
                                                Collections.singletonList(result),
                                                false);
}
 
Example #11
Source File: JsonSentTranscriptMessage.java    From signald with GNU General Public License v3.0 5 votes vote down vote up
JsonSentTranscriptMessage(SentTranscriptMessage s, String username) throws IOException, NoSuchAccountException {
    if(s.getDestination().isPresent()) {
        destination = s.getDestination().get();
    }

    timestamp = s.getTimestamp();
    expirationStartTimestamp = s.getExpirationStartTimestamp();
    message = new JsonDataMessage(s.getMessage(), username);
    for(String r : s.getRecipients()) {
        unidentifiedStatus.put(r, s.isUnidentified(r));
    }
    isRecipientUpdate = s.isRecipientUpdate(); 
}
 
Example #12
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
private static boolean isUnidentified(@NonNull SentTranscriptMessage message, @NonNull Recipient recipient) {
  boolean unidentified = false;

  if (recipient.hasE164()) {
    unidentified |= message.isUnidentified(recipient.requireE164());
  }
  if (recipient.hasUuid()) {
    unidentified |= message.isUnidentified(recipient.requireUuid());
  }

  return unidentified;
}
 
Example #13
Source File: PushDecryptJob.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
private @NonNull Recipient getSyncMessageDestination(SentTranscriptMessage message) {
    if (message.getMessage().getGroupInfo().isPresent()) {
        return Recipient.from(Address.from(accountContext, GroupUtil.getEncodedId(message.getMessage().getGroupInfo().get().getGroupId(), false)), false);
    } else {
        return Recipient.from(Address.from(accountContext, message.getDestination().get()), false);
    }
}
 
Example #14
Source File: PushDecryptJob.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
private void handleSynchronizeSentMessage(@NonNull MasterSecretUnion masterSecret,
                                          @NonNull SignalServiceProtos.Envelope envelope,
                                          @NonNull SentTranscriptMessage message) {
    ALog.i(TAG, "handleSynchronizeSentMessage");
    long threadId;

    if (message.getMessage().isEndSession()) {
        threadId = handleSynchronizeSentEndSessionMessage(message);
    } else if (message.getMessage().isGroupUpdate()) {
        threadId = -1L;
    } else if (message.getMessage().isExpirationUpdate()) {
        threadId = handleSynchronizeSentExpirationUpdate(masterSecret, message);
    } else if (message.getMessage().getAttachments().isPresent()) {
        threadId = handleSynchronizeSentMediaMessage(masterSecret, message);
    } else {
        threadId = handleSynchronizeSentTextMessage(masterSecret, message);
    }

    if (message.getMessage().getProfileKey().isPresent()) {
        Recipient recipient = null;

        if (message.getDestination().isPresent()) {
            recipient = Recipient.from(Address.from(accountContext, message.getDestination().get()), false);
        } else if (message.getMessage().getGroupInfo().isPresent()) {
            recipient = Recipient.from(Address.from(accountContext, GroupUtil.getEncodedId(message.getMessage().getGroupInfo().get().getGroupId(), false)), false);
        }


        if (recipient != null && !recipient.isProfileSharing()) {
            repository.getRecipientRepo().setProfileSharing(recipient, true);
        }
    }

    if (threadId > 0L) {
        repository.getThreadRepo().setRead(threadId, true);
    }
}
 
Example #15
Source File: JsonSyncDataMessage.java    From signal-cli with GNU General Public License v3.0 4 votes vote down vote up
JsonSyncDataMessage(SentTranscriptMessage transcriptMessage) {
    super(transcriptMessage.getMessage());
    if (transcriptMessage.getDestination().isPresent()) {
        this.destination = transcriptMessage.getDestination().get().getNumber().get();
    }
}
 
Example #16
Source File: PushDecryptJob.java    From bcm-android with GNU General Public License v3.0 4 votes vote down vote up
private long handleSynchronizeSentTextMessage(@NonNull MasterSecretUnion masterSecret,
                                              @NonNull SentTranscriptMessage message) {

    ALog.i(TAG, "handleSynchronizeSentTextMessage");

    Recipient recipient = getSyncMessageDestination(message);
    String body = message.getMessage().getBody().or("");
    long expiresInMillis = message.getMessage().getExpiresInSeconds() * 1000;

    if (recipient.getExpireMessages() != message.getMessage().getExpiresInSeconds()) {
        handleSynchronizeSentExpirationUpdate(masterSecret, message);
    }

    long threadId = repository.getThreadRepo().getThreadIdFor(recipient);

    PrivateChatRepo chatRepo = repository.getChatRepo();
    long messageId;

    if (recipient.getAddress().isGroup()) {
        OutgoingMediaMessage outgoingMediaMessage = new OutgoingMediaMessage(recipient, new SlideDeck(), body, message.getTimestamp(), -1, expiresInMillis, ThreadRepo.DistributionTypes.DEFAULT);
        outgoingMediaMessage = new OutgoingSecureMediaMessage(outgoingMediaMessage);

        messageId = chatRepo.insertOutgoingMediaMessage(threadId, masterSecret.getMasterSecret().get(), outgoingMediaMessage, null);
    } else {
        OutgoingTextMessage outgoingTextMessage = new OutgoingEncryptedMessage(recipient, body, expiresInMillis);

        messageId = chatRepo.insertOutgoingTextMessage(threadId, outgoingTextMessage, message.getTimestamp(), null);
    }

    chatRepo.setMessageSendSuccess(messageId);

    if (expiresInMillis > 0) {
        chatRepo.setMessageExpiresStart(messageId);
        chatRepo.setMessageExpiresStart(messageId);

        IExpiringScheduler manager = ExpirationManager.INSTANCE.get(accountContext);
        manager.scheduleDeletion(messageId, false, message.getExpirationStartTimestamp(), expiresInMillis);
    }

    return threadId;
}
 
Example #17
Source File: PushDecryptJob.java    From bcm-android with GNU General Public License v3.0 4 votes vote down vote up
private long handleSynchronizeSentMediaMessage(@NonNull MasterSecretUnion masterSecret,
                                               @NonNull SentTranscriptMessage message) {
    ALog.i(TAG, "handleSynchronizeSentMediaMessage");

    PrivateChatRepo chatRepo = repository.getChatRepo();
    Recipient recipients = getSyncMessageDestination(message);
    OutgoingMediaMessage mediaMessage = new OutgoingMediaMessage(recipients, message.getMessage().getBody().orNull(),
            PointerAttachment.forPointers(masterSecret, message.getMessage().getAttachments()),
            message.getTimestamp(), -1,
            message.getMessage().getExpiresInSeconds() * 1000,
            ThreadRepo.DistributionTypes.DEFAULT);

    mediaMessage = new OutgoingSecureMediaMessage(mediaMessage);

    if (recipients.getExpireMessages() != message.getMessage().getExpiresInSeconds()) {
        handleSynchronizeSentExpirationUpdate(masterSecret, message);
    }

    long threadId = repository.getThreadRepo().getThreadIdFor(recipients);
    long messageId = chatRepo.insertOutgoingMediaMessage(threadId, masterSecret.getMasterSecret().get(), mediaMessage, null);

    chatRepo.setMessageSendSuccess(messageId);

    for (AttachmentRecord attachment : repository.getAttachmentRepo().getAttachments(messageId)) {
        JobManager jobManager = AmeModuleCenter.INSTANCE.accountJobMgr(accountContext);
        if (jobManager != null) {
            jobManager.add(new AttachmentDownloadJob(context, accountContext, messageId, attachment.getId(), attachment.getUniqueId(), false));
        }
    }

    if (message.getMessage().getExpiresInSeconds() > 0) {
        chatRepo.setMessageExpiresStart(messageId);

        IExpiringScheduler manager = ExpirationManager.INSTANCE.get(accountContext);
        manager.scheduleDeletion(messageId, true,
                message.getExpirationStartTimestamp(),
                message.getMessage().getExpiresInSeconds() * 1000);

    }

    return threadId;
}
 
Example #18
Source File: SignalServiceCipher.java    From bcm-android with GNU General Public License v3.0 4 votes vote down vote up
private SignalServiceSyncMessage createSynchronizeMessage(SignalServiceProtos.Envelope envelope, SyncMessage content) throws InvalidMessageException {
  if (content.hasSent()) {
    SyncMessage.Sent sentContent = content.getSent();
    return SignalServiceSyncMessage.forSentTranscript(new SentTranscriptMessage(sentContent.getDestination(),
                                                                                sentContent.getTimestamp(),
                                                                                createSignalServiceMessage(envelope, sentContent.getMessage()),
                                                                                sentContent.getExpirationStartTimestamp()));
  }

  if (content.hasRequest()) {
    return SignalServiceSyncMessage.forRequest(new RequestMessage(content.getRequest()));
  }

  if (content.getReadList().size() > 0) {
    List<ReadMessage> readMessages = new LinkedList<>();

    for (SyncMessage.Read read : content.getReadList()) {
      readMessages.add(new ReadMessage(read.getSender(), read.getTimestamp()));
    }

    return SignalServiceSyncMessage.forRead(readMessages);
  }

  if (content.hasVerified()) {
    try {
      Verified    verified    = content.getVerified();
      String      destination = verified.getDestination();
      IdentityKey identityKey = new IdentityKey(verified.getIdentityKey().toByteArray(), 0);

      VerifiedState verifiedState;

      if (verified.getState() == Verified.State.DEFAULT) {
        verifiedState = VerifiedState.DEFAULT;
      } else if (verified.getState() == Verified.State.VERIFIED) {
        verifiedState = VerifiedState.VERIFIED;
      } else if (verified.getState() == Verified.State.UNVERIFIED) {
        verifiedState = VerifiedState.UNVERIFIED;
      } else {
        throw new InvalidMessageException("Unknown state: " + verified.getState().getNumber());
      }

      return SignalServiceSyncMessage.forVerified(new VerifiedMessage(destination, identityKey, verifiedState, System.currentTimeMillis()));
    } catch (InvalidKeyException e) {
      throw new InvalidMessageException(e);
    }
  }

  return SignalServiceSyncMessage.empty();
}
 
Example #19
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 4 votes vote down vote up
private Recipient getSyncMessageDestination(@NonNull SentTranscriptMessage message)
    throws BadGroupIdException
{
  return getGroupRecipient(message.getMessage().getGroupContext()).or(() -> Recipient.externalPush(context, message.getDestination().get()));
}
 
Example #20
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 4 votes vote down vote up
private long handleSynchronizeSentTextMessage(@NonNull SentTranscriptMessage message)
    throws MmsException, BadGroupIdException
{
  Recipient recipient       = getSyncMessageDestination(message);
  String    body            = message.getMessage().getBody().or("");
  long      expiresInMillis = message.getMessage().getExpiresInSeconds() * 1000L;

  if (recipient.getExpireMessages() != message.getMessage().getExpiresInSeconds()) {
    handleSynchronizeSentExpirationUpdate(message);
  }

  long    threadId  = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient);
  boolean isGroup   = recipient.isGroup();

  MessagingDatabase database;
  long              messageId;

  if (isGroup) {
    OutgoingMediaMessage outgoingMediaMessage = new OutgoingMediaMessage(recipient, new SlideDeck(), body, message.getTimestamp(), -1, expiresInMillis, false, ThreadDatabase.DistributionTypes.DEFAULT, null, Collections.emptyList(), Collections.emptyList());
    outgoingMediaMessage = new OutgoingSecureMediaMessage(outgoingMediaMessage);

    messageId = DatabaseFactory.getMmsDatabase(context).insertMessageOutbox(outgoingMediaMessage, threadId, false, GroupReceiptDatabase.STATUS_UNKNOWN, null);
    database  = DatabaseFactory.getMmsDatabase(context);

    updateGroupReceiptStatus(message, messageId, recipient.requireGroupId());
  } else {
    OutgoingTextMessage outgoingTextMessage = new OutgoingEncryptedMessage(recipient, body, expiresInMillis);

    messageId = DatabaseFactory.getSmsDatabase(context).insertMessageOutbox(threadId, outgoingTextMessage, false, message.getTimestamp(), null);
    database  = DatabaseFactory.getSmsDatabase(context);
    database.markUnidentified(messageId, isUnidentified(message, recipient));
  }

  database.markAsSent(messageId, true);

  if (expiresInMillis > 0) {
    database.markExpireStarted(messageId, message.getExpirationStartTimestamp());
    ApplicationContext.getInstance(context)
                      .getExpiringMessageManager()
                      .scheduleDeletion(messageId, isGroup, message.getExpirationStartTimestamp(), expiresInMillis);
  }

  if (recipient.isLocalNumber()) {
    SyncMessageId id = new SyncMessageId(recipient.getId(), message.getTimestamp());
    DatabaseFactory.getMmsSmsDatabase(context).incrementDeliveryReceiptCount(id, System.currentTimeMillis());
    DatabaseFactory.getMmsSmsDatabase(context).incrementReadReceiptCount(id, System.currentTimeMillis());
  }

  return threadId;
}
 
Example #21
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 4 votes vote down vote up
private long handleSynchronizeSentMediaMessage(@NonNull SentTranscriptMessage message)
    throws MmsException, BadGroupIdException
{
  MmsDatabase                 database        = DatabaseFactory.getMmsDatabase(context);
  Recipient                   recipients      = getSyncMessageDestination(message);
  Optional<QuoteModel>        quote           = getValidatedQuote(message.getMessage().getQuote());
  Optional<Attachment>        sticker         = getStickerAttachment(message.getMessage().getSticker());
  Optional<List<Contact>>     sharedContacts  = getContacts(message.getMessage().getSharedContacts());
  Optional<List<LinkPreview>> previews        = getLinkPreviews(message.getMessage().getPreviews(), message.getMessage().getBody().or(""));
  boolean                     viewOnce        = message.getMessage().isViewOnce();
  List<Attachment>            syncAttachments = viewOnce ? Collections.singletonList(new TombstoneAttachment(MediaUtil.VIEW_ONCE, false))
                                                         : PointerAttachment.forPointers(message.getMessage().getAttachments());

  if (sticker.isPresent()) {
    syncAttachments.add(sticker.get());
  }

  OutgoingMediaMessage mediaMessage = new OutgoingMediaMessage(recipients, message.getMessage().getBody().orNull(),
                                                               syncAttachments,
                                                               message.getTimestamp(), -1,
                                                               message.getMessage().getExpiresInSeconds() * 1000,
                                                               viewOnce,
                                                               ThreadDatabase.DistributionTypes.DEFAULT, quote.orNull(),
                                                               sharedContacts.or(Collections.emptyList()),
                                                               previews.or(Collections.emptyList()),
                                                               Collections.emptyList(), Collections.emptyList());

  mediaMessage = new OutgoingSecureMediaMessage(mediaMessage);

  if (recipients.getExpireMessages() != message.getMessage().getExpiresInSeconds()) {
    handleSynchronizeSentExpirationUpdate(message);
  }

  long threadId  = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipients);

  database.beginTransaction();

  try {
    long messageId = database.insertMessageOutbox(mediaMessage, threadId, false, GroupReceiptDatabase.STATUS_UNKNOWN, null);

    if (recipients.isGroup()) {
      updateGroupReceiptStatus(message, messageId, recipients.requireGroupId());
    } else {
      database.markUnidentified(messageId, isUnidentified(message, recipients));
    }

    database.markAsSent(messageId, true);

    List<DatabaseAttachment> allAttachments     = DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(messageId);
    List<DatabaseAttachment> stickerAttachments = Stream.of(allAttachments).filter(Attachment::isSticker).toList();
    List<DatabaseAttachment> attachments        = Stream.of(allAttachments).filterNot(Attachment::isSticker).toList();

    forceStickerDownloadIfNecessary(stickerAttachments);

    for (DatabaseAttachment attachment : attachments) {
      ApplicationDependencies.getJobManager().add(new AttachmentDownloadJob(messageId, attachment.getAttachmentId(), false));
    }

    if (message.getMessage().getExpiresInSeconds() > 0) {
      database.markExpireStarted(messageId, message.getExpirationStartTimestamp());
      ApplicationContext.getInstance(context)
                        .getExpiringMessageManager()
                        .scheduleDeletion(messageId, true,
                                          message.getExpirationStartTimestamp(),
                                          message.getMessage().getExpiresInSeconds() * 1000L);
    }

    if (recipients.isLocalNumber()) {
      SyncMessageId id = new SyncMessageId(recipients.getId(), message.getTimestamp());
      DatabaseFactory.getMmsSmsDatabase(context).incrementDeliveryReceiptCount(id, System.currentTimeMillis());
      DatabaseFactory.getMmsSmsDatabase(context).incrementReadReceiptCount(id, System.currentTimeMillis());
    }

    database.setTransactionSuccessful();
  } finally {
    database.endTransaction();
  }
  return threadId;
}
 
Example #22
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 4 votes vote down vote up
private void handleSynchronizeSentMessage(@NonNull SignalServiceContent content,
                                          @NonNull SentTranscriptMessage message)
    throws StorageFailedException, BadGroupIdException, VerificationFailedException, IOException, InvalidGroupStateException
{
  try {
    GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);

    Long threadId = null;

    if (message.isRecipientUpdate()) {
      handleGroupRecipientUpdate(message);
    } else if (message.getMessage().isEndSession()) {
      threadId = handleSynchronizeSentEndSessionMessage(message);
    } else if (message.getMessage().isGroupV1Update()) {
      threadId = GroupV1MessageProcessor.process(context, content, message.getMessage(), true);
    } else if (message.getMessage().isExpirationUpdate()) {
      threadId = handleSynchronizeSentExpirationUpdate(message);
    } else if (message.getMessage().getReaction().isPresent()) {
      handleReaction(content, message.getMessage());
      threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(getSyncMessageDestination(message));
      threadId = threadId != -1 ? threadId : null;
    } else if (message.getMessage().getRemoteDelete().isPresent()) {
      handleRemoteDelete(content, message.getMessage());
    } else if (message.getMessage().getAttachments().isPresent() || message.getMessage().getQuote().isPresent() || message.getMessage().getPreviews().isPresent() || message.getMessage().getSticker().isPresent() || message.getMessage().isViewOnce()) {
      threadId = handleSynchronizeSentMediaMessage(message);
    } else {
      threadId = handleSynchronizeSentTextMessage(message);
    }

    if (message.getMessage().getGroupContext().isPresent() && groupDatabase.isUnknownGroup(GroupUtil.idFromGroupContext(message.getMessage().getGroupContext().get()))) {        handleUnknownGroupMessage(content, message.getMessage().getGroupContext().get());
    }

    if (message.getMessage().getProfileKey().isPresent()) {
      Recipient recipient = getSyncMessageDestination(message);

      if (recipient != null && !recipient.isSystemContact() && !recipient.isProfileSharing()) {
        DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient.getId(), true);
      }
    }

    if (threadId != null) {
      DatabaseFactory.getThreadDatabase(context).setRead(threadId, true);
      ApplicationDependencies.getMessageNotifier().updateNotification(context);
    }

    ApplicationDependencies.getMessageNotifier().setLastDesktopActivityTimestamp(message.getTimestamp());
  } catch (MmsException e) {
    throw new StorageFailedException(e, content.getSender().getIdentifier(), content.getSenderDevice());
  }
}