org.whispersystems.signalservice.api.messages.SignalServiceContent Java Examples

The following examples show how to use org.whispersystems.signalservice.api.messages.SignalServiceContent. 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 PushProcessMessageJob(@NonNull Parameters parameters,
                              @NonNull MessageState messageState,
                              @Nullable SignalServiceContent content,
                              @Nullable ExceptionMetadata exceptionMetadata,
                              long pushMessageId,
                              long smsMessageId,
                              long timestamp)
{
  super(parameters);

  this.messageState      = messageState;
  this.exceptionMetadata = exceptionMetadata;
  this.content           = content;
  this.messageId         = pushMessageId;
  this.smsMessageId      = smsMessageId;
  this.timestamp         = timestamp;
}
 
Example #2
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
private void handleReaction(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message) {
  SignalServiceDataMessage.Reaction reaction = message.getReaction().get();

  Recipient     targetAuthor  = Recipient.externalPush(context, reaction.getTargetAuthor());
  MessageRecord targetMessage = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(reaction.getTargetSentTimestamp(), targetAuthor.getId());

  if (targetMessage != null && !targetMessage.isRemoteDelete()) {
    Recipient         reactionAuthor = Recipient.externalPush(context, content.getSender());
    MessagingDatabase db             = targetMessage.isMms() ? DatabaseFactory.getMmsDatabase(context) : DatabaseFactory.getSmsDatabase(context);

    if (reaction.isRemove()) {
      db.deleteReaction(targetMessage.getId(), reactionAuthor.getId());
      ApplicationDependencies.getMessageNotifier().updateNotification(context);
    } else {
      ReactionRecord reactionRecord = new ReactionRecord(reaction.getEmoji(), reactionAuthor.getId(), message.getTimestamp(), System.currentTimeMillis());
      db.addReaction(targetMessage.getId(), reactionRecord);
      ApplicationDependencies.getMessageNotifier().updateNotification(context, targetMessage.getThreadId(), false);
    }
  } else if (targetMessage != null) {
    Log.w(TAG, "[handleReaction] Found a matching message, but it's flagged as remotely deleted. timestamp: " + reaction.getTargetSentTimestamp() + "  author: " + targetAuthor.getId());
  } else {
    Log.w(TAG, "[handleReaction] Could not find matching message! timestamp: " + reaction.getTargetSentTimestamp() + "  author: " + targetAuthor.getId());
    ApplicationDependencies.getEarlyMessageCache().store(targetAuthor.getId(), reaction.getTargetSentTimestamp(), content);
  }
}
 
Example #3
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
private void handleGroupV1Message(@NonNull SignalServiceContent content,
                                  @NonNull SignalServiceDataMessage message,
                                  @NonNull Optional<Long> smsMessageId,
                                  @NonNull GroupId.V1 groupId)
    throws StorageFailedException, BadGroupIdException
{
  GroupV1MessageProcessor.process(context, content, message, false);

  if (message.getExpiresInSeconds() != 0 && message.getExpiresInSeconds() != getMessageDestination(content, message).getExpireMessages()) {
    handleExpirationUpdate(content, message, Optional.absent(), Optional.of(groupId));
  }

  if (smsMessageId.isPresent()) {
    DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get());
  }
}
 
Example #4
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
private void handleRemoteDelete(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message) {
  SignalServiceDataMessage.RemoteDelete delete = message.getRemoteDelete().get();

  Recipient     sender        = Recipient.externalPush(context, content.getSender());
  MessageRecord targetMessage = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(delete.getTargetSentTimestamp(), sender.getId());

  if (targetMessage != null && RemoteDeleteUtil.isValidReceive(targetMessage, sender, content.getServerTimestamp())) {
    MessagingDatabase db = targetMessage.isMms() ? DatabaseFactory.getMmsDatabase(context) : DatabaseFactory.getSmsDatabase(context);
    db.markAsRemoteDelete(targetMessage.getId());
    ApplicationDependencies.getMessageNotifier().updateNotification(context, targetMessage.getThreadId(), false);
  } else if (targetMessage == null) {
    Log.w(TAG, "[handleRemoteDelete] Could not find matching message! timestamp: " + delete.getTargetSentTimestamp() + "  author: " + sender.getId());
    ApplicationDependencies.getEarlyMessageCache().store(sender.getId(), delete.getTargetSentTimestamp(), content);
  } else {
    Log.w(TAG, String.format(Locale.ENGLISH, "[handleRemoteDelete] Invalid remote delete! deleteTime: %d, targetTime: %d, deleteAuthor: %s, targetAuthor: %s",
                                              content.getServerTimestamp(), targetMessage.getServerTimestamp(), sender.getId(), targetMessage.getRecipient().getId()));
  }
}
 
