Optimistically fetch profiles.
This commit is contained in:
parent
f5626f678d
commit
ce940235b0
11 changed files with 169 additions and 29 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
|
||||
|
|
|
@ -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<RecipientId> 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<RecipientId> recipientIds) {
|
||||
this(new Job.Parameters.Builder()
|
||||
.addConstraint(NetworkConstraint.KEY)
|
||||
|
@ -197,6 +228,9 @@ public class RetrieveProfileJob extends BaseJob {
|
|||
process(profile.first(), profile.second());
|
||||
}
|
||||
|
||||
Set<RecipientId> 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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ public final class FeatureFlags {
|
|||
* desired test state.
|
||||
*/
|
||||
private static final Map<String, OnFlagChange> FLAG_CHANGE_LISTENERS = new HashMap<String, OnFlagChange>() {{
|
||||
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());
|
||||
|
|
Loading…
Add table
Reference in a new issue