diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java index 94b23d023b..6e7003889c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushProcessMessageJob.java @@ -14,7 +14,6 @@ import com.annimon.stream.Collectors; import com.annimon.stream.Stream; import org.signal.zkgroup.VerificationFailedException; -import org.signal.zkgroup.groups.GroupMasterKey; import org.signal.zkgroup.profiles.ProfileKey; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.attachments.Attachment; @@ -346,10 +345,9 @@ public final class PushProcessMessageJob extends BaseJob { boolean isGv2Message = groupId.isPresent() && groupId.get().isV2(); if (isGv2Message) { - GroupMasterKey groupMasterKey = message.getGroupContext().get().getGroupV2().get().getMasterKey(); - GroupId.V2 groupIdV2 = groupId.get().requireV2(); + GroupId.V2 groupIdV2 = groupId.get().requireV2(); - if (!groupV2PreProcessMessage(content, groupMasterKey, message.getGroupContext().get().getGroupV2().get())) { + if (!updateGv2GroupFromServerOrP2PChange(content, message.getGroupContext().get().getGroupV2().get())) { Log.i(TAG, "Ignoring GV2 message for group we are not currently in " + groupIdV2); return; } @@ -434,18 +432,20 @@ public final class PushProcessMessageJob extends BaseJob { } /** - * 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. + * Attempts to update the group to the revision mentioned in the message. + * If the local version is at least the revision in the message it will not query the server. + * If the message includes a signed change proto that is sufficient (i.e. local revision is only + * 1 revision behind), it will also not query the server in this case. * - * @return false iff self is not a current member of the group. + * @return false iff needed to query the server and was not able to because self is not a current + * member of the group. */ - private boolean groupV2PreProcessMessage(@NonNull SignalServiceContent content, - @NonNull GroupMasterKey groupMasterKey, - @NonNull SignalServiceGroupV2 groupV2) + private boolean updateGv2GroupFromServerOrP2PChange(@NonNull SignalServiceContent content, + @NonNull SignalServiceGroupV2 groupV2) throws IOException, GroupChangeBusyException { try { - GroupManager.updateGroupFromServer(context, groupMasterKey, groupV2.getRevision(), content.getTimestamp(), groupV2.getSignedGroupChange()); + GroupManager.updateGroupFromServer(context, groupV2.getMasterKey(), groupV2.getRevision(), content.getTimestamp(), groupV2.getSignedGroupChange()); return true; } catch (GroupNotAMemberException e) { Log.w(TAG, "Ignoring message for a group we're not in"); @@ -898,25 +898,28 @@ public final class PushProcessMessageJob extends BaseJob { private void handleSynchronizeSentMessage(@NonNull SignalServiceContent content, @NonNull SentTranscriptMessage message) - throws StorageFailedException, BadGroupIdException, VerificationFailedException, IOException, InvalidGroupStateException + throws StorageFailedException, BadGroupIdException, IOException, GroupChangeBusyException { try { GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); - Long threadId = null; + long threadId = -1; 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); + Long gv1ThreadId = GroupV1MessageProcessor.process(context, content, message.getMessage(), true); + threadId = gv1ThreadId == null ? -1 : gv1ThreadId; + } else if (message.getMessage().isGroupV2Update()) { + handleSynchronizeSentGv2Update(content, message); + threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(getSyncMessageDestination(message)); } 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()) { @@ -925,7 +928,8 @@ public final class PushProcessMessageJob extends BaseJob { 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().getGroupContext().isPresent() && groupDatabase.isUnknownGroup(GroupUtil.idFromGroupContext(message.getMessage().getGroupContext().get()))) { + handleUnknownGroupMessage(content, message.getMessage().getGroupContext().get()); } if (message.getMessage().getProfileKey().isPresent()) { @@ -936,7 +940,7 @@ public final class PushProcessMessageJob extends BaseJob { } } - if (threadId != null) { + if (threadId != -1) { DatabaseFactory.getThreadDatabase(context).setRead(threadId, true); ApplicationDependencies.getMessageNotifier().updateNotification(context); } @@ -947,6 +951,18 @@ public final class PushProcessMessageJob extends BaseJob { } } + private void handleSynchronizeSentGv2Update(@NonNull SignalServiceContent content, + @NonNull SentTranscriptMessage message) + throws IOException, GroupChangeBusyException + { + SignalServiceGroupV2 signalServiceGroupV2 = message.getMessage().getGroupContext().get().getGroupV2().get(); + GroupId.V2 groupIdV2 = GroupId.v2(signalServiceGroupV2.getMasterKey()); + + if (!updateGv2GroupFromServerOrP2PChange(content, signalServiceGroupV2)) { + Log.i(TAG, "Ignoring GV2 message for group we are not currently in " + groupIdV2); + } + } + private void handleSynchronizeRequestMessage(@NonNull RequestMessage message) { if (message.isContactsRequest()) {