Example #5
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
private void handleCallHangupMessage(@NonNull SignalServiceContent content,
                                     @NonNull HangupMessage message,
                                     @NonNull Optional<Long> smsMessageId)
{
  Log.i(TAG, "handleCallHangupMessage");
  if (smsMessageId.isPresent()) {
    DatabaseFactory.getSmsDatabase(context).markAsMissedCall(smsMessageId.get());
  } else {
    Intent     intent     = new Intent(context, WebRtcCallService.class);
    RemotePeer remotePeer = new RemotePeer(Recipient.externalPush(context, content.getSender()).getId());

    intent.setAction(WebRtcCallService.ACTION_RECEIVE_HANGUP)
          .putExtra(WebRtcCallService.EXTRA_CALL_ID,          message.getId())
          .putExtra(WebRtcCallService.EXTRA_REMOTE_PEER,      remotePeer)
          .putExtra(WebRtcCallService.EXTRA_REMOTE_DEVICE,    content.getSenderDevice())
          .putExtra(WebRtcCallService.EXTRA_HANGUP_IS_LEGACY, message.isLegacy())
          .putExtra(WebRtcCallService.EXTRA_HANGUP_DEVICE_ID, message.getDeviceId())
          .putExtra(WebRtcCallService.EXTRA_HANGUP_TYPE,      message.getType().getCode());

    context.startService(intent);
  }
}
 
Example #6
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
private void handleCallIceUpdateMessage(@NonNull SignalServiceContent content,
                                        @NonNull List<IceUpdateMessage> messages)
{
  Log.i(TAG, "handleCallIceUpdateMessage... " + messages.size());

  ArrayList<IceCandidateParcel> iceCandidates = new ArrayList<>(messages.size());
  long callId = -1;
  for (IceUpdateMessage iceMessage : messages) {
    iceCandidates.add(new IceCandidateParcel(iceMessage));
    callId = iceMessage.getId();
  }

  Intent     intent     = new Intent(context, WebRtcCallService.class);
  RemotePeer remotePeer = new RemotePeer(Recipient.externalPush(context, content.getSender()).getId());

  intent.setAction(WebRtcCallService.ACTION_RECEIVE_ICE_CANDIDATES)
        .putExtra(WebRtcCallService.EXTRA_CALL_ID,       callId)
        .putExtra(WebRtcCallService.EXTRA_REMOTE_PEER,   remotePeer)
        .putExtra(WebRtcCallService.EXTRA_REMOTE_DEVICE, content.getSenderDevice())
        .putParcelableArrayListExtra(WebRtcCallService.EXTRA_ICE_CANDIDATES, iceCandidates);

  context.startService(intent);
}
 
Example #7
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
private void handleCallAnswerMessage(@NonNull SignalServiceContent content,
                                     @NonNull AnswerMessage message)
{
  Log.i(TAG, "handleCallAnswerMessage...");
  Intent     intent     = new Intent(context, WebRtcCallService.class);
  RemotePeer remotePeer = new RemotePeer(Recipient.externalPush(context, content.getSender()).getId());

  intent.setAction(WebRtcCallService.ACTION_RECEIVE_ANSWER)
        .putExtra(WebRtcCallService.EXTRA_CALL_ID,            message.getId())
        .putExtra(WebRtcCallService.EXTRA_REMOTE_PEER,        remotePeer)
        .putExtra(WebRtcCallService.EXTRA_REMOTE_DEVICE,      content.getSenderDevice())
        .putExtra(WebRtcCallService.EXTRA_ANSWER_DESCRIPTION, message.getDescription())
        .putExtra(WebRtcCallService.EXTRA_MULTI_RING,         content.getCallMessage().get().isMultiRing());

  context.startService(intent);
}
 
