Improve prekey refresh logic.

This commit is contained in:
Greyson Parrelli 2020-02-19 14:16:31 -05:00
parent 5158a15379
commit 3824e90997
4 changed files with 42 additions and 4 deletions

View file

@ -48,6 +48,7 @@ import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
import org.thoughtcrime.securesms.jobs.FcmRefreshJob; import org.thoughtcrime.securesms.jobs.FcmRefreshJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob; import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob; import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob;
import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob;
import org.thoughtcrime.securesms.jobs.StickerPackDownloadJob; import org.thoughtcrime.securesms.jobs.StickerPackDownloadJob;
import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.megaphone.MegaphoneRepository; import org.thoughtcrime.securesms.megaphone.MegaphoneRepository;
@ -138,6 +139,7 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi
initializeCameraX(); initializeCameraX();
FeatureFlags.init(); FeatureFlags.init();
NotificationChannels.create(this); NotificationChannels.create(this);
RefreshPreKeysJob.scheduleIfNecessary();
ProcessLifecycleOwner.get().getLifecycle().addObserver(this); ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
if (Build.VERSION.SDK_INT < 21) { if (Build.VERSION.SDK_INT < 21) {

View file

@ -9,6 +9,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.IdentityKeyPair; import org.whispersystems.libsignal.IdentityKeyPair;
@ -17,9 +18,11 @@ import org.whispersystems.libsignal.state.SignedPreKeyRecord;
import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException; import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
import org.whispersystems.signalservice.api.storage.SignalStorageRecord;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
public class RefreshPreKeysJob extends BaseJob { public class RefreshPreKeysJob extends BaseJob {
@ -29,14 +32,27 @@ public class RefreshPreKeysJob extends BaseJob {
private static final int PREKEY_MINIMUM = 10; private static final int PREKEY_MINIMUM = 10;
private static final long REFRESH_INTERVAL = TimeUnit.DAYS.toMillis(3);
public RefreshPreKeysJob() { public RefreshPreKeysJob() {
this(new Job.Parameters.Builder() this(new Job.Parameters.Builder()
.setQueue("RefreshPreKeysJob") .setQueue("RefreshPreKeysJob")
.addConstraint(NetworkConstraint.KEY) .addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(5) .setMaxInstances(1)
.setMaxAttempts(Parameters.UNLIMITED)
.setLifespan(TimeUnit.DAYS.toMillis(30))
.build()); .build());
} }
public static void scheduleIfNecessary() {
long timeSinceLastRefresh = System.currentTimeMillis() - SignalStore.getLastPrekeyRefreshTime();
if (timeSinceLastRefresh > REFRESH_INTERVAL) {
Log.i(TAG, "Scheduling a prekey refresh. Time since last schedule: " + timeSinceLastRefresh + " ms");
ApplicationDependencies.getJobManager().add(new RefreshPreKeysJob());
}
}
private RefreshPreKeysJob(@NonNull Job.Parameters parameters) { private RefreshPreKeysJob(@NonNull Job.Parameters parameters) {
super(parameters); super(parameters);
} }
@ -53,14 +69,20 @@ public class RefreshPreKeysJob extends BaseJob {
@Override @Override
public void onRun() throws IOException { public void onRun() throws IOException {
if (!TextSecurePreferences.isPushRegistered(context)) return; if (!TextSecurePreferences.isPushRegistered(context)) {
Log.w(TAG, "Not registered. Skipping.");
return;
}
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager(); SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
int availableKeys = accountManager.getPreKeysCount(); int availableKeys = accountManager.getPreKeysCount();
Log.i(TAG, "Available keys: " + availableKeys);
if (availableKeys >= PREKEY_MINIMUM && TextSecurePreferences.isSignedPreKeyRegistered(context)) { if (availableKeys >= PREKEY_MINIMUM && TextSecurePreferences.isSignedPreKeyRegistered(context)) {
Log.i(TAG, "Available keys sufficient: " + availableKeys); Log.i(TAG, "Available keys sufficient.");
SignalStore.setLastPrekeyRefreshTime(System.currentTimeMillis());
return; return;
} }
@ -76,6 +98,8 @@ public class RefreshPreKeysJob extends BaseJob {
TextSecurePreferences.setSignedPreKeyRegistered(context, true); TextSecurePreferences.setSignedPreKeyRegistered(context, true);
ApplicationDependencies.getJobManager().add(new CleanPreKeysJob()); ApplicationDependencies.getJobManager().add(new CleanPreKeysJob());
SignalStore.setLastPrekeyRefreshTime(System.currentTimeMillis());
Log.i(TAG, "Successfully refreshed prekeys.");
} }
@Override @Override

View file

@ -17,6 +17,8 @@ import org.whispersystems.libsignal.state.SignedPreKeyRecord;
import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
import java.util.concurrent.TimeUnit;
public class RotateSignedPreKeyJob extends BaseJob { public class RotateSignedPreKeyJob extends BaseJob {
public static final String KEY = "RotateSignedPreKeyJob"; public static final String KEY = "RotateSignedPreKeyJob";
@ -27,7 +29,9 @@ public class RotateSignedPreKeyJob extends BaseJob {
this(new Job.Parameters.Builder() this(new Job.Parameters.Builder()
.setQueue("RotateSignedPreKeyJob") .setQueue("RotateSignedPreKeyJob")
.addConstraint(NetworkConstraint.KEY) .addConstraint(NetworkConstraint.KEY)
.setMaxAttempts(5) .setMaxInstances(1)
.setMaxAttempts(Parameters.UNLIMITED)
.setLifespan(TimeUnit.DAYS.toMillis(2))
.build()); .build());
} }

View file

@ -14,6 +14,7 @@ public final class SignalStore {
private static final String REMOTE_CONFIG = "remote_config"; private static final String REMOTE_CONFIG = "remote_config";
private static final String REMOTE_CONFIG_LAST_FETCH_TIME = "remote_config_last_fetch_time"; private static final String REMOTE_CONFIG_LAST_FETCH_TIME = "remote_config_last_fetch_time";
private static final String LAST_PREKEY_REFRESH_TIME = "last_prekey_refresh_time";
private SignalStore() {} private SignalStore() {}
@ -45,6 +46,13 @@ public final class SignalStore {
putLong(REMOTE_CONFIG_LAST_FETCH_TIME, time); putLong(REMOTE_CONFIG_LAST_FETCH_TIME, time);
} }
public static long getLastPrekeyRefreshTime() {
return getStore().getLong(LAST_PREKEY_REFRESH_TIME, 0);
}
public static void setLastPrekeyRefreshTime(long time) {
putLong(LAST_PREKEY_REFRESH_TIME, time);
}
/** /**
* Ensures any pending writes are finished. Only intended to be called by * Ensures any pending writes are finished. Only intended to be called by