Improve group change defensive checks and update logic.

This commit is contained in:
Cody Henthorne
2026-04-15 16:09:58 -04:00
committed by jeffrey-signal
parent fa19ed7ffc
commit f427f31303
2 changed files with 43 additions and 21 deletions

View File

@@ -591,26 +591,7 @@ class GroupsV2StateProcessor private constructor(
Log.i(TAG, "$logPrefix Local state (revision: ${currentLocalState?.revision}) does not match, updating to ${updatedGroupState.revision}")
}
val wasTerminated = updatedGroupState.terminated && (currentLocalState == null || !currentLocalState.terminated)
val terminatorRecipientId: RecipientId? = if (wasTerminated) {
groupStateDiff.serverHistory
.mapNotNull { it.change }
.firstOrNull { it.terminateGroup }
?.let { ServiceId.parseOrNull(it.editorServiceIdBytes) }
?.let { RecipientId.from(it) }
} else {
null
}
saveGroupState(groupStateDiff, updatedGroupState, groupSendEndorsements, terminatorRecipientId)
if (terminatorRecipientId != null) {
profileAndMessageHelper.stopAllTypingForGroup()
}
if (wasTerminated) {
ConversationShortcutUpdateJob.enqueue()
}
saveGroupState(groupStateDiff, updatedGroupState, groupSendEndorsements)
if (currentLocalState == null || currentLocalState.revision == RESTORE_PLACEHOLDER_REVISION) {
if (!updatedGroupState.terminated) {
@@ -639,13 +620,29 @@ class GroupsV2StateProcessor private constructor(
return InternalUpdateResult.Updated(updatedGroupState)
}
private fun saveGroupState(groupStateDiff: GroupStateDiff, updatedGroupState: DecryptedGroup, groupSendEndorsements: ReceivedGroupSendEndorsements?, terminatorRecipientId: RecipientId? = null) {
private fun saveGroupState(
groupStateDiff: GroupStateDiff,
updatedGroupState: DecryptedGroup,
groupSendEndorsements: ReceivedGroupSendEndorsements?
) {
val previousGroupState = groupStateDiff.previousGroupState
if (groupSendEndorsements != null) {
Log.i(TAG, "$logPrefix Updating send endorsements")
}
val wasTerminated = updatedGroupState.terminated && (previousGroupState == null || !previousGroupState.terminated)
val terminatorRecipientId: RecipientId? = if (wasTerminated) {
groupStateDiff
.serverHistory
.mapNotNull { it.change }
.firstOrNull { it.terminateGroup }
?.let { ServiceId.parseOrNull(it.editorServiceIdBytes) }
?.let { RecipientId.from(it) }
} else {
null
}
val needsAvatarFetch = if (previousGroupState == null) {
val groupId = SignalDatabase.groups.create(groupMasterKey, updatedGroupState, groupSendEndorsements)
@@ -661,6 +658,11 @@ class GroupsV2StateProcessor private constructor(
updatedGroupState.avatar != previousGroupState.avatar
}
if (wasTerminated) {
profileAndMessageHelper.stopAllTypingForGroup()
ConversationShortcutUpdateJob.enqueue()
}
if (needsAvatarFetch) {
AppDependencies.jobManager.add(AvatarGroupsV2DownloadJob(groupId, updatedGroupState.avatar))
}

View File

@@ -123,6 +123,10 @@ public final class GroupV2UpdateSelfProfileKeyJob extends BaseJob {
continue;
}
if (Recipient.externalGroupExact(id).isBlocked()) {
continue;
}
ByteString selfUuidBytes = Recipient.self().requireAci().toByteString();
boolean isActive = group.get().isActive();
DecryptedMember selfMember = group.get().requireV2GroupProperties().getDecryptedGroup().members
@@ -170,6 +174,22 @@ public final class GroupV2UpdateSelfProfileKeyJob extends BaseJob {
return;
}
Optional<GroupRecord> group = SignalDatabase.groups().getGroup(groupId);
if (!group.isPresent()) {
Log.w(TAG, "Group " + group + " no longer exists?");
return;
}
if (Recipient.externalGroupExact(groupId).isBlocked()) {
Log.i(TAG, "Not updating blocked group " + groupId);
return;
}
if (!group.get().isActive()) {
Log.i(TAG, "Group is not active, skipping update.");
return;
}
Log.i(TAG, "Ensuring profile key up to date on group " + groupId);
GroupManager.updateSelfProfileKeyInGroup(context, groupId);
}