GroupId class.
This commit is contained in:
parent
a73a73e42c
commit
a860315587
43 changed files with 519 additions and 365 deletions
|
@ -54,6 +54,7 @@ import org.thoughtcrime.securesms.database.GroupDatabase;
|
|||
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.GroupManager;
|
||||
import org.thoughtcrime.securesms.groups.GroupManager.GroupActionResult;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
@ -208,7 +209,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
|||
}
|
||||
|
||||
private void initializeExistingGroup() {
|
||||
final String groupId = getIntent().getStringExtra(GROUP_ID_EXTRA);
|
||||
final GroupId groupId = GroupId.parseNullable(getIntent().getStringExtra(GROUP_ID_EXTRA));
|
||||
|
||||
if (groupId != null) {
|
||||
new FillExistingGroupInfoAsyncTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, groupId);
|
||||
|
@ -361,7 +362,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
|||
}
|
||||
memberAddresses.add(Recipient.self().getId());
|
||||
|
||||
String groupId = DatabaseFactory.getGroupDatabase(activity).getOrCreateGroupForMembers(memberAddresses, true);
|
||||
GroupId groupId = DatabaseFactory.getGroupDatabase(activity).getOrCreateGroupForMembers(memberAddresses, true);
|
||||
RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(activity).getOrInsertFromGroupId(groupId);
|
||||
Recipient groupRecipient = Recipient.resolved(groupRecipientId);
|
||||
long threadId = DatabaseFactory.getThreadDatabase(activity).getThreadIdFor(groupRecipient, ThreadDatabase.DistributionTypes.DEFAULT);
|
||||
|
@ -443,9 +444,9 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
|||
}
|
||||
|
||||
private static class UpdateSignalGroupTask extends SignalGroupTask {
|
||||
private String groupId;
|
||||
private final GroupId groupId;
|
||||
|
||||
public UpdateSignalGroupTask(GroupCreateActivity activity, String groupId,
|
||||
public UpdateSignalGroupTask(GroupCreateActivity activity, GroupId groupId,
|
||||
Bitmap avatar, String name, Set<Recipient> members)
|
||||
{
|
||||
super(activity, avatar, name, members);
|
||||
|
@ -467,7 +468,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
|||
if (!activity.isFinishing()) {
|
||||
Intent intent = activity.getIntent();
|
||||
intent.putExtra(GROUP_THREAD_EXTRA, result.get().getThreadId());
|
||||
intent.putExtra(GROUP_ID_EXTRA, result.get().getGroupRecipient().requireGroupId());
|
||||
intent.putExtra(GROUP_ID_EXTRA, result.get().getGroupRecipient().requireGroupId().toString());
|
||||
activity.setResult(RESULT_OK, intent);
|
||||
activity.finish();
|
||||
}
|
||||
|
@ -534,7 +535,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
|||
}
|
||||
}
|
||||
|
||||
private static class FillExistingGroupInfoAsyncTask extends ProgressDialogAsyncTask<String,Void,Optional<GroupData>> {
|
||||
private static class FillExistingGroupInfoAsyncTask extends ProgressDialogAsyncTask<GroupId, Void, Optional<GroupData>> {
|
||||
private GroupCreateActivity activity;
|
||||
|
||||
public FillExistingGroupInfoAsyncTask(GroupCreateActivity activity) {
|
||||
|
@ -545,7 +546,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Optional<GroupData> doInBackground(String... groupIds) {
|
||||
protected Optional<GroupData> doInBackground(GroupId... groupIds) {
|
||||
final GroupDatabase db = DatabaseFactory.getGroupDatabase(activity);
|
||||
final List<Recipient> recipients = db.getGroupMembers(groupIds[0], false);
|
||||
final Optional<GroupRecord> group = db.getGroup(groupIds[0]);
|
||||
|
@ -593,13 +594,13 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
|||
}
|
||||
|
||||
private static class GroupData {
|
||||
String id;
|
||||
GroupId id;
|
||||
Set<Recipient> recipients;
|
||||
Bitmap avatarBmp;
|
||||
byte[] avatarBytes;
|
||||
String name;
|
||||
|
||||
public GroupData(String id, Set<Recipient> recipients, Bitmap avatarBmp, byte[] avatarBytes, String name) {
|
||||
GroupData(GroupId id, Set<Recipient> recipients, Bitmap avatarBmp, byte[] avatarBytes, String name) {
|
||||
this.id = id;
|
||||
this.recipients = recipients;
|
||||
this.avatarBmp = avatarBmp;
|
||||
|
|
|
@ -202,7 +202,7 @@ public class ContactAccessor {
|
|||
reader = DatabaseFactory.getGroupDatabase(context).getGroupsFilteredByTitle(constraint, true);
|
||||
|
||||
while ((record = reader.getNext()) != null) {
|
||||
numberList.add(record.getEncodedId());
|
||||
numberList.add(record.getId().toString());
|
||||
}
|
||||
} finally {
|
||||
if (reader != null)
|
||||
|
|
|
@ -2,24 +2,24 @@ package org.thoughtcrime.securesms.contacts;
|
|||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.AvatarImageView;
|
||||
import org.thoughtcrime.securesms.components.FromTextView;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.recipients.LiveRecipient;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientForeverObserver;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
|
@ -106,7 +106,7 @@ public class ContactSelectionListItem extends LinearLayout implements RecipientF
|
|||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private void setText(@Nullable Recipient recipient, int type, String name, String number, String label) {
|
||||
if (number == null || number.isEmpty() || GroupUtil.isEncodedGroup(number)) {
|
||||
if (number == null || number.isEmpty() || GroupId.isEncodedGroup(number)) {
|
||||
this.nameView.setEnabled(false);
|
||||
this.numberView.setText("");
|
||||
this.labelView.setVisibility(View.GONE);
|
||||
|
|
|
@ -22,10 +22,11 @@ import android.database.Cursor;
|
|||
import android.database.MatrixCursor;
|
||||
import android.database.MergeCursor;
|
||||
import android.provider.ContactsContract;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.loader.content.CursorLoader;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
|
@ -35,8 +36,8 @@ import org.thoughtcrime.securesms.database.ThreadDatabase;
|
|||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.phonenumbers.NumberUtil;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.UsernameUtil;
|
||||
|
@ -226,7 +227,7 @@ public class ContactsCursorLoader extends CursorLoader {
|
|||
ThreadRecord threadRecord;
|
||||
while ((threadRecord = reader.getNext()) != null) {
|
||||
Recipient recipient = threadRecord.getRecipient();
|
||||
String stringId = recipient.isGroup() ? recipient.requireGroupId() : recipient.getE164().or(recipient.getEmail()).or("");
|
||||
String stringId = recipient.isGroup() ? recipient.requireGroupId().toString() : recipient.getE164().or(recipient.getEmail()).or("");
|
||||
|
||||
recentConversations.addRow(new Object[] { recipient.getId().serialize(),
|
||||
recipient.toShortString(getContext()),
|
||||
|
@ -265,7 +266,7 @@ public class ContactsCursorLoader extends CursorLoader {
|
|||
while ((groupRecord = reader.getNext()) != null) {
|
||||
groupContacts.addRow(new Object[] { groupRecord.getRecipientId().serialize(),
|
||||
groupRecord.getTitle(),
|
||||
groupRecord.getEncodedId(),
|
||||
groupRecord.getId(),
|
||||
ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM,
|
||||
"",
|
||||
ContactRepository.NORMAL_TYPE });
|
||||
|
|
|
@ -3,11 +3,13 @@ package org.thoughtcrime.securesms.contacts.avatars;
|
|||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.util.Conversions;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
|
@ -16,12 +18,12 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public class GroupRecordContactPhoto implements ContactPhoto {
|
||||
public final class GroupRecordContactPhoto implements ContactPhoto {
|
||||
|
||||
private final String groupId;
|
||||
private final long avatarId;
|
||||
private final GroupId groupId;
|
||||
private final long avatarId;
|
||||
|
||||
public GroupRecordContactPhoto(@NonNull String groupId, long avatarId) {
|
||||
public GroupRecordContactPhoto(@NonNull GroupId groupId, long avatarId) {
|
||||
this.groupId = groupId;
|
||||
this.avatarId = avatarId;
|
||||
}
|
||||
|
@ -50,13 +52,13 @@ public class GroupRecordContactPhoto implements ContactPhoto {
|
|||
|
||||
@Override
|
||||
public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) {
|
||||
messageDigest.update(groupId.getBytes());
|
||||
messageDigest.update(groupId.toString().getBytes());
|
||||
messageDigest.update(Conversions.longToByteArray(avatarId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || !(other instanceof GroupRecordContactPhoto)) return false;
|
||||
if (!(other instanceof GroupRecordContactPhoto)) return false;
|
||||
|
||||
GroupRecordContactPhoto that = (GroupRecordContactPhoto)other;
|
||||
return this.groupId.equals(that.groupId) && this.avatarId == that.avatarId;
|
||||
|
|
|
@ -1140,7 +1140,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
|
||||
private void handleEditPushGroup() {
|
||||
Intent intent = new Intent(ConversationActivity.this, GroupCreateActivity.class);
|
||||
intent.putExtra(GroupCreateActivity.GROUP_ID_EXTRA, recipient.get().requireGroupId());
|
||||
intent.putExtra(GroupCreateActivity.GROUP_ID_EXTRA, recipient.get().requireGroupId().toString());
|
||||
startActivityForResult(intent, GROUP_EDIT);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,25 +6,25 @@ import android.content.ContentValues;
|
|||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import net.sqlcipher.database.SQLiteDatabase;
|
||||
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -95,9 +95,9 @@ public class GroupDatabase extends Database {
|
|||
}
|
||||
}
|
||||
|
||||
public Optional<GroupRecord> getGroup(String groupId) {
|
||||
public Optional<GroupRecord> getGroup(@NonNull GroupId groupId) {
|
||||
try (Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, null, GROUP_ID + " = ?",
|
||||
new String[] {groupId},
|
||||
new String[] {groupId.toString()},
|
||||
null, null, null))
|
||||
{
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
|
@ -113,7 +113,7 @@ public class GroupDatabase extends Database {
|
|||
return Optional.fromNullable(reader.getCurrent());
|
||||
}
|
||||
|
||||
public boolean isUnknownGroup(String groupId) {
|
||||
public boolean isUnknownGroup(@NonNull GroupId groupId) {
|
||||
Optional<GroupRecord> group = getGroup(groupId);
|
||||
|
||||
if (!group.isPresent()) {
|
||||
|
@ -143,7 +143,7 @@ public class GroupDatabase extends Database {
|
|||
return new Reader(cursor);
|
||||
}
|
||||
|
||||
public String getOrCreateGroupForMembers(List<RecipientId> members, boolean mms) {
|
||||
public GroupId getOrCreateGroupForMembers(List<RecipientId> members, boolean mms) {
|
||||
Collections.sort(members);
|
||||
|
||||
Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[] {GROUP_ID},
|
||||
|
@ -152,9 +152,9 @@ public class GroupDatabase extends Database {
|
|||
null, null, null);
|
||||
try {
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
return cursor.getString(cursor.getColumnIndexOrThrow(GROUP_ID));
|
||||
return GroupId.parse(cursor.getString(cursor.getColumnIndexOrThrow(GROUP_ID)));
|
||||
} else {
|
||||
String groupId = GroupUtil.getEncodedId(allocateGroupId(), mms);
|
||||
GroupId groupId = allocateGroupId(mms);
|
||||
create(groupId, null, members, null, null);
|
||||
return groupId;
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ public class GroupDatabase extends Database {
|
|||
return new Reader(cursor);
|
||||
}
|
||||
|
||||
public @NonNull List<Recipient> getGroupMembers(String groupId, boolean includeSelf) {
|
||||
public @NonNull List<Recipient> getGroupMembers(@NonNull GroupId groupId, boolean includeSelf) {
|
||||
List<RecipientId> members = getCurrentMembers(groupId);
|
||||
List<Recipient> recipients = new LinkedList<>();
|
||||
|
||||
|
@ -212,14 +212,14 @@ public class GroupDatabase extends Database {
|
|||
return recipients;
|
||||
}
|
||||
|
||||
public void create(@NonNull String groupId, @Nullable String title, @NonNull List<RecipientId> members,
|
||||
public void create(@NonNull GroupId groupId, @Nullable String title, @NonNull List<RecipientId> members,
|
||||
@Nullable SignalServiceAttachmentPointer avatar, @Nullable String relay)
|
||||
{
|
||||
Collections.sort(members);
|
||||
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(RECIPIENT_ID, DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId).serialize());
|
||||
contentValues.put(GROUP_ID, groupId);
|
||||
contentValues.put(GROUP_ID, groupId.toString());
|
||||
contentValues.put(TITLE, title);
|
||||
contentValues.put(MEMBERS, RecipientId.toSerializedList(members));
|
||||
|
||||
|
@ -233,7 +233,7 @@ public class GroupDatabase extends Database {
|
|||
contentValues.put(AVATAR_RELAY, relay);
|
||||
contentValues.put(TIMESTAMP, System.currentTimeMillis());
|
||||
contentValues.put(ACTIVE, 1);
|
||||
contentValues.put(MMS, GroupUtil.isMmsGroup(groupId));
|
||||
contentValues.put(MMS, groupId.isMmsGroup());
|
||||
|
||||
databaseHelper.getWritableDatabase().insert(TABLE_NAME, null, contentValues);
|
||||
|
||||
|
@ -243,7 +243,7 @@ public class GroupDatabase extends Database {
|
|||
notifyConversationListListeners();
|
||||
}
|
||||
|
||||
public void update(String groupId, String title, SignalServiceAttachmentPointer avatar) {
|
||||
public void update(@NonNull GroupId groupId, String title, SignalServiceAttachmentPointer avatar) {
|
||||
ContentValues contentValues = new ContentValues();
|
||||
if (title != null) contentValues.put(TITLE, title);
|
||||
|
||||
|
@ -256,7 +256,7 @@ public class GroupDatabase extends Database {
|
|||
|
||||
databaseHelper.getWritableDatabase().update(TABLE_NAME, contentValues,
|
||||
GROUP_ID + " = ?",
|
||||
new String[] {groupId});
|
||||
new String[] {groupId.toString()});
|
||||
|
||||
RecipientId groupRecipient = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId);
|
||||
Recipient.live(groupRecipient).refresh();
|
||||
|
@ -264,21 +264,21 @@ public class GroupDatabase extends Database {
|
|||
notifyConversationListListeners();
|
||||
}
|
||||
|
||||
public void updateTitle(String groupId, String title) {
|
||||
public void updateTitle(@NonNull GroupId groupId, String title) {
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(TITLE, title);
|
||||
databaseHelper.getWritableDatabase().update(TABLE_NAME, contentValues, GROUP_ID + " = ?",
|
||||
new String[] {groupId});
|
||||
new String[] {groupId.toString()});
|
||||
|
||||
RecipientId groupRecipient = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId);
|
||||
Recipient.live(groupRecipient).refresh();
|
||||
}
|
||||
|
||||
public void updateAvatar(String groupId, Bitmap avatar) {
|
||||
public void updateAvatar(@NonNull GroupId groupId, @Nullable Bitmap avatar) {
|
||||
updateAvatar(groupId, BitmapUtil.toByteArray(avatar));
|
||||
}
|
||||
|
||||
public void updateAvatar(String groupId, byte[] avatar) {
|
||||
public void updateAvatar(@NonNull GroupId groupId, @Nullable byte[] avatar) {
|
||||
long avatarId;
|
||||
|
||||
if (avatar != null) avatarId = Math.abs(new SecureRandom().nextLong());
|
||||
|
@ -290,13 +290,13 @@ public class GroupDatabase extends Database {
|
|||
contentValues.put(AVATAR_ID, avatarId);
|
||||
|
||||
databaseHelper.getWritableDatabase().update(TABLE_NAME, contentValues, GROUP_ID + " = ?",
|
||||
new String[] {groupId});
|
||||
new String[] {groupId.toString()});
|
||||
|
||||
RecipientId groupRecipient = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId);
|
||||
Recipient.live(groupRecipient).refresh();
|
||||
}
|
||||
|
||||
public void updateMembers(String groupId, List<RecipientId> members) {
|
||||
public void updateMembers(@NonNull GroupId groupId, List<RecipientId> members) {
|
||||
Collections.sort(members);
|
||||
|
||||
ContentValues contents = new ContentValues();
|
||||
|
@ -304,13 +304,13 @@ public class GroupDatabase extends Database {
|
|||
contents.put(ACTIVE, 1);
|
||||
|
||||
databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?",
|
||||
new String[] {groupId});
|
||||
new String[] {groupId.toString()});
|
||||
|
||||
RecipientId groupRecipient = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId);
|
||||
Recipient.live(groupRecipient).refresh();
|
||||
}
|
||||
|
||||
public void remove(String groupId, RecipientId source) {
|
||||
public void remove(@NonNull GroupId groupId, RecipientId source) {
|
||||
List<RecipientId> currentMembers = getCurrentMembers(groupId);
|
||||
currentMembers.remove(source);
|
||||
|
||||
|
@ -318,19 +318,19 @@ public class GroupDatabase extends Database {
|
|||
contents.put(MEMBERS, RecipientId.toSerializedList(currentMembers));
|
||||
|
||||
databaseHelper.getWritableDatabase().update(TABLE_NAME, contents, GROUP_ID + " = ?",
|
||||
new String[] {groupId});
|
||||
new String[] {groupId.toString()});
|
||||
|
||||
RecipientId groupRecipient = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId);
|
||||
Recipient.live(groupRecipient).refresh();
|
||||
}
|
||||
|
||||
private List<RecipientId> getCurrentMembers(String groupId) {
|
||||
private List<RecipientId> getCurrentMembers(@NonNull GroupId groupId) {
|
||||
Cursor cursor = null;
|
||||
|
||||
try {
|
||||
cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[] {MEMBERS},
|
||||
GROUP_ID + " = ?",
|
||||
new String[] {groupId},
|
||||
new String[] {groupId.toString()},
|
||||
null, null, null);
|
||||
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
|
@ -345,23 +345,22 @@ public class GroupDatabase extends Database {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isActive(String groupId) {
|
||||
public boolean isActive(@NonNull GroupId groupId) {
|
||||
Optional<GroupRecord> record = getGroup(groupId);
|
||||
return record.isPresent() && record.get().isActive();
|
||||
}
|
||||
|
||||
public void setActive(String groupId, boolean active) {
|
||||
public void setActive(@NonNull GroupId groupId, boolean active) {
|
||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(ACTIVE, active ? 1 : 0);
|
||||
database.update(TABLE_NAME, values, GROUP_ID + " = ?", new String[] {groupId});
|
||||
database.update(TABLE_NAME, values, GROUP_ID + " = ?", new String[] {groupId.toString()});
|
||||
}
|
||||
|
||||
|
||||
public byte[] allocateGroupId() {
|
||||
public static GroupId allocateGroupId(boolean mms) {
|
||||
byte[] groupId = new byte[16];
|
||||
new SecureRandom().nextBytes(groupId);
|
||||
return groupId;
|
||||
return mms ? GroupId.mms(groupId) : GroupId.v1(groupId);
|
||||
}
|
||||
|
||||
public static class Reader implements Closeable {
|
||||
|
@ -385,7 +384,7 @@ public class GroupDatabase extends Database {
|
|||
return null;
|
||||
}
|
||||
|
||||
return new GroupRecord(cursor.getString(cursor.getColumnIndexOrThrow(GROUP_ID)),
|
||||
return new GroupRecord(GroupId.parse(cursor.getString(cursor.getColumnIndexOrThrow(GROUP_ID))),
|
||||
RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(RECIPIENT_ID))),
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(TITLE)),
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(MEMBERS)),
|
||||
|
@ -408,7 +407,7 @@ public class GroupDatabase extends Database {
|
|||
|
||||
public static class GroupRecord {
|
||||
|
||||
private final String id;
|
||||
private final GroupId id;
|
||||
private final RecipientId recipientId;
|
||||
private final String title;
|
||||
private final List<RecipientId> members;
|
||||
|
@ -421,7 +420,7 @@ public class GroupDatabase extends Database {
|
|||
private final boolean active;
|
||||
private final boolean mms;
|
||||
|
||||
public GroupRecord(String id, @NonNull RecipientId recipientId, String title, String members, byte[] avatar,
|
||||
public GroupRecord(@NonNull GroupId id, @NonNull RecipientId recipientId, String title, String members, byte[] avatar,
|
||||
long avatarId, byte[] avatarKey, String avatarContentType,
|
||||
String relay, boolean active, byte[] avatarDigest, boolean mms)
|
||||
{
|
||||
|
@ -441,22 +440,14 @@ public class GroupDatabase extends Database {
|
|||
else this.members = new LinkedList<>();
|
||||
}
|
||||
|
||||
public byte[] getId() {
|
||||
try {
|
||||
return GroupUtil.getDecodedId(id);
|
||||
} catch (IOException ioe) {
|
||||
throw new AssertionError(ioe);
|
||||
}
|
||||
public GroupId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public @NonNull RecipientId getRecipientId() {
|
||||
return recipientId;
|
||||
}
|
||||
|
||||
public String getEncodedId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
|
|
@ -17,22 +17,20 @@ import net.sqlcipher.database.SQLiteDatabase;
|
|||
import org.signal.zkgroup.profiles.ProfileKey;
|
||||
import org.signal.zkgroup.profiles.ProfileKeyCredential;
|
||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper.RecordUpdate;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncModels;
|
||||
import org.thoughtcrime.securesms.database.IdentityDatabase.IdentityRecord;
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.jobs.StorageSyncJob;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper.RecordUpdate;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncModels;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||
import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.IdentityKey;
|
||||
import org.whispersystems.libsignal.InvalidKeyException;
|
||||
|
@ -352,13 +350,13 @@ public class RecipientDatabase extends Database {
|
|||
return getOrInsertByColumn(EMAIL, email).recipientId;
|
||||
}
|
||||
|
||||
public @NonNull RecipientId getOrInsertFromGroupId(@NonNull String groupId) {
|
||||
GetOrInsertResult result = getOrInsertByColumn(GROUP_ID, groupId);
|
||||
public @NonNull RecipientId getOrInsertFromGroupId(@NonNull GroupId groupId) {
|
||||
GetOrInsertResult result = getOrInsertByColumn(GROUP_ID, groupId.toString());
|
||||
|
||||
if (result.neededInsert) {
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
if (GroupUtil.isMmsGroup(groupId)) {
|
||||
if (groupId.isMmsGroup()) {
|
||||
values.put(GROUP_TYPE, GroupType.MMS.getId());
|
||||
} else {
|
||||
values.put(GROUP_TYPE, GroupType.SIGNAL_V1.getId());
|
||||
|
@ -563,7 +561,7 @@ public class RecipientDatabase extends Database {
|
|||
for (SignalGroupV1Record insert : groupV1Inserts) {
|
||||
db.insertOrThrow(TABLE_NAME, null, getValuesForStorageGroupV1(insert));
|
||||
|
||||
Recipient recipient = Recipient.externalGroup(context, GroupUtil.getEncodedId(insert.getGroupId(), false));
|
||||
Recipient recipient = Recipient.externalGroup(context, GroupId.v1(insert.getGroupId()));
|
||||
|
||||
threadDatabase.setArchived(recipient.getId(), insert.isArchived());
|
||||
recipient.live().refresh();
|
||||
|
@ -577,7 +575,7 @@ public class RecipientDatabase extends Database {
|
|||
throw new AssertionError("Had an update, but it didn't match any rows!");
|
||||
}
|
||||
|
||||
Recipient recipient = Recipient.externalGroup(context, GroupUtil.getEncodedId(update.getOld().getGroupId(), false));
|
||||
Recipient recipient = Recipient.externalGroup(context, GroupId.v1(update.getOld().getGroupId()));
|
||||
|
||||
threadDatabase.setArchived(recipient.getId(), update.getNew().isArchived());
|
||||
recipient.live().refresh();
|
||||
|
@ -672,7 +670,7 @@ public class RecipientDatabase extends Database {
|
|||
|
||||
private static @NonNull ContentValues getValuesForStorageGroupV1(@NonNull SignalGroupV1Record groupV1) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(GROUP_ID, GroupUtil.getEncodedId(groupV1.getGroupId(), false));
|
||||
values.put(GROUP_ID, GroupId.v1(groupV1.getGroupId()).toString());
|
||||
values.put(GROUP_TYPE, GroupType.SIGNAL_V1.getId());
|
||||
values.put(PROFILE_SHARING, groupV1.isProfileSharingEnabled() ? "1" : "0");
|
||||
values.put(BLOCKED, groupV1.isBlocked() ? "1" : "0");
|
||||
|
@ -729,13 +727,13 @@ public class RecipientDatabase extends Database {
|
|||
return out;
|
||||
}
|
||||
|
||||
private @NonNull RecipientSettings getRecipientSettings(@NonNull Cursor cursor) {
|
||||
private static @NonNull RecipientSettings getRecipientSettings(@NonNull Cursor cursor) {
|
||||
long id = cursor.getLong(cursor.getColumnIndexOrThrow(ID));
|
||||
UUID uuid = UuidUtil.parseOrNull(cursor.getString(cursor.getColumnIndexOrThrow(UUID)));
|
||||
String username = cursor.getString(cursor.getColumnIndexOrThrow(USERNAME));
|
||||
String e164 = cursor.getString(cursor.getColumnIndexOrThrow(PHONE));
|
||||
String email = cursor.getString(cursor.getColumnIndexOrThrow(EMAIL));
|
||||
String groupId = cursor.getString(cursor.getColumnIndexOrThrow(GROUP_ID));
|
||||
GroupId groupId = GroupId.parseNullable(cursor.getString(cursor.getColumnIndexOrThrow(GROUP_ID)));
|
||||
int groupType = cursor.getInt(cursor.getColumnIndexOrThrow(GROUP_TYPE));
|
||||
boolean blocked = cursor.getInt(cursor.getColumnIndexOrThrow(BLOCKED)) == 1;
|
||||
String messageRingtone = cursor.getString(cursor.getColumnIndexOrThrow(MESSAGE_RINGTONE));
|
||||
|
@ -1408,10 +1406,10 @@ public class RecipientDatabase extends Database {
|
|||
db.update(TABLE_NAME, setBlocked, UUID + " = ?", new String[] { uuid });
|
||||
}
|
||||
|
||||
List<String> groupIdStrings = Stream.of(groupIds).map(g -> GroupUtil.getEncodedId(g, false)).toList();
|
||||
List<GroupId> groupIdStrings = Stream.of(groupIds).map(GroupId::v1).toList();
|
||||
|
||||
for (String groupId : groupIdStrings) {
|
||||
db.update(TABLE_NAME, setBlocked, GROUP_ID + " = ?", new String[] { groupId });
|
||||
for (GroupId groupId : groupIdStrings) {
|
||||
db.update(TABLE_NAME, setBlocked, GROUP_ID + " = ?", new String[] { groupId.toString() });
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
|
@ -1637,7 +1635,7 @@ public class RecipientDatabase extends Database {
|
|||
private final String username;
|
||||
private final String e164;
|
||||
private final String email;
|
||||
private final String groupId;
|
||||
private final GroupId groupId;
|
||||
private final GroupType groupType;
|
||||
private final boolean blocked;
|
||||
private final long muteUntil;
|
||||
|
@ -1673,7 +1671,7 @@ public class RecipientDatabase extends Database {
|
|||
@Nullable String username,
|
||||
@Nullable String e164,
|
||||
@Nullable String email,
|
||||
@Nullable String groupId,
|
||||
@Nullable GroupId groupId,
|
||||
@NonNull GroupType groupType,
|
||||
boolean blocked,
|
||||
long muteUntil,
|
||||
|
@ -1761,7 +1759,7 @@ public class RecipientDatabase extends Database {
|
|||
return email;
|
||||
}
|
||||
|
||||
public @Nullable String getGroupId() {
|
||||
public @Nullable GroupId getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.content.Context;
|
|||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
@ -27,6 +28,7 @@ import com.annimon.stream.Stream;
|
|||
import net.sqlcipher.database.SQLiteDatabase;
|
||||
import net.sqlcipher.database.SQLiteStatement;
|
||||
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
|
@ -231,7 +233,7 @@ public class SmsMigrator {
|
|||
|
||||
List<RecipientId> recipientIds = Stream.of(ourRecipients).map(Recipient::getId).toList();
|
||||
|
||||
String ourGroupId = DatabaseFactory.getGroupDatabase(context).getOrCreateGroupForMembers(recipientIds, true);
|
||||
GroupId ourGroupId = DatabaseFactory.getGroupDatabase(context).getOrCreateGroupForMembers(recipientIds, true);
|
||||
RecipientId ourGroupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(ourGroupId);
|
||||
Recipient ourGroupRecipient = Recipient.resolved(ourGroupRecipientId);
|
||||
long ourThreadId = threadDatabase.getThreadIdFor(ourGroupRecipient, ThreadDatabase.DistributionTypes.CONVERSATION);
|
||||
|
|
|
@ -10,9 +10,9 @@ import android.database.sqlite.SQLiteDatabase;
|
|||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.net.Uri;
|
||||
import android.provider.ContactsContract;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.i18n.phonenumbers.NumberParseException;
|
||||
|
@ -35,13 +35,14 @@ import org.thoughtcrime.securesms.database.PushDatabase;
|
|||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.migrations.LegacyMigrationJob;
|
||||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
import org.thoughtcrime.securesms.phonenumbers.NumberUtil;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.DelimiterUtil;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.Hex;
|
||||
import org.thoughtcrime.securesms.util.JsonUtils;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
|
@ -1274,7 +1275,7 @@ public class ClassicOpenHelper extends SQLiteOpenHelper {
|
|||
while (cursor != null && cursor.moveToNext()) {
|
||||
String address = cursor.getString(cursor.getColumnIndexOrThrow("recipient_ids"));
|
||||
|
||||
if (!TextUtils.isEmpty(address) && !GroupUtil.isEncodedGroup(address) && !NumberUtil.isValidEmail(address)) {
|
||||
if (!TextUtils.isEmpty(address) && !GroupId.isEncodedGroup(address) && !NumberUtil.isValidEmail(address)) {
|
||||
Uri lookup = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address));
|
||||
|
||||
try (Cursor contactCursor = context.getContentResolver().query(lookup, new String[] {ContactsContract.PhoneLookup.DISPLAY_NAME,
|
||||
|
|
|
@ -9,10 +9,10 @@ import androidx.annotation.Nullable;
|
|||
|
||||
import net.sqlcipher.database.SQLiteDatabase;
|
||||
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.phonenumbers.NumberUtil;
|
||||
import org.thoughtcrime.securesms.util.DelimiterUtil;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
@ -153,7 +153,7 @@ public class RecipientIdMigrationHelper {
|
|||
try (Cursor cursor = db.query("recipient_preferences", null, null, null, null, null, null)) {
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
String address = cursor.getString(cursor.getColumnIndexOrThrow("recipient_ids"));
|
||||
boolean isGroup = GroupUtil.isEncodedGroup(address);
|
||||
boolean isGroup = GroupId.isEncodedGroup(address);
|
||||
boolean isEmail = !isGroup && NumberUtil.isValidEmail(address);
|
||||
boolean isPhone = !isGroup && !isEmail;
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ import net.sqlcipher.database.SQLiteDatabase;
|
|||
import net.sqlcipher.database.SQLiteDatabaseHook;
|
||||
import net.sqlcipher.database.SQLiteOpenHelper;
|
||||
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.crypto.DatabaseSecret;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
|
@ -44,13 +43,14 @@ import org.thoughtcrime.securesms.database.StickerDatabase;
|
|||
import org.thoughtcrime.securesms.database.StorageKeyDatabase;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter;
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
@ -349,7 +349,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
|||
String displayName = NotificationChannels.getChannelDisplayNameFor(context, systemName, profileName, null, address);
|
||||
boolean vibrateEnabled = vibrateState == 0 ? TextSecurePreferences.isNotificationVibrateEnabled(context) : vibrateState == 1;
|
||||
|
||||
if (GroupUtil.isEncodedGroup(address)) {
|
||||
if (GroupId.isEncodedGroup(address)) {
|
||||
try(Cursor groupCursor = db.rawQuery("SELECT title FROM groups WHERE group_id = ?", new String[] { address })) {
|
||||
if (groupCursor != null && groupCursor.moveToFirst()) {
|
||||
String title = groupCursor.getString(groupCursor.getColumnIndexOrThrow("title"));
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
package org.thoughtcrime.securesms.groups;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.util.Hex;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class GroupId {
|
||||
|
||||
private static final String ENCODED_SIGNAL_GROUP_PREFIX = "__textsecure_group__!";
|
||||
private static final String ENCODED_MMS_GROUP_PREFIX = "__signal_mms_group__!";
|
||||
|
||||
private final String encodedId;
|
||||
|
||||
private GroupId(@NonNull String encodedId) {
|
||||
this.encodedId = encodedId;
|
||||
}
|
||||
|
||||
public static @NonNull GroupId v1(byte[] gv1GroupIdBytes) {
|
||||
return new GroupId(ENCODED_SIGNAL_GROUP_PREFIX + Hex.toStringCondensed(gv1GroupIdBytes));
|
||||
}
|
||||
|
||||
public static @NonNull GroupId mms(byte[] mmsGroupIdBytes) {
|
||||
return new GroupId(ENCODED_MMS_GROUP_PREFIX + Hex.toStringCondensed(mmsGroupIdBytes));
|
||||
}
|
||||
|
||||
public static @NonNull GroupId parse(@NonNull String encodedGroupId) {
|
||||
try {
|
||||
if (!isEncodedGroup(encodedGroupId)) {
|
||||
throw new IOException("Invalid encoding");
|
||||
}
|
||||
|
||||
byte[] bytes = extractDecodedId(encodedGroupId);
|
||||
return isMmsGroup(encodedGroupId) ? mms(bytes) : v1(bytes);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static @Nullable GroupId parseNullable(@Nullable String encodedGroupId) {
|
||||
if (encodedGroupId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return parse(encodedGroupId);
|
||||
}
|
||||
|
||||
public static boolean isEncodedGroup(@NonNull String groupId) {
|
||||
return groupId.startsWith(ENCODED_SIGNAL_GROUP_PREFIX) || groupId.startsWith(ENCODED_MMS_GROUP_PREFIX);
|
||||
}
|
||||
|
||||
private static byte[] extractDecodedId(@NonNull String encodedGroupId) throws IOException {
|
||||
return Hex.fromStringCondensed(encodedGroupId.split("!", 2)[1]);
|
||||
}
|
||||
|
||||
private static boolean isMmsGroup(@NonNull String groupId) {
|
||||
return groupId.startsWith(ENCODED_MMS_GROUP_PREFIX);
|
||||
}
|
||||
|
||||
public byte[] getDecodedId() {
|
||||
try {
|
||||
return extractDecodedId(encodedId);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isMmsGroup() {
|
||||
return isMmsGroup(encodedId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (obj instanceof GroupId) {
|
||||
return ((GroupId) obj).encodedId.equals(encodedId);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return encodedId.hashCode();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return encodedId;
|
||||
}
|
||||
}
|
|
@ -29,7 +29,7 @@ public final class GroupManager {
|
|||
}
|
||||
|
||||
public static GroupActionResult updateGroup(@NonNull Context context,
|
||||
@NonNull String groupId,
|
||||
@NonNull GroupId groupId,
|
||||
@NonNull Set<Recipient> members,
|
||||
@Nullable Bitmap avatar,
|
||||
@Nullable String name)
|
||||
|
@ -51,7 +51,7 @@ public final class GroupManager {
|
|||
|
||||
@WorkerThread
|
||||
public static boolean leaveGroup(@NonNull Context context, @NonNull Recipient groupRecipient) {
|
||||
String groupId = groupRecipient.requireGroupId();
|
||||
GroupId groupId = groupRecipient.requireGroupId();
|
||||
|
||||
return V1GroupManager.leaveGroup(context, groupId, groupRecipient);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.thoughtcrime.securesms.sms.IncomingGroupMessage;
|
|||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceContent;
|
||||
|
@ -63,7 +62,7 @@ public class GroupMessageProcessor {
|
|||
|
||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||
SignalServiceGroup group = message.getGroupInfo().get();
|
||||
String id = GroupUtil.getEncodedId(group.getGroupId(), false);
|
||||
GroupId id = GroupId.v1(group.getGroupId());
|
||||
Optional<GroupRecord> record = database.getGroup(id);
|
||||
|
||||
if (record.isPresent() && group.getType() == Type.UPDATE) {
|
||||
|
@ -73,7 +72,7 @@ public class GroupMessageProcessor {
|
|||
} else if (record.isPresent() && group.getType() == Type.QUIT) {
|
||||
return handleGroupLeave(context, content, group, record.get(), outgoing);
|
||||
} else if (record.isPresent() && group.getType() == Type.REQUEST_INFO) {
|
||||
return handleGroupInfoRequest(context, content, group, record.get());
|
||||
return handleGroupInfoRequest(context, content, record.get());
|
||||
} else {
|
||||
Log.w(TAG, "Received unknown type, ignoring...");
|
||||
return null;
|
||||
|
@ -86,7 +85,7 @@ public class GroupMessageProcessor {
|
|||
boolean outgoing)
|
||||
{
|
||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||
String id = GroupUtil.getEncodedId(group.getGroupId(), false);
|
||||
GroupId id = GroupId.v1(group.getGroupId());
|
||||
GroupContext.Builder builder = createGroupContext(group);
|
||||
builder.setType(GroupContext.Type.UPDATE);
|
||||
|
||||
|
@ -106,7 +105,7 @@ public class GroupMessageProcessor {
|
|||
|
||||
if (FeatureFlags.messageRequests() && (sender.isSystemContact() || sender.isProfileSharing())) {
|
||||
Log.i(TAG, "Auto-enabling profile sharing because 'adder' is trusted. contact: " + sender.isSystemContact() + ", profileSharing: " + sender.isProfileSharing());
|
||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(Recipient.external(context, id).getId(), true);
|
||||
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(Recipient.externalGroup(context, id).getId(), true);
|
||||
}
|
||||
|
||||
return storeMessage(context, content, group, builder.build(), outgoing);
|
||||
|
@ -120,7 +119,7 @@ public class GroupMessageProcessor {
|
|||
{
|
||||
|
||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||
String id = GroupUtil.getEncodedId(group.getGroupId(), false);
|
||||
GroupId id = GroupId.v1(group.getGroupId());
|
||||
|
||||
Set<RecipientId> recordMembers = new HashSet<>(groupRecord.getMembers());
|
||||
Set<RecipientId> messageMembers = new HashSet<>();
|
||||
|
@ -178,13 +177,12 @@ public class GroupMessageProcessor {
|
|||
|
||||
private static Long handleGroupInfoRequest(@NonNull Context context,
|
||||
@NonNull SignalServiceContent content,
|
||||
@NonNull SignalServiceGroup group,
|
||||
@NonNull GroupRecord record)
|
||||
{
|
||||
Recipient sender = Recipient.externalPush(context, content.getSender());
|
||||
|
||||
if (record.getMembers().contains(sender.getId())) {
|
||||
ApplicationDependencies.getJobManager().add(new PushGroupUpdateJob(sender.getId(), group.getGroupId()));
|
||||
ApplicationDependencies.getJobManager().add(new PushGroupUpdateJob(sender.getId(), record.getId()));
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -197,7 +195,7 @@ public class GroupMessageProcessor {
|
|||
boolean outgoing)
|
||||
{
|
||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||
String id = GroupUtil.getEncodedId(group.getGroupId(), false);
|
||||
GroupId id = GroupId.v1(group.getGroupId());
|
||||
List<RecipientId> members = record.getMembers();
|
||||
|
||||
GroupContext.Builder builder = createGroupContext(group);
|
||||
|
@ -222,13 +220,13 @@ public class GroupMessageProcessor {
|
|||
{
|
||||
if (group.getAvatar().isPresent()) {
|
||||
ApplicationDependencies.getJobManager()
|
||||
.add(new AvatarDownloadJob(group.getGroupId()));
|
||||
.add(new AvatarDownloadJob(GroupId.v1(group.getGroupId())));
|
||||
}
|
||||
|
||||
try {
|
||||
if (outgoing) {
|
||||
MmsDatabase mmsDatabase = DatabaseFactory.getMmsDatabase(context);
|
||||
RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(GroupUtil.getEncodedId(group.getGroupId(), false));
|
||||
RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(GroupId.v1(group.getGroupId()));
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
OutgoingGroupMediaMessage outgoingMessage = new OutgoingGroupMediaMessage(recipient, storage, null, content.getTimestamp(), 0, false, null, Collections.emptyList(), Collections.emptyList());
|
||||
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient);
|
||||
|
@ -240,7 +238,7 @@ public class GroupMessageProcessor {
|
|||
} else {
|
||||
SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context);
|
||||
String body = Base64.encodeBytes(storage.toByteArray());
|
||||
IncomingTextMessage incoming = new IncomingTextMessage(Recipient.externalPush(context, content.getSender()).getId(), content.getSenderDevice(), content.getTimestamp(), body, Optional.of(GroupUtil.getEncodedId(group.getGroupId(), false)), 0, content.isNeedsReceipt());
|
||||
IncomingTextMessage incoming = new IncomingTextMessage(Recipient.externalPush(context, content.getSender()).getId(), content.getSenderDevice(), content.getTimestamp(), body, Optional.of(GroupId.v1(group.getGroupId())), 0, content.isNeedsReceipt());
|
||||
IncomingGroupMessage groupMessage = new IncomingGroupMessage(incoming, storage, body);
|
||||
|
||||
Optional<InsertResult> insertResult = smsDatabase.insertMessageInbox(groupMessage);
|
||||
|
|
|
@ -3,6 +3,7 @@ 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 androidx.annotation.WorkerThread;
|
||||
|
@ -11,7 +12,6 @@ import com.google.protobuf.ByteString;
|
|||
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.attachments.UriAttachment;
|
||||
import org.thoughtcrime.securesms.blurhash.BlurHash;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
|
@ -28,12 +28,10 @@ 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.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.util.InvalidNumberException;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
@ -49,7 +47,7 @@ final class V1GroupManager {
|
|||
{
|
||||
final byte[] avatarBytes = BitmapUtil.toByteArray(avatar);
|
||||
final GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||
final String groupId = GroupUtil.getEncodedId(groupDatabase.allocateGroupId(), mms);
|
||||
final GroupId groupId = GroupDatabase.allocateGroupId(mms);
|
||||
final RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId);
|
||||
final Recipient groupRecipient = Recipient.resolved(groupRecipientId);
|
||||
|
||||
|
@ -67,7 +65,7 @@ final class V1GroupManager {
|
|||
}
|
||||
|
||||
static GroupActionResult updateGroup(@NonNull Context context,
|
||||
@NonNull String groupId,
|
||||
@NonNull GroupId groupId,
|
||||
@NonNull Set<RecipientId> memberAddresses,
|
||||
@Nullable Bitmap avatar,
|
||||
@Nullable String name)
|
||||
|
@ -81,7 +79,7 @@ final class V1GroupManager {
|
|||
groupDatabase.updateTitle(groupId, name);
|
||||
groupDatabase.updateAvatar(groupId, avatarBytes);
|
||||
|
||||
if (!GroupUtil.isMmsGroup(groupId)) {
|
||||
if (!groupId.isMmsGroup()) {
|
||||
return sendGroupUpdate(context, groupId, memberAddresses, name, avatarBytes);
|
||||
} else {
|
||||
RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId);
|
||||
|
@ -92,48 +90,44 @@ final class V1GroupManager {
|
|||
}
|
||||
|
||||
private static GroupActionResult sendGroupUpdate(@NonNull Context context,
|
||||
@NonNull String groupId,
|
||||
@NonNull GroupId groupId,
|
||||
@NonNull Set<RecipientId> members,
|
||||
@Nullable String groupName,
|
||||
@Nullable byte[] avatar)
|
||||
{
|
||||
try {
|
||||
Attachment avatarAttachment = null;
|
||||
RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId);
|
||||
Recipient groupRecipient = Recipient.resolved(groupRecipientId);
|
||||
Attachment avatarAttachment = null;
|
||||
RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId);
|
||||
Recipient groupRecipient = Recipient.resolved(groupRecipientId);
|
||||
|
||||
List<GroupContext.Member> uuidMembers = new LinkedList<>();
|
||||
List<String> e164Members = new LinkedList<>();
|
||||
List<GroupContext.Member> uuidMembers = new LinkedList<>();
|
||||
List<String> e164Members = new LinkedList<>();
|
||||
|
||||
for (RecipientId member : members) {
|
||||
Recipient recipient = Recipient.resolved(member);
|
||||
uuidMembers.add(GroupMessageProcessor.createMember(RecipientUtil.toSignalServiceAddress(context, recipient)));
|
||||
}
|
||||
|
||||
GroupContext.Builder groupContextBuilder = GroupContext.newBuilder()
|
||||
.setId(ByteString.copyFrom(GroupUtil.getDecodedId(groupId)))
|
||||
.setType(GroupContext.Type.UPDATE)
|
||||
.addAllMembersE164(e164Members)
|
||||
.addAllMembers(uuidMembers);
|
||||
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, 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);
|
||||
for (RecipientId member : members) {
|
||||
Recipient recipient = Recipient.resolved(member);
|
||||
uuidMembers.add(GroupMessageProcessor.createMember(RecipientUtil.toSignalServiceAddress(context, recipient)));
|
||||
}
|
||||
|
||||
GroupContext.Builder groupContextBuilder = GroupContext.newBuilder()
|
||||
.setId(ByteString.copyFrom(groupId.getDecodedId()))
|
||||
.setType(GroupContext.Type.UPDATE)
|
||||
.addAllMembersE164(e164Members)
|
||||
.addAllMembers(uuidMembers);
|
||||
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, 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);
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
static boolean leaveGroup(@NonNull Context context, @NonNull String groupId, @NonNull Recipient groupRecipient) {
|
||||
static boolean leaveGroup(@NonNull Context context, @NonNull GroupId groupId, @NonNull Recipient groupRecipient) {
|
||||
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipient);
|
||||
Optional<OutgoingGroupMediaMessage> leaveMessage = GroupUtil.createGroupLeaveMessage(context, groupRecipient);
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package org.thoughtcrime.securesms.jobs;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
|
@ -14,7 +16,6 @@ import org.thoughtcrime.securesms.logging.Log;
|
|||
import org.thoughtcrime.securesms.mms.AttachmentStreamUriLoader.AttachmentModel;
|
||||
import org.thoughtcrime.securesms.util.BitmapDecodingException;
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.Hex;
|
||||
import org.whispersystems.libsignal.InvalidMessageException;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
@ -36,9 +37,9 @@ public class AvatarDownloadJob extends BaseJob {
|
|||
|
||||
private static final String KEY_GROUP_ID = "group_id";
|
||||
|
||||
private byte[] groupId;
|
||||
private @NonNull GroupId groupId;
|
||||
|
||||
public AvatarDownloadJob(@NonNull byte[] groupId) {
|
||||
public AvatarDownloadJob(@NonNull GroupId groupId) {
|
||||
this(new Job.Parameters.Builder()
|
||||
.addConstraint(NetworkConstraint.KEY)
|
||||
.setMaxAttempts(10)
|
||||
|
@ -46,14 +47,14 @@ public class AvatarDownloadJob extends BaseJob {
|
|||
groupId);
|
||||
}
|
||||
|
||||
private AvatarDownloadJob(@NonNull Job.Parameters parameters, @NonNull byte[] groupId) {
|
||||
private AvatarDownloadJob(@NonNull Job.Parameters parameters, @NonNull GroupId groupId) {
|
||||
super(parameters);
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Data serialize() {
|
||||
return new Data.Builder().putString(KEY_GROUP_ID, GroupUtil.getEncodedId(groupId, false)).build();
|
||||
return new Data.Builder().putString(KEY_GROUP_ID, groupId.toString()).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -63,9 +64,8 @@ public class AvatarDownloadJob extends BaseJob {
|
|||
|
||||
@Override
|
||||
public void onRun() throws IOException {
|
||||
String encodeId = GroupUtil.getEncodedId(groupId, false);
|
||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||
Optional<GroupRecord> record = database.getGroup(encodeId);
|
||||
Optional<GroupRecord> record = database.getGroup(groupId);
|
||||
File attachment = null;
|
||||
|
||||
try {
|
||||
|
@ -93,7 +93,7 @@ public class AvatarDownloadJob extends BaseJob {
|
|||
InputStream inputStream = receiver.retrieveAttachment(pointer, attachment, MAX_AVATAR_SIZE);
|
||||
Bitmap avatar = BitmapUtil.createScaledBitmap(context, new AttachmentModel(attachment, key, 0, digest), 500, 500);
|
||||
|
||||
database.updateAvatar(encodeId, avatar);
|
||||
database.updateAvatar(groupId, avatar);
|
||||
inputStream.close();
|
||||
}
|
||||
} catch (BitmapDecodingException | NonSuccessfulResponseCodeException | InvalidMessageException e) {
|
||||
|
@ -116,11 +116,7 @@ public class AvatarDownloadJob extends BaseJob {
|
|||
public static final class Factory implements Job.Factory<AvatarDownloadJob> {
|
||||
@Override
|
||||
public @NonNull AvatarDownloadJob create(@NonNull Parameters parameters, @NonNull Data data) {
|
||||
try {
|
||||
return new AvatarDownloadJob(parameters, GroupUtil.getDecodedId(data.getString(KEY_GROUP_ID)));
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
return new AvatarDownloadJob(parameters, GroupId.parse(data.getString(KEY_GROUP_ID)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,12 @@ package org.thoughtcrime.securesms.jobs;
|
|||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
|
@ -18,7 +18,6 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
|
|||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
|
||||
|
@ -27,8 +26,6 @@ import org.whispersystems.signalservice.api.messages.SendMessageResult;
|
|||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
@ -54,7 +51,7 @@ public class LeaveGroupJob extends BaseJob {
|
|||
private static final String KEY_MEMBERS = "members";
|
||||
private static final String KEY_RECIPIENTS = "recipients";
|
||||
|
||||
private final byte[] groupId;
|
||||
private final GroupId groupId;
|
||||
private final String name;
|
||||
private final List<RecipientId> members;
|
||||
private final List<RecipientId> recipients;
|
||||
|
@ -63,7 +60,7 @@ public class LeaveGroupJob extends BaseJob {
|
|||
List<RecipientId> members = Stream.of(group.resolve().getParticipants()).map(Recipient::getId).toList();
|
||||
members.remove(Recipient.self().getId());
|
||||
|
||||
return new LeaveGroupJob(GroupUtil.getDecodedIdOrThrow(group.getGroupId().get()),
|
||||
return new LeaveGroupJob(group.getGroupId().get(),
|
||||
group.resolve().getDisplayName(ApplicationDependencies.getApplication()),
|
||||
members,
|
||||
members,
|
||||
|
@ -75,7 +72,7 @@ public class LeaveGroupJob extends BaseJob {
|
|||
.build());
|
||||
}
|
||||
|
||||
private LeaveGroupJob(@NonNull byte[] groupId,
|
||||
private LeaveGroupJob(@NonNull GroupId groupId,
|
||||
@NonNull String name,
|
||||
@NonNull List<RecipientId> members,
|
||||
@NonNull List<RecipientId> recipients,
|
||||
|
@ -90,7 +87,7 @@ public class LeaveGroupJob extends BaseJob {
|
|||
|
||||
@Override
|
||||
public @NonNull Data serialize() {
|
||||
return new Data.Builder().putString(KEY_GROUP_ID, Base64.encodeBytes(groupId))
|
||||
return new Data.Builder().putString(KEY_GROUP_ID, Base64.encodeBytes(groupId.getDecodedId()))
|
||||
.putString(KEY_GROUP_NAME, name)
|
||||
.putString(KEY_MEMBERS, RecipientId.toSerializedList(members))
|
||||
.putString(KEY_RECIPIENTS, RecipientId.toSerializedList(recipients))
|
||||
|
@ -128,7 +125,7 @@ public class LeaveGroupJob extends BaseJob {
|
|||
}
|
||||
|
||||
private static @NonNull List<Recipient> deliver(@NonNull Context context,
|
||||
@NonNull byte[] groupId,
|
||||
@NonNull GroupId groupId,
|
||||
@NonNull String name,
|
||||
@NonNull List<RecipientId> members,
|
||||
@NonNull List<RecipientId> destinations)
|
||||
|
@ -138,7 +135,7 @@ public class LeaveGroupJob extends BaseJob {
|
|||
List<SignalServiceAddress> addresses = Stream.of(destinations).map(Recipient::resolved).map(t -> RecipientUtil.toSignalServiceAddress(context, t)).toList();
|
||||
List<SignalServiceAddress> memberAddresses = Stream.of(members).map(Recipient::resolved).map(t -> RecipientUtil.toSignalServiceAddress(context, t)).toList();
|
||||
List<Optional<UnidentifiedAccessPair>> unidentifiedAccess = Stream.of(destinations).map(Recipient::resolved).map(recipient -> UnidentifiedAccessUtil.getAccessFor(context, recipient)).toList();
|
||||
SignalServiceGroup serviceGroup = new SignalServiceGroup(SignalServiceGroup.Type.QUIT, groupId, name, memberAddresses, null);
|
||||
SignalServiceGroup serviceGroup = new SignalServiceGroup(SignalServiceGroup.Type.QUIT, groupId.getDecodedId(), name, memberAddresses, null);
|
||||
SignalServiceDataMessage.Builder dataMessage = SignalServiceDataMessage.newBuilder()
|
||||
.withTimestamp(System.currentTimeMillis())
|
||||
.asGroupMessage(serviceGroup);
|
||||
|
@ -169,7 +166,7 @@ public class LeaveGroupJob extends BaseJob {
|
|||
public static class Factory implements Job.Factory<LeaveGroupJob> {
|
||||
@Override
|
||||
public @NonNull LeaveGroupJob create(@NonNull Parameters parameters, @NonNull Data data) {
|
||||
return new LeaveGroupJob(Base64.decodeOrThrow(data.getString(KEY_GROUP_ID)),
|
||||
return new LeaveGroupJob(GroupId.v1(Base64.decodeOrThrow(data.getString(KEY_GROUP_ID))),
|
||||
data.getString(KEY_GROUP_NAME),
|
||||
RecipientId.fromSerializedList(data.getString(KEY_MEMBERS)),
|
||||
RecipientId.fromSerializedList(data.getString(KEY_RECIPIENTS)),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.thoughtcrime.securesms.jobs;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
|
@ -16,6 +17,7 @@ import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
|||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
@ -177,11 +179,11 @@ public class MmsDownloadJob extends BaseJob {
|
|||
int subscriptionId, @Nullable RecipientId notificationFrom)
|
||||
throws MmsException
|
||||
{
|
||||
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
||||
Optional<String> group = Optional.absent();
|
||||
Set<RecipientId> members = new HashSet<>();
|
||||
String body = null;
|
||||
List<Attachment> attachments = new LinkedList<>();
|
||||
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
||||
Optional<GroupId> group = Optional.absent();
|
||||
Set<RecipientId> members = new HashSet<>();
|
||||
String body = null;
|
||||
List<Attachment> attachments = new LinkedList<>();
|
||||
|
||||
RecipientId from = null;
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
|||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
||||
|
@ -76,7 +75,7 @@ public class MultiDeviceBlockedUpdateJob extends BaseJob {
|
|||
|
||||
while ((recipient = reader.getNext()) != null) {
|
||||
if (recipient.isPushGroup()) {
|
||||
blockedGroups.add(GroupUtil.getDecodedId(recipient.requireGroupId()));
|
||||
blockedGroups.add(recipient.requireGroupId().getDecodedId());
|
||||
} else if (recipient.hasServiceIdentifier()) {
|
||||
blockedIndividuals.add(RecipientUtil.toSignalServiceAddress(context, recipient));
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import org.thoughtcrime.securesms.logging.Log;
|
|||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||
|
@ -92,13 +91,13 @@ public class MultiDeviceGroupUpdateJob extends BaseJob {
|
|||
members.add(RecipientUtil.toSignalServiceAddress(context, Recipient.resolved(member)));
|
||||
}
|
||||
|
||||
RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(GroupUtil.getEncodedId(record.getId(), record.isMms()));
|
||||
RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(record.getId());
|
||||
Recipient recipient = Recipient.resolved(recipientId);
|
||||
Optional<Integer> expirationTimer = recipient.getExpireMessages() > 0 ? Optional.of(recipient.getExpireMessages()) : Optional.absent();
|
||||
Map<RecipientId, Integer> inboxPositions = DatabaseFactory.getThreadDatabase(context).getInboxPositions();
|
||||
Set<RecipientId> archived = DatabaseFactory.getThreadDatabase(context).getArchivedRecipients();
|
||||
|
||||
out.write(new DeviceGroup(record.getId(),
|
||||
out.write(new DeviceGroup(record.getId().getDecodedId(),
|
||||
Optional.fromNullable(record.getTitle()),
|
||||
members,
|
||||
getAvatar(record.getAvatar()),
|
||||
|
|
|
@ -8,18 +8,13 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
|||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
||||
import org.whispersystems.signalservice.api.kbs.MasterKey;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.KeysMessage;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.MessageRequestResponseMessage;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
|
@ -100,7 +95,7 @@ public class MultiDeviceMessageRequestResponseJob extends BaseJob {
|
|||
MessageRequestResponseMessage response;
|
||||
|
||||
if (recipient.isGroup()) {
|
||||
response = MessageRequestResponseMessage.forGroup(GroupUtil.getDecodedId(recipient.getGroupId().get()), localToRemoteType(type));
|
||||
response = MessageRequestResponseMessage.forGroup(recipient.getGroupId().get().getDecodedId(), localToRemoteType(type));
|
||||
} else {
|
||||
response = MessageRequestResponseMessage.forIndividual(RecipientUtil.toSignalServiceAddress(context, recipient), localToRemoteType(type));
|
||||
}
|
||||
|
|
|
@ -29,13 +29,13 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
|
|||
import org.thoughtcrime.securesms.database.NoSuchMessageException;
|
||||
import org.thoughtcrime.securesms.database.PushDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.libsignal.state.SignalProtocolStore;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
@ -233,7 +233,7 @@ public final class PushDecryptMessageJob extends BaseJob {
|
|||
|
||||
return new PushProcessMessageJob.ExceptionMetadata(sender,
|
||||
e.getSenderDevice(),
|
||||
e.getGroup().transform(g -> GroupUtil.getEncodedId(g.getGroupId(), false)).orNull());
|
||||
e.getGroup().transform(g -> GroupId.v1(g.getGroupId())).orNull());
|
||||
}
|
||||
|
||||
private static PushProcessMessageJob.ExceptionMetadata toExceptionMetadata(@NonNull ProtocolException e) throws NoSenderException {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.thoughtcrime.securesms.jobs;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
@ -18,6 +19,7 @@ import org.thoughtcrime.securesms.database.NoSuchMessageException;
|
|||
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
|
||||
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||
|
@ -31,8 +33,6 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
|
|||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
|
||||
|
@ -242,7 +242,7 @@ public class PushGroupSendJob extends PushSendJob {
|
|||
rotateSenderCertificateIfNecessary();
|
||||
|
||||
SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
|
||||
String groupId = groupRecipient.requireGroupId();
|
||||
GroupId groupId = groupRecipient.requireGroupId();
|
||||
Optional<byte[]> profileKey = getProfileKey(groupRecipient);
|
||||
Optional<Quote> quote = getQuoteFor(message);
|
||||
Optional<SignalServiceDataMessage.Sticker> sticker = getStickerFor(message);
|
||||
|
@ -266,7 +266,7 @@ public class PushGroupSendJob extends PushSendJob {
|
|||
List<SignalServiceAddress> members = Stream.of(groupContext.getMembersList())
|
||||
.map(m -> new SignalServiceAddress(UuidUtil.parseOrNull(m.getUuid()), m.getE164()))
|
||||
.toList();
|
||||
SignalServiceGroup group = new SignalServiceGroup(type, GroupUtil.getDecodedId(groupId), groupContext.getName(), members, avatar);
|
||||
SignalServiceGroup group = new SignalServiceGroup(type, groupId.getDecodedId(), groupContext.getName(), members, avatar);
|
||||
SignalServiceDataMessage groupDataMessage = SignalServiceDataMessage.newBuilder()
|
||||
.withTimestamp(message.getSentTimeMillis())
|
||||
.withExpiration(groupRecipient.getExpireMessages())
|
||||
|
@ -275,7 +275,7 @@ public class PushGroupSendJob extends PushSendJob {
|
|||
|
||||
return messageSender.sendMessage(addresses, unidentifiedAccess, isRecipientUpdate, groupDataMessage);
|
||||
} else {
|
||||
SignalServiceGroup group = new SignalServiceGroup(GroupUtil.getDecodedId(groupId));
|
||||
SignalServiceGroup group = new SignalServiceGroup(groupId.getDecodedId());
|
||||
SignalServiceDataMessage groupMessage = SignalServiceDataMessage.newBuilder()
|
||||
.withTimestamp(message.getSentTimeMillis())
|
||||
.asGroupMessage(group)
|
||||
|
@ -295,7 +295,7 @@ public class PushGroupSendJob extends PushSendJob {
|
|||
}
|
||||
}
|
||||
|
||||
private @NonNull List<RecipientId> getGroupMessageRecipients(String groupId, long messageId) {
|
||||
private @NonNull List<RecipientId> getGroupMessageRecipients(@NonNull GroupId groupId, long messageId) {
|
||||
List<GroupReceiptInfo> destinations = DatabaseFactory.getGroupReceiptDatabase(context).getGroupReceiptInfo(messageId);
|
||||
if (!destinations.isEmpty()) return Stream.of(destinations).map(GroupReceiptInfo::getRecipientId).toList();
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.thoughtcrime.securesms.database.DatabaseFactory;
|
|||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
|
@ -15,7 +16,6 @@ import org.thoughtcrime.securesms.logging.Log;
|
|||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
||||
|
@ -26,8 +26,6 @@ import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
|
|||
import org.whispersystems.signalservice.api.messages.SignalServiceGroup.Type;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -44,10 +42,10 @@ public class PushGroupUpdateJob extends BaseJob {
|
|||
private static final String KEY_SOURCE = "source";
|
||||
private static final String KEY_GROUP_ID = "group_id";
|
||||
|
||||
private RecipientId source;
|
||||
private byte[] groupId;
|
||||
private final RecipientId source;
|
||||
private final GroupId groupId;
|
||||
|
||||
public PushGroupUpdateJob(@NonNull RecipientId source, byte[] groupId) {
|
||||
public PushGroupUpdateJob(@NonNull RecipientId source, @NonNull GroupId groupId) {
|
||||
this(new Job.Parameters.Builder()
|
||||
.addConstraint(NetworkConstraint.KEY)
|
||||
.setLifespan(TimeUnit.DAYS.toMillis(1))
|
||||
|
@ -57,7 +55,7 @@ public class PushGroupUpdateJob extends BaseJob {
|
|||
groupId);
|
||||
}
|
||||
|
||||
private PushGroupUpdateJob(@NonNull Job.Parameters parameters, RecipientId source, byte[] groupId) {
|
||||
private PushGroupUpdateJob(@NonNull Job.Parameters parameters, RecipientId source, @NonNull GroupId groupId) {
|
||||
super(parameters);
|
||||
|
||||
this.source = source;
|
||||
|
@ -67,7 +65,7 @@ public class PushGroupUpdateJob extends BaseJob {
|
|||
@Override
|
||||
public @NonNull Data serialize() {
|
||||
return new Data.Builder().putString(KEY_SOURCE, source.serialize())
|
||||
.putString(KEY_GROUP_ID, GroupUtil.getEncodedId(groupId, false))
|
||||
.putString(KEY_GROUP_ID, groupId.toString())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -79,11 +77,11 @@ public class PushGroupUpdateJob extends BaseJob {
|
|||
@Override
|
||||
public void onRun() throws IOException, UntrustedIdentityException {
|
||||
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||
Optional<GroupRecord> record = groupDatabase.getGroup(GroupUtil.getEncodedId(groupId, false));
|
||||
Optional<GroupRecord> record = groupDatabase.getGroup(groupId);
|
||||
SignalServiceAttachment avatar = null;
|
||||
|
||||
if (record == null) {
|
||||
Log.w(TAG, "No information for group record info request: " + new String(groupId));
|
||||
Log.w(TAG, "No information for group record info request: " + groupId.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -104,12 +102,12 @@ public class PushGroupUpdateJob extends BaseJob {
|
|||
|
||||
SignalServiceGroup groupContext = SignalServiceGroup.newBuilder(Type.UPDATE)
|
||||
.withAvatar(avatar)
|
||||
.withId(groupId)
|
||||
.withId(groupId.getDecodedId())
|
||||
.withMembers(members)
|
||||
.withName(record.get().getTitle())
|
||||
.build();
|
||||
|
||||
RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(GroupUtil.getEncodedId(groupId, false));
|
||||
RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId);
|
||||
Recipient groupRecipient = Recipient.resolved(groupRecipientId);
|
||||
|
||||
SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder()
|
||||
|
@ -139,13 +137,9 @@ public class PushGroupUpdateJob extends BaseJob {
|
|||
public static final class Factory implements Job.Factory<PushGroupUpdateJob> {
|
||||
@Override
|
||||
public @NonNull PushGroupUpdateJob create(@NonNull Parameters parameters, @NonNull org.thoughtcrime.securesms.jobmanager.Data data) {
|
||||
try {
|
||||
return new PushGroupUpdateJob(parameters,
|
||||
RecipientId.from(data.getString(KEY_SOURCE)),
|
||||
GroupUtil.getDecodedId(data.getString(KEY_GROUP_ID)));
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
return new PushGroupUpdateJob(parameters,
|
||||
RecipientId.from(data.getString(KEY_SOURCE)),
|
||||
GroupId.parse(data.getString(KEY_GROUP_ID)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
|||
import org.thoughtcrime.securesms.database.model.ReactionRecord;
|
||||
import org.thoughtcrime.securesms.database.model.StickerRecord;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.GroupMessageProcessor;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
|
@ -62,9 +63,9 @@ import org.thoughtcrime.securesms.mms.StickerSlide;
|
|||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.service.WebRtcCallService;
|
||||
import org.thoughtcrime.securesms.ringrtc.IceCandidateParcel;
|
||||
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
|
||||
import org.thoughtcrime.securesms.service.WebRtcCallService;
|
||||
import org.thoughtcrime.securesms.sms.IncomingEncryptedMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingEndSessionMessage;
|
||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||
|
@ -74,7 +75,6 @@ import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
|||
import org.thoughtcrime.securesms.stickers.StickerLocator;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.Hex;
|
||||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
|
@ -217,7 +217,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
//noinspection ConstantConditions
|
||||
dataBuilder.putString(KEY_EXCEPTION_SENDER, exceptionMetadata.sender)
|
||||
.putInt(KEY_EXCEPTION_DEVICE, exceptionMetadata.senderDevice)
|
||||
.putString(KEY_EXCEPTION_GROUP_ID, exceptionMetadata.groupId);
|
||||
.putString(KEY_EXCEPTION_GROUP_ID, exceptionMetadata.groupId == null ? null : exceptionMetadata.groupId.toString());
|
||||
}
|
||||
|
||||
return dataBuilder.build();
|
||||
|
@ -272,7 +272,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
else if (isMediaMessage) handleMediaMessage(content, message, smsMessageId);
|
||||
else if (message.getBody().isPresent()) handleTextMessage(content, message, smsMessageId);
|
||||
|
||||
if (message.getGroupInfo().isPresent() && groupDatabase.isUnknownGroup(GroupUtil.getEncodedId(message.getGroupInfo().get().getGroupId(), false))) {
|
||||
if (message.getGroupInfo().isPresent() && groupDatabase.isUnknownGroup(GroupId.v1(message.getGroupInfo().get().getGroupId()))) {
|
||||
handleUnknownGroupMessage(content, message.getGroupInfo().get());
|
||||
}
|
||||
|
||||
|
@ -327,8 +327,8 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
}
|
||||
}
|
||||
|
||||
private static @NonNull Optional<String> toEncodedId(@NonNull Optional<SignalServiceGroup> groupInfo) {
|
||||
return groupInfo.transform(g -> GroupUtil.getEncodedId(g.getGroupId(), false));
|
||||
private static @NonNull Optional<GroupId> toEncodedId(@NonNull Optional<SignalServiceGroup> groupInfo) {
|
||||
return groupInfo.transform(g -> GroupId.v1(g.getGroupId()));
|
||||
}
|
||||
|
||||
private void handleExceptionMessage(@NonNull ExceptionMetadata e, @NonNull Optional<Long> smsMessageId) {
|
||||
|
@ -546,7 +546,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
@NonNull SignalServiceGroup group)
|
||||
{
|
||||
if (group.getType() != SignalServiceGroup.Type.REQUEST_INFO) {
|
||||
ApplicationDependencies.getJobManager().add(new RequestGroupInfoJob(Recipient.externalPush(context, content.getSender()).getId(), group.getGroupId()));
|
||||
ApplicationDependencies.getJobManager().add(new RequestGroupInfoJob(Recipient.externalPush(context, content.getSender()).getId(), GroupId.v1(group.getGroupId())));
|
||||
} else {
|
||||
Log.w(TAG, "Received a REQUEST_INFO message for a group we don't know about. Ignoring.");
|
||||
}
|
||||
|
@ -682,7 +682,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
if (response.getPerson().isPresent()) {
|
||||
recipient = Recipient.externalPush(context, response.getPerson().get());
|
||||
} else if (response.getGroupId().isPresent()) {
|
||||
String groupId = GroupUtil.getEncodedId(response.getGroupId().get(), false);
|
||||
GroupId groupId = GroupId.v1(response.getGroupId().get());
|
||||
recipient = Recipient.externalGroup(context, groupId);
|
||||
} else {
|
||||
Log.w(TAG, "Message request response was missing a thread recipient! Skipping.");
|
||||
|
@ -743,7 +743,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
threadId = handleSynchronizeSentTextMessage(message);
|
||||
}
|
||||
|
||||
if (message.getMessage().getGroupInfo().isPresent() && groupDatabase.isUnknownGroup(GroupUtil.getEncodedId(message.getMessage().getGroupInfo().get().getGroupId(), false))) {
|
||||
if (message.getMessage().getGroupInfo().isPresent() && groupDatabase.isUnknownGroup(GroupId.v1(message.getMessage().getGroupInfo().get().getGroupId()))) {
|
||||
handleUnknownGroupMessage(content, message.getMessage().getGroupInfo().get());
|
||||
}
|
||||
|
||||
|
@ -1017,7 +1017,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
updateGroupReceiptStatus(message, record.getId(), recipient.requireGroupId());
|
||||
}
|
||||
|
||||
private void updateGroupReceiptStatus(@NonNull SentTranscriptMessage message, long messageId, @NonNull String groupString) {
|
||||
private void updateGroupReceiptStatus(@NonNull SentTranscriptMessage message, long messageId, @NonNull GroupId groupString) {
|
||||
GroupReceiptDatabase receiptDatabase = DatabaseFactory.getGroupReceiptDatabase(context);
|
||||
List<Recipient> messageRecipients = Stream.of(message.getRecipients()).map(address -> Recipient.externalPush(context, address)).toList();
|
||||
List<Recipient> members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupString, false);
|
||||
|
@ -1183,7 +1183,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
|
||||
private void handleUnsupportedDataMessage(@NonNull String sender,
|
||||
int senderDevice,
|
||||
@NonNull Optional<String> groupId,
|
||||
@NonNull Optional<GroupId> groupId,
|
||||
long timestamp,
|
||||
@NonNull Optional<Long> smsMessageId)
|
||||
{
|
||||
|
@ -1203,7 +1203,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
|
||||
private void handleInvalidMessage(@NonNull SignalServiceAddress sender,
|
||||
int senderDevice,
|
||||
@NonNull Optional<String> groupId,
|
||||
@NonNull Optional<GroupId> groupId,
|
||||
long timestamp,
|
||||
@NonNull Optional<Long> smsMessageId)
|
||||
{
|
||||
|
@ -1313,7 +1313,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
long threadId;
|
||||
|
||||
if (typingMessage.getGroupId().isPresent()) {
|
||||
RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(GroupUtil.getEncodedId(typingMessage.getGroupId().get(), false));
|
||||
RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(GroupId.v1(typingMessage.getGroupId().get()));
|
||||
Recipient groupRecipient = Recipient.resolved(recipientId);
|
||||
|
||||
threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipient);
|
||||
|
@ -1478,7 +1478,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
return insertPlaceholder(sender, senderDevice, timestamp, Optional.absent());
|
||||
}
|
||||
|
||||
private Optional<InsertResult> insertPlaceholder(@NonNull String sender, int senderDevice, long timestamp, Optional<String> groupId) {
|
||||
private Optional<InsertResult> insertPlaceholder(@NonNull String sender, int senderDevice, long timestamp, Optional<GroupId> groupId) {
|
||||
SmsDatabase database = DatabaseFactory.getSmsDatabase(context);
|
||||
IncomingTextMessage textMessage = new IncomingTextMessage(Recipient.external(context, sender).getId(),
|
||||
senderDevice, timestamp, "",
|
||||
|
@ -1490,7 +1490,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
|
||||
private Recipient getSyncMessageDestination(SentTranscriptMessage message) {
|
||||
if (message.getMessage().getGroupInfo().isPresent()) {
|
||||
return Recipient.external(context, GroupUtil.getEncodedId(message.getMessage().getGroupInfo().get().getGroupId(), false));
|
||||
return Recipient.externalGroup(context, GroupId.v1(message.getMessage().getGroupInfo().get().getGroupId()));
|
||||
} else {
|
||||
return Recipient.externalPush(context, message.getDestination().get());
|
||||
}
|
||||
|
@ -1498,7 +1498,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
|
||||
private Recipient getMessageDestination(SignalServiceContent content, SignalServiceDataMessage message) {
|
||||
if (message.getGroupInfo().isPresent()) {
|
||||
return Recipient.external(context, GroupUtil.getEncodedId(message.getGroupInfo().get().getGroupId(), false));
|
||||
return Recipient.externalGroup(context, GroupId.v1(message.getGroupInfo().get().getGroupId()));
|
||||
} else {
|
||||
return Recipient.externalPush(context, content.getSender());
|
||||
}
|
||||
|
@ -1529,9 +1529,9 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
if (conversation.isGroup() && conversation.isBlocked()) {
|
||||
return true;
|
||||
} else if (conversation.isGroup()) {
|
||||
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||
Optional<String> groupId = message.getGroupInfo().isPresent() ? Optional.of(GroupUtil.getEncodedId(message.getGroupInfo().get().getGroupId(), false))
|
||||
: Optional.absent();
|
||||
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||
Optional<GroupId> groupId = message.getGroupInfo().isPresent() ? Optional.of(GroupId.v1(message.getGroupInfo().get().getGroupId()))
|
||||
: Optional.absent();
|
||||
|
||||
if (groupId.isPresent() && groupDatabase.isUnknownGroup(groupId.get())) {
|
||||
return false;
|
||||
|
@ -1616,7 +1616,7 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
} else {
|
||||
ExceptionMetadata exceptionMetadata = new ExceptionMetadata(data.getString(KEY_EXCEPTION_SENDER),
|
||||
data.getInt(KEY_EXCEPTION_DEVICE),
|
||||
data.getStringOrDefault(KEY_EXCEPTION_GROUP_ID, null));
|
||||
GroupId.parseNullable(data.getStringOrDefault(KEY_EXCEPTION_GROUP_ID, null)));
|
||||
|
||||
return new PushProcessMessageJob(parameters,
|
||||
state,
|
||||
|
@ -1643,11 +1643,11 @@ public final class PushProcessMessageJob extends BaseJob {
|
|||
}
|
||||
|
||||
static class ExceptionMetadata {
|
||||
@NonNull private final String sender;
|
||||
private final int senderDevice;
|
||||
@Nullable private final String groupId;
|
||||
@NonNull private final String sender;
|
||||
private final int senderDevice;
|
||||
@Nullable private final GroupId groupId;
|
||||
|
||||
ExceptionMetadata(@NonNull String sender, int senderDevice, @Nullable String groupId) {
|
||||
ExceptionMetadata(@NonNull String sender, int senderDevice, @Nullable GroupId groupId) {
|
||||
this.sender = sender;
|
||||
this.senderDevice = senderDevice;
|
||||
this.groupId = groupId;
|
||||
|
|
|
@ -21,7 +21,6 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
|||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.transport.RetryLaterException;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
|
||||
|
@ -217,7 +216,7 @@ public class ReactionSendJob extends BaseJob {
|
|||
.withReaction(buildReaction(context, reaction, remove, targetAuthor, targetSentTimestamp));
|
||||
|
||||
if (conversationRecipient.isGroup()) {
|
||||
dataMessage.asGroupMessage(new SignalServiceGroup(GroupUtil.getDecodedId(conversationRecipient.requireGroupId())));
|
||||
dataMessage.asGroupMessage(new SignalServiceGroup(conversationRecipient.requireGroupId().getDecodedId()));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,20 +4,18 @@ import androidx.annotation.NonNull;
|
|||
|
||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroup.Type;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -33,10 +31,10 @@ public class RequestGroupInfoJob extends BaseJob {
|
|||
private static final String KEY_SOURCE = "source";
|
||||
private static final String KEY_GROUP_ID = "group_id";
|
||||
|
||||
private RecipientId source;
|
||||
private byte[] groupId;
|
||||
private final RecipientId source;
|
||||
private final GroupId groupId;
|
||||
|
||||
public RequestGroupInfoJob(@NonNull RecipientId source, @NonNull byte[] groupId) {
|
||||
public RequestGroupInfoJob(@NonNull RecipientId source, @NonNull GroupId groupId) {
|
||||
this(new Job.Parameters.Builder()
|
||||
.addConstraint(NetworkConstraint.KEY)
|
||||
.setLifespan(TimeUnit.DAYS.toMillis(1))
|
||||
|
@ -47,7 +45,7 @@ public class RequestGroupInfoJob extends BaseJob {
|
|||
|
||||
}
|
||||
|
||||
private RequestGroupInfoJob(@NonNull Job.Parameters parameters, @NonNull RecipientId source, @NonNull byte[] groupId) {
|
||||
private RequestGroupInfoJob(@NonNull Job.Parameters parameters, @NonNull RecipientId source, @NonNull GroupId groupId) {
|
||||
super(parameters);
|
||||
|
||||
this.source = source;
|
||||
|
@ -57,7 +55,7 @@ public class RequestGroupInfoJob extends BaseJob {
|
|||
@Override
|
||||
public @NonNull Data serialize() {
|
||||
return new Data.Builder().putString(KEY_SOURCE, source.serialize())
|
||||
.putString(KEY_GROUP_ID, GroupUtil.getEncodedId(groupId, false))
|
||||
.putString(KEY_GROUP_ID, groupId.toString())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -69,7 +67,7 @@ public class RequestGroupInfoJob extends BaseJob {
|
|||
@Override
|
||||
public void onRun() throws IOException, UntrustedIdentityException {
|
||||
SignalServiceGroup group = SignalServiceGroup.newBuilder(Type.REQUEST_INFO)
|
||||
.withId(groupId)
|
||||
.withId(groupId.getDecodedId())
|
||||
.build();
|
||||
|
||||
SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder()
|
||||
|
@ -99,13 +97,9 @@ public class RequestGroupInfoJob extends BaseJob {
|
|||
|
||||
@Override
|
||||
public @NonNull RequestGroupInfoJob create(@NonNull Parameters parameters, @NonNull Data data) {
|
||||
try {
|
||||
return new RequestGroupInfoJob(parameters,
|
||||
RecipientId.from(data.getString(KEY_SOURCE)),
|
||||
GroupUtil.getDecodedId(data.getString(KEY_GROUP_ID)));
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
return new RequestGroupInfoJob(parameters,
|
||||
RecipientId.from(data.getString(KEY_SOURCE)),
|
||||
GroupId.parse(data.getString(KEY_GROUP_ID)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import org.thoughtcrime.securesms.jobmanager.Job;
|
|||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||
|
@ -87,7 +86,7 @@ public class TypingSendJob extends BaseJob {
|
|||
|
||||
if (recipient.isGroup()) {
|
||||
recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(recipient.requireGroupId(), false);
|
||||
groupId = Optional.of(GroupUtil.getDecodedId(recipient.requireGroupId()));
|
||||
groupId = Optional.of(recipient.requireGroupId().getDecodedId());
|
||||
}
|
||||
|
||||
recipients = Stream.of(recipients).map(Recipient::resolve).toList();
|
||||
|
|
|
@ -101,7 +101,7 @@ class CameraContactsRepository {
|
|||
try (GroupDatabase.Reader reader = groupDatabase.getGroupsFilteredByTitle(query, false)) {
|
||||
GroupDatabase.GroupRecord groupRecord;
|
||||
while ((groupRecord = reader.getNext()) != null) {
|
||||
RecipientId recipientId = recipientDatabase.getOrInsertFromGroupId(groupRecord.getEncodedId());
|
||||
RecipientId recipientId = recipientDatabase.getOrInsertFromGroupId(groupRecord.getId());
|
||||
recipients.add(Recipient.resolved(recipientId));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,13 @@ package org.thoughtcrime.securesms.migrations;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.phonenumbers.NumberUtil;
|
||||
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -83,7 +82,7 @@ public class AvatarMigrationJob extends MigrationJob {
|
|||
}
|
||||
|
||||
private static boolean isValidFileName(@NonNull String name) {
|
||||
return NUMBER_PATTERN.matcher(name).matches() || GroupUtil.isEncodedGroup(name) || NumberUtil.isValidEmail(name);
|
||||
return NUMBER_PATTERN.matcher(name).matches() || GroupId.isEncodedGroup(name) || NumberUtil.isValidEmail(name);
|
||||
}
|
||||
|
||||
public static class Factory implements Job.Factory<AvatarMigrationJob> {
|
||||
|
|
|
@ -5,9 +5,9 @@ import androidx.annotation.NonNull;
|
|||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.attachments.PointerAttachment;
|
||||
import org.thoughtcrime.securesms.contactshare.Contact;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
|
||||
|
@ -19,7 +19,7 @@ import java.util.List;
|
|||
public class IncomingMediaMessage {
|
||||
|
||||
private final RecipientId from;
|
||||
private final String groupId;
|
||||
private final GroupId groupId;
|
||||
private final String body;
|
||||
private final boolean push;
|
||||
private final long sentTimeMillis;
|
||||
|
@ -35,7 +35,7 @@ public class IncomingMediaMessage {
|
|||
private final List<LinkPreview> linkPreviews = new LinkedList<>();
|
||||
|
||||
public IncomingMediaMessage(@NonNull RecipientId from,
|
||||
Optional<String> groupId,
|
||||
Optional<GroupId> groupId,
|
||||
String body,
|
||||
long sentTimeMillis,
|
||||
List<Attachment> attachments,
|
||||
|
@ -86,7 +86,7 @@ public class IncomingMediaMessage {
|
|||
this.quote = quote.orNull();
|
||||
this.unidentified = unidentified;
|
||||
|
||||
if (group.isPresent()) this.groupId = GroupUtil.getEncodedId(group.get().getGroupId(), false);
|
||||
if (group.isPresent()) this.groupId = GroupId.v1(group.get().getGroupId());
|
||||
else this.groupId = null;
|
||||
|
||||
this.attachments.addAll(PointerAttachment.forPointers(attachments));
|
||||
|
@ -114,7 +114,7 @@ public class IncomingMediaMessage {
|
|||
return from;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
public GroupId getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ import com.google.i18n.phonenumbers.PhoneNumberUtil;
|
|||
import com.google.i18n.phonenumbers.Phonenumber;
|
||||
import com.google.i18n.phonenumbers.ShortNumberInfo;
|
||||
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.util.Pair;
|
||||
|
@ -83,7 +83,7 @@ public class PhoneNumberFormatter {
|
|||
|
||||
public String format(@Nullable String number) {
|
||||
if (number == null) return "Unknown";
|
||||
if (GroupUtil.isEncodedGroup(number)) return number;
|
||||
if (GroupId.isEncodedGroup(number)) return number;
|
||||
if (ALPHA_PATTERN.matcher(number).find()) return number.trim();
|
||||
|
||||
String bareNumber = number.replaceAll("[^0-9+]", "");
|
||||
|
|
|
@ -19,7 +19,6 @@ import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
|||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
@ -198,7 +197,7 @@ public final class LiveRecipient {
|
|||
List<Recipient> members = Stream.of(groupRecord.get().getMembers()).filterNot(RecipientId::isUnknown).map(this::fetchRecipientFromDisk).toList();
|
||||
Optional<Long> avatarId = Optional.absent();
|
||||
|
||||
if (settings.getGroupId() != null && !GroupUtil.isMmsGroup(settings.getGroupId()) && title == null) {
|
||||
if (settings.getGroupId() != null && !settings.getGroupId().isMmsGroup() && title == null) {
|
||||
title = unnamedGroupName;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
|||
import org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
|
@ -35,7 +36,6 @@ import org.thoughtcrime.securesms.phonenumbers.NumberUtil;
|
|||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter;
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.libsignal.util.guava.Preconditions;
|
||||
|
@ -64,7 +64,7 @@ public class Recipient {
|
|||
private final String username;
|
||||
private final String e164;
|
||||
private final String email;
|
||||
private final String groupId;
|
||||
private final GroupId groupId;
|
||||
private final List<Recipient> participants;
|
||||
private final Optional<Long> groupAvatarId;
|
||||
private final boolean localNumber;
|
||||
|
@ -236,11 +236,7 @@ public class Recipient {
|
|||
* identifier is a groupId.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static @NonNull Recipient externalGroup(@NonNull Context context, @NonNull String groupId) {
|
||||
if (!GroupUtil.isEncodedGroup(groupId)) {
|
||||
throw new IllegalArgumentException("Invalid groupId!");
|
||||
}
|
||||
|
||||
public static @NonNull Recipient externalGroup(@NonNull Context context, @NonNull GroupId groupId) {
|
||||
return Recipient.resolved(DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId));
|
||||
}
|
||||
|
||||
|
@ -274,8 +270,8 @@ public class Recipient {
|
|||
throw new UuidRecipientError();
|
||||
}
|
||||
}
|
||||
} else if (GroupUtil.isEncodedGroup(identifier)) {
|
||||
id = db.getOrInsertFromGroupId(identifier);
|
||||
} else if (GroupId.isEncodedGroup(identifier)) {
|
||||
id = db.getOrInsertFromGroupId(GroupId.parse(identifier));
|
||||
} else if (NumberUtil.isValidEmail(identifier)) {
|
||||
id = db.getOrInsertFromEmail(identifier);
|
||||
} else {
|
||||
|
@ -385,7 +381,7 @@ public class Recipient {
|
|||
}
|
||||
|
||||
public @Nullable String getName(@NonNull Context context) {
|
||||
if (this.name == null && groupId != null && GroupUtil.isMmsGroup(groupId)) {
|
||||
if (this.name == null && groupId != null && groupId.isMmsGroup()) {
|
||||
List<String> names = new LinkedList<>();
|
||||
|
||||
for (Recipient recipient : participants) {
|
||||
|
@ -443,7 +439,7 @@ public class Recipient {
|
|||
return Optional.fromNullable(email);
|
||||
}
|
||||
|
||||
public @NonNull Optional<String> getGroupId() {
|
||||
public @NonNull Optional<GroupId> getGroupId() {
|
||||
return Optional.fromNullable(groupId);
|
||||
}
|
||||
|
||||
|
@ -495,8 +491,8 @@ public class Recipient {
|
|||
return getUuid().isPresent();
|
||||
}
|
||||
|
||||
public @NonNull String requireGroupId() {
|
||||
String resolved = resolving ? resolve().groupId : groupId;
|
||||
public @NonNull GroupId requireGroupId() {
|
||||
GroupId resolved = resolving ? resolve().groupId : groupId;
|
||||
|
||||
if (resolved == null) {
|
||||
throw new MissingAddressError();
|
||||
|
@ -532,7 +528,7 @@ public class Recipient {
|
|||
Recipient resolved = resolving ? resolve() : this;
|
||||
|
||||
if (resolved.isGroup()) {
|
||||
return resolved.requireGroupId();
|
||||
return resolved.requireGroupId().toString();
|
||||
} else if (resolved.getUuid().isPresent()) {
|
||||
return resolved.getUuid().get().toString();
|
||||
}
|
||||
|
@ -570,13 +566,13 @@ public class Recipient {
|
|||
}
|
||||
|
||||
public boolean isMmsGroup() {
|
||||
String groupId = resolve().groupId;
|
||||
return groupId != null && GroupUtil.isMmsGroup(groupId);
|
||||
GroupId groupId = resolve().groupId;
|
||||
return groupId != null && groupId.isMmsGroup();
|
||||
}
|
||||
|
||||
public boolean isPushGroup() {
|
||||
String groupId = resolve().groupId;
|
||||
return groupId != null && !GroupUtil.isMmsGroup(groupId);
|
||||
GroupId groupId = resolve().groupId;
|
||||
return groupId != null && !groupId.isMmsGroup();
|
||||
}
|
||||
|
||||
public @NonNull List<Recipient> getParticipants() {
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
|||
import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.VibrateState;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
@ -28,7 +29,7 @@ public class RecipientDetails {
|
|||
final String username;
|
||||
final String e164;
|
||||
final String email;
|
||||
final String groupId;
|
||||
final GroupId groupId;
|
||||
final String name;
|
||||
final String customLabel;
|
||||
final Uri systemContactPhoto;
|
||||
|
|
|
@ -14,8 +14,9 @@ import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper;
|
|||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
|
||||
import org.thoughtcrime.securesms.jobs.LeaveGroupJob;
|
||||
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob;
|
||||
|
@ -23,9 +24,9 @@ import org.thoughtcrime.securesms.jobs.MultiDeviceMessageRequestResponseJob;
|
|||
import org.thoughtcrime.securesms.jobs.RotateProfileKeyJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
|
@ -123,7 +124,7 @@ public class RecipientUtil {
|
|||
ApplicationDependencies.getJobManager().add(LeaveGroupJob.create(recipient));
|
||||
|
||||
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||
String groupId = resolved.requireGroupId();
|
||||
GroupId groupId = resolved.requireGroupId();
|
||||
groupDatabase.setActive(groupId, false);
|
||||
groupDatabase.remove(groupId, Recipient.self().getId());
|
||||
} else {
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.telephony.SmsMessage;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
|
@ -28,19 +29,19 @@ public class IncomingTextMessage implements Parcelable {
|
|||
};
|
||||
private static final String TAG = IncomingTextMessage.class.getSimpleName();
|
||||
|
||||
private final String message;
|
||||
private RecipientId sender;
|
||||
private final int senderDeviceId;
|
||||
private final int protocol;
|
||||
private final String serviceCenterAddress;
|
||||
private final boolean replyPathPresent;
|
||||
private final String pseudoSubject;
|
||||
private final long sentTimestampMillis;
|
||||
private final String groupId;
|
||||
private final boolean push;
|
||||
private final int subscriptionId;
|
||||
private final long expiresInMillis;
|
||||
private final boolean unidentified;
|
||||
private final String message;
|
||||
private final RecipientId sender;
|
||||
private final int senderDeviceId;
|
||||
private final int protocol;
|
||||
private final String serviceCenterAddress;
|
||||
private final boolean replyPathPresent;
|
||||
private final String pseudoSubject;
|
||||
private final long sentTimestampMillis;
|
||||
@Nullable private final GroupId groupId;
|
||||
private final boolean push;
|
||||
private final int subscriptionId;
|
||||
private final long expiresInMillis;
|
||||
private final boolean unidentified;
|
||||
|
||||
public IncomingTextMessage(@NonNull RecipientId sender, @NonNull SmsMessage message, int subscriptionId) {
|
||||
this.message = message.getDisplayMessageBody();
|
||||
|
@ -59,7 +60,7 @@ public class IncomingTextMessage implements Parcelable {
|
|||
}
|
||||
|
||||
public IncomingTextMessage(@NonNull RecipientId sender, int senderDeviceId, long sentTimestampMillis,
|
||||
String encodedBody, Optional<String> groupId,
|
||||
String encodedBody, Optional<GroupId> groupId,
|
||||
long expiresInMillis, boolean unidentified)
|
||||
{
|
||||
this.message = encodedBody;
|
||||
|
@ -86,7 +87,7 @@ public class IncomingTextMessage implements Parcelable {
|
|||
this.replyPathPresent = (in.readInt() == 1);
|
||||
this.pseudoSubject = in.readString();
|
||||
this.sentTimestampMillis = in.readLong();
|
||||
this.groupId = in.readString();
|
||||
this.groupId = GroupId.parseNullable(in.readString());
|
||||
this.push = (in.readInt() == 1);
|
||||
this.subscriptionId = in.readInt();
|
||||
this.expiresInMillis = in.readLong();
|
||||
|
@ -131,7 +132,7 @@ public class IncomingTextMessage implements Parcelable {
|
|||
this.unidentified = fragments.get(0).isUnidentified();
|
||||
}
|
||||
|
||||
protected IncomingTextMessage(@NonNull RecipientId sender, @Nullable String groupId)
|
||||
protected IncomingTextMessage(@NonNull RecipientId sender, @Nullable GroupId groupId)
|
||||
{
|
||||
this.message = "";
|
||||
this.sender = sender;
|
||||
|
@ -216,7 +217,7 @@ public class IncomingTextMessage implements Parcelable {
|
|||
return push;
|
||||
}
|
||||
|
||||
public @Nullable String getGroupId() {
|
||||
public @Nullable GroupId getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
|
@ -259,7 +260,7 @@ public class IncomingTextMessage implements Parcelable {
|
|||
out.writeInt(replyPathPresent ? 1 : 0);
|
||||
out.writeString(pseudoSubject);
|
||||
out.writeLong(sentTimestampMillis);
|
||||
out.writeString(groupId);
|
||||
out.writeString(groupId == null ? null : groupId.toString());
|
||||
out.writeInt(push ? 1 : 0);
|
||||
out.writeInt(subscriptionId);
|
||||
out.writeLong(expiresInMillis);
|
||||
|
|
|
@ -5,7 +5,7 @@ import androidx.annotation.NonNull;
|
|||
import com.annimon.stream.Collectors;
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.storage.SignalGroupV1Record;
|
||||
|
||||
|
@ -15,15 +15,15 @@ import java.util.Map;
|
|||
|
||||
class GroupV1ConflictMerger implements StorageSyncHelper.ConflictMerger<SignalGroupV1Record> {
|
||||
|
||||
private final Map<String, SignalGroupV1Record> localByGroupId;
|
||||
private final Map<GroupId, SignalGroupV1Record> localByGroupId;
|
||||
|
||||
GroupV1ConflictMerger(@NonNull Collection<SignalGroupV1Record> localOnly) {
|
||||
localByGroupId = Stream.of(localOnly).collect(Collectors.toMap(g -> GroupUtil.getEncodedId(g.getGroupId(), false), g -> g));
|
||||
localByGroupId = Stream.of(localOnly).collect(Collectors.toMap(g -> GroupId.v1(g.getGroupId()), g -> g));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Optional<SignalGroupV1Record> getMatching(@NonNull SignalGroupV1Record record) {
|
||||
return Optional.fromNullable(localByGroupId.get(GroupUtil.getEncodedId(record.getGroupId(), false)));
|
||||
return Optional.fromNullable(localByGroupId.get(GroupId.v1(record.getGroupId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -5,7 +5,6 @@ import androidx.annotation.NonNull;
|
|||
import org.thoughtcrime.securesms.database.IdentityDatabase;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.storage.SignalContactRecord;
|
||||
import org.whispersystems.signalservice.api.storage.SignalGroupV1Record;
|
||||
|
@ -56,7 +55,7 @@ public final class StorageSyncModels {
|
|||
throw new AssertionError("Must have a groupId!");
|
||||
}
|
||||
|
||||
return new SignalGroupV1Record.Builder(rawStorageId, GroupUtil.getDecodedIdOrThrow(recipient.getGroupId()))
|
||||
return new SignalGroupV1Record.Builder(rawStorageId, recipient.getGroupId().getDecodedId())
|
||||
.setBlocked(recipient.isBlocked())
|
||||
.setProfileSharingEnabled(recipient.isProfileSharing())
|
||||
.setArchived(archived.contains(recipient.getId()))
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.google.protobuf.ByteString;
|
|||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
@ -26,43 +27,16 @@ import java.util.List;
|
|||
|
||||
import static org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext;
|
||||
|
||||
public class GroupUtil {
|
||||
public final class GroupUtil {
|
||||
|
||||
private static final String ENCODED_SIGNAL_GROUP_PREFIX = "__textsecure_group__!";
|
||||
private static final String ENCODED_MMS_GROUP_PREFIX = "__signal_mms_group__!";
|
||||
private static final String TAG = GroupUtil.class.getSimpleName();
|
||||
|
||||
public static String getEncodedId(byte[] groupId, boolean mms) {
|
||||
return (mms ? ENCODED_MMS_GROUP_PREFIX : ENCODED_SIGNAL_GROUP_PREFIX) + Hex.toStringCondensed(groupId);
|
||||
private GroupUtil() {
|
||||
}
|
||||
|
||||
public static byte[] getDecodedId(String groupId) throws IOException {
|
||||
if (!isEncodedGroup(groupId)) {
|
||||
throw new IOException("Invalid encoding");
|
||||
}
|
||||
|
||||
return Hex.fromStringCondensed(groupId.split("!", 2)[1]);
|
||||
}
|
||||
|
||||
public static byte[] getDecodedIdOrThrow(String groupId) {
|
||||
try {
|
||||
return getDecodedId(groupId);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isEncodedGroup(@NonNull String groupId) {
|
||||
return groupId.startsWith(ENCODED_SIGNAL_GROUP_PREFIX) || groupId.startsWith(ENCODED_MMS_GROUP_PREFIX);
|
||||
}
|
||||
|
||||
public static boolean isMmsGroup(@NonNull String groupId) {
|
||||
return groupId.startsWith(ENCODED_MMS_GROUP_PREFIX);
|
||||
}
|
||||
private static final String TAG = Log.tag(GroupUtil.class);
|
||||
|
||||
@WorkerThread
|
||||
public static Optional<OutgoingGroupMediaMessage> createGroupLeaveMessage(@NonNull Context context, @NonNull Recipient groupRecipient) {
|
||||
String encodedGroupId = groupRecipient.requireGroupId();
|
||||
GroupId encodedGroupId = groupRecipient.requireGroupId();
|
||||
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||
|
||||
if (!groupDatabase.isActive(encodedGroupId)) {
|
||||
|
@ -70,13 +44,7 @@ public class GroupUtil {
|
|||
return Optional.absent();
|
||||
}
|
||||
|
||||
ByteString decodedGroupId;
|
||||
try {
|
||||
decodedGroupId = ByteString.copyFrom(getDecodedId(encodedGroupId));
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Failed to decode group ID.", e);
|
||||
return Optional.absent();
|
||||
}
|
||||
ByteString decodedGroupId = ByteString.copyFrom(encodedGroupId.getDecodedId());
|
||||
|
||||
GroupContext groupContext = GroupContext.newBuilder()
|
||||
.setId(decodedGroupId)
|
||||
|
|
|
@ -78,14 +78,14 @@ public class IdentityUtil {
|
|||
if (groupRecord.getMembers().contains(recipient.getId()) && groupRecord.isActive() && !groupRecord.isMms()) {
|
||||
|
||||
if (remote) {
|
||||
IncomingTextMessage incoming = new IncomingTextMessage(recipient.getId(), 1, time, null, Optional.of(groupRecord.getEncodedId()), 0, false);
|
||||
IncomingTextMessage incoming = new IncomingTextMessage(recipient.getId(), 1, time, null, Optional.of(groupRecord.getId()), 0, false);
|
||||
|
||||
if (verified) incoming = new IncomingIdentityVerifiedMessage(incoming);
|
||||
else incoming = new IncomingIdentityDefaultMessage(incoming);
|
||||
|
||||
smsDatabase.insertMessageInbox(incoming);
|
||||
} else {
|
||||
RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupRecord.getEncodedId());
|
||||
RecipientId recipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupRecord.getId());
|
||||
Recipient groupRecipient = Recipient.resolved(recipientId);
|
||||
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipient);
|
||||
OutgoingTextMessage outgoing ;
|
||||
|
@ -129,7 +129,7 @@ public class IdentityUtil {
|
|||
|
||||
while ((groupRecord = reader.getNext()) != null) {
|
||||
if (groupRecord.getMembers().contains(recipient.getId()) && groupRecord.isActive()) {
|
||||
IncomingTextMessage incoming = new IncomingTextMessage(recipient.getId(), 1, time, null, Optional.of(groupRecord.getEncodedId()), 0, false);
|
||||
IncomingTextMessage incoming = new IncomingTextMessage(recipient.getId(), 1, time, null, Optional.of(groupRecord.getId()), 0, false);
|
||||
IncomingIdentityUpdateMessage groupUpdate = new IncomingIdentityUpdateMessage(incoming);
|
||||
|
||||
smsDatabase.insertMessageInbox(groupUpdate);
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
package org.thoughtcrime.securesms.groups;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public final class GroupIdTest {
|
||||
|
||||
@Test
|
||||
public void can_create_for_gv1() {
|
||||
GroupId groupId = GroupId.v1(new byte[]{ 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15 });
|
||||
|
||||
assertEquals("__textsecure_group__!0001020305060708090b0c0d0e0f", groupId.toString());
|
||||
assertFalse(groupId.isMmsGroup());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void can_parse_gv1() {
|
||||
GroupId groupId = GroupId.parse("__textsecure_group__!0001020305060708090b0c0d0e0f");
|
||||
|
||||
assertEquals("__textsecure_group__!0001020305060708090b0c0d0e0f", groupId.toString());
|
||||
assertArrayEquals(new byte[]{ 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15 }, groupId.getDecodedId());
|
||||
assertFalse(groupId.isMmsGroup());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void can_create_for_mms() {
|
||||
GroupId groupId = GroupId.mms(new byte[]{ 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15 });
|
||||
|
||||
assertEquals("__signal_mms_group__!0001020305060708090b0c0d0e0f", groupId.toString());
|
||||
assertTrue(groupId.isMmsGroup());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void can_parse_mms() {
|
||||
GroupId groupId = GroupId.parse("__signal_mms_group__!0001020305060708090b0c0d0e0f");
|
||||
|
||||
assertEquals("__signal_mms_group__!0001020305060708090b0c0d0e0f", groupId.toString());
|
||||
assertArrayEquals(new byte[]{ 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15 }, groupId.getDecodedId());
|
||||
assertTrue(groupId.isMmsGroup());
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Test
|
||||
public void can_parse_null() {
|
||||
GroupId groupId = GroupId.parseNullable(null);
|
||||
|
||||
assertNull(groupId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void can_parse_gv1_with_parseNullable() {
|
||||
GroupId groupId = GroupId.parseNullable("__textsecure_group__!0001020305060708090b0c0d0e0f");
|
||||
|
||||
assertEquals("__textsecure_group__!0001020305060708090b0c0d0e0f", groupId.toString());
|
||||
assertArrayEquals(new byte[]{ 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15 }, groupId.getDecodedId());
|
||||
assertFalse(groupId.isMmsGroup());
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void bad_encoding__bad_prefix__parseNullable() {
|
||||
GroupId.parseNullable("__BAD_PREFIX__!0001020305060708090b0c0d0e0f");
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void bad_encoding__empty__parseNullable() {
|
||||
GroupId.parseNullable("");
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void bad_encoding__odd_hex__parseNullable() {
|
||||
GroupId.parseNullable("__textsecure_group__!0001020305060708090bODD_HEX");
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void bad_encoding__bad_prefix__parse() {
|
||||
GroupId.parse("__BAD_PREFIX__!0001020305060708090b0c0d0e0f");
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void bad_encoding__odd_hex__parse() {
|
||||
GroupId.parse("__textsecure_group__!0001020305060708090b0c0d0e0fODD_HEX");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void get_bytes() {
|
||||
byte[] bytes = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15 };
|
||||
GroupId groupId = GroupId.v1(bytes);
|
||||
|
||||
assertArrayEquals(bytes, groupId.getDecodedId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equality() {
|
||||
GroupId groupId1 = GroupId.v1(new byte[]{ 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15 });
|
||||
GroupId groupId2 = GroupId.v1(new byte[]{ 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15 });
|
||||
|
||||
assertNotSame(groupId1, groupId2);
|
||||
assertEquals(groupId1, groupId2);
|
||||
assertEquals(groupId1.hashCode(), groupId2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void inequality_by_bytes() {
|
||||
GroupId groupId1 = GroupId.v1(new byte[]{ 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15 });
|
||||
GroupId groupId2 = GroupId.v1(new byte[]{ 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 16 });
|
||||
|
||||
assertNotSame(groupId1, groupId2);
|
||||
assertNotEquals(groupId1, groupId2);
|
||||
assertNotEquals(groupId1.hashCode(), groupId2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void inequality_of_sms_and_mms() {
|
||||
GroupId groupId1 = GroupId.v1(new byte[]{ 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15 });
|
||||
GroupId groupId2 = GroupId.mms(new byte[]{ 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15 });
|
||||
|
||||
assertNotSame(groupId1, groupId2);
|
||||
assertNotEquals(groupId1, groupId2);
|
||||
assertNotEquals(groupId1.hashCode(), groupId2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void inequality_with_null() {
|
||||
GroupId groupId = GroupId.v1(new byte[]{ 0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15 });
|
||||
|
||||
assertNotEquals(groupId, null);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue