Replace prekey jobs with one overall sync job.

fork-5.53.8
Cody Henthorne 2022-08-16 15:58:43 -04:00
rodzic 2740b5e300
commit 3252871ed5
21 zmienionych plików z 433 dodań i 418 usunięć

Wyświetl plik

@ -0,0 +1,212 @@
package org.thoughtcrime.securesms.jobs
import androidx.test.ext.junit.runners.AndroidJUnit4
import okhttp3.mockwebserver.MockResponse
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.signal.libsignal.protocol.ecc.Curve
import org.thoughtcrime.securesms.crypto.storage.PreKeyMetadataStore
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.dependencies.InstrumentationApplicationDependencyProvider
import org.thoughtcrime.securesms.jobmanager.Job
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.testing.Get
import org.thoughtcrime.securesms.testing.Put
import org.thoughtcrime.securesms.testing.SignalActivityRule
import org.thoughtcrime.securesms.testing.assertIs
import org.thoughtcrime.securesms.testing.assertIsNot
import org.thoughtcrime.securesms.testing.parsedRequestBody
import org.thoughtcrime.securesms.testing.success
import org.whispersystems.signalservice.api.push.SignedPreKeyEntity
import org.whispersystems.signalservice.internal.push.PreKeyState
import org.whispersystems.signalservice.internal.push.PreKeyStatus
@RunWith(AndroidJUnit4::class)
class PreKeysSyncJobTest {
@get:Rule
val harness = SignalActivityRule()
private val aciPreKeyMeta: PreKeyMetadataStore
get() = SignalStore.account().aciPreKeys
private val pniPreKeyMeta: PreKeyMetadataStore
get() = SignalStore.account().pniPreKeys
private lateinit var job: PreKeysSyncJob
@Before
fun setUp() {
job = PreKeysSyncJob()
}
@After
fun tearDown() {
InstrumentationApplicationDependencyProvider.clearHandlers()
}
/**
* Create signed prekeys for both identities when both do not have registered prekeys according
* to our local state.
*/
@Test
fun runWithoutRegisteredKeysForBothIdentities() {
// GIVEN
aciPreKeyMeta.isSignedPreKeyRegistered = false
pniPreKeyMeta.isSignedPreKeyRegistered = false
lateinit var aciSignedPreKey: SignedPreKeyEntity
lateinit var pniSignedPreKey: SignedPreKeyEntity
InstrumentationApplicationDependencyProvider.addMockWebRequestHandlers(
Put("/v2/keys/signed?identity=aci") { r ->
aciSignedPreKey = r.parsedRequestBody()
MockResponse().success()
},
Put("/v2/keys/signed?identity=pni") { r ->
pniSignedPreKey = r.parsedRequestBody()
MockResponse().success()
},
)
// WHEN
val result: Job.Result = job.run()
// THEN
result.isSuccess assertIs true
aciPreKeyMeta.isSignedPreKeyRegistered assertIs true
pniPreKeyMeta.isSignedPreKeyRegistered assertIs true
val aciVerifySignatureResult = Curve.verifySignature(
ApplicationDependencies.getProtocolStore().aci().identityKeyPair.publicKey.publicKey,
aciSignedPreKey.publicKey.serialize(),
aciSignedPreKey.signature
)
aciVerifySignatureResult assertIs true
val pniVerifySignatureResult = Curve.verifySignature(
ApplicationDependencies.getProtocolStore().pni().identityKeyPair.publicKey.publicKey,
pniSignedPreKey.publicKey.serialize(),
pniSignedPreKey.signature
)
pniVerifySignatureResult assertIs true
}
/**
* With 100 prekeys registered for each identity, do nothing.
*/
@Test
fun runWithRegisteredKeysForBothIdentities() {
// GIVEN
val currentAciKeyId = aciPreKeyMeta.activeSignedPreKeyId
val currentPniKeyId = pniPreKeyMeta.activeSignedPreKeyId
InstrumentationApplicationDependencyProvider.addMockWebRequestHandlers(
Get("/v2/keys?identity=aci") { MockResponse().success(PreKeyStatus(100)) },
Get("/v2/keys?identity=pni") { MockResponse().success(PreKeyStatus(100)) },
)
// WHEN
val result: Job.Result = job.run()
// THEN
result.isSuccess assertIs true
aciPreKeyMeta.activeSignedPreKeyId assertIs currentAciKeyId
pniPreKeyMeta.activeSignedPreKeyId assertIs currentPniKeyId
}
/**
* With 100 prekeys registered for ACI, but no PNI prekeys registered according to local state,
* do nothing for ACI but create PNI prekeys and update local state.
*/
@Test
fun runWithRegisteredKeysForAciIdentityOnly() {
// GIVEN
pniPreKeyMeta.isSignedPreKeyRegistered = false
val currentAciKeyId = aciPreKeyMeta.activeSignedPreKeyId
val currentPniKeyId = pniPreKeyMeta.activeSignedPreKeyId
InstrumentationApplicationDependencyProvider.addMockWebRequestHandlers(
Get("/v2/keys?identity=aci") { MockResponse().success(PreKeyStatus(100)) },
Put("/v2/keys/signed?identity=pni") { MockResponse().success() },
)
// WHEN
val result: Job.Result = job.run()
// THEN
result.isSuccess assertIs true
pniPreKeyMeta.isSignedPreKeyRegistered assertIs true
aciPreKeyMeta.activeSignedPreKeyId assertIs currentAciKeyId
pniPreKeyMeta.activeSignedPreKeyId assertIsNot currentPniKeyId
}
/**
* With <10 prekeys registered for each identity, upload new.
*/
@Test
fun runWithLowNumberOfRegisteredKeysForBothIdentities() {
// GIVEN
val currentAciKeyId = aciPreKeyMeta.activeSignedPreKeyId
val currentPniKeyId = pniPreKeyMeta.activeSignedPreKeyId
val currentNextAciPreKeyId = aciPreKeyMeta.nextOneTimePreKeyId
val currentNextPniPreKeyId = pniPreKeyMeta.nextOneTimePreKeyId
lateinit var aciPreKeyStateRequest: PreKeyState
lateinit var pniPreKeyStateRequest: PreKeyState
InstrumentationApplicationDependencyProvider.addMockWebRequestHandlers(
Get("/v2/keys?identity=aci") { MockResponse().success(PreKeyStatus(5)) },
Get("/v2/keys?identity=pni") { MockResponse().success(PreKeyStatus(5)) },
Put("/v2/keys/?identity=aci") { r ->
aciPreKeyStateRequest = r.parsedRequestBody()
MockResponse().success()
},
Put("/v2/keys/?identity=pni") { r ->
pniPreKeyStateRequest = r.parsedRequestBody()
MockResponse().success()
},
)
// WHEN
val result: Job.Result = job.run()
// THEN
result.isSuccess assertIs true
aciPreKeyMeta.activeSignedPreKeyId assertIsNot currentAciKeyId
pniPreKeyMeta.activeSignedPreKeyId assertIsNot currentPniKeyId
aciPreKeyMeta.nextOneTimePreKeyId assertIsNot currentNextAciPreKeyId
pniPreKeyMeta.nextOneTimePreKeyId assertIsNot currentNextPniPreKeyId
ApplicationDependencies.getProtocolStore().aci().identityKeyPair.publicKey.let { aciIdentityKey ->
aciPreKeyStateRequest.identityKey assertIs aciIdentityKey
val verifySignatureResult = Curve.verifySignature(
aciIdentityKey.publicKey,
aciPreKeyStateRequest.signedPreKey.publicKey.serialize(),
aciPreKeyStateRequest.signedPreKey.signature
)
verifySignatureResult assertIs true
}
ApplicationDependencies.getProtocolStore().pni().identityKeyPair.publicKey.let { pniIdentityKey ->
pniPreKeyStateRequest.identityKey assertIs pniIdentityKey
val verifySignatureResult = Curve.verifySignature(
pniIdentityKey.publicKey,
pniPreKeyStateRequest.signedPreKey.publicKey.serialize(),
pniPreKeyStateRequest.signedPreKey.signature
)
verifySignatureResult assertIs true
}
}
}