Example #8
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
private void handleCallOfferMessage(@NonNull SignalServiceContent content,
                                    @NonNull OfferMessage message,
                                    @NonNull Optional<Long> smsMessageId)
{
  Log.i(TAG, "handleCallOfferMessage...");

  if (smsMessageId.isPresent()) {
    SmsDatabase database = DatabaseFactory.getSmsDatabase(context);
    database.markAsMissedCall(smsMessageId.get());
  } else {
    Intent     intent     = new Intent(context, WebRtcCallService.class);
    RemotePeer remotePeer = new RemotePeer(Recipient.externalPush(context, content.getSender()).getId());

    intent.setAction(WebRtcCallService.ACTION_RECEIVE_OFFER)
          .putExtra(WebRtcCallService.EXTRA_CALL_ID,           message.getId())
          .putExtra(WebRtcCallService.EXTRA_REMOTE_PEER,       remotePeer)
          .putExtra(WebRtcCallService.EXTRA_REMOTE_DEVICE,     content.getSenderDevice())
          .putExtra(WebRtcCallService.EXTRA_OFFER_DESCRIPTION, message.getDescription())
          .putExtra(WebRtcCallService.EXTRA_TIMESTAMP,         content.getTimestamp())
          .putExtra(WebRtcCallService.EXTRA_OFFER_TYPE,        message.getType().getCode())
          .putExtra(WebRtcCallService.EXTRA_MULTI_RING,        content.getCallMessage().get().isMultiRing());

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) context.startForegroundService(intent);
    else                                                context.startService(intent);
  }
}
 
Example #9
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
@Override
public void onRun() throws Exception {
  Optional<Long> optionalSmsMessageId = smsMessageId > 0 ? Optional.of(smsMessageId) : Optional.absent();

  if (messageState == MessageState.DECRYPTED_OK) {
    handleMessage(content, optionalSmsMessageId);

    Optional<List<SignalServiceContent>> earlyContent = ApplicationDependencies.getEarlyMessageCache()
                                                                               .retrieve(Recipient.externalPush(context, content.getSender()).getId(),
                                                                                         content.getTimestamp());
    if (earlyContent.isPresent()) {
      Log.i(TAG, "Found " + earlyContent.get().size() + " dependent item(s) that were retrieved earlier. Processing.");

      for (SignalServiceContent earlyItem : earlyContent.get()) {
        handleMessage(earlyItem, Optional.absent());
      }
    }
  } else if (exceptionMetadata != null) {
    handleExceptionMessage(exceptionMetadata, optionalSmsMessageId);
  } else {
    Log.w(TAG, "Bad state! messageState: " + messageState);
  }
}
 
Example #10
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
@WorkerThread
private PushProcessMessageJob(@NonNull MessageState messageState,
                              @Nullable SignalServiceContent content,
                              @Nullable ExceptionMetadata exceptionMetadata,
                              long pushMessageId,
                              long smsMessageId,
                              long timestamp)
{
  this(createParameters(content, exceptionMetadata),
       messageState,
       content,
       exceptionMetadata,
       pushMessageId,
       smsMessageId,
       timestamp);
}
 
