mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-31 15:36:09 +00:00
Optimistically fetch profiles.
This commit is contained in:
committed by
Greyson Parrelli
parent
f5626f678d
commit
ce940235b0
@@ -23,6 +23,7 @@ import org.thoughtcrime.securesms.contacts.avatars.ContactColors;
|
||||
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
|
||||
import org.thoughtcrime.securesms.database.IdentityDatabase.IdentityRecord;
|
||||
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.v2.ProfileKeySet;
|
||||
@@ -60,6 +61,7 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -102,6 +104,7 @@ public class RecipientDatabase extends Database {
|
||||
private static final String PROFILE_KEY_CREDENTIAL = "profile_key_credential";
|
||||
private static final String SIGNAL_PROFILE_AVATAR = "signal_profile_avatar";
|
||||
private static final String PROFILE_SHARING = "profile_sharing";
|
||||
private static final String LAST_PROFILE_FETCH = "last_profile_fetch";
|
||||
private static final String UNIDENTIFIED_ACCESS_MODE = "unidentified_access_mode";
|
||||
private static final String FORCE_SMS_SELECTION = "force_sms_selection";
|
||||
private static final String UUID_CAPABILITY = "uuid_supported";
|
||||
@@ -123,7 +126,8 @@ public class RecipientDatabase extends Database {
|
||||
BLOCKED, MESSAGE_RINGTONE, CALL_RINGTONE, MESSAGE_VIBRATE, CALL_VIBRATE, MUTE_UNTIL, COLOR, SEEN_INVITE_REMINDER, DEFAULT_SUBSCRIPTION_ID, MESSAGE_EXPIRATION_TIME, REGISTERED,
|
||||
PROFILE_KEY, PROFILE_KEY_CREDENTIAL,
|
||||
SYSTEM_DISPLAY_NAME, SYSTEM_PHOTO_URI, SYSTEM_PHONE_LABEL, SYSTEM_PHONE_TYPE, SYSTEM_CONTACT_URI,
|
||||
PROFILE_GIVEN_NAME, PROFILE_FAMILY_NAME, SIGNAL_PROFILE_AVATAR, PROFILE_SHARING, NOTIFICATION_CHANNEL,
|
||||
PROFILE_GIVEN_NAME, PROFILE_FAMILY_NAME, SIGNAL_PROFILE_AVATAR, PROFILE_SHARING, LAST_PROFILE_FETCH,
|
||||
NOTIFICATION_CHANNEL,
|
||||
UNIDENTIFIED_ACCESS_MODE,
|
||||
FORCE_SMS_SELECTION,
|
||||
UUID_CAPABILITY, GROUPS_V2_CAPABILITY,
|
||||
@@ -295,6 +299,7 @@ public class RecipientDatabase extends Database {
|
||||
PROFILE_JOINED_NAME + " TEXT DEFAULT NULL, " +
|
||||
SIGNAL_PROFILE_AVATAR + " TEXT DEFAULT NULL, " +
|
||||
PROFILE_SHARING + " INTEGER DEFAULT 0, " +
|
||||
LAST_PROFILE_FETCH + " INTEGER DEFAULT 0, " +
|
||||
UNIDENTIFIED_ACCESS_MODE + " INTEGER DEFAULT 0, " +
|
||||
FORCE_SMS_SELECTION + " INTEGER DEFAULT 0, " +
|
||||
UUID_CAPABILITY + " INTEGER DEFAULT " + Recipient.Capability.UNKNOWN.serialize() + ", " +
|
||||
@@ -842,6 +847,7 @@ public class RecipientDatabase extends Database {
|
||||
String profileFamilyName = cursor.getString(cursor.getColumnIndexOrThrow(PROFILE_FAMILY_NAME));
|
||||
String signalProfileAvatar = cursor.getString(cursor.getColumnIndexOrThrow(SIGNAL_PROFILE_AVATAR));
|
||||
boolean profileSharing = cursor.getInt(cursor.getColumnIndexOrThrow(PROFILE_SHARING)) == 1;
|
||||
long lastProfileFetch = cursor.getLong(cursor.getColumnIndexOrThrow(LAST_PROFILE_FETCH));
|
||||
String notificationChannel = cursor.getString(cursor.getColumnIndexOrThrow(NOTIFICATION_CHANNEL));
|
||||
int unidentifiedAccessMode = cursor.getInt(cursor.getColumnIndexOrThrow(UNIDENTIFIED_ACCESS_MODE));
|
||||
boolean forceSmsSelection = cursor.getInt(cursor.getColumnIndexOrThrow(FORCE_SMS_SELECTION)) == 1;
|
||||
@@ -908,7 +914,7 @@ public class RecipientDatabase extends Database {
|
||||
systemDisplayName, systemContactPhoto,
|
||||
systemPhoneLabel, systemContactUri,
|
||||
ProfileName.fromParts(profileGivenName, profileFamilyName), signalProfileAvatar,
|
||||
AvatarHelper.hasAvatar(context, RecipientId.from(id)), profileSharing,
|
||||
AvatarHelper.hasAvatar(context, RecipientId.from(id)), profileSharing, lastProfileFetch,
|
||||
notificationChannel, UnidentifiedAccessMode.fromMode(unidentifiedAccessMode),
|
||||
forceSmsSelection,
|
||||
Recipient.Capability.deserialize(uuidCapabilityValue),
|
||||
@@ -1587,6 +1593,53 @@ public class RecipientDatabase extends Database {
|
||||
return recipients;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param lastInteractionThreshold Only include contacts that have been interacted with since this time.
|
||||
* @param lastProfileFetchThreshold Only include contacts that haven't their profile fetched after this time.
|
||||
* @param limit Only return at most this many contact.
|
||||
*/
|
||||
public List<RecipientId> getRecipientsForRoutineProfileFetch(long lastInteractionThreshold, long lastProfileFetchThreshold, int limit) {
|
||||
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
|
||||
Set<Recipient> recipientsWithinInteractionThreshold = new LinkedHashSet<>();
|
||||
|
||||
try (ThreadDatabase.Reader reader = threadDatabase.readerFor(threadDatabase.getRecentPushConversationList(-1, false))) {
|
||||
ThreadRecord record;
|
||||
|
||||
while ((record = reader.getNext()) != null && record.getDate() > lastInteractionThreshold) {
|
||||
Recipient recipient = Recipient.resolved(record.getRecipient().getId());
|
||||
|
||||
if (recipient.isGroup()) {
|
||||
recipientsWithinInteractionThreshold.addAll(recipient.getParticipants());
|
||||
} else {
|
||||
recipientsWithinInteractionThreshold.add(recipient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Stream.of(recipientsWithinInteractionThreshold)
|
||||
.filterNot(Recipient::isLocalNumber)
|
||||
.filter(r -> r.getLastProfileFetchTime() < lastProfileFetchThreshold)
|
||||
.limit(limit)
|
||||
.map(Recipient::getId)
|
||||
.toList();
|
||||
}
|
||||
|
||||
public void markProfilesFetched(@NonNull Collection<RecipientId> ids, long time) {
|
||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||
db.beginTransaction();
|
||||
try {
|
||||
ContentValues values = new ContentValues(1);
|
||||
values.put(LAST_PROFILE_FETCH, time);
|
||||
|
||||
for (RecipientId id : ids) {
|
||||
db.update(TABLE_NAME, values, ID_WHERE, new String[] { id.serialize() });
|
||||
}
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
public void applyBlockedUpdate(@NonNull List<SignalServiceAddress> blocked, List<byte[]> groupIds) {
|
||||
List<String> blockedE164 = Stream.of(blocked)
|
||||
.filter(b -> b.getNumber().isPresent())
|
||||
@@ -1885,6 +1938,7 @@ public class RecipientDatabase extends Database {
|
||||
private final String signalProfileAvatar;
|
||||
private final boolean hasProfileImage;
|
||||
private final boolean profileSharing;
|
||||
private final long lastProfileFetch;
|
||||
private final String notificationChannel;
|
||||
private final UnidentifiedAccessMode unidentifiedAccessMode;
|
||||
private final boolean forceSmsSelection;
|
||||
@@ -1923,6 +1977,7 @@ public class RecipientDatabase extends Database {
|
||||
@Nullable String signalProfileAvatar,
|
||||
boolean hasProfileImage,
|
||||
boolean profileSharing,
|
||||
long lastProfileFetch,
|
||||
@Nullable String notificationChannel,
|
||||
@NonNull UnidentifiedAccessMode unidentifiedAccessMode,
|
||||
boolean forceSmsSelection,
|
||||
@@ -1961,6 +2016,7 @@ public class RecipientDatabase extends Database {
|
||||
this.signalProfileAvatar = signalProfileAvatar;
|
||||
this.hasProfileImage = hasProfileImage;
|
||||
this.profileSharing = profileSharing;
|
||||
this.lastProfileFetch = lastProfileFetch;
|
||||
this.notificationChannel = notificationChannel;
|
||||
this.unidentifiedAccessMode = unidentifiedAccessMode;
|
||||
this.forceSmsSelection = forceSmsSelection;
|
||||
@@ -2091,6 +2147,10 @@ public class RecipientDatabase extends Database {
|
||||
return profileSharing;
|
||||
}
|
||||
|
||||
public long getLastProfileFetch() {
|
||||
return lastProfileFetch;
|
||||
}
|
||||
|
||||
public @Nullable String getNotificationChannel() {
|
||||
return notificationChannel;
|
||||
}
|
||||
|
||||
@@ -135,8 +135,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
private static final int REMOTE_DELETE = 60;
|
||||
private static final int COLOR_MIGRATION = 61;
|
||||
private static final int LAST_SCROLLED = 62;
|
||||
private static final int LAST_PROFILE_FETCH = 63;
|
||||
|
||||
private static final int DATABASE_VERSION = 62;
|
||||
private static final int DATABASE_VERSION = 63;
|
||||
private static final String DATABASE_NAME = "signal.db";
|
||||
|
||||
private final Context context;
|
||||
@@ -911,6 +912,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
||||
db.execSQL("ALTER TABLE thread ADD COLUMN last_scrolled INTEGER DEFAULT 0");
|
||||
}
|
||||
|
||||
if (oldVersion < LAST_PROFILE_FETCH) {
|
||||
db.execSQL("ALTER TABLE recipient ADD COLUMN last_profile_fetch INTEGER DEFAULT 0");
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
|
||||
Reference in New Issue
Block a user