Wyświetl plik

@ -50,16 +50,15 @@ import org.thoughtcrime.securesms.emoji.EmojiSource;
import org.thoughtcrime.securesms.emoji.JumboEmoji;
import org.thoughtcrime.securesms.gcm.FcmJobService;
import org.thoughtcrime.securesms.jobs.CheckServiceReachabilityJob;
import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
import org.thoughtcrime.securesms.jobs.DownloadLatestEmojiDataJob;
import org.thoughtcrime.securesms.jobs.EmojiSearchIndexDownloadJob;
import org.thoughtcrime.securesms.jobs.FcmRefreshJob;
import org.thoughtcrime.securesms.jobs.FontDownloaderJob;
import org.thoughtcrime.securesms.jobs.GroupV2UpdateSelfProfileKeyJob;
import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob;
import org.thoughtcrime.securesms.jobs.PreKeysSyncJob;
import org.thoughtcrime.securesms.jobs.ProfileUploadJob;
import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob;
import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob;
import org.thoughtcrime.securesms.jobs.RetrieveProfileJob;
import org.thoughtcrime.securesms.jobs.RetrieveRemoteAnnouncementsJob;
import org.thoughtcrime.securesms.jobs.StoryOnboardingDownloadJob;
@ -180,13 +179,12 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr
.addNonBlocking(this::initializeRevealableMessageManager)
.addNonBlocking(this::initializePendingRetryReceiptManager)
.addNonBlocking(this::initializeFcmCheck)
.addNonBlocking(CreateSignedPreKeyJob::enqueueIfNeeded)
.addNonBlocking(PreKeysSyncJob::enqueueIfNeeded)
.addNonBlocking(this::initializePeriodicTasks)
.addNonBlocking(this::initializeCircumvention)
.addNonBlocking(this::initializePendingMessages)
.addNonBlocking(this::initializeCleanup)
.addNonBlocking(this::initializeGlideCodecs)
.addNonBlocking(RefreshPreKeysJob::scheduleIfNecessary)
.addNonBlocking(StorageSyncHelper::scheduleRoutineSync)
.addNonBlocking(() -> ApplicationDependencies.getJobManager().beginJobLoop())
.addNonBlocking(EmojiSource::refresh)

Wyświetl plik