Example #11
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
@SuppressLint("DefaultLocale")
private void handleReadReceipt(@NonNull SignalServiceContent content,
                               @NonNull SignalServiceReceiptMessage message)
{
  if (TextSecurePreferences.isReadReceiptsEnabled(context)) {
    for (long timestamp : message.getTimestamps()) {
      Log.i(TAG, String.format("Received encrypted read receipt: (XXXXX, %d)", timestamp));

      Recipient     sender  = Recipient.externalPush(context, content.getSender());
      SyncMessageId id      = new SyncMessageId(sender.getId(), timestamp);
      boolean       handled = DatabaseFactory.getMmsSmsDatabase(context)
                                             .incrementReadReceiptCount(id, content.getTimestamp());

      if (!handled) {
        Log.w(TAG, "[handleReadReceipt] Could not find matching message! timestamp: " + timestamp + "  author: " + sender.getId());
        ApplicationDependencies.getEarlyMessageCache().store(sender.getId(), timestamp, content);
      }
    }
  }
}
 
Example #12
Source File: MessageReceiver.java    From signald with GNU General Public License v3.0 6 votes vote down vote up
@Override
public void handleMessage(SignalServiceEnvelope envelope, SignalServiceContent content, Throwable exception) {
  String type = "message";
  if(exception != null) {
    logger.catching(exception);
    type = "unreadable_message";
  }

  try {
    if(envelope != null) {
      JsonMessageEnvelope message = new JsonMessageEnvelope(envelope, content, username);
      this.sockets.broadcast(new JsonMessageWrapper(type, message, exception));
    } else {
        this.sockets.broadcast(new JsonMessageWrapper(type, null, exception));
    }
  } catch (IOException | NoSuchAccountException e) {
    logger.catching(e);
  }
}
 
Example #13
Source File: GroupV1MessageProcessor.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
private static Long handleGroupLeave(@NonNull Context               context,
                                     @NonNull SignalServiceContent  content,
                                     @NonNull SignalServiceGroup    group,
                                     @NonNull GroupRecord           record,
                                     boolean  outgoing)
{
  GroupDatabase     database = DatabaseFactory.getGroupDatabase(context);
  GroupId           id       = GroupId.v1orThrow(group.getGroupId());
  List<RecipientId> members  = record.getMembers();

  GroupContext.Builder builder = createGroupContext(group);
  builder.setType(GroupContext.Type.QUIT);

  if (members.contains(Recipient.externalPush(context, content.getSender()).getId())) {
    database.remove(id, Recipient.externalPush(context, content.getSender()).getId());
    if (outgoing) database.setActive(id, false);

    return storeMessage(context, content, group, builder.build(), outgoing);
  }

  return null;
}
 
Example #14
Source File: Manager.java    From signal-cli with GNU General Public License v3.0 6 votes vote down vote up
private boolean isMessageBlocked(SignalServiceEnvelope envelope, SignalServiceContent content) {
    SignalServiceAddress source;
    if (!envelope.isUnidentifiedSender() && envelope.hasSource()) {
        source = envelope.getSourceAddress();
    } else if (content != null) {
        source = content.getSender();
    } else {
        return false;
    }
    ContactInfo sourceContact = account.getContactStore().getContact(source);
    if (sourceContact != null && sourceContact.blocked) {
        return true;
    }

    if (content != null && content.getDataMessage().isPresent()) {
        SignalServiceDataMessage message = content.getDataMessage().get();
        if (message.getGroupContext().isPresent() && message.getGroupContext().get().getGroupV1().isPresent()) {
            SignalServiceGroup groupInfo = message.getGroupContext().get().getGroupV1().get();
            GroupInfo group = getGroup(groupInfo.getGroupId());
            if (groupInfo.getType() == SignalServiceGroup.Type.DELIVER && group != null && group.blocked) {
                return true;
            }
        }
    }
    return false;
}
 
