That fuck shit the fascists are using
at master 229 lines 11 kB view raw
1package org.tm.archive.groups; 2 3import android.content.Context; 4import android.net.Uri; 5 6import androidx.annotation.NonNull; 7import androidx.annotation.Nullable; 8import androidx.annotation.WorkerThread; 9 10import org.signal.core.util.logging.Log; 11import org.tm.archive.attachments.Attachment; 12import org.tm.archive.attachments.UriAttachment; 13import org.tm.archive.database.AttachmentTable; 14import org.tm.archive.database.GroupTable; 15import org.tm.archive.database.RecipientTable; 16import org.tm.archive.database.SignalDatabase; 17import org.tm.archive.database.ThreadTable; 18import org.tm.archive.groups.GroupManager.GroupActionResult; 19import org.tm.archive.mms.MessageGroupContext; 20import org.tm.archive.mms.OutgoingMessage; 21import org.tm.archive.profiles.AvatarHelper; 22import org.tm.archive.providers.BlobProvider; 23import org.tm.archive.recipients.Recipient; 24import org.tm.archive.recipients.RecipientId; 25import org.tm.archive.sms.MessageSender; 26import org.tm.archive.util.MediaUtil; 27import org.whispersystems.signalservice.internal.push.GroupContext; 28 29import java.io.ByteArrayInputStream; 30import java.io.IOException; 31import java.security.SecureRandom; 32import java.util.ArrayList; 33import java.util.Collections; 34import java.util.LinkedList; 35import java.util.List; 36import java.util.Optional; 37import java.util.Set; 38 39import okio.ByteString; 40 41final class GroupManagerV1 { 42 43 private static final String TAG = Log.tag(GroupManagerV1.class); 44 45 static @NonNull GroupActionResult createGroup(@NonNull Context context, 46 @NonNull Set<RecipientId> memberIds, 47 @Nullable byte[] avatarBytes, 48 @Nullable String name, 49 boolean mms) 50 { 51 final GroupTable groupDatabase = SignalDatabase.groups(); 52 final SecureRandom secureRandom = new SecureRandom(); 53 final GroupId groupId = mms ? GroupId.createMms(secureRandom) : GroupId.createV1(secureRandom); 54 final RecipientId groupRecipientId = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); 55 final Recipient groupRecipient = Recipient.resolved(groupRecipientId); 56 57 memberIds.add(Recipient.self().getId()); 58 59 if (groupId.isV1()) { 60 GroupId.V1 groupIdV1 = groupId.requireV1(); 61 62 groupDatabase.create(groupIdV1, name, memberIds, null); 63 64 try { 65 AvatarHelper.setAvatar(context, groupRecipientId, avatarBytes != null ? new ByteArrayInputStream(avatarBytes) : null); 66 } catch (IOException e) { 67 Log.w(TAG, "Failed to save avatar!", e); 68 } 69 groupDatabase.onAvatarUpdated(groupIdV1, avatarBytes != null); 70 SignalDatabase.recipients().setProfileSharing(groupRecipient.getId(), true); 71 return sendGroupUpdate(context, groupIdV1, memberIds, name, avatarBytes, memberIds.size() - 1); 72 } else { 73 groupDatabase.create(groupId.requireMms(), name, memberIds); 74 75 try { 76 AvatarHelper.setAvatar(context, groupRecipientId, avatarBytes != null ? new ByteArrayInputStream(avatarBytes) : null); 77 } catch (IOException e) { 78 Log.w(TAG, "Failed to save avatar!", e); 79 } 80 groupDatabase.onAvatarUpdated(groupId, avatarBytes != null); 81 82 long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(groupRecipient, ThreadTable.DistributionTypes.CONVERSATION); 83 return new GroupActionResult(groupRecipient, threadId, memberIds.size() - 1, Collections.emptyList()); 84 } 85 } 86 87 static GroupActionResult updateGroup(@NonNull Context context, 88 @NonNull GroupId groupId, 89 @NonNull Set<RecipientId> memberAddresses, 90 @Nullable byte[] avatarBytes, 91 @Nullable String name, 92 int newMemberCount) 93 { 94 final GroupTable groupDatabase = SignalDatabase.groups(); 95 final RecipientId groupRecipientId = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); 96 97 memberAddresses.add(Recipient.self().getId()); 98 groupDatabase.updateMembers(groupId, new LinkedList<>(memberAddresses)); 99 100 if (groupId.isPush()) { 101 GroupId.V1 groupIdV1 = groupId.requireV1(); 102 103 groupDatabase.updateTitle(groupIdV1, name); 104 groupDatabase.onAvatarUpdated(groupIdV1, avatarBytes != null); 105 106 try { 107 AvatarHelper.setAvatar(context, groupRecipientId, avatarBytes != null ? new ByteArrayInputStream(avatarBytes) : null); 108 } catch (IOException e) { 109 Log.w(TAG, "Failed to save avatar!", e); 110 } 111 return sendGroupUpdate(context, groupIdV1, memberAddresses, name, avatarBytes, newMemberCount); 112 } else { 113 Recipient groupRecipient = Recipient.resolved(groupRecipientId); 114 long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(groupRecipient); 115 return new GroupActionResult(groupRecipient, threadId, newMemberCount, Collections.emptyList()); 116 } 117 } 118 119 static GroupActionResult updateGroup(@NonNull Context context, 120 @NonNull GroupId.Mms groupId, 121 @Nullable byte[] avatarBytes, 122 @Nullable String name) 123 { 124 GroupTable groupDatabase = SignalDatabase.groups(); 125 RecipientId groupRecipientId = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); 126 Recipient groupRecipient = Recipient.resolved(groupRecipientId); 127 long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(groupRecipient); 128 129 groupDatabase.updateTitle(groupId, name); 130 groupDatabase.onAvatarUpdated(groupId, avatarBytes != null); 131 132 try { 133 AvatarHelper.setAvatar(context, groupRecipientId, avatarBytes != null ? new ByteArrayInputStream(avatarBytes) : null); 134 } catch (IOException e) { 135 Log.w(TAG, "Failed to save avatar!", e); 136 } 137 138 return new GroupActionResult(groupRecipient, threadId, 0, Collections.emptyList()); 139 } 140 141 private static GroupActionResult sendGroupUpdate(@NonNull Context context, 142 @NonNull GroupId.V1 groupId, 143 @NonNull Set<RecipientId> members, 144 @Nullable String groupName, 145 @Nullable byte[] avatar, 146 int newMemberCount) 147 { 148 Attachment avatarAttachment = null; 149 RecipientId groupRecipientId = SignalDatabase.recipients().getOrInsertFromGroupId(groupId); 150 Recipient groupRecipient = Recipient.resolved(groupRecipientId); 151 152 List<GroupContext.Member> uuidMembers = new ArrayList<>(members.size()); 153 List<String> e164Members = new ArrayList<>(members.size()); 154 155 for (RecipientId member : members) { 156 Recipient recipient = Recipient.resolved(member); 157 if (recipient.hasE164()) { 158 e164Members.add(recipient.requireE164()); 159 } 160 } 161 162 GroupContext.Builder groupContextBuilder = new GroupContext.Builder() 163 .id(ByteString.of(groupId.getDecodedId())) 164 .type(GroupContext.Type.UPDATE) 165 .membersE164(e164Members) 166 .members(uuidMembers); 167 168 if (groupName != null) groupContextBuilder.name(groupName); 169 170 GroupContext groupContext = groupContextBuilder.build(); 171 172 if (avatar != null) { 173 Uri avatarUri = BlobProvider.getInstance().forData(avatar).createForSingleUseInMemory(); 174 avatarAttachment = new UriAttachment(avatarUri, MediaUtil.IMAGE_PNG, AttachmentTable.TRANSFER_PROGRESS_DONE, avatar.length, null, false, false, false, false, null, null, null, null, null); 175 } 176 177 OutgoingMessage outgoingMessage = OutgoingMessage.groupUpdateMessage(groupRecipient, 178 new MessageGroupContext(groupContext), 179 avatarAttachment != null ? Collections.singletonList(avatarAttachment) : Collections.emptyList(), 180 System.currentTimeMillis(), 181 0, 182 false, 183 null, 184 Collections.emptyList(), 185 Collections.emptyList(), 186 Collections.emptyList()); 187 188 long threadId = MessageSender.send(context, outgoingMessage, -1, MessageSender.SendType.SIGNAL, null, null); 189 190 return new GroupActionResult(groupRecipient, threadId, newMemberCount, Collections.emptyList()); 191 } 192 193 @WorkerThread 194 static boolean leaveGroup(@NonNull Context context, @NonNull GroupId.V1 groupId) { 195 return false; 196 } 197 198 @WorkerThread 199 static boolean silentLeaveGroup(@NonNull Context context, @NonNull GroupId.V1 groupId) { 200 return false; 201 } 202 203 @WorkerThread 204 static void updateGroupTimer(@NonNull Context context, @NonNull GroupId.V1 groupId, int expirationTime) { 205 RecipientTable recipientTable = SignalDatabase.recipients(); 206 ThreadTable threadTable = SignalDatabase.threads(); 207 Recipient recipient = Recipient.externalGroupExact(groupId); 208 long threadId = threadTable.getOrCreateThreadIdFor(recipient); 209 210 recipientTable.setExpireMessages(recipient.getId(), expirationTime); 211 OutgoingMessage outgoingMessage = OutgoingMessage.expirationUpdateMessage(recipient, System.currentTimeMillis(), expirationTime * 1000L); 212 MessageSender.send(context, outgoingMessage, threadId, MessageSender.SendType.SIGNAL, null, null); 213 } 214 215 @WorkerThread 216 private static Optional<OutgoingMessage> createGroupLeaveMessage(@NonNull Context context, 217 @NonNull GroupId.V1 groupId, 218 @NonNull Recipient groupRecipient) 219 { 220 GroupTable groupDatabase = SignalDatabase.groups(); 221 222 if (!groupDatabase.isActive(groupId)) { 223 Log.w(TAG, "Group has already been left."); 224 return Optional.empty(); 225 } 226 227 return Optional.empty(); 228 } 229}