@ -217,7 +217,7 @@ class ChangeNumberRepository(private val accountManager: SignalServiceAccountMan
// Signed Prekeys
val signedPreKeyRecord = if (deviceId == primaryDeviceId) {
PreKeyUtil.generateAndStoreSignedPreKey(pniProtocolStore, pniMetadataStore, pniIdentity.privateKey, false)
PreKeyUtil.generateAndStoreSignedPreKey(pniProtocolStore, pniMetadataStore, pniIdentity.privateKey)
} else {
PreKeyUtil.generateSignedPreKey(SecureRandom().nextInt(Medium.MAX_VALUE), pniIdentity.privateKey)
}

Wyświetl plik

@ -64,14 +64,13 @@ public class PreKeyUtil {
return records;
}
public synchronized static @NonNull SignedPreKeyRecord generateAndStoreSignedPreKey(@NonNull SignalProtocolStore protocolStore, @NonNull PreKeyMetadataStore metadataStore, boolean setAsActive) {
return generateAndStoreSignedPreKey(protocolStore, metadataStore, protocolStore.getIdentityKeyPair().getPrivateKey(), setAsActive);
public synchronized static @NonNull SignedPreKeyRecord generateAndStoreSignedPreKey(@NonNull SignalProtocolStore protocolStore, @NonNull PreKeyMetadataStore metadataStore) {
return generateAndStoreSignedPreKey(protocolStore, metadataStore, protocolStore.getIdentityKeyPair().getPrivateKey());
}
public synchronized static @NonNull SignedPreKeyRecord generateAndStoreSignedPreKey(@NonNull SignalProtocolStore protocolStore,
@NonNull PreKeyMetadataStore metadataStore,
@NonNull ECPrivateKey privateKey,
boolean setAsActive)
@NonNull ECPrivateKey privateKey)
{
Log.i(TAG, "Generating signed prekeys...");
@ -81,10 +80,6 @@ public class PreKeyUtil {
protocolStore.storeSignedPreKey(signedPreKeyId, record);
metadataStore.setNextSignedPreKeyId((signedPreKeyId + 1) % Medium.MAX_VALUE);
if (setAsActive) {
metadataStore.setActiveSignedPreKeyId(signedPreKeyId);
}
return record;
}

Wyświetl plik

@ -16,8 +16,7 @@ import org.thoughtcrime.securesms.database.helpers.SignalDatabaseMigrations
import org.thoughtcrime.securesms.database.helpers.SignalDatabaseMigrations.migrate
import org.thoughtcrime.securesms.database.helpers.SignalDatabaseMigrations.migratePostTransaction
import org.thoughtcrime.securesms.database.model.AvatarPickerDatabase
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob
import org.thoughtcrime.securesms.jobs.PreKeysSyncJob
import org.thoughtcrime.securesms.migrations.LegacyMigrationJob
import org.thoughtcrime.securesms.migrations.LegacyMigrationJob.DatabaseUpgradeListener
import org.thoughtcrime.securesms.service.KeyCachingService
@ -145,7 +144,7 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data
val masterSecret = KeyCachingService.getMasterSecret(context)
if (masterSecret != null) SQLCipherMigrationHelper.migrateCiphertext(context, masterSecret, legacyDb, db, null) else TextSecurePreferences.setNeedsSqlCipherMigration(context, true)
if (!PreKeyMigrationHelper.migratePreKeys(context, db)) {
ApplicationDependencies.getJobManager().add(RefreshPreKeysJob())
PreKeysSyncJob.enqueue()
}
SessionStoreMigrationHelper.migrateSessions(context, db)
PreKeyMigrationHelper.cleanUpPreKeys(context)

Wyświetl plik

@ -30,9 +30,8 @@ import org.thoughtcrime.securesms.database.RecipientDatabase
import org.thoughtcrime.securesms.database.helpers.migration.MyStoryMigration
import org.thoughtcrime.securesms.database.helpers.migration.UrgentMslFlagMigration
import org.thoughtcrime.securesms.database.model.databaseprotos.ReactionList
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.groups.GroupId
import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob
import org.thoughtcrime.securesms.jobs.PreKeysSyncJob
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.notifications.NotificationChannels
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
@ -224,7 +223,7 @@ object SignalDatabaseMigrations {
db.execSQL("CREATE TABLE one_time_prekeys (_id INTEGER PRIMARY KEY, key_id INTEGER UNIQUE, public_key TEXT NOT NULL, private_key TEXT NOT NULL)")
if (!PreKeyMigrationHelper.migratePreKeys(context, db)) {
ApplicationDependencies.getJobManager().add(RefreshPreKeysJob())
PreKeysSyncJob.enqueue()
}
}

Wyświetl plik

@ -31,11 +31,11 @@ import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.jobmanager.JobMigrator;
import org.thoughtcrime.securesms.jobmanager.impl.FactoryJobPredicate;
import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer;
import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
import org.thoughtcrime.securesms.jobs.FastJobStorage;
import org.thoughtcrime.securesms.jobs.GroupCallUpdateSendJob;
import org.thoughtcrime.securesms.jobs.JobManagerFactories;
import org.thoughtcrime.securesms.jobs.MarkerJob;
import org.thoughtcrime.securesms.jobs.PreKeysSyncJob;
import org.thoughtcrime.securesms.jobs.PushDecryptMessageJob;
import org.thoughtcrime.securesms.jobs.PushGroupSendJob;
import org.thoughtcrime.securesms.jobs.PushMediaSendJob;
@ -317,7 +317,7 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
}
if (needsPreKeyJob) {
CreateSignedPreKeyJob.enqueueIfNeeded();
PreKeysSyncJob.enqueueIfNeeded();
}
SignalBaseIdentityKeyStore baseIdentityStore = new SignalBaseIdentityKeyStore(context);

Wyświetl plik

@ -4,6 +4,7 @@ import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.annotation.WorkerThread;
import org.signal.core.util.logging.Log;
@ -14,6 +15,8 @@ import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import static androidx.annotation.VisibleForTesting.PACKAGE_PRIVATE;
/**
* A durable unit of work.
*
@ -193,15 +196,18 @@ public abstract class Job {
return new Result(ResultType.FAILURE, runtimeException, null, INVALID_BACKOFF);
}
boolean isSuccess() {
@VisibleForTesting(otherwise = PACKAGE_PRIVATE)
public boolean isSuccess() {
return resultType == ResultType.SUCCESS;
}
boolean isRetry() {
@VisibleForTesting(otherwise = PACKAGE_PRIVATE)
public boolean isRetry() {
return resultType == ResultType.RETRY;
}
boolean isFailure() {
@VisibleForTesting(otherwise = PACKAGE_PRIVATE)
public boolean isFailure() {
return resultType == ResultType.FAILURE;
}

Wyświetl plik

@ -92,8 +92,8 @@ public abstract class BaseJob extends Job {
warn(tag, "", message, null);
}
protected void warn(@NonNull String tag, @NonNull String event, @NonNull String message) {
warn(tag, event, message, null);
protected void warn(@NonNull String tag, @NonNull Object extra, @NonNull String message) {
warn(tag, extra.toString(), message, null);
}
protected void warn(@NonNull String tag, @Nullable Throwable t) {

Wyświetl plik

@ -1,113 +0,0 @@
package org.thoughtcrime.securesms.jobs;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.state.SignalProtocolStore;
import org.signal.libsignal.protocol.state.SignedPreKeyRecord;
import org.thoughtcrime.securesms.crypto.PreKeyUtil;
import org.thoughtcrime.securesms.crypto.storage.PreKeyMetadataStore;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.ServiceId;
import org.whispersystems.signalservice.api.push.ServiceIdType;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* Creates and uploads a new signed prekey for an identity if one hasn't been uploaded yet.
*/
public class CreateSignedPreKeyJob extends BaseJob {
public static final String KEY = "CreateSignedPreKeyJob";
private static final String TAG = Log.tag(CreateSignedPreKeyJob.class);
private CreateSignedPreKeyJob() {
this(new Job.Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setMaxInstancesForFactory(1)
.setQueue("CreateSignedPreKeyJob")
.setLifespan(TimeUnit.DAYS.toMillis(30))
.setMaxAttempts(Parameters.UNLIMITED)
.build());
}
private CreateSignedPreKeyJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
/**
* Enqueues an instance of this job if we not yet created + uploaded signed prekeys for one of our identities.
*/
public static void enqueueIfNeeded() {
if (!SignalStore.account().aciPreKeys().isSignedPreKeyRegistered() || !SignalStore.account().pniPreKeys().isSignedPreKeyRegistered()) {
Log.i(TAG, "Some signed prekeys aren't registered yet. Enqueuing a job.");
ApplicationDependencies.getJobManager().add(new CreateSignedPreKeyJob());
}
}
@Override
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
public void onRun() throws IOException {
if (!SignalStore.account().isRegistered() || SignalStore.account().getAci() == null || SignalStore.account().getPni() == null) {
Log.w(TAG, "Not yet registered...");
return;
}
createPreKeys(ServiceIdType.ACI, SignalStore.account().getAci(), ApplicationDependencies.getProtocolStore().aci(), SignalStore.account().aciPreKeys());
createPreKeys(ServiceIdType.PNI, SignalStore.account().getPni(), ApplicationDependencies.getProtocolStore().pni(), SignalStore.account().pniPreKeys());
}
private void createPreKeys(@NonNull ServiceIdType serviceIdType, @Nullable ServiceId serviceId, @NonNull SignalProtocolStore protocolStore, @NonNull PreKeyMetadataStore metadataStore)
throws IOException
{
if (serviceId == null) {
warn(TAG, "AccountId not set!");
return;
}
if (metadataStore.isSignedPreKeyRegistered()) {
warn(TAG, "Signed prekey for " + serviceIdType + " already registered...");
return;
}
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore, true);
accountManager.setSignedPreKey(serviceIdType, signedPreKeyRecord);
metadataStore.setSignedPreKeyRegistered(true);
}
@Override
public void onFailure() {}
@Override
public boolean onShouldRetry(@NonNull Exception exception) {
if (exception instanceof PushNetworkException) return true;
return false;
}
public static final class Factory implements Job.Factory<CreateSignedPreKeyJob> {
@Override
public @NonNull CreateSignedPreKeyJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new CreateSignedPreKeyJob(parameters);
}
}
}

