diff --git a/src/org/thoughtcrime/securesms/groups/GroupManager.java b/src/org/thoughtcrime/securesms/groups/GroupManager.java index 924e402b98..4d6eb04def 100644 --- a/src/org/thoughtcrime/securesms/groups/GroupManager.java +++ b/src/org/thoughtcrime/securesms/groups/GroupManager.java @@ -2,39 +2,19 @@ package org.thoughtcrime.securesms.groups; import android.content.Context; import android.graphics.Bitmap; -import android.net.Uri; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.google.protobuf.ByteString; - -import org.thoughtcrime.securesms.attachments.Attachment; -import org.thoughtcrime.securesms.attachments.UriAttachment; import org.thoughtcrime.securesms.database.Address; -import org.thoughtcrime.securesms.database.AttachmentDatabase; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.GroupDatabase; -import org.thoughtcrime.securesms.database.ThreadDatabase; -import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage; -import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.sms.MessageSender; -import org.thoughtcrime.securesms.util.BitmapUtil; -import org.thoughtcrime.securesms.util.GroupUtil; -import org.thoughtcrime.securesms.util.MediaUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.util.InvalidNumberException; -import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext; -import java.io.IOException; import java.util.Collection; -import java.util.Collections; import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Set; -public class GroupManager { +public final class GroupManager { public static @NonNull GroupActionResult createGroup(@NonNull Context context, @NonNull Set members, @@ -42,23 +22,9 @@ public class GroupManager { @Nullable String name, boolean mms) { - final byte[] avatarBytes = BitmapUtil.toByteArray(avatar); - final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); - final String groupId = GroupUtil.getEncodedId(groupDatabase.allocateGroupId(), mms); - final Recipient groupRecipient = Recipient.from(context, Address.fromSerialized(groupId), false); - final Set
memberAddresses = getMemberAddresses(members); + Set
addresses = getMemberAddresses(members); - memberAddresses.add(Address.fromSerialized(TextSecurePreferences.getLocalNumber(context))); - groupDatabase.create(groupId, name, new LinkedList<>(memberAddresses), null, null); - - if (!mms) { - groupDatabase.updateAvatar(groupId, avatarBytes); - DatabaseFactory.getRecipientDatabase(context).setProfileSharing(groupRecipient, true); - return sendGroupUpdate(context, groupId, memberAddresses, name, avatarBytes); - } else { - long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipient, ThreadDatabase.DistributionTypes.CONVERSATION); - return new GroupActionResult(groupRecipient, threadId); - } + return V1GroupManager.createGroup(context, addresses, avatar, name, mms); } public static GroupActionResult updateGroup(@NonNull Context context, @@ -68,60 +34,9 @@ public class GroupManager { @Nullable String name) throws InvalidNumberException { - final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); - final Set
memberAddresses = getMemberAddresses(members); - final byte[] avatarBytes = BitmapUtil.toByteArray(avatar); + Set
addresses = getMemberAddresses(members); - memberAddresses.add(Address.fromSerialized(TextSecurePreferences.getLocalNumber(context))); - groupDatabase.updateMembers(groupId, new LinkedList<>(memberAddresses)); - groupDatabase.updateTitle(groupId, name); - groupDatabase.updateAvatar(groupId, avatarBytes); - - if (!GroupUtil.isMmsGroup(groupId)) { - return sendGroupUpdate(context, groupId, memberAddresses, name, avatarBytes); - } else { - Recipient groupRecipient = Recipient.from(context, Address.fromSerialized(groupId), true); - long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipient); - return new GroupActionResult(groupRecipient, threadId); - } - } - - private static GroupActionResult sendGroupUpdate(@NonNull Context context, - @NonNull String groupId, - @NonNull Set
members, - @Nullable String groupName, - @Nullable byte[] avatar) - { - try { - Attachment avatarAttachment = null; - Address groupAddress = Address.fromSerialized(groupId); - Recipient groupRecipient = Recipient.from(context, groupAddress, false); - - List numbers = new LinkedList<>(); - - for (Address member : members) { - numbers.add(member.serialize()); - } - - GroupContext.Builder groupContextBuilder = GroupContext.newBuilder() - .setId(ByteString.copyFrom(GroupUtil.getDecodedId(groupId))) - .setType(GroupContext.Type.UPDATE) - .addAllMembers(numbers); - if (groupName != null) groupContextBuilder.setName(groupName); - GroupContext groupContext = groupContextBuilder.build(); - - if (avatar != null) { - Uri avatarUri = BlobProvider.getInstance().forData(avatar).createForSingleUseInMemory(); - avatarAttachment = new UriAttachment(avatarUri, MediaUtil.IMAGE_PNG, AttachmentDatabase.TRANSFER_PROGRESS_DONE, avatar.length, null, false, false, null, null); - } - - OutgoingGroupMediaMessage outgoingMessage = new OutgoingGroupMediaMessage(groupRecipient, groupContext, avatarAttachment, System.currentTimeMillis(), 0, false, null, Collections.emptyList(), Collections.emptyList()); - long threadId = MessageSender.send(context, outgoingMessage, -1, false, null); - - return new GroupActionResult(groupRecipient, threadId); - } catch (IOException e) { - throw new AssertionError(e); - } + return V1GroupManager.updateGroup(context, groupId, addresses, avatar, name); } private static Set
getMemberAddresses(Collection recipients) { @@ -134,8 +49,8 @@ public class GroupManager { } public static class GroupActionResult { - private Recipient groupRecipient; - private long threadId; + private final Recipient groupRecipient; + private final long threadId; public GroupActionResult(Recipient groupRecipient, long threadId) { this.groupRecipient = groupRecipient; diff --git a/src/org/thoughtcrime/securesms/groups/V1GroupManager.java b/src/org/thoughtcrime/securesms/groups/V1GroupManager.java new file mode 100644 index 0000000000..b9fb0beef9 --- /dev/null +++ b/src/org/thoughtcrime/securesms/groups/V1GroupManager.java @@ -0,0 +1,125 @@ +package org.thoughtcrime.securesms.groups; + +import android.content.Context; +import android.graphics.Bitmap; +import android.net.Uri; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.google.protobuf.ByteString; + +import org.thoughtcrime.securesms.attachments.Attachment; +import org.thoughtcrime.securesms.attachments.UriAttachment; +import org.thoughtcrime.securesms.database.Address; +import org.thoughtcrime.securesms.database.AttachmentDatabase; +import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.database.GroupDatabase; +import org.thoughtcrime.securesms.database.ThreadDatabase; +import org.thoughtcrime.securesms.groups.GroupManager.GroupActionResult; +import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage; +import org.thoughtcrime.securesms.providers.BlobProvider; +import org.thoughtcrime.securesms.recipients.Recipient; +import org.thoughtcrime.securesms.sms.MessageSender; +import org.thoughtcrime.securesms.util.BitmapUtil; +import org.thoughtcrime.securesms.util.GroupUtil; +import org.thoughtcrime.securesms.util.MediaUtil; +import org.thoughtcrime.securesms.util.TextSecurePreferences; +import org.whispersystems.signalservice.api.util.InvalidNumberException; +import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +final class V1GroupManager { + + static @NonNull GroupActionResult createGroup(@NonNull Context context, + @NonNull Set
memberAddresses, + @Nullable Bitmap avatar, + @Nullable String name, + boolean mms) + { + final byte[] avatarBytes = BitmapUtil.toByteArray(avatar); + final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + final String groupId = GroupUtil.getEncodedId(groupDatabase.allocateGroupId(), mms); + final Recipient groupRecipient = Recipient.from(context, Address.fromSerialized(groupId), false); + + memberAddresses.add(Address.fromSerialized(TextSecurePreferences.getLocalNumber(context))); + groupDatabase.create(groupId, name, new LinkedList<>(memberAddresses), null, null); + + if (!mms) { + groupDatabase.updateAvatar(groupId, avatarBytes); + DatabaseFactory.getRecipientDatabase(context).setProfileSharing(groupRecipient, true); + return sendGroupUpdate(context, groupId, memberAddresses, name, avatarBytes); + } else { + long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipient, ThreadDatabase.DistributionTypes.CONVERSATION); + return new GroupActionResult(groupRecipient, threadId); + } + } + + static GroupActionResult updateGroup(@NonNull Context context, + @NonNull String groupId, + @NonNull Set
memberAddresses, + @Nullable Bitmap avatar, + @Nullable String name) + throws InvalidNumberException + { + final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); + final byte[] avatarBytes = BitmapUtil.toByteArray(avatar); + + memberAddresses.add(Address.fromSerialized(TextSecurePreferences.getLocalNumber(context))); + groupDatabase.updateMembers(groupId, new LinkedList<>(memberAddresses)); + groupDatabase.updateTitle(groupId, name); + groupDatabase.updateAvatar(groupId, avatarBytes); + + if (!GroupUtil.isMmsGroup(groupId)) { + return sendGroupUpdate(context, groupId, memberAddresses, name, avatarBytes); + } else { + Recipient groupRecipient = Recipient.from(context, Address.fromSerialized(groupId), true); + long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipient); + return new GroupActionResult(groupRecipient, threadId); + } + } + + private static GroupActionResult sendGroupUpdate(@NonNull Context context, + @NonNull String groupId, + @NonNull Set
members, + @Nullable String groupName, + @Nullable byte[] avatar) + { + try { + Attachment avatarAttachment = null; + Address groupAddress = Address.fromSerialized(groupId); + Recipient groupRecipient = Recipient.from(context, groupAddress, false); + + List numbers = new LinkedList<>(); + + for (Address member : members) { + numbers.add(member.serialize()); + } + + GroupContext.Builder groupContextBuilder = GroupContext.newBuilder() + .setId(ByteString.copyFrom(GroupUtil.getDecodedId(groupId))) + .setType(GroupContext.Type.UPDATE) + .addAllMembers(numbers); + if (groupName != null) groupContextBuilder.setName(groupName); + GroupContext groupContext = groupContextBuilder.build(); + + if (avatar != null) { + Uri avatarUri = BlobProvider.getInstance().forData(avatar).createForSingleUseInMemory(); + avatarAttachment = new UriAttachment(avatarUri, MediaUtil.IMAGE_PNG, AttachmentDatabase.TRANSFER_PROGRESS_DONE, avatar.length, null, false, false, null, null); + } + + OutgoingGroupMediaMessage outgoingMessage = new OutgoingGroupMediaMessage(groupRecipient, groupContext, avatarAttachment, System.currentTimeMillis(), 0, false, null, Collections.emptyList(), Collections.emptyList()); + long threadId = MessageSender.send(context, outgoingMessage, -1, false, null); + + return new GroupActionResult(groupRecipient, threadId); + } catch (IOException e) { + throw new AssertionError(e); + } + } +}