diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/Argon2TestJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/Argon2TestJob.java deleted file mode 100644 index 34cb9b2151..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/Argon2TestJob.java +++ /dev/null @@ -1,244 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import android.app.ActivityManager; - -import androidx.annotation.NonNull; - -import org.signal.argon2.Argon2; -import org.signal.argon2.Argon2Exception; -import org.signal.argon2.MemoryCost; -import org.signal.argon2.Type; -import org.signal.argon2.Version; -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.util.ServiceUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; - -import java.nio.charset.StandardCharsets; -import java.text.NumberFormat; -import java.util.Locale; - -public final class Argon2TestJob extends BaseJob { - - public static final String KEY = "Argon2TestJob"; - - private static final String TAG = Log.tag(Argon2TestJob.class); - - private Argon2TestJob(@NonNull Parameters parameters) { - super(parameters); - } - - public Argon2TestJob() { - this(new Parameters.Builder() - .setMaxAttempts(1) - .build()); - } - - @Override - protected void onRun() throws InterruptedException { - if (TextSecurePreferences.isArgon2Tested(context)) { - Log.w(TAG, "Skipping Argon2 test, it has been run before"); - return; - } - - TextSecurePreferences.setArgon2Tested(context,true); - - Log.i(TAG, "Starting Argon2 test"); - - Argon2.Builder argon2Builder = new Argon2.Builder(Version.V13) - .type(Type.Argon2id) - .parallelism(1); - - MemoryCost memoryCost = MemoryCost.MiB(4); - try { - checkRam(memoryCost); - } catch (Exception e) { - throw new Argon2NotEnoughRam4(e.getMessage()); - } - test(argon2Builder.memoryCost(memoryCost) - .iterations(8) - .build(), - "c0286e8dfd91b633f41d9dc13dc99b3705b62e23349dd399ff68be5fc7720c41", - "$argon2id$v=19$m=4096,t=8,p=1$c29tZXNhbHQ$wChujf2RtjP0HZ3BPcmbNwW2LiM0ndOZ/2i+X8dyDEE"); - - Thread.sleep(3000); - - memoryCost = MemoryCost.MiB(8); - try { - checkRam(memoryCost); - } catch (Exception e) { - throw new Argon2NotEnoughRam8(e.getMessage()); - } - test(argon2Builder.memoryCost(memoryCost) - .iterations(3) - .build(), - "c52fdf6c6dc5e4e82b826b00d795781540d6d50458a43f0ccc44a7d701830318", - "$argon2id$v=19$m=8192,t=3,p=1$c29tZXNhbHQ$xS/fbG3F5OgrgmsA15V4FUDW1QRYpD8MzESn1wGDAxg"); - - Thread.sleep(3000); - - memoryCost = MemoryCost.MiB(16); - try { - checkRam(memoryCost); - } catch (Exception e) { - throw new Argon2NotEnoughRam16(e.getMessage()); - } - test(argon2Builder.memoryCost(memoryCost) - .iterations(3) - .build(), - "d41922d454814e3dbf2828108bb43a5b6319b22fc9f169528c20d1a2846e06c6", - "$argon2id$v=19$m=16384,t=3,p=1$c29tZXNhbHQ$1Bki1FSBTj2/KCgQi7Q6W2MZsi/J8WlSjCDRooRuBsY"); - - Thread.sleep(3000); - - memoryCost = MemoryCost.MiB(32); - try { - checkRam(memoryCost); - } catch (Exception e) { - throw new Argon2NotEnoughRam32(e.getMessage()); - } - test(argon2Builder.memoryCost(memoryCost) - .iterations(2) - .build(), - "8365c0271b505e7fa397982790802de7b62f71f4e11e05f7a4e6b2ad4f75fec0", - "$argon2id$v=19$m=32768,t=2,p=1$c29tZXNhbHQ$g2XAJxtQXn+jl5gnkIAt57YvcfThHgX3pOayrU91/sA"); - - Log.i(TAG, "Argon2 test complete"); - } - - private void test(Argon2 argon2, String expectedHashHex, String expectedEncoded) { - long startTime = System.currentTimeMillis(); - - Argon2.Result hash; - try { - hash = argon2.hash("signal".getBytes(StandardCharsets.UTF_8), - "somesalt".getBytes(StandardCharsets.UTF_8)); - } catch (Argon2Exception e) { - throw new Argon2TestJobRuntimeException(e); - } - - long endTime = System.currentTimeMillis(); - - Log.i(TAG, String.format(Locale.US, "Argon2 hash complete:%n%s%.3f seconds", hash, (endTime - startTime) / 1000f)); - - if (!hash.getHashHex().equals(expectedHashHex)) { - throw new Argon2HashIncorrectRuntimeException("Hash was not correct"); - } - - if (!hash.getEncoded().equals(expectedEncoded)) { - throw new Argon2EncodedHashIncorrectRuntimeException("Encoded Hash was not correct"); - } - } - - private void checkRam(MemoryCost memoryCost) throws Exception { - NumberFormat numberFormat = NumberFormat.getInstance(Locale.US); - ActivityManager activityManager = ServiceUtil.getActivityManager(context); - ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); - - activityManager.getMemoryInfo(memoryInfo); - - long remainingRam = memoryInfo.availMem - memoryInfo.threshold - memoryCost.toBytes(); - - if (remainingRam <= 0) { - throw new Exception(String.format("Not enough RAM available without taking the system into a low memory state.%n" + - "Available: %s%n" + - "Low memory threshold: %s%n" + - "Requested: %s%n" + - "Shortfall: %s", - numberFormat.format(memoryInfo.availMem), - numberFormat.format(memoryInfo.threshold), - numberFormat.format(memoryCost.toBytes()), - numberFormat.format(-remainingRam) - )); - } else { - Log.i(TAG, String.format("Enough RAM available without taking the system into a low memory state.%n" + - "Available: %s%n" + - "Low memory threshold: %s%n" + - "Requested: %s%n" + - "Surplus: %s", - numberFormat.format(memoryInfo.availMem), - numberFormat.format(memoryInfo.threshold), - numberFormat.format(memoryCost.toBytes()), - numberFormat.format(remainingRam) - )); - } - } - - @Override - protected boolean onShouldRetry(@NonNull Exception e) { - return false; - } - - @Override - public @NonNull Data serialize() { - return Data.EMPTY; - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onFailure() {} - - private static abstract class Argon2RuntimeException extends RuntimeException { - private Argon2RuntimeException(String message) { - super(message); - } - - private Argon2RuntimeException(Throwable inner) { - super(inner); - } - } - - private static class Argon2HashIncorrectRuntimeException extends Argon2RuntimeException { - private Argon2HashIncorrectRuntimeException(String message) { - super(message); - } - } - - private static class Argon2EncodedHashIncorrectRuntimeException extends Argon2RuntimeException { - private Argon2EncodedHashIncorrectRuntimeException(String message) { - super(message); - } - } - - private static class Argon2TestJobRuntimeException extends Argon2RuntimeException { - private Argon2TestJobRuntimeException(Throwable t) { - super(t); - } - } - - private static class Argon2NotEnoughRam4 extends Argon2RuntimeException { - private Argon2NotEnoughRam4(String message) { - super(message); - } - } - - private static class Argon2NotEnoughRam8 extends Argon2RuntimeException { - private Argon2NotEnoughRam8(String message) { - super(message); - } - } - - private static class Argon2NotEnoughRam16 extends Argon2RuntimeException { - private Argon2NotEnoughRam16(String message) { - super(message); - } - } - - private static class Argon2NotEnoughRam32 extends Argon2RuntimeException { - private Argon2NotEnoughRam32(String message) { - super(message); - } - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull Argon2TestJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new Argon2TestJob(parameters); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index 6bddfec20d..0a172bf002 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -20,7 +20,7 @@ import org.thoughtcrime.securesms.jobmanager.migrations.RecipientIdFollowUpJobMi import org.thoughtcrime.securesms.jobmanager.migrations.RecipientIdFollowUpJobMigration2; import org.thoughtcrime.securesms.jobmanager.migrations.RecipientIdJobMigration; import org.thoughtcrime.securesms.jobmanager.migrations.SendReadReceiptsJobMigration; -import org.thoughtcrime.securesms.migrations.Argon2TestMigrationJob; +import org.thoughtcrime.securesms.migrations.PassingMigrationJob; import org.thoughtcrime.securesms.migrations.AvatarMigrationJob; import org.thoughtcrime.securesms.migrations.CachedAttachmentsMigrationJob; import org.thoughtcrime.securesms.migrations.DatabaseMigrationJob; @@ -104,11 +104,9 @@ public final class JobManagerFactories { put(TypingSendJob.KEY, new TypingSendJob.Factory()); put(UpdateApkJob.KEY, new UpdateApkJob.Factory()); put(MarkerJob.KEY, new MarkerJob.Factory()); - put(Argon2TestJob.KEY, new Argon2TestJob.Factory()); put(ProfileUploadJob.KEY, new ProfileUploadJob.Factory()); // Migrations - put(Argon2TestMigrationJob.KEY, new Argon2TestMigrationJob.Factory()); put(AvatarMigrationJob.KEY, new AvatarMigrationJob.Factory()); put(CachedAttachmentsMigrationJob.KEY, new CachedAttachmentsMigrationJob.Factory()); put(DatabaseMigrationJob.KEY, new DatabaseMigrationJob.Factory()); @@ -123,10 +121,14 @@ public final class JobManagerFactories { put(UuidMigrationJob.KEY, new UuidMigrationJob.Factory()); // Dead jobs + put(FailingJob.KEY, new FailingJob.Factory()); + put(PassingMigrationJob.KEY, new PassingMigrationJob.Factory()); put("PushContentReceiveJob", new FailingJob.Factory()); put("AttachmentUploadJob", new FailingJob.Factory()); put("MmsSendJob", new FailingJob.Factory()); put("RefreshUnidentifiedDeliveryAbilityJob", new FailingJob.Factory()); + put("Argon2TestJob", new FailingJob.Factory()); + put("Argon2TestMigrationJob", new PassingMigrationJob.Factory()); }}; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java index 10f7a2934b..b7bae93f01 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java @@ -10,7 +10,6 @@ import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import org.thoughtcrime.securesms.jobmanager.JobManager; -import org.thoughtcrime.securesms.jobs.Argon2TestJob; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.stickers.BlessedPacks; import org.thoughtcrime.securesms.util.TextSecurePreferences; @@ -51,7 +50,7 @@ public class ApplicationMigrations { static final int UUIDS = 6; static final int CACHED_ATTACHMENTS = 7; static final int STICKERS_LAUNCH = 8; - static final int TEST_ARGON2 = 9; + //static final int TEST_ARGON2 = 9; static final int SWOON_STICKERS = 10; static final int STORAGE_SERVICE = 11; static final int STORAGE_KEY_ROTATE = 12; @@ -199,9 +198,10 @@ public class ApplicationMigrations { jobs.put(Version.STICKERS_LAUNCH, new StickerLaunchMigrationJob()); } - if (lastSeenVersion < Version.TEST_ARGON2) { - jobs.put(Version.TEST_ARGON2, new Argon2TestMigrationJob()); - } + // This migration only triggered a test we aren't interested in any more. + // if (lastSeenVersion < Version.TEST_ARGON2) { + // jobs.put(Version.TEST_ARGON2, new Argon2TestMigrationJob()); + // } if (lastSeenVersion < Version.SWOON_STICKERS) { jobs.put(Version.SWOON_STICKERS, new StickerAdditionMigrationJob(BlessedPacks.SWOON_HANDS, BlessedPacks.SWOON_FACES)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/Argon2TestMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/Argon2TestMigrationJob.java deleted file mode 100644 index bc619188aa..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/Argon2TestMigrationJob.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.thoughtcrime.securesms.migrations; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobs.Argon2TestJob; - -/** - * Triggers a Argon2 Test, just once. - */ -public final class Argon2TestMigrationJob extends MigrationJob { - - public static final String KEY = "Argon2TestMigrationJob"; - - private Argon2TestMigrationJob(Parameters parameters) { - super(parameters); - } - - public Argon2TestMigrationJob() { - this(new Parameters.Builder().build()); - } - - @Override - boolean isUiBlocking() { - return false; - } - - @Override - void performMigration() { - ApplicationDependencies.getJobManager().add(new Argon2TestJob()); - } - - @Override - boolean shouldRetry(@NonNull Exception e) { - return false; - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull Argon2TestMigrationJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new Argon2TestMigrationJob(parameters); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/PassingMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/PassingMigrationJob.java new file mode 100644 index 0000000000..c3ae04494f --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/PassingMigrationJob.java @@ -0,0 +1,46 @@ +package org.thoughtcrime.securesms.migrations; + +import androidx.annotation.NonNull; + +import org.thoughtcrime.securesms.jobmanager.Data; +import org.thoughtcrime.securesms.jobmanager.Job; + +/** + * A migration job that always passes. Not useful on it's own, but you can register it's factory for jobs that + * have been removed that you'd like to pass instead of keeping around. + */ +public final class PassingMigrationJob extends MigrationJob { + + public static final String KEY = "PassingMigrationJob"; + + private PassingMigrationJob(Parameters parameters) { + super(parameters); + } + + @Override + boolean isUiBlocking() { + return false; + } + + @Override + void performMigration() { + // Nothing + } + + @Override + boolean shouldRetry(@NonNull Exception e) { + return false; + } + + @Override + public @NonNull String getFactoryKey() { + return KEY; + } + + public static final class Factory implements Job.Factory { + @Override + public @NonNull PassingMigrationJob create(@NonNull Parameters parameters, @NonNull Data data) { + return new PassingMigrationJob(parameters); + } + } +}