Example #15
Source File: JsonReceiveMessageHandler.java    From signal-cli with GNU General Public License v3.0 6 votes vote down vote up
@Override
public void handleMessage(SignalServiceEnvelope envelope, SignalServiceContent content, Throwable exception) {
    ObjectNode result = jsonProcessor.createObjectNode();
    if (exception != null) {
        result.putPOJO("error", new JsonError(exception));
    }
    if (envelope != null) {
        result.putPOJO("envelope", new JsonMessageEnvelope(envelope, content));
    }
    try {
        jsonProcessor.writeValue(System.out, result);
        System.out.println();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
 
Example #16
Source File: JsonMessageEnvelope.java    From signal-cli with GNU General Public License v3.0 5 votes vote down vote up
public JsonMessageEnvelope(SignalServiceEnvelope envelope, SignalServiceContent content) {
    if (!envelope.isUnidentifiedSender() && envelope.hasSource()) {
        SignalServiceAddress source = envelope.getSourceAddress();
        this.source = source.getNumber().get();
        this.relay = source.getRelay().isPresent() ? source.getRelay().get() : null;
    }
    this.sourceDevice = envelope.getSourceDevice();
    this.timestamp = envelope.getTimestamp();
    this.isReceipt = envelope.isReceipt();
    if (content != null) {
        if (envelope.isUnidentifiedSender()) {
            this.source = content.getSender().getNumber().get();
            this.sourceDevice = content.getSenderDevice();
        }
        if (content.getDataMessage().isPresent()) {
            this.dataMessage = new JsonDataMessage(content.getDataMessage().get());
        }
        if (content.getSyncMessage().isPresent()) {
            this.syncMessage = new JsonSyncMessage(content.getSyncMessage().get());
        }
        if (content.getCallMessage().isPresent()) {
            this.callMessage = new JsonCallMessage(content.getCallMessage().get());
        }
        if (content.getReceiptMessage().isPresent()) {
            this.receiptMessage = new JsonReceiptMessage(content.getReceiptMessage().get());
        }
    }
}
 
Example #17
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
private void handleTypingMessage(@NonNull SignalServiceContent content,
                                 @NonNull SignalServiceTypingMessage typingMessage)
    throws BadGroupIdException
{
  if (!TextSecurePreferences.isTypingIndicatorsEnabled(context)) {
    return;
  }

  Recipient author = Recipient.externalPush(context, content.getSender());

  long threadId;

  if (typingMessage.getGroupId().isPresent()) {
    GroupId.Push groupId = GroupId.push(typingMessage.getGroupId().get());

    if (!DatabaseFactory.getGroupDatabase(context).isCurrentMember(groupId, author.getId())) {
      Log.w(TAG, "Seen typing indicator for non-member");
      return;
    }

    Recipient groupRecipient = Recipient.externalGroup(context, groupId);

    threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipient);
  } else {
    threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(author);
  }

  if (threadId <= 0) {
    Log.w(TAG, "Couldn't find a matching thread for a typing message.");
    return;
  }

  if (typingMessage.isTypingStarted()) {
    Log.d(TAG, "Typing started on thread " + threadId);
    ApplicationContext.getInstance(context).getTypingStatusRepository().onTypingStarted(context,threadId, author, content.getSenderDevice());
  } else {
    Log.d(TAG, "Typing stopped on thread " + threadId);
    ApplicationContext.getInstance(context).getTypingStatusRepository().onTypingStopped(context, threadId, author, content.getSenderDevice(), false);
  }
}
 
Example #18
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
@SuppressLint("DefaultLocale")
private void handleDeliveryReceipt(@NonNull SignalServiceContent content,
                                   @NonNull SignalServiceReceiptMessage message)
{
  for (long timestamp : message.getTimestamps()) {
    Log.i(TAG, String.format("Received encrypted delivery receipt: (XXXXX, %d)", timestamp));
    DatabaseFactory.getMmsSmsDatabase(context)
                   .incrementDeliveryReceiptCount(new SyncMessageId(Recipient.externalPush(context, content.getSender()).getId(), timestamp), System.currentTimeMillis());
  }
}
 
Example #19
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
@Override
public @NonNull PushProcessMessageJob create(@NonNull Parameters parameters, @NonNull Data data) {
  try {
    MessageState state = MessageState.values()[data.getInt(KEY_MESSAGE_STATE)];

    if (state == MessageState.DECRYPTED_OK) {
      return new PushProcessMessageJob(parameters,
                                       state,
                                       SignalServiceContent.deserialize(Base64.decode(data.getString(KEY_MESSAGE_PLAINTEXT))),
                                       null,
                                       data.getLong(KEY_MESSAGE_ID),
                                       data.getLong(KEY_SMS_MESSAGE_ID),
                                       data.getLong(KEY_TIMESTAMP));
    } else {
      ExceptionMetadata exceptionMetadata = new ExceptionMetadata(data.getString(KEY_EXCEPTION_SENDER),
                                                                  data.getInt(KEY_EXCEPTION_DEVICE),
                                                                  GroupId.parseNullableOrThrow(data.getStringOrDefault(KEY_EXCEPTION_GROUP_ID, null)));

      return new PushProcessMessageJob(parameters,
                                       state,
                                       null,
                                       exceptionMetadata,
                                       data.getLong(KEY_MESSAGE_ID),
                                       data.getLong(KEY_SMS_MESSAGE_ID),
                                       data.getLong(KEY_TIMESTAMP));
    }
  } catch (IOException e) {
    throw new AssertionError(e);
  }
}
 
Example #20
Source File: Manager.java    From signal-cli with GNU General Public License v3.0 5 votes vote down vote up
private SignalServiceContent decryptMessage(SignalServiceEnvelope envelope) throws InvalidMetadataMessageException, ProtocolInvalidMessageException, ProtocolDuplicateMessageException, ProtocolLegacyMessageException, ProtocolInvalidKeyIdException, InvalidMetadataVersionException, ProtocolInvalidVersionException, ProtocolNoSessionException, ProtocolInvalidKeyException, SelfSendException, UnsupportedDataMessageException, org.whispersystems.libsignal.UntrustedIdentityException {
    SignalServiceCipher cipher = new SignalServiceCipher(account.getSelfAddress(), account.getSignalProtocolStore(), Utils.getCertificateValidator());
    try {
        return cipher.decrypt(envelope);
    } catch (ProtocolUntrustedIdentityException e) {
        if (e.getCause() instanceof org.whispersystems.libsignal.UntrustedIdentityException) {
            org.whispersystems.libsignal.UntrustedIdentityException identityException = (org.whispersystems.libsignal.UntrustedIdentityException) e.getCause();
            account.getSignalProtocolStore().saveIdentity(resolveSignalServiceAddress(identityException.getName()), identityException.getUntrustedIdentity(), TrustLevel.UNTRUSTED);
            throw identityException;
        }
        throw new AssertionError(e);
    }
}
 
Example #21
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
private void handleProfileKey(@NonNull SignalServiceContent content,
                              @NonNull byte[] messageProfileKeyBytes)
{
  RecipientDatabase database          = DatabaseFactory.getRecipientDatabase(context);
  Recipient         recipient         = Recipient.externalPush(context, content.getSender());
  ProfileKey        messageProfileKey = ProfileKeyUtil.profileKeyOrNull(messageProfileKeyBytes);

  if (messageProfileKey != null) {
    if (database.setProfileKey(recipient.getId(), messageProfileKey)) {
      ApplicationDependencies.getJobManager().add(RetrieveProfileJob.forRecipient(recipient));
    }
  } else {
    Log.w(TAG, "Ignored invalid profile key seen in message");
  }
}
 
Example #22
Source File: GroupV1MessageProcessor.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
public static @Nullable Long process(@NonNull Context context,
                                     @NonNull SignalServiceContent content,
                                     @NonNull SignalServiceDataMessage message,
                                     boolean outgoing)
{
  SignalServiceGroupContext    signalServiceGroupContext = message.getGroupContext().get();
  Optional<SignalServiceGroup> groupV1                   = signalServiceGroupContext.getGroupV1();

  if (signalServiceGroupContext.getGroupV2().isPresent()) {
    throw new AssertionError("Cannot process GV2");
  }

  if (!groupV1.isPresent() || groupV1.get().getGroupId() == null) {
    Log.w(TAG, "Received group message with no id! Ignoring...");
    return null;
  }

  GroupDatabase         database = DatabaseFactory.getGroupDatabase(context);
  SignalServiceGroup    group    = groupV1.get();
  GroupId               id       = GroupId.v1orThrow(group.getGroupId());
  Optional<GroupRecord> record   = database.getGroup(id);

  if (record.isPresent() && group.getType() == Type.UPDATE) {
    return handleGroupUpdate(context, content, group, record.get(), outgoing);
  } else if (!record.isPresent() && group.getType() == Type.UPDATE) {
    return handleGroupCreate(context, content, group, outgoing);
  } else if (record.isPresent() && group.getType() == Type.QUIT) {
    return handleGroupLeave(context, content, group, record.get(), outgoing);
  } else if (record.isPresent() && group.getType() == Type.REQUEST_INFO) {
    return handleGroupInfoRequest(context, content, record.get());
  } else {
    Log.w(TAG, "Received unknown type, ignoring...");
    return null;
  }
}
 
Example #23
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
private void handleUnknownGroupMessage(@NonNull SignalServiceContent content,
                                       @NonNull SignalServiceGroupContext group)
    throws BadGroupIdException
{
  if (group.getGroupV1().isPresent()) {
    SignalServiceGroup groupV1 = group.getGroupV1().get();
    if (groupV1.getType() != SignalServiceGroup.Type.REQUEST_INFO) {
      ApplicationDependencies.getJobManager().add(new RequestGroupInfoJob(Recipient.externalPush(context, content.getSender()).getId(), GroupId.v1(groupV1.getGroupId())));
    } else {
      Log.w(TAG, "Received a REQUEST_INFO message for a group we don't know about. Ignoring.");
    }
  } else {
    Log.w(TAG, "Received a message for a group we don't know about without a GV1 context. Ignoring.");
  }
}
 
Example #24
Source File: GroupV1MessageProcessor.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
private static @Nullable Long handleGroupCreate(@NonNull Context context,
                                                @NonNull SignalServiceContent content,
                                                @NonNull SignalServiceGroup group,
                                                boolean outgoing)
{
  GroupDatabase        database = DatabaseFactory.getGroupDatabase(context);
  GroupId.V1           id       = GroupId.v1orThrow(group.getGroupId());
  GroupContext.Builder builder  = createGroupContext(group);
  builder.setType(GroupContext.Type.UPDATE);

  SignalServiceAttachment avatar  = group.getAvatar().orNull();
  List<RecipientId>       members = new LinkedList<>();

  if (group.getMembers().isPresent()) {
    for (SignalServiceAddress member : group.getMembers().get()) {
      members.add(Recipient.externalPush(context, member).getId());
    }
  }

  database.create(id, group.getName().orNull(), members,
                  avatar != null && avatar.isPointer() ? avatar.asPointer() : null, null);

  Recipient sender = Recipient.externalPush(context, content.getSender());

  if (FeatureFlags.messageRequests() && (sender.isSystemContact() || sender.isProfileSharing())) {
    Log.i(TAG, "Auto-enabling profile sharing because 'adder' is trusted. contact: " + sender.isSystemContact() + ", profileSharing: " + sender.isProfileSharing());
    DatabaseFactory.getRecipientDatabase(context).setProfileSharing(Recipient.externalGroup(context, id).getId(), true);
  }

  return storeMessage(context, content, group, builder.build(), outgoing);
}
 
Example #25
Source File: GroupV1MessageProcessor.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
private static Long handleGroupInfoRequest(@NonNull Context context,
                                           @NonNull SignalServiceContent content,
                                           @NonNull GroupRecord record)
{
  Recipient sender = Recipient.externalPush(context, content.getSender());

  if (record.getMembers().contains(sender.getId())) {
    ApplicationDependencies.getJobManager().add(new PushGroupUpdateJob(sender.getId(), record.getId()));
  }

  return null;
}
 
Example #26
Source File: EarlyMessageCache.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
/**
 * @param targetSender        The sender of the message this message depends on.
 * @param targetSentTimestamp The sent timestamp of the message this message depends on.
 */
public void store(@NonNull RecipientId targetSender, long targetSentTimestamp, @NonNull SignalServiceContent content) {
  MessageId                  messageId   = new MessageId(targetSender, targetSentTimestamp);
  List<SignalServiceContent> contentList = cache.get(messageId);

  if (contentList == null) {
    contentList = new LinkedList<>();
  }

  contentList.add(content);

  cache.put(messageId, contentList);
}
 
Example #27
Source File: PushProcessMessageQueueJobMigration.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
private static @NonNull JobData migratePushProcessMessageJob(@NonNull Context context, @NonNull JobData jobData) throws IOException {
  Data data = jobData.getData();

  String suffix = "";

  if (data.getInt("message_state") == 0) {
    SignalServiceContent content = SignalServiceContent.deserialize(Base64.decode(data.getString("message_content")));

    if (content != null && content.getDataMessage().isPresent() && content.getDataMessage().get().getGroupContext().isPresent()) {
      Log.i(TAG, "Migrating a group message.");
      try {
        GroupId   groupId   = GroupUtil.idFromGroupContext(content.getDataMessage().get().getGroupContext().get());
        Recipient recipient = Recipient.externalGroup(context, groupId);

        suffix = recipient.getId().toQueueKey();
      } catch (BadGroupIdException e) {
        Log.w(TAG, "Bad groupId! Using default queue.");
      }
    } else if (content != null) {
      Log.i(TAG, "Migrating an individual message.");
      suffix = RecipientId.from(content.getSender()).toQueueKey();
    }
  } else {
    Log.i(TAG, "Migrating an exception message.");

    String  exceptionSender = data.getString("exception_sender");
    GroupId exceptionGroup  =  GroupId.parseNullableOrThrow(data.getStringOrDefault("exception_groupId", null));

    if (exceptionGroup != null) {
      suffix = Recipient.externalGroup(context, exceptionGroup).getId().toQueueKey();
    } else if (exceptionSender != null) {
      suffix = Recipient.external(context, exceptionSender).getId().toQueueKey();
    }
  }

  return jobData.withQueueKey("__PUSH_PROCESS_JOB__" + suffix);
}
 
Example #28
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
@WorkerThread
PushProcessMessageJob(@NonNull SignalServiceContent content,
                      long pushMessageId,
                      long smsMessageId,
                      long timestamp)
{
  this(MessageState.DECRYPTED_OK,
       content,
       null,
       pushMessageId,
       smsMessageId,
       timestamp);
}
 
Example #29
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Attempts to update the group to the version mentioned in the message.
 * If the local version is at least that it will not check the server.
 *
 * @return false iff self is not a current member of the group.
 */
private boolean groupV2PreProcessMessage(@NonNull SignalServiceContent content,
                                         @NonNull GroupMasterKey groupMasterKey,
                                         @NonNull SignalServiceGroupV2 groupV2)
    throws IOException, GroupChangeBusyException
{
  try {
    GroupManager.updateGroupFromServer(context, groupMasterKey, groupV2.getRevision(), content.getTimestamp(), groupV2.getSignedGroupChange());
    return true;
  } catch (GroupNotAMemberException e) {
    Log.w(TAG, "Ignoring message for a group we're not in");
    return false;
  }
}
 
Example #30
Source File: PushProcessMessageJob.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
private void handleCallBusyMessage(@NonNull SignalServiceContent content,
                                   @NonNull BusyMessage message)
{
  Log.i(TAG, "handleCallBusyMessage");

  Intent     intent     = new Intent(context, WebRtcCallService.class);
  RemotePeer remotePeer = new RemotePeer(Recipient.externalPush(context, content.getSender()).getId());

  intent.setAction(WebRtcCallService.ACTION_RECEIVE_BUSY)
        .putExtra(WebRtcCallService.EXTRA_CALL_ID,       message.getId())
        .putExtra(WebRtcCallService.EXTRA_REMOTE_PEER,   remotePeer)
        .putExtra(WebRtcCallService.EXTRA_REMOTE_DEVICE, content.getSenderDevice());

  context.startService(intent);
}