From ce940235b020ec019fdfe3a55e2a983090d1c607 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli <37311915+greyson-signal@users.noreply.github.com> Date: Fri, 12 Jun 2020 10:22:46 -0700 Subject: [PATCH] Optimistically fetch profiles. --- .../securesms/ApplicationContext.java | 2 + .../securesms/database/RecipientDatabase.java | 64 ++++++++++++++++++- .../database/helpers/SQLCipherOpenHelper.java | 7 +- .../securesms/jobs/RefreshPreKeysJob.java | 6 +- .../securesms/jobs/RetrieveProfileJob.java | 38 ++++++++++- .../keyvalue/MiscellaneousValues.java | 42 ++++++++++++ .../securesms/keyvalue/SignalStore.java | 25 ++------ .../securesms/recipients/Recipient.java | 7 ++ .../recipients/RecipientDetails.java | 3 + .../securesms/recipients/RecipientUtil.java | 2 +- .../securesms/util/FeatureFlags.java | 2 +- 11 files changed, 169 insertions(+), 29 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/keyvalue/MiscellaneousValues.java diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 6dc4d31bc8..88c6d2f0b5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -45,6 +45,7 @@ import org.thoughtcrime.securesms.jobs.FcmRefreshJob; import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob; import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob; import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob; +import org.thoughtcrime.securesms.jobs.RetrieveProfileJob; import org.thoughtcrime.securesms.logging.AndroidLogger; import org.thoughtcrime.securesms.logging.CustomSignalProtocolLogger; import org.thoughtcrime.securesms.logging.Log; @@ -133,6 +134,7 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi NotificationChannels.create(this); RefreshPreKeysJob.scheduleIfNecessary(); StorageSyncHelper.scheduleRoutineSync(); + RetrieveProfileJob.enqueueRoutineFetchIfNeccessary(this); RegistrationUtil.markRegistrationPossiblyComplete(); ProcessLifecycleOwner.get().getLifecycle().addObserver(this); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java index 7aaf6345be..941014edb2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java @@ -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 getRecipientsForRoutineProfileFetch(long lastInteractionThreshold, long lastProfileFetchThreshold, int limit) { + ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); + Set 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 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 blocked, List groupIds) { List 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; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index 146a43a0e0..1bc7b52017 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -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(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java index aec4bb733e..bcb67ca69c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java @@ -45,7 +45,7 @@ public class RefreshPreKeysJob extends BaseJob { } public static void scheduleIfNecessary() { - long timeSinceLastRefresh = System.currentTimeMillis() - SignalStore.getLastPrekeyRefreshTime(); + long timeSinceLastRefresh = System.currentTimeMillis() - SignalStore.misc().getLastPrekeyRefreshTime(); if (timeSinceLastRefresh > REFRESH_INTERVAL) { Log.i(TAG, "Scheduling a prekey refresh. Time since last schedule: " + timeSinceLastRefresh + " ms"); @@ -82,7 +82,7 @@ public class RefreshPreKeysJob extends BaseJob { if (availableKeys >= PREKEY_MINIMUM && TextSecurePreferences.isSignedPreKeyRegistered(context)) { Log.i(TAG, "Available keys sufficient."); - SignalStore.setLastPrekeyRefreshTime(System.currentTimeMillis()); + SignalStore.misc().setLastPrekeyRefreshTime(System.currentTimeMillis()); return; } @@ -98,7 +98,7 @@ public class RefreshPreKeysJob extends BaseJob { TextSecurePreferences.setSignedPreKeyRegistered(context, true); ApplicationDependencies.getJobManager().add(new CleanPreKeysJob()); - SignalStore.setLastPrekeyRefreshTime(System.currentTimeMillis()); + SignalStore.misc().setLastPrekeyRefreshTime(System.currentTimeMillis()); Log.i(TAG, "Successfully refreshed prekeys."); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java index e4357a4304..30c6e50314 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileJob.java @@ -1,6 +1,7 @@ package org.thoughtcrime.securesms.jobs; +import android.app.Application; import android.content.Context; import android.text.TextUtils; @@ -22,7 +23,7 @@ import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.JobManager; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.linkpreview.Link; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.profiles.ProfileName; import org.thoughtcrime.securesms.recipients.Recipient; @@ -32,6 +33,7 @@ import org.thoughtcrime.securesms.util.Base64; import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.IdentityUtil; import org.thoughtcrime.securesms.util.ProfileUtil; +import org.thoughtcrime.securesms.util.SetUtil; import org.thoughtcrime.securesms.util.Stopwatch; import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.util.concurrent.SignalExecutors; @@ -48,7 +50,6 @@ import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException import org.whispersystems.signalservice.internal.util.concurrent.ListenableFuture; import java.io.IOException; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -128,6 +129,36 @@ public class RetrieveProfileJob extends BaseJob { } } + /** + * Will fetch some profiles to ensure we're decently up-to-date if we haven't done so within a + * certain time period. + */ + public static void enqueueRoutineFetchIfNeccessary(Application application) { + long timeSinceRefresh = System.currentTimeMillis() - SignalStore.misc().getLastProfileRefreshTime(); + if (timeSinceRefresh < TimeUnit.HOURS.toMillis(12)) { + Log.i(TAG, "Too soon to refresh. Did the last refresh " + timeSinceRefresh + " ms ago."); + return; + } + + SignalExecutors.BOUNDED.execute(() -> { + RecipientDatabase db = DatabaseFactory.getRecipientDatabase(application); + long current = System.currentTimeMillis(); + + List ids = db.getRecipientsForRoutineProfileFetch(current - TimeUnit.DAYS.toMillis(30), + current - TimeUnit.DAYS.toMillis(1), + 50); + + if (ids.size() > 0) { + Log.i(TAG, "Optimistically refreshing " + ids.size() + " eligible recipient(s)."); + enqueue(ids); + } else { + Log.i(TAG, "No recipients to refresh."); + } + + SignalStore.misc().setLastProfileRefreshTime(System.currentTimeMillis()); + }); + } + private RetrieveProfileJob(@NonNull List recipientIds) { this(new Job.Parameters.Builder() .addConstraint(NetworkConstraint.KEY) @@ -197,6 +228,9 @@ public class RetrieveProfileJob extends BaseJob { process(profile.first(), profile.second()); } + Set success = SetUtil.difference(recipientIds, retries); + DatabaseFactory.getRecipientDatabase(context).markProfilesFetched(success, System.currentTimeMillis()); + stopwatch.split("process"); long keyCount = Stream.of(profiles).map(Pair::first).map(Recipient::getProfileKey).withoutNulls().count(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/MiscellaneousValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/MiscellaneousValues.java new file mode 100644 index 0000000000..f319fdcc77 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/MiscellaneousValues.java @@ -0,0 +1,42 @@ +package org.thoughtcrime.securesms.keyvalue; + +import androidx.annotation.NonNull; + +public final class MiscellaneousValues extends SignalStoreValues { + + private static final String LAST_PREKEY_REFRESH_TIME = "last_prekey_refresh_time"; + private static final String MESSAGE_REQUEST_ENABLE_TIME = "message_request_enable_time"; + private static final String LAST_PROFILE_REFRESH_TIME = "misc.last_profile_refresh_time"; + + MiscellaneousValues(@NonNull KeyValueStore store) { + super(store); + } + + @Override + void onFirstEverAppLaunch() { + } + + public long getLastPrekeyRefreshTime() { + return getLong(LAST_PREKEY_REFRESH_TIME, 0); + } + + public void setLastPrekeyRefreshTime(long time) { + putLong(LAST_PREKEY_REFRESH_TIME, time); + } + + public long getMessageRequestEnableTime() { + return getLong(MESSAGE_REQUEST_ENABLE_TIME, 0); + } + + public void setMessageRequestEnableTime(long time) { + putLong(MESSAGE_REQUEST_ENABLE_TIME, time); + } + + public long getLastProfileRefreshTime() { + return getLong(LAST_PROFILE_REFRESH_TIME, 0); + } + + public void setLastProfileRefreshTime(long time) { + putLong(LAST_PROFILE_REFRESH_TIME, time); + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.java index bd8460f7ff..b4699dc5d5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/SignalStore.java @@ -12,9 +12,6 @@ import org.thoughtcrime.securesms.logging.SignalUncaughtExceptionHandler; */ public final class SignalStore { - private static final String LAST_PREKEY_REFRESH_TIME = "last_prekey_refresh_time"; - private static final String MESSAGE_REQUEST_ENABLE_TIME = "message_request_enable_time"; - private static final SignalStore INSTANCE = new SignalStore(); private final KeyValueStore store; @@ -25,6 +22,7 @@ public final class SignalStore { private final StorageServiceValues storageServiceValues; private final UiHints uiHints; private final TooltipValues tooltipValues; + private final MiscellaneousValues misc; private SignalStore() { this.store = ApplicationDependencies.getKeyValueStore(); @@ -35,6 +33,7 @@ public final class SignalStore { this.storageServiceValues = new StorageServiceValues(store); this.uiHints = new UiHints(store); this.tooltipValues = new TooltipValues(store); + this.misc = new MiscellaneousValues(store); } public static void onFirstEverAppLaunch() { @@ -71,26 +70,14 @@ public final class SignalStore { return INSTANCE.tooltipValues; } + public static @NonNull MiscellaneousValues misc() { + return INSTANCE.misc; + } + public static @NonNull GroupsV2AuthorizationSignalStoreCache groupsV2AuthorizationCache() { return new GroupsV2AuthorizationSignalStoreCache(getStore()); } - public static long getLastPrekeyRefreshTime() { - return getStore().getLong(LAST_PREKEY_REFRESH_TIME, 0); - } - - public static void setLastPrekeyRefreshTime(long time) { - putLong(LAST_PREKEY_REFRESH_TIME, time); - } - - public static long getMessageRequestEnableTime() { - return getStore().getLong(MESSAGE_REQUEST_ENABLE_TIME, 0); - } - - public static void setMessageRequestEnableTime(long time) { - putLong(MESSAGE_REQUEST_ENABLE_TIME, time); - } - public static @NonNull PreferenceDataStore getPreferenceDataStore() { return new SignalPreferenceDataStore(getStore()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java index 28eccf965b..1e0f822c4c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java @@ -89,6 +89,7 @@ public class Recipient { private final String profileAvatar; private final boolean hasProfileImage; private final boolean profileSharing; + private final long lastProfileFetch; private final String notificationChannel; private final UnidentifiedAccessMode unidentifiedAccessMode; private final boolean forceSmsSelection; @@ -332,6 +333,7 @@ public class Recipient { this.profileAvatar = null; this.hasProfileImage = false; this.profileSharing = false; + this.lastProfileFetch = 0; this.notificationChannel = null; this.unidentifiedAccessMode = UnidentifiedAccessMode.DISABLED; this.forceSmsSelection = false; @@ -374,6 +376,7 @@ public class Recipient { this.profileAvatar = details.profileAvatar; this.hasProfileImage = details.hasProfileImage; this.profileSharing = details.profileSharing; + this.lastProfileFetch = details.lastProfileFetch; this.notificationChannel = details.notificationChannel; this.unidentifiedAccessMode = details.unidentifiedAccessMode; this.forceSmsSelection = details.forceSmsSelection; @@ -610,6 +613,10 @@ public class Recipient { return profileSharing; } + public long getLastProfileFetchTime() { + return lastProfileFetch; + } + public boolean isGroup() { return resolve().groupId != null; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java index 83330b94da..d116c6d964 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java @@ -53,6 +53,7 @@ public class RecipientDetails { final String profileAvatar; final boolean hasProfileImage; final boolean profileSharing; + final long lastProfileFetch; final boolean systemContact; final boolean isLocalNumber; final String notificationChannel; @@ -99,6 +100,7 @@ public class RecipientDetails { this.profileAvatar = settings.getProfileAvatar(); this.hasProfileImage = settings.hasProfileImage(); this.profileSharing = settings.isProfileSharing(); + this.lastProfileFetch = settings.getLastProfileFetch(); this.systemContact = systemContact; this.isLocalNumber = isLocalNumber; this.notificationChannel = settings.getNotificationChannel(); @@ -146,6 +148,7 @@ public class RecipientDetails { this.profileAvatar = null; this.hasProfileImage = false; this.profileSharing = false; + this.lastProfileFetch = 0; this.systemContact = true; this.isLocalNumber = false; this.notificationChannel = null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java index daddff547d..dd9dd3c4a5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java @@ -163,7 +163,7 @@ public class RecipientUtil { return true; } - long beforeTime = SignalStore.getMessageRequestEnableTime(); + long beforeTime = SignalStore.misc().getMessageRequestEnableTime(); return DatabaseFactory.getMmsSmsDatabase(context).getConversationCount(threadId, beforeTime) > 0; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java index a7f9f9d9d4..613b1b0633 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java @@ -130,7 +130,7 @@ public final class FeatureFlags { * desired test state. */ private static final Map FLAG_CHANGE_LISTENERS = new HashMap() {{ - put(MESSAGE_REQUESTS, (change) -> SignalStore.setMessageRequestEnableTime(change == Change.ENABLED ? System.currentTimeMillis() : 0)); + put(MESSAGE_REQUESTS, (change) -> SignalStore.misc().setMessageRequestEnableTime(change == Change.ENABLED ? System.currentTimeMillis() : 0)); put(VERSIONED_PROFILES, (change) -> { if (change == Change.ENABLED) { ApplicationDependencies.getJobManager().add(new ProfileUploadJob());