Wyświetl plik

@ -46,7 +46,6 @@ import org.thoughtcrime.securesms.migrations.EmojiDownloadMigrationJob;
import org.thoughtcrime.securesms.migrations.KbsEnclaveMigrationJob;
import org.thoughtcrime.securesms.migrations.LegacyMigrationJob;
import org.thoughtcrime.securesms.migrations.MigrationCompleteJob;
import org.thoughtcrime.securesms.migrations.SyncDistributionListsMigrationJob;
import org.thoughtcrime.securesms.migrations.PassingMigrationJob;
import org.thoughtcrime.securesms.migrations.PinOptOutMigration;
import org.thoughtcrime.securesms.migrations.PinReminderMigrationJob;
@ -62,6 +61,7 @@ import org.thoughtcrime.securesms.migrations.StickerLaunchMigrationJob;
import org.thoughtcrime.securesms.migrations.StickerMyDailyLifeMigrationJob;
import org.thoughtcrime.securesms.migrations.StorageCapabilityMigrationJob;
import org.thoughtcrime.securesms.migrations.StorageServiceMigrationJob;
import org.thoughtcrime.securesms.migrations.SyncDistributionListsMigrationJob;
import org.thoughtcrime.securesms.migrations.TrimByLengthSettingsMigrationJob;
import org.thoughtcrime.securesms.migrations.UserNotificationMigrationJob;
import org.thoughtcrime.securesms.migrations.UuidMigrationJob;
@ -89,7 +89,6 @@ public final class JobManagerFactories {
put(ClearFallbackKbsEnclaveJob.KEY, new ClearFallbackKbsEnclaveJob.Factory());
put(ConversationShortcutUpdateJob.KEY, new ConversationShortcutUpdateJob.Factory());
put(CreateReleaseChannelJob.KEY, new CreateReleaseChannelJob.Factory());
put(CreateSignedPreKeyJob.KEY, new CreateSignedPreKeyJob.Factory());
put(DirectoryRefreshJob.KEY, new DirectoryRefreshJob.Factory());
put(DonationReceiptRedemptionJob.KEY, new DonationReceiptRedemptionJob.Factory());
put(DownloadLatestEmojiDataJob.KEY, new DownloadLatestEmojiDataJob.Factory());
@ -136,6 +135,7 @@ public final class JobManagerFactories {
put(PaymentNotificationSendJob.KEY, new PaymentNotificationSendJob.Factory());
put(PaymentSendJob.KEY, new PaymentSendJob.Factory());
put(PaymentTransactionCheckJob.KEY, new PaymentTransactionCheckJob.Factory());
put(PreKeysSyncJob.KEY, new PreKeysSyncJob.Factory());
put(ProfileKeySendJob.KEY, new ProfileKeySendJob.Factory());
put(ProfileUploadJob.KEY, new ProfileUploadJob.Factory());
put(PushDecryptMessageJob.KEY, new PushDecryptMessageJob.Factory());
@ -152,7 +152,6 @@ public final class JobManagerFactories {
put(RecipientChangedNumberJob.KEY, new RecipientChangedNumberJob.Factory());
put(RefreshAttributesJob.KEY, new RefreshAttributesJob.Factory());
put(RefreshOwnProfileJob.KEY, new RefreshOwnProfileJob.Factory());
put(RefreshPreKeysJob.KEY, new RefreshPreKeysJob.Factory());
put(RemoteConfigRefreshJob.KEY, new RemoteConfigRefreshJob.Factory());
put(RemoteDeleteSendJob.KEY, new RemoteDeleteSendJob.Factory());
put(ReportSpamJob.KEY, new ReportSpamJob.Factory());
@ -165,7 +164,6 @@ public final class JobManagerFactories {
put(RetrieveRemoteAnnouncementsJob.KEY, new RetrieveRemoteAnnouncementsJob.Factory());
put(RotateCertificateJob.KEY, new RotateCertificateJob.Factory());
put(RotateProfileKeyJob.KEY, new RotateProfileKeyJob.Factory());
put(RotateSignedPreKeyJob.KEY, new RotateSignedPreKeyJob.Factory());
put(SenderKeyDistributionSendJob.KEY, new SenderKeyDistributionSendJob.Factory());
put(SendDeliveryReceiptJob.KEY, new SendDeliveryReceiptJob.Factory());
put(SendReadReceiptJob.KEY, new SendReadReceiptJob.Factory(application));
@ -241,6 +239,9 @@ public final class JobManagerFactories {
put("LeaveGroupJob", new FailingJob.Factory());
put("PushGroupUpdateJob", new FailingJob.Factory());
put("RequestGroupInfoJob", new FailingJob.Factory());
put("RotateSignedPreKeyJob", new PreKeysSyncJob.Factory());
put("CreateSignedPreKeyJob", new PreKeysSyncJob.Factory());
put("RefreshPreKeysJob", new PreKeysSyncJob.Factory());
}};
}

Wyświetl plik

@ -0,0 +1,178 @@
package org.thoughtcrime.securesms.jobs
import androidx.annotation.VisibleForTesting
import org.signal.core.util.logging.Log
import org.signal.libsignal.protocol.state.SignalProtocolStore
import org.thoughtcrime.securesms.crypto.PreKeyUtil
import org.thoughtcrime.securesms.crypto.storage.PreKeyMetadataStore
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.jobmanager.Data
import org.thoughtcrime.securesms.jobmanager.Job
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.signalservice.api.push.ServiceId
import org.whispersystems.signalservice.api.push.ServiceIdType
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException
import java.util.concurrent.TimeUnit
/**
* Regardless of the current state of affairs with respect to prekeys for either ACI or PNI identities, will
* attempt to make the state valid.
*
* If prekeys aren't registered for an identity they will be created.
*
* If prekeys are registered but the count is below the minimum threshold, then new ones will be uploaded.
*/
class PreKeysSyncJob private constructor(private val forceRotate: Boolean = false, parameters: Parameters) : BaseJob(parameters) {
companion object {
const val KEY = "PreKeysSyncJob"
private val TAG = Log.tag(PreKeysSyncJob::class.java)
private val KEY_FORCE_ROTATE = "force_rotate"
private const val PREKEY_MINIMUM = 10
private val REFRESH_INTERVAL = TimeUnit.DAYS.toMillis(3)
@JvmStatic
@JvmOverloads
fun enqueue(forceRotate: Boolean = false) {
ApplicationDependencies.getJobManager().add(PreKeysSyncJob(forceRotate))
}
@JvmStatic
fun enqueueIfNeeded() {
if (!SignalStore.account().aciPreKeys.isSignedPreKeyRegistered || !SignalStore.account().pniPreKeys.isSignedPreKeyRegistered) {
Log.i(TAG, "Some signed prekeys aren't registered yet. Enqueuing a job. ACI: ${SignalStore.account().aciPreKeys.isSignedPreKeyRegistered} PNI: ${SignalStore.account().pniPreKeys.isSignedPreKeyRegistered}")
ApplicationDependencies.getJobManager().add(PreKeysSyncJob())
} else if (SignalStore.account().aciPreKeys.activeSignedPreKeyId < 0 || SignalStore.account().pniPreKeys.activeSignedPreKeyId < 0) {
Log.i(TAG, "Some signed prekeys aren't active yet. Enqueuing a job. ACI: ${SignalStore.account().aciPreKeys.activeSignedPreKeyId >= 0} PNI: ${SignalStore.account().pniPreKeys.activeSignedPreKeyId >= 0}")
ApplicationDependencies.getJobManager().add(PreKeysSyncJob())
} else {
val timeSinceLastRefresh = System.currentTimeMillis() - SignalStore.misc().lastPrekeyRefreshTime
if (timeSinceLastRefresh > REFRESH_INTERVAL) {
Log.i(TAG, "Scheduling a prekey refresh. Time since last schedule: $timeSinceLastRefresh ms")
ApplicationDependencies.getJobManager().add(PreKeysSyncJob())
}
}
}
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
constructor(forceRotate: Boolean = false) : this(
forceRotate,
Parameters.Builder()
.setQueue("PreKeysSyncJob")
.addConstraint(NetworkConstraint.KEY)
.setMaxInstancesForFactory(1)
.setMaxAttempts(Parameters.UNLIMITED)
.setLifespan(TimeUnit.DAYS.toMillis(30))
.build()
)
override fun getFactoryKey(): String = KEY
override fun serialize(): Data {
return Data.Builder()
.putBoolean(KEY_FORCE_ROTATE, forceRotate)
.build()
}
override fun onRun() {
if (!SignalStore.account().isRegistered || SignalStore.account().aci == null || SignalStore.account().pni == null) {
warn(TAG, "Not yet registered")
return
}
syncPreKeys(ServiceIdType.ACI, SignalStore.account().aci, ApplicationDependencies.getProtocolStore().aci(), SignalStore.account().aciPreKeys)
syncPreKeys(ServiceIdType.PNI, SignalStore.account().pni, ApplicationDependencies.getProtocolStore().pni(), SignalStore.account().pniPreKeys)
SignalStore.misc().lastPrekeyRefreshTime = System.currentTimeMillis()
}
private fun syncPreKeys(serviceIdType: ServiceIdType, serviceId: ServiceId?, protocolStore: SignalProtocolStore, metadataStore: PreKeyMetadataStore) {
if (serviceId == null) {
warn(TAG, serviceIdType, "AccountId not set!")
return
}
if (metadataStore.isSignedPreKeyRegistered && metadataStore.activeSignedPreKeyId >= 0) {
if (forceRotate || System.currentTimeMillis() > TextSecurePreferences.getSignedPreKeyRotationTime(context) || metadataStore.signedPreKeyFailureCount > 5) {
log(serviceIdType, "Rotating signed prekey...")
rotateSignedPreKey(serviceIdType, protocolStore, metadataStore)
} else {
log(serviceIdType, "Refreshing prekeys...")
refreshKeys(serviceIdType, protocolStore, metadataStore)
}
} else {
log(serviceIdType, "Creating signed prekey...")
rotateSignedPreKey(serviceIdType, protocolStore, metadataStore)
}
}
private fun rotateSignedPreKey(serviceIdType: ServiceIdType, protocolStore: SignalProtocolStore, metadataStore: PreKeyMetadataStore) {
val signedPreKeyRecord = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore)
ApplicationDependencies.getSignalServiceAccountManager().setSignedPreKey(serviceIdType, signedPreKeyRecord)
metadataStore.activeSignedPreKeyId = signedPreKeyRecord.id
metadataStore.isSignedPreKeyRegistered = true
metadataStore.signedPreKeyFailureCount = 0
}
private fun refreshKeys(serviceIdType: ServiceIdType, protocolStore: SignalProtocolStore, metadataStore: PreKeyMetadataStore) {
val accountManager = ApplicationDependencies.getSignalServiceAccountManager()
val availableKeys = accountManager.getPreKeysCount(serviceIdType)
log(serviceIdType, "Available keys: $availableKeys")
if (availableKeys >= PREKEY_MINIMUM && metadataStore.isSignedPreKeyRegistered) {
log(serviceIdType, "Available keys sufficient.")
return
}
val preKeyRecords = PreKeyUtil.generateAndStoreOneTimePreKeys(protocolStore, metadataStore)
val signedPreKeyRecord = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore)
val identityKey = protocolStore.identityKeyPair
log(serviceIdType, "Registering new prekeys...")
accountManager.setPreKeys(serviceIdType, identityKey.publicKey, signedPreKeyRecord, preKeyRecords)
metadataStore.activeSignedPreKeyId = signedPreKeyRecord.id
metadataStore.isSignedPreKeyRegistered = true
log(serviceIdType, "Cleaning prekeys...")
PreKeyUtil.cleanSignedPreKeys(protocolStore, metadataStore)
SignalStore.misc().lastPrekeyRefreshTime = System.currentTimeMillis()
log(serviceIdType, "Successfully refreshed prekeys.")
}
override fun onShouldRetry(e: Exception): Boolean {
return when (e) {
is NonSuccessfulResponseCodeException -> false
is PushNetworkException -> true
else -> false
}
}
override fun onFailure() {
val aciStore = SignalStore.account().aciPreKeys
val pniStore = SignalStore.account().pniPreKeys
if ((aciStore.isSignedPreKeyRegistered || pniStore.isSignedPreKeyRegistered) && forceRotate) {
aciStore.signedPreKeyFailureCount++
pniStore.signedPreKeyFailureCount++
}
}
private fun log(serviceIdType: ServiceIdType, message: String) {
Log.i(TAG, "[$serviceIdType] $message")
}
class Factory : Job.Factory<PreKeysSyncJob> {
override fun create(parameters: Parameters, data: Data): PreKeysSyncJob {
return PreKeysSyncJob(data.getBooleanOrDefault(KEY_FORCE_ROTATE, false), parameters)
}
}
}

Wyświetl plik

@ -103,7 +103,7 @@ public abstract class PushSendJob extends SendJob {
@Override
protected final void onSend() throws Exception {
if (SignalStore.account().aciPreKeys().getSignedPreKeyFailureCount() > 5) {
ApplicationDependencies.getJobManager().add(new RotateSignedPreKeyJob());
PreKeysSyncJob.enqueue(true);
throw new TextSecureExpiredException("Too many signed prekey rotation failures");
}

Wyświetl plik

@ -1,148 +0,0 @@
package org.thoughtcrime.securesms.jobs;
import androidx.annotation.NonNull;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.IdentityKeyPair;
import org.signal.libsignal.protocol.state.PreKeyRecord;
import org.signal.libsignal.protocol.state.SignalProtocolStore;
import org.signal.libsignal.protocol.state.SignedPreKeyRecord;
import org.thoughtcrime.securesms.crypto.PreKeyUtil;
import org.thoughtcrime.securesms.crypto.storage.PreKeyMetadataStore;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.ServiceIdType;
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Ensures that our prekeys are up to date for both our ACI and PNI identities.
* Specifically, if we have less than {@link #PREKEY_MINIMUM} one-time prekeys, we will generate and upload
* a new batch of one-time prekeys, as well as a new signed prekey.
*/
public class RefreshPreKeysJob extends BaseJob {
public static final String KEY = "RefreshPreKeysJob";
private static final String TAG = Log.tag(RefreshPreKeysJob.class);
private static final int PREKEY_MINIMUM = 10;
private static final long REFRESH_INTERVAL = TimeUnit.DAYS.toMillis(3);
public RefreshPreKeysJob() {
this(new Job.Parameters.Builder()
.setQueue("RefreshPreKeysJob")
.addConstraint(NetworkConstraint.KEY)
.setMaxInstancesForFactory(1)
.setMaxAttempts(Parameters.UNLIMITED)
.setLifespan(TimeUnit.DAYS.toMillis(30))
.build());
}
public static void scheduleIfNecessary() {
long timeSinceLastRefresh = System.currentTimeMillis() - SignalStore.misc().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) {
super(parameters);
}
@Override
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
public void onRun() throws IOException {
if (!SignalStore.account().isRegistered() || SignalStore.account().getAci() == null || SignalStore.account().getPni() == null) {
Log.w(TAG, "Not registered. Skipping.");
return;
}
SignalProtocolStore aciProtocolStore = ApplicationDependencies.getProtocolStore().aci();
PreKeyMetadataStore aciPreKeyStore = SignalStore.account().aciPreKeys();
SignalProtocolStore pniProtocolStore = ApplicationDependencies.getProtocolStore().pni();
PreKeyMetadataStore pniPreKeyStore = SignalStore.account().pniPreKeys();
if (refreshKeys(ServiceIdType.ACI, aciProtocolStore, aciPreKeyStore)) {
PreKeyUtil.cleanSignedPreKeys(aciProtocolStore, aciPreKeyStore);
}
if (refreshKeys(ServiceIdType.PNI, pniProtocolStore, pniPreKeyStore)) {
PreKeyUtil.cleanSignedPreKeys(pniProtocolStore, pniPreKeyStore);
}
SignalStore.misc().setLastPrekeyRefreshTime(System.currentTimeMillis());
Log.i(TAG, "Successfully refreshed prekeys.");
}
/**
* @return True if we need to clean prekeys, otherwise false.
*/
private boolean refreshKeys(@NonNull ServiceIdType serviceIdType, @NonNull SignalProtocolStore protocolStore, @NonNull PreKeyMetadataStore metadataStore) throws IOException {
String logPrefix = "[" + serviceIdType + "] ";
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
int availableKeys = accountManager.getPreKeysCount(serviceIdType);
log(TAG, logPrefix + "Available keys: " + availableKeys);
if (availableKeys >= PREKEY_MINIMUM && metadataStore.isSignedPreKeyRegistered()) {
log(TAG, logPrefix + "Available keys sufficient.");
return false;
}
List<PreKeyRecord> preKeyRecords = PreKeyUtil.generateAndStoreOneTimePreKeys(protocolStore, metadataStore);
SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore, false);
IdentityKeyPair identityKey = protocolStore.getIdentityKeyPair();
log(TAG, logPrefix + "Registering new prekeys...");
accountManager.setPreKeys(serviceIdType, identityKey.getPublicKey(), signedPreKeyRecord, preKeyRecords);
metadataStore.setActiveSignedPreKeyId(signedPreKeyRecord.getId());
metadataStore.setSignedPreKeyRegistered(true);
log(TAG, logPrefix + "Need to clean prekeys.");
return true;
}
@Override
public boolean onShouldRetry(@NonNull Exception exception) {
if (exception instanceof NonSuccessfulResponseCodeException) return false;
if (exception instanceof PushNetworkException) return true;
return false;
}
@Override
public void onFailure() {
}
public static final class Factory implements Job.Factory<RefreshPreKeysJob> {
@Override
public @NonNull RefreshPreKeysJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new RefreshPreKeysJob(parameters);
}
}
}

Wyświetl plik

@ -1,117 +0,0 @@
package org.thoughtcrime.securesms.jobs;
import androidx.annotation.NonNull;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.state.SignalProtocolStore;
import org.signal.libsignal.protocol.state.SignedPreKeyRecord;
import org.thoughtcrime.securesms.crypto.PreKeyUtil;
import org.thoughtcrime.securesms.crypto.storage.PreKeyMetadataStore;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.ACI;
import org.whispersystems.signalservice.api.push.PNI;
import org.whispersystems.signalservice.api.push.ServiceIdType;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* Forces the creation + upload of new signed prekeys for both the ACI and PNI identities.
*/
public class RotateSignedPreKeyJob extends BaseJob {
public static final String KEY = "RotateSignedPreKeyJob";
private static final String TAG = Log.tag(RotateSignedPreKeyJob.class);
public RotateSignedPreKeyJob() {
this(new Job.Parameters.Builder()
.setQueue("RotateSignedPreKeyJob")
.addConstraint(NetworkConstraint.KEY)
.setMaxInstancesForFactory(1)
.setMaxAttempts(Parameters.UNLIMITED)
.setLifespan(TimeUnit.DAYS.toMillis(2))
.build());
}
private RotateSignedPreKeyJob(@NonNull Job.Parameters parameters) {
super(parameters);
}
@Override
public @NonNull Data serialize() {
return Data.EMPTY;
}
@Override
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
public void onRun() throws Exception {
if (!SignalStore.account().isRegistered() || SignalStore.account().getAci() == null || SignalStore.account().getPni() == null) {
Log.w(TAG, "Not registered. Skipping.");
return;
}
Log.i(TAG, "Rotating signed prekey...");
ACI aci = SignalStore.account().getAci();
PNI pni = SignalStore.account().getPni();
if (aci == null) {
Log.w(TAG, "ACI is unset!");
return;
}
if (pni == null) {
Log.w(TAG, "PNI is unset!");
return;
}
rotate(ServiceIdType.ACI, ApplicationDependencies.getProtocolStore().aci(), SignalStore.account().aciPreKeys());
rotate(ServiceIdType.PNI, ApplicationDependencies.getProtocolStore().pni(), SignalStore.account().pniPreKeys());
}
private void rotate(@NonNull ServiceIdType serviceIdType, @NonNull SignalProtocolStore protocolStore, @NonNull PreKeyMetadataStore metadataStore)
throws IOException
{
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore, false);
accountManager.setSignedPreKey(serviceIdType, signedPreKeyRecord);
metadataStore.setActiveSignedPreKeyId(signedPreKeyRecord.getId());
metadataStore.setSignedPreKeyRegistered(true);
metadataStore.setSignedPreKeyFailureCount(0);
}
@Override
public boolean onShouldRetry(@NonNull Exception exception) {
return exception instanceof PushNetworkException;
}
@Override
public void onFailure() {
PreKeyMetadataStore aciStore = SignalStore.account().aciPreKeys();
PreKeyMetadataStore pniStore = SignalStore.account().pniPreKeys();
aciStore.setSignedPreKeyFailureCount(aciStore.getSignedPreKeyFailureCount() + 1);
pniStore.setSignedPreKeyFailureCount(pniStore.getSignedPreKeyFailureCount() + 1);
}
public static final class Factory implements Job.Factory<RotateSignedPreKeyJob> {
@Override
public @NonNull RotateSignedPreKeyJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new RotateSignedPreKeyJob(parameters);
}
}
}

