mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-25 01:07:47 +00:00
Join group information into conversation list query
// FREEBIE
This commit is contained in:
parent
159fdb317f
commit
da94fd5f9e
@ -1497,8 +1497,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
private boolean isActiveGroup() {
|
private boolean isActiveGroup() {
|
||||||
if (!isGroupConversation()) return false;
|
if (!isGroupConversation()) return false;
|
||||||
|
|
||||||
GroupRecord record = DatabaseFactory.getGroupDatabase(this).getGroup(getRecipient().getAddress().toGroupString());
|
Optional<GroupRecord> record = DatabaseFactory.getGroupDatabase(this).getGroup(getRecipient().getAddress().toGroupString());
|
||||||
return record != null && record.isActive();
|
return record.isPresent() && record.get().isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSelfConversation() {
|
private boolean isSelfConversation() {
|
||||||
|
@ -537,18 +537,18 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Optional<GroupData> doInBackground(String... groupIds) {
|
protected Optional<GroupData> doInBackground(String... groupIds) {
|
||||||
final GroupDatabase db = DatabaseFactory.getGroupDatabase(activity);
|
final GroupDatabase db = DatabaseFactory.getGroupDatabase(activity);
|
||||||
final List<Recipient> recipients = db.getGroupMembers(groupIds[0], false);
|
final List<Recipient> recipients = db.getGroupMembers(groupIds[0], false);
|
||||||
final GroupRecord group = db.getGroup(groupIds[0]);
|
final Optional<GroupRecord> group = db.getGroup(groupIds[0]);
|
||||||
final Set<Recipient> existingContacts = new HashSet<>(recipients.size());
|
final Set<Recipient> existingContacts = new HashSet<>(recipients.size());
|
||||||
existingContacts.addAll(recipients);
|
existingContacts.addAll(recipients);
|
||||||
|
|
||||||
if (group != null) {
|
if (group.isPresent()) {
|
||||||
return Optional.of(new GroupData(groupIds[0],
|
return Optional.of(new GroupData(groupIds[0],
|
||||||
existingContacts,
|
existingContacts,
|
||||||
BitmapUtil.fromByteArray(group.getAvatar()),
|
BitmapUtil.fromByteArray(group.get().getAvatar()),
|
||||||
group.getAvatar(),
|
group.get().getAvatar(),
|
||||||
group.getTitle()));
|
group.get().getTitle()));
|
||||||
} else {
|
} else {
|
||||||
return Optional.absent();
|
return Optional.absent();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package org.thoughtcrime.securesms.database;
|
package org.thoughtcrime.securesms.database;
|
||||||
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -11,12 +10,17 @@ import android.database.sqlite.SQLiteOpenHelper;
|
|||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.annimon.stream.Stream;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
||||||
import org.thoughtcrime.securesms.util.BitmapUtil;
|
import org.thoughtcrime.securesms.util.BitmapUtil;
|
||||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -32,9 +36,9 @@ public class GroupDatabase extends Database {
|
|||||||
|
|
||||||
private static final String TAG = GroupDatabase.class.getSimpleName();
|
private static final String TAG = GroupDatabase.class.getSimpleName();
|
||||||
|
|
||||||
private static final String TABLE_NAME = "groups";
|
static final String TABLE_NAME = "groups";
|
||||||
private static final String ID = "_id";
|
private static final String ID = "_id";
|
||||||
private static final String GROUP_ID = "group_id";
|
static final String GROUP_ID = "group_id";
|
||||||
private static final String TITLE = "title";
|
private static final String TITLE = "title";
|
||||||
private static final String MEMBERS = "members";
|
private static final String MEMBERS = "members";
|
||||||
private static final String AVATAR = "avatar";
|
private static final String AVATAR = "avatar";
|
||||||
@ -67,21 +71,33 @@ public class GroupDatabase extends Database {
|
|||||||
"CREATE UNIQUE INDEX IF NOT EXISTS group_id_index ON " + TABLE_NAME + " (" + GROUP_ID + ");",
|
"CREATE UNIQUE INDEX IF NOT EXISTS group_id_index ON " + TABLE_NAME + " (" + GROUP_ID + ");",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final String[] GROUP_PROJECTION = {
|
||||||
|
GROUP_ID, TITLE, MEMBERS, AVATAR, AVATAR_ID, AVATAR_KEY, AVATAR_CONTENT_TYPE, AVATAR_RELAY, AVATAR_DIGEST,
|
||||||
|
TIMESTAMP, ACTIVE, MMS
|
||||||
|
};
|
||||||
|
|
||||||
|
static final List<String> TYPED_GROUP_PROJECTION = Stream.of(GROUP_PROJECTION).map(columnName -> TABLE_NAME + "." + columnName).toList();
|
||||||
|
|
||||||
public GroupDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
public GroupDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
||||||
super(context, databaseHelper);
|
super(context, databaseHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable GroupRecord getGroup(String groupId) {
|
public Optional<GroupRecord> getGroup(String groupId) {
|
||||||
@SuppressLint("Recycle")
|
try (Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, null, GROUP_ID + " = ?",
|
||||||
Cursor cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, null, GROUP_ID + " = ?",
|
new String[] {groupId},
|
||||||
new String[] {groupId},
|
null, null, null))
|
||||||
null, null, null);
|
{
|
||||||
|
if (cursor != null && cursor.moveToNext()) {
|
||||||
|
return getGroup(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
Reader reader = new Reader(cursor);
|
return Optional.absent();
|
||||||
GroupRecord record = reader.getNext();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
reader.close();
|
Optional<GroupRecord> getGroup(Cursor cursor) {
|
||||||
return record;
|
Reader reader = new Reader(cursor);
|
||||||
|
return Optional.fromNullable(reader.getCurrent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUnknownGroup(String groupId) {
|
public boolean isUnknownGroup(String groupId) {
|
||||||
@ -251,8 +267,8 @@ public class GroupDatabase extends Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isActive(String groupId) {
|
public boolean isActive(String groupId) {
|
||||||
GroupRecord record = getGroup(groupId);
|
Optional<GroupRecord> record = getGroup(groupId);
|
||||||
return record != null && record.isActive();
|
return record.isPresent() && record.get().isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setActive(String groupId, boolean active) {
|
public void setActive(String groupId, boolean active) {
|
||||||
@ -291,6 +307,14 @@ public class GroupDatabase extends Database {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return getCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable GroupRecord getCurrent() {
|
||||||
|
if (cursor == null || cursor.getString(cursor.getColumnIndexOrThrow(GROUP_ID)) == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return new GroupRecord(cursor.getString(cursor.getColumnIndexOrThrow(GROUP_ID)),
|
return new GroupRecord(cursor.getString(cursor.getColumnIndexOrThrow(GROUP_ID)),
|
||||||
cursor.getString(cursor.getColumnIndexOrThrow(TITLE)),
|
cursor.getString(cursor.getColumnIndexOrThrow(TITLE)),
|
||||||
cursor.getString(cursor.getColumnIndexOrThrow(MEMBERS)),
|
cursor.getString(cursor.getColumnIndexOrThrow(MEMBERS)),
|
||||||
@ -330,7 +354,6 @@ public class GroupDatabase extends Database {
|
|||||||
{
|
{
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.members = Address.fromSerializedList(members, ',');
|
|
||||||
this.avatar = avatar;
|
this.avatar = avatar;
|
||||||
this.avatarId = avatarId;
|
this.avatarId = avatarId;
|
||||||
this.avatarKey = avatarKey;
|
this.avatarKey = avatarKey;
|
||||||
@ -339,6 +362,9 @@ public class GroupDatabase extends Database {
|
|||||||
this.relay = relay;
|
this.relay = relay;
|
||||||
this.active = active;
|
this.active = active;
|
||||||
this.mms = mms;
|
this.mms = mms;
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(members)) this.members = Address.fromSerializedList(members, ',');
|
||||||
|
else this.members = new LinkedList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getId() {
|
public byte[] getId() {
|
||||||
|
@ -30,7 +30,7 @@ public class RecipientPreferenceDatabase extends Database {
|
|||||||
|
|
||||||
static final String TABLE_NAME = "recipient_preferences";
|
static final String TABLE_NAME = "recipient_preferences";
|
||||||
private static final String ID = "_id";
|
private static final String ID = "_id";
|
||||||
private static final String ADDRESS = "recipient_ids";
|
static final String ADDRESS = "recipient_ids";
|
||||||
private static final String BLOCK = "block";
|
private static final String BLOCK = "block";
|
||||||
private static final String NOTIFICATION = "notification";
|
private static final String NOTIFICATION = "notification";
|
||||||
private static final String VIBRATE = "vibrate";
|
private static final String VIBRATE = "vibrate";
|
||||||
@ -110,7 +110,7 @@ public class RecipientPreferenceDatabase extends Database {
|
|||||||
cursor = database.query(TABLE_NAME, null, ADDRESS + " = ?", new String[] {address.serialize()}, null, null, null);
|
cursor = database.query(TABLE_NAME, null, ADDRESS + " = ?", new String[] {address.serialize()}, null, null, null);
|
||||||
|
|
||||||
if (cursor != null && cursor.moveToNext()) {
|
if (cursor != null && cursor.moveToNext()) {
|
||||||
return Optional.of(getRecipientPreferences(cursor));
|
return getRecipientPreferences(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Optional.absent();
|
return Optional.absent();
|
||||||
@ -119,7 +119,7 @@ public class RecipientPreferenceDatabase extends Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RecipientsPreferences getRecipientPreferences(@NonNull Cursor cursor) {
|
Optional<RecipientsPreferences> getRecipientPreferences(@NonNull Cursor cursor) {
|
||||||
boolean blocked = cursor.getInt(cursor.getColumnIndexOrThrow(BLOCK)) == 1;
|
boolean blocked = cursor.getInt(cursor.getColumnIndexOrThrow(BLOCK)) == 1;
|
||||||
String notification = cursor.getString(cursor.getColumnIndexOrThrow(NOTIFICATION));
|
String notification = cursor.getString(cursor.getColumnIndexOrThrow(NOTIFICATION));
|
||||||
int vibrateState = cursor.getInt(cursor.getColumnIndexOrThrow(VIBRATE));
|
int vibrateState = cursor.getInt(cursor.getColumnIndexOrThrow(VIBRATE));
|
||||||
@ -141,11 +141,11 @@ public class RecipientPreferenceDatabase extends Database {
|
|||||||
color = null;
|
color = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RecipientsPreferences(blocked, muteUntil,
|
return Optional.of(new RecipientsPreferences(blocked, muteUntil,
|
||||||
VibrateState.fromId(vibrateState),
|
VibrateState.fromId(vibrateState),
|
||||||
notificationUri, color, seenInviteReminder,
|
notificationUri, color, seenInviteReminder,
|
||||||
defaultSubscriptionId, expireMessages, registered,
|
defaultSubscriptionId, expireMessages, registered,
|
||||||
systemDisplayname);
|
systemDisplayname));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColor(Recipient recipient, MaterialColor color) {
|
public void setColor(Recipient recipient, MaterialColor color) {
|
||||||
|
@ -31,6 +31,7 @@ import com.annimon.stream.Stream;
|
|||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
import org.thoughtcrime.securesms.crypto.MasterCipher;
|
||||||
|
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||||
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
|
import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo;
|
||||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.RecipientsPreferences;
|
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.RecipientsPreferences;
|
||||||
import org.thoughtcrime.securesms.database.model.DisplayRecord;
|
import org.thoughtcrime.securesms.database.model.DisplayRecord;
|
||||||
@ -44,6 +45,7 @@ import org.thoughtcrime.securesms.recipients.RecipientFactory;
|
|||||||
import org.thoughtcrime.securesms.util.DelimiterUtil;
|
import org.thoughtcrime.securesms.util.DelimiterUtil;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.whispersystems.libsignal.InvalidMessageException;
|
import org.whispersystems.libsignal.InvalidMessageException;
|
||||||
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -95,9 +97,10 @@ public class ThreadDatabase extends Database {
|
|||||||
.map(columnName -> TABLE_NAME + "." + columnName)
|
.map(columnName -> TABLE_NAME + "." + columnName)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
private static final List<String> COMBINED_THREAD_RECIPIENT_PROJECTION = Stream.concat(Stream.of(TYPED_THREAD_PROJECTION),
|
private static final List<String> COMBINED_THREAD_RECIPIENT_GROUP_PROJECTION = Stream.concat(Stream.concat(Stream.of(TYPED_THREAD_PROJECTION),
|
||||||
Stream.of(RecipientPreferenceDatabase.TYPED_RECIPIENT_PROJECTION))
|
Stream.of(RecipientPreferenceDatabase.TYPED_RECIPIENT_PROJECTION)),
|
||||||
.toList();
|
Stream.of(GroupDatabase.TYPED_GROUP_PROJECTION))
|
||||||
|
.toList();
|
||||||
|
|
||||||
public ThreadDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
public ThreadDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
||||||
super(context, databaseHelper);
|
super(context, databaseHelper);
|
||||||
@ -340,11 +343,13 @@ public class ThreadDatabase extends Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Cursor getConversationList(String archived) {
|
private Cursor getConversationList(String archived) {
|
||||||
String projection = Util.join(COMBINED_THREAD_RECIPIENT_PROJECTION, ",");
|
String projection = Util.join(COMBINED_THREAD_RECIPIENT_GROUP_PROJECTION, ",");
|
||||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||||
Cursor cursor = db.rawQuery("SELECT " + projection + " FROM " + TABLE_NAME +
|
Cursor cursor = db.rawQuery("SELECT " + projection + " FROM " + TABLE_NAME +
|
||||||
" LEFT OUTER JOIN " + RecipientPreferenceDatabase.TABLE_NAME +
|
" LEFT OUTER JOIN " + RecipientPreferenceDatabase.TABLE_NAME +
|
||||||
" ON " + TABLE_NAME + "." + ADDRESS + " = " + RecipientPreferenceDatabase.TABLE_NAME + "." + ADDRESS +
|
" ON " + TABLE_NAME + "." + ADDRESS + " = " + RecipientPreferenceDatabase.TABLE_NAME + "." + RecipientPreferenceDatabase.ADDRESS +
|
||||||
|
" LEFT OUTER JOIN " + GroupDatabase.TABLE_NAME +
|
||||||
|
" ON " + TABLE_NAME + "." + ADDRESS + " = " + GroupDatabase.TABLE_NAME + "." + GroupDatabase.GROUP_ID +
|
||||||
" WHERE " + ARCHIVED + " = ? AND " + MESSAGE_COUNT + " != 0" +
|
" WHERE " + ARCHIVED + " = ? AND " + MESSAGE_COUNT + " != 0" +
|
||||||
" ORDER BY " + TABLE_NAME + "." + DATE + " DESC",
|
" ORDER BY " + TABLE_NAME + "." + DATE + " DESC",
|
||||||
new String[] {archived});
|
new String[] {archived});
|
||||||
@ -356,7 +361,7 @@ public class ThreadDatabase extends Database {
|
|||||||
|
|
||||||
public Cursor getDirectShareList() {
|
public Cursor getDirectShareList() {
|
||||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||||
String projection = Util.join(COMBINED_THREAD_RECIPIENT_PROJECTION, ",");
|
String projection = Util.join(COMBINED_THREAD_RECIPIENT_GROUP_PROJECTION, ",");
|
||||||
|
|
||||||
return db.rawQuery("SELECT " + projection + " FROM " + TABLE_NAME +
|
return db.rawQuery("SELECT " + projection + " FROM " + TABLE_NAME +
|
||||||
" LEFT OUTER JOIN " + RecipientPreferenceDatabase.TABLE_NAME +
|
" LEFT OUTER JOIN " + RecipientPreferenceDatabase.TABLE_NAME +
|
||||||
@ -601,10 +606,11 @@ public class ThreadDatabase extends Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ThreadRecord getCurrent() {
|
public ThreadRecord getCurrent() {
|
||||||
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.ID));
|
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.ID));
|
||||||
Address address = Address.fromSerialized(cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.ADDRESS)));
|
Address address = Address.fromSerialized(cursor.getString(cursor.getColumnIndexOrThrow(ThreadDatabase.ADDRESS)));
|
||||||
RecipientsPreferences preferences = DatabaseFactory.getRecipientPreferenceDatabase(context).getRecipientPreferences(cursor);
|
Optional<RecipientsPreferences> preferences = DatabaseFactory.getRecipientPreferenceDatabase(context).getRecipientPreferences(cursor);
|
||||||
Recipient recipient = RecipientFactory.getRecipientFor(context, address, preferences, true);
|
Optional<GroupRecord> groupRecord = DatabaseFactory.getGroupDatabase(context).getGroup(cursor);
|
||||||
|
Recipient recipient = RecipientFactory.getRecipientFor(context, address, preferences, groupRecord, true);
|
||||||
|
|
||||||
DisplayRecord.Body body = getPlaintextBody(cursor);
|
DisplayRecord.Body body = getPlaintextBody(cursor);
|
||||||
long date = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.DATE));
|
long date = cursor.getLong(cursor.getColumnIndexOrThrow(ThreadDatabase.DATE));
|
||||||
|
@ -58,19 +58,19 @@ public class GroupMessageProcessor {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||||
SignalServiceGroup group = message.getGroupInfo().get();
|
SignalServiceGroup group = message.getGroupInfo().get();
|
||||||
String id = GroupUtil.getEncodedId(group.getGroupId(), false);
|
String id = GroupUtil.getEncodedId(group.getGroupId(), false);
|
||||||
GroupRecord record = database.getGroup(id);
|
Optional<GroupRecord> record = database.getGroup(id);
|
||||||
|
|
||||||
if (record != null && group.getType() == Type.UPDATE) {
|
if (record.isPresent() && group.getType() == Type.UPDATE) {
|
||||||
return handleGroupUpdate(context, masterSecret, envelope, group, record, outgoing);
|
return handleGroupUpdate(context, masterSecret, envelope, group, record.get(), outgoing);
|
||||||
} else if (record == null && group.getType() == Type.UPDATE) {
|
} else if (record.isPresent() && group.getType() == Type.UPDATE) {
|
||||||
return handleGroupCreate(context, masterSecret, envelope, group, outgoing);
|
return handleGroupCreate(context, masterSecret, envelope, group, outgoing);
|
||||||
} else if (record != null && group.getType() == Type.QUIT) {
|
} else if (record.isPresent() && group.getType() == Type.QUIT) {
|
||||||
return handleGroupLeave(context, masterSecret, envelope, group, record, outgoing);
|
return handleGroupLeave(context, masterSecret, envelope, group, record.get(), outgoing);
|
||||||
} else if (record != null && group.getType() == Type.REQUEST_INFO) {
|
} else if (record.isPresent() && group.getType() == Type.REQUEST_INFO) {
|
||||||
return handleGroupInfoRequest(context, envelope, group, record);
|
return handleGroupInfoRequest(context, envelope, group, record.get());
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "Received unknown type, ignoring...");
|
Log.w(TAG, "Received unknown type, ignoring...");
|
||||||
return null;
|
return null;
|
||||||
|
@ -8,6 +8,7 @@ import android.util.Log;
|
|||||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||||
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
|
import org.thoughtcrime.securesms.jobs.requirements.MasterSecretRequirement;
|
||||||
import org.thoughtcrime.securesms.mms.AttachmentStreamUriLoader.AttachmentModel;
|
import org.thoughtcrime.securesms.mms.AttachmentStreamUriLoader.AttachmentModel;
|
||||||
@ -55,18 +56,18 @@ public class AvatarDownloadJob extends MasterSecretJob implements InjectableType
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRun(MasterSecret masterSecret) throws IOException {
|
public void onRun(MasterSecret masterSecret) throws IOException {
|
||||||
String encodeId = GroupUtil.getEncodedId(groupId, false);
|
String encodeId = GroupUtil.getEncodedId(groupId, false);
|
||||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||||
GroupDatabase.GroupRecord record = database.getGroup(encodeId);
|
Optional<GroupRecord> record = database.getGroup(encodeId);
|
||||||
File attachment = null;
|
File attachment = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (record != null) {
|
if (record.isPresent()) {
|
||||||
long avatarId = record.getAvatarId();
|
long avatarId = record.get().getAvatarId();
|
||||||
String contentType = record.getAvatarContentType();
|
String contentType = record.get().getAvatarContentType();
|
||||||
byte[] key = record.getAvatarKey();
|
byte[] key = record.get().getAvatarKey();
|
||||||
String relay = record.getRelay();
|
String relay = record.get().getRelay();
|
||||||
Optional<byte[]> digest = Optional.fromNullable(record.getAvatarDigest());
|
Optional<byte[]> digest = Optional.fromNullable(record.get().getAvatarDigest());
|
||||||
Optional<String> fileName = Optional.absent();
|
Optional<String> fileName = Optional.absent();
|
||||||
|
|
||||||
if (avatarId == -1 || key == null) {
|
if (avatarId == -1 || key == null) {
|
||||||
|
@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.dependencies.SignalCommunicationModule.SignalM
|
|||||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||||
import org.whispersystems.jobqueue.JobParameters;
|
import org.whispersystems.jobqueue.JobParameters;
|
||||||
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
|
import org.whispersystems.jobqueue.requirements.NetworkRequirement;
|
||||||
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||||
@ -60,7 +61,7 @@ public class PushGroupUpdateJob extends ContextJob implements InjectableType {
|
|||||||
public void onRun() throws IOException, UntrustedIdentityException {
|
public void onRun() throws IOException, UntrustedIdentityException {
|
||||||
SignalServiceMessageSender messageSender = messageSenderFactory.create();
|
SignalServiceMessageSender messageSender = messageSenderFactory.create();
|
||||||
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||||
GroupRecord record = groupDatabase.getGroup(GroupUtil.getEncodedId(groupId, false));
|
Optional<GroupRecord> record = groupDatabase.getGroup(GroupUtil.getEncodedId(groupId, false));
|
||||||
SignalServiceAttachment avatar = null;
|
SignalServiceAttachment avatar = null;
|
||||||
|
|
||||||
if (record == null) {
|
if (record == null) {
|
||||||
@ -68,17 +69,17 @@ public class PushGroupUpdateJob extends ContextJob implements InjectableType {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (record.getAvatar() != null) {
|
if (record.get().getAvatar() != null) {
|
||||||
avatar = SignalServiceAttachmentStream.newStreamBuilder()
|
avatar = SignalServiceAttachmentStream.newStreamBuilder()
|
||||||
.withContentType("image/jpeg")
|
.withContentType("image/jpeg")
|
||||||
.withStream(new ByteArrayInputStream(record.getAvatar()))
|
.withStream(new ByteArrayInputStream(record.get().getAvatar()))
|
||||||
.withLength(record.getAvatar().length)
|
.withLength(record.get().getAvatar().length)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> members = new LinkedList<>();
|
List<String> members = new LinkedList<>();
|
||||||
|
|
||||||
for (Address member : record.getMembers()) {
|
for (Address member : record.get().getMembers()) {
|
||||||
members.add(member.serialize());
|
members.add(member.serialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +87,7 @@ public class PushGroupUpdateJob extends ContextJob implements InjectableType {
|
|||||||
.withAvatar(avatar)
|
.withAvatar(avatar)
|
||||||
.withId(groupId)
|
.withId(groupId)
|
||||||
.withMembers(members)
|
.withMembers(members)
|
||||||
.withName(record.getTitle())
|
.withName(record.get().getTitle())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder()
|
SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder()
|
||||||
|
@ -69,7 +69,7 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
|
|
||||||
Recipient(@NonNull Address address,
|
Recipient(@NonNull Address address,
|
||||||
@Nullable Recipient stale,
|
@Nullable Recipient stale,
|
||||||
@NonNull Optional<RecipientsPreferences> preferences,
|
@NonNull Optional<RecipientDetails> details,
|
||||||
@NonNull ListenableFutureTask<RecipientDetails> future)
|
@NonNull ListenableFutureTask<RecipientDetails> future)
|
||||||
{
|
{
|
||||||
this.address = address;
|
this.address = address;
|
||||||
@ -90,17 +90,17 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
this.expireMessages = stale.expireMessages;
|
this.expireMessages = stale.expireMessages;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preferences.isPresent()) {
|
if (details.isPresent()) {
|
||||||
if (!TextUtils.isEmpty(preferences.get().getSystemDisplayName())) {
|
this.name = details.get().name;
|
||||||
this.name = preferences.get().getSystemDisplayName();
|
this.contactPhoto = details.get().avatar;
|
||||||
}
|
this.color = details.get().color;
|
||||||
|
this.ringtone = details.get().ringtone;
|
||||||
this.color = preferences.get().getColor();
|
this.mutedUntil = details.get().mutedUntil;
|
||||||
this.ringtone = preferences.get().getRingtone();
|
this.blocked = details.get().blocked;
|
||||||
this.mutedUntil = preferences.get().getMuteUntil();
|
this.vibrate = details.get().vibrateState;
|
||||||
this.blocked = preferences.get().isBlocked();
|
this.expireMessages = details.get().expireMessages;
|
||||||
this.vibrate = preferences.get().getVibrateState();
|
this.participants.clear();
|
||||||
this.expireMessages = preferences.get().getExpireMessages();
|
this.participants.addAll(details.get().participants);
|
||||||
}
|
}
|
||||||
|
|
||||||
future.addListener(new FutureTaskListener<RecipientDetails>() {
|
future.addListener(new FutureTaskListener<RecipientDetails>() {
|
||||||
@ -118,6 +118,8 @@ public class Recipient implements RecipientModifiedListener {
|
|||||||
Recipient.this.blocked = result.blocked;
|
Recipient.this.blocked = result.blocked;
|
||||||
Recipient.this.vibrate = result.vibrateState;
|
Recipient.this.vibrate = result.vibrateState;
|
||||||
Recipient.this.expireMessages = result.expireMessages;
|
Recipient.this.expireMessages = result.expireMessages;
|
||||||
|
|
||||||
|
Recipient.this.participants.clear();
|
||||||
Recipient.this.participants.addAll(result.participants);
|
Recipient.this.participants.addAll(result.participants);
|
||||||
Recipient.this.resolving = false;
|
Recipient.this.resolving = false;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import android.content.Intent;
|
|||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.database.Address;
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase;
|
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.RecipientsPreferences;
|
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.RecipientsPreferences;
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
|
|
||||||
@ -33,12 +33,12 @@ public class RecipientFactory {
|
|||||||
|
|
||||||
public static @NonNull Recipient getRecipientFor(@NonNull Context context, @NonNull Address address, boolean asynchronous) {
|
public static @NonNull Recipient getRecipientFor(@NonNull Context context, @NonNull Address address, boolean asynchronous) {
|
||||||
if (address == null) throw new AssertionError(address);
|
if (address == null) throw new AssertionError(address);
|
||||||
return provider.getRecipient(context, address, Optional.absent(), asynchronous);
|
return provider.getRecipient(context, address, Optional.absent(), Optional.absent(), asynchronous);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NonNull Recipient getRecipientFor(@NonNull Context context, @NonNull Address address, @NonNull RecipientsPreferences preferences, boolean asynchronous) {
|
public static @NonNull Recipient getRecipientFor(@NonNull Context context, @NonNull Address address, @NonNull Optional<RecipientsPreferences> preferences, @NonNull Optional<GroupRecord> groupRecord, boolean asynchronous) {
|
||||||
if (address == null) throw new AssertionError(address);
|
if (address == null) throw new AssertionError(address);
|
||||||
return provider.getRecipient(context, address, Optional.of(preferences), asynchronous);
|
return provider.getRecipient(context, address, preferences, groupRecord, asynchronous);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clearCache(Context context) {
|
public static void clearCache(Context context) {
|
||||||
|
@ -32,7 +32,7 @@ import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
|||||||
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
import org.thoughtcrime.securesms.contacts.avatars.ContactPhotoFactory;
|
||||||
import org.thoughtcrime.securesms.database.Address;
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.RecipientsPreferences;
|
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.RecipientsPreferences;
|
||||||
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.VibrateState;
|
import org.thoughtcrime.securesms.database.RecipientPreferenceDatabase.VibrateState;
|
||||||
import org.thoughtcrime.securesms.util.LRUCache;
|
import org.thoughtcrime.securesms.util.LRUCache;
|
||||||
@ -68,16 +68,18 @@ class RecipientProvider {
|
|||||||
null, null));
|
null, null));
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@NonNull Recipient getRecipient(Context context, Address address, Optional<RecipientsPreferences> preferences, boolean asynchronous) {
|
@NonNull Recipient getRecipient(Context context, Address address, Optional<RecipientsPreferences> preferences, Optional<GroupRecord> groupRecord, boolean asynchronous) {
|
||||||
Recipient cachedRecipient = recipientCache.get(address);
|
Recipient cachedRecipient = recipientCache.get(address);
|
||||||
if (cachedRecipient != null && !cachedRecipient.isStale() && (asynchronous || !cachedRecipient.isResolving())) {
|
if (cachedRecipient != null && !cachedRecipient.isStale() && (asynchronous || !cachedRecipient.isResolving())) {
|
||||||
return cachedRecipient;
|
return cachedRecipient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Optional<RecipientDetails> prefetchedRecipientDetails = createPrefetchedRecipientDetails(context, address, preferences, groupRecord);
|
||||||
|
|
||||||
if (asynchronous) {
|
if (asynchronous) {
|
||||||
cachedRecipient = new Recipient(address, cachedRecipient, preferences, getRecipientDetailsAsync(context, address, preferences));
|
cachedRecipient = new Recipient(address, cachedRecipient, prefetchedRecipientDetails, getRecipientDetailsAsync(context, address, preferences, groupRecord));
|
||||||
} else {
|
} else {
|
||||||
cachedRecipient = new Recipient(address, getRecipientDetailsSync(context, address, preferences, false));
|
cachedRecipient = new Recipient(address, getRecipientDetailsSync(context, address, preferences, groupRecord, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
recipientCache.set(address, cachedRecipient);
|
recipientCache.set(address, cachedRecipient);
|
||||||
@ -88,12 +90,25 @@ class RecipientProvider {
|
|||||||
recipientCache.reset();
|
recipientCache.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private @NonNull ListenableFutureTask<RecipientDetails> getRecipientDetailsAsync(final Context context, final @NonNull Address address, final @NonNull Optional<RecipientsPreferences> preferences)
|
private @NonNull Optional<RecipientDetails> createPrefetchedRecipientDetails(@NonNull Context context, @NonNull Address address,
|
||||||
|
@NonNull Optional<RecipientsPreferences> preferences,
|
||||||
|
@NonNull Optional<GroupRecord> groupRecord)
|
||||||
|
{
|
||||||
|
if (address.isGroup() && preferences.isPresent() && groupRecord.isPresent()) {
|
||||||
|
return Optional.of(getGroupRecipientDetails(context, address, groupRecord, preferences, true));
|
||||||
|
} else if (!address.isGroup() && preferences.isPresent()) {
|
||||||
|
return Optional.of(new RecipientDetails(null, null, null, ContactPhotoFactory.getLoadingPhoto(), preferences.get(), null));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.absent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private @NonNull ListenableFutureTask<RecipientDetails> getRecipientDetailsAsync(final Context context, final @NonNull Address address, final @NonNull Optional<RecipientsPreferences> preferences, final @NonNull Optional<GroupRecord> groupRecord)
|
||||||
{
|
{
|
||||||
Callable<RecipientDetails> task = new Callable<RecipientDetails>() {
|
Callable<RecipientDetails> task = new Callable<RecipientDetails>() {
|
||||||
@Override
|
@Override
|
||||||
public RecipientDetails call() throws Exception {
|
public RecipientDetails call() throws Exception {
|
||||||
return getRecipientDetailsSync(context, address, preferences, true);
|
return getRecipientDetailsSync(context, address, preferences, groupRecord, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -102,8 +117,8 @@ class RecipientProvider {
|
|||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
private @NonNull RecipientDetails getRecipientDetailsSync(Context context, @NonNull Address address, Optional<RecipientsPreferences> preferences, boolean nestedAsynchronous) {
|
private @NonNull RecipientDetails getRecipientDetailsSync(Context context, @NonNull Address address, Optional<RecipientsPreferences> preferences, Optional<GroupRecord> groupRecord, boolean nestedAsynchronous) {
|
||||||
if (address.isGroup()) return getGroupRecipientDetails(context, address, nestedAsynchronous);
|
if (address.isGroup()) return getGroupRecipientDetails(context, address, groupRecord, preferences, nestedAsynchronous);
|
||||||
else return getIndividualRecipientDetails(context, address, preferences);
|
else return getIndividualRecipientDetails(context, address, preferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,27 +156,33 @@ class RecipientProvider {
|
|||||||
else return new RecipientDetails(null, null, null, ContactPhotoFactory.getDefaultContactPhoto(null), preferences.orNull(), null);
|
else return new RecipientDetails(null, null, null, ContactPhotoFactory.getDefaultContactPhoto(null), preferences.orNull(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private @NonNull RecipientDetails getGroupRecipientDetails(Context context, Address groupId, boolean asynchronous) {
|
private @NonNull RecipientDetails getGroupRecipientDetails(Context context, Address groupId, Optional<GroupRecord> groupRecord, Optional<RecipientsPreferences> preferences, boolean asynchronous) {
|
||||||
GroupDatabase.GroupRecord record = DatabaseFactory.getGroupDatabase(context).getGroup(groupId.toGroupString());
|
if (!groupRecord.isPresent()) {
|
||||||
|
groupRecord = DatabaseFactory.getGroupDatabase(context).getGroup(groupId.toGroupString());
|
||||||
|
}
|
||||||
|
|
||||||
if (record != null) {
|
if (!preferences.isPresent()) {
|
||||||
ContactPhoto contactPhoto = ContactPhotoFactory.getGroupContactPhoto(record.getAvatar());
|
preferences = DatabaseFactory.getRecipientPreferenceDatabase(context).getRecipientsPreferences(groupId);
|
||||||
String title = record.getTitle();
|
}
|
||||||
List<Address> memberAddresses = record.getMembers();
|
|
||||||
|
if (groupRecord.isPresent()) {
|
||||||
|
ContactPhoto contactPhoto = ContactPhotoFactory.getGroupContactPhoto(groupRecord.get().getAvatar());
|
||||||
|
String title = groupRecord.get().getTitle();
|
||||||
|
List<Address> memberAddresses = groupRecord.get().getMembers();
|
||||||
List<Recipient> members = new LinkedList<>();
|
List<Recipient> members = new LinkedList<>();
|
||||||
|
|
||||||
for (Address memberAddress : memberAddresses) {
|
for (Address memberAddress : memberAddresses) {
|
||||||
members.add(getRecipient(context, memberAddress, Optional.absent(), asynchronous));
|
members.add(getRecipient(context, memberAddress, Optional.absent(), Optional.absent(), asynchronous));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!groupId.isMmsGroup() && title == null) {
|
if (!groupId.isMmsGroup() && title == null) {
|
||||||
title = context.getString(R.string.RecipientProvider_unnamed_group);;
|
title = context.getString(R.string.RecipientProvider_unnamed_group);;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RecipientDetails(title, null, null, contactPhoto, null, members);
|
return new RecipientDetails(title, null, null, contactPhoto, preferences.orNull(), members);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RecipientDetails(context.getString(R.string.RecipientProvider_unnamed_group), null, null, ContactPhotoFactory.getDefaultGroupPhoto(), null, null);
|
return new RecipientDetails(context.getString(R.string.RecipientProvider_unnamed_group), null, null, ContactPhotoFactory.getDefaultGroupPhoto(), preferences.orNull(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class RecipientDetails {
|
static class RecipientDetails {
|
||||||
@ -182,7 +203,6 @@ class RecipientProvider {
|
|||||||
@Nullable RecipientsPreferences preferences,
|
@Nullable RecipientsPreferences preferences,
|
||||||
@Nullable List<Recipient> participants)
|
@Nullable List<Recipient> participants)
|
||||||
{
|
{
|
||||||
this.name = name;
|
|
||||||
this.customLabel = customLabel;
|
this.customLabel = customLabel;
|
||||||
this.avatar = avatar;
|
this.avatar = avatar;
|
||||||
this.contactUri = contactUri;
|
this.contactUri = contactUri;
|
||||||
@ -193,6 +213,9 @@ class RecipientProvider {
|
|||||||
this.blocked = preferences != null && preferences.isBlocked();
|
this.blocked = preferences != null && preferences.isBlocked();
|
||||||
this.expireMessages = preferences != null ? preferences.getExpireMessages() : 0;
|
this.expireMessages = preferences != null ? preferences.getExpireMessages() : 0;
|
||||||
this.participants = participants == null ? new LinkedList<Recipient>() : participants;
|
this.participants = participants == null ? new LinkedList<Recipient>() : participants;
|
||||||
|
|
||||||
|
if (name == null && preferences != null) this.name = preferences.getSystemDisplayName();
|
||||||
|
else this.name = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user