diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java index f0e1d59a56..c0fbf15863 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/GroupManager.java @@ -20,6 +20,7 @@ import org.thoughtcrime.securesms.database.model.GroupRecord; import org.thoughtcrime.securesms.groups.v2.GroupInviteLinkUrl; import org.thoughtcrime.securesms.groups.v2.GroupLinkPassword; import org.thoughtcrime.securesms.groups.v2.processing.GroupUpdateResult; +import org.thoughtcrime.securesms.jobs.ConversationShortcutUpdateJob; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; import org.whispersystems.signalservice.api.groupsv2.GroupLinkNotActiveException; @@ -82,6 +83,7 @@ public final class GroupManager { try (GroupManagerV2.GroupEditor edit = new GroupManagerV2(context).edit(groupId.requireV2())) { edit.terminateGroup(); SignalDatabase.groups().setTerminatedBy(groupId, Recipient.self().getId()); + ConversationShortcutUpdateJob.enqueue(); Log.i(TAG, "Terminated group " + groupId); } catch (GroupInsufficientRightsException e) { Log.w(TAG, "Insufficient rights to terminate " + groupId, e); diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.kt index 07f739d5b0..37823ffdbe 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.kt @@ -31,6 +31,7 @@ import org.thoughtcrime.securesms.groups.GroupProtoUtil import org.thoughtcrime.securesms.groups.v2.ProfileKeySet import org.thoughtcrime.securesms.groups.v2.processing.GroupsV2StateProcessor.Companion.LATEST import org.thoughtcrime.securesms.jobs.AvatarGroupsV2DownloadJob +import org.thoughtcrime.securesms.jobs.ConversationShortcutUpdateJob import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob import org.thoughtcrime.securesms.jobs.LeaveGroupV2Job import org.thoughtcrime.securesms.jobs.RequestGroupV2InfoJob @@ -543,7 +544,8 @@ class GroupsV2StateProcessor private constructor( Log.i(TAG, "$logPrefix Local state (revision: ${currentLocalState?.revision}) does not match, updating to ${updatedGroupState.revision}") } - val terminatorRecipientId: RecipientId? = if (updatedGroupState.terminated && (currentLocalState == null || !currentLocalState.terminated)) { + val wasTerminated = updatedGroupState.terminated && (currentLocalState == null || !currentLocalState.terminated) + val terminatorRecipientId: RecipientId? = if (wasTerminated) { groupStateDiff.serverHistory .mapNotNull { it.change } .firstOrNull { it.terminateGroup } @@ -559,6 +561,10 @@ class GroupsV2StateProcessor private constructor( profileAndMessageHelper.stopAllTypingForGroup() } + if (wasTerminated) { + ConversationShortcutUpdateJob.enqueue() + } + if (currentLocalState == null || currentLocalState.revision == RESTORE_PLACEHOLDER_REVISION) { if (!updatedGroupState.terminated) { Log.i(TAG, "$logPrefix Inserting single update message for no local state or restore placeholder") @@ -787,6 +793,7 @@ class GroupsV2StateProcessor private constructor( } SignalDatabase.groups.update(masterKey, simulatedGroupState, null) + ConversationShortcutUpdateJob.enqueue() } fun markJoinRequestRejectedLocally() { diff --git a/app/src/test/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessorTest.kt b/app/src/test/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessorTest.kt index 4d33964cf5..c52ae027b1 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessorTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessorTest.kt @@ -56,6 +56,7 @@ import org.thoughtcrime.securesms.groups.GroupsV2Authorization import org.thoughtcrime.securesms.groups.v2.ProfileKeySet import org.thoughtcrime.securesms.groups.v2.processing.GroupsV2StateProcessor.ProfileAndMessageHelper import org.thoughtcrime.securesms.jobmanager.JobManager +import org.thoughtcrime.securesms.jobs.ConversationShortcutUpdateJob import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob import org.thoughtcrime.securesms.jobs.RequestGroupV2InfoJob import org.thoughtcrime.securesms.keyvalue.SignalStore @@ -1066,6 +1067,7 @@ class GroupsV2StateProcessorTest { } every { recipientTable.getAndPossiblyMerge(adminAci, null) } returns adminRecipientId + justRun { jobManager.add(any()) } val signedChange = DecryptedGroupChange( revision = 6, @@ -1088,6 +1090,7 @@ class GroupsV2StateProcessorTest { } verify { groupTable.update(masterKey, match { it.terminated }, null, adminRecipientId) } + verify { jobManager.add(ofType(ConversationShortcutUpdateJob::class)) } } @Test @@ -1100,6 +1103,8 @@ class GroupsV2StateProcessorTest { expectTableUpdate = true } + justRun { jobManager.add(any()) } + val signedChange = DecryptedGroupChange( revision = 6, terminateGroup = true @@ -1120,6 +1125,7 @@ class GroupsV2StateProcessorTest { } verify(exactly = 0) { groupTable.setTerminatedBy(any(), any()) } + verify { jobManager.add(ofType(ConversationShortcutUpdateJob::class)) } } @Test @@ -1139,6 +1145,8 @@ class GroupsV2StateProcessorTest { expectTableUpdate = true } + justRun { jobManager.add(any()) } + val result = processor.forceSanityUpdateFromServer(0) assertThat(result.updateStatus).isEqualTo(GroupUpdateResult.UpdateStatus.GROUP_UPDATED) @@ -1149,6 +1157,7 @@ class GroupsV2StateProcessorTest { } verify(exactly = 0) { groupTable.setTerminatedBy(any(), any()) } + verify { jobManager.add(ofType(ConversationShortcutUpdateJob::class)) } } @Test