Wyświetl plik

@ -33,7 +33,7 @@ import org.thoughtcrime.securesms.groups.BadGroupIdException;
import org.thoughtcrime.securesms.groups.GroupId;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobs.AutomaticSessionResetJob;
import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob;
import org.thoughtcrime.securesms.jobs.PreKeysSyncJob;
import org.thoughtcrime.securesms.jobs.SendRetryReceiptJob;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.logsubmit.SubmitDebugLogActivity;
@ -43,7 +43,6 @@ import org.thoughtcrime.securesms.notifications.NotificationChannels;
import org.thoughtcrime.securesms.notifications.NotificationIds;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.whispersystems.signalservice.api.InvalidMessageStructureException;
import org.whispersystems.signalservice.api.SignalServiceAccountDataStore;
import org.whispersystems.signalservice.api.crypto.ContentHint;
@ -101,7 +100,7 @@ public final class MessageDecryptionUtil {
List<Job> jobs = new LinkedList<>();
if (envelope.isPreKeySignalMessage()) {
jobs.add(new RefreshPreKeysJob());
PreKeysSyncJob.enqueue();
}
try {

Wyświetl plik

@ -20,8 +20,8 @@ import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob;
import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob;
import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob;
import org.thoughtcrime.securesms.jobs.PreKeysSyncJob;
import org.thoughtcrime.securesms.jobs.PushDecryptMessageJob;
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
@ -129,7 +129,7 @@ public class LegacyMigrationJob extends MigrationJob {
}
if (lastSeenVersion < SIGNED_PREKEY_VERSION) {
CreateSignedPreKeyJob.enqueueIfNeeded();
PreKeysSyncJob.enqueueIfNeeded();
}
if (lastSeenVersion < NO_DECRYPT_QUEUE_VERSION) {

Wyświetl plik

@ -75,10 +75,11 @@ public class PniAccountInitializationMigrationJob extends MigrationJob {
if (!metadataStore.isSignedPreKeyRegistered()) {
Log.i(TAG, "Uploading signed prekey for PNI.");
SignedPreKeyRecord signedPreKey = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore, true);
SignedPreKeyRecord signedPreKey = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore);
List<PreKeyRecord> oneTimePreKeys = PreKeyUtil.generateAndStoreOneTimePreKeys(protocolStore, metadataStore);
accountManager.setPreKeys(ServiceIdType.PNI, protocolStore.getIdentityKeyPair().getPublicKey(), signedPreKey, oneTimePreKeys);
metadataStore.setActiveSignedPreKeyId(signedPreKey.getId());
metadataStore.setSignedPreKeyRegistered(true);
} else {
Log.w(TAG, "Already uploaded signed prekey for PNI. Skipping this step.");

Wyświetl plik

@ -190,10 +190,11 @@ public final class RegistrationRepository {
@NonNull PreKeyMetadataStore metadataStore)
throws IOException
{
SignedPreKeyRecord signedPreKey = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore, true);
SignedPreKeyRecord signedPreKey = PreKeyUtil.generateAndStoreSignedPreKey(protocolStore, metadataStore);
List<PreKeyRecord> oneTimePreKeys = PreKeyUtil.generateAndStoreOneTimePreKeys(protocolStore, metadataStore);
accountManager.setPreKeys(serviceIdType, protocolStore.getIdentityKeyPair().getPublicKey(), signedPreKey, oneTimePreKeys);
metadataStore.setActiveSignedPreKeyId(signedPreKey.getId());
metadataStore.setSignedPreKeyRegistered(true);
}

Wyświetl plik

@ -5,7 +5,7 @@ import android.content.Context;
import android.content.Intent;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobs.RotateSignedPreKeyJob;
import org.thoughtcrime.securesms.jobs.PreKeysSyncJob;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
@ -23,7 +23,7 @@ public class RotateSignedPreKeyListener extends PersistentAlarmManagerListener {
@Override
protected long onAlarm(Context context, long scheduledTime) {
if (scheduledTime != 0 && SignalStore.account().isRegistered()) {
ApplicationDependencies.getJobManager().add(new RotateSignedPreKeyJob());
PreKeysSyncJob.enqueue(true);
}
long nextTime = System.currentTimeMillis() + INTERVAL;

Wyświetl plik

@ -15,6 +15,10 @@ public class PreKeyStatus {
public PreKeyStatus() {}
public PreKeyStatus(int count) {
this.count = count;
}
public int getCount() {
return count;
}