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 81259695ed..15dab0058d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -75,6 +75,7 @@ import org.thoughtcrime.securesms.migrations.StickerDayByDayMigrationJob; import org.thoughtcrime.securesms.migrations.StickerLaunchMigrationJob; import org.thoughtcrime.securesms.migrations.StickerMyDailyLifeMigrationJob; import org.thoughtcrime.securesms.migrations.StorageCapabilityMigrationJob; +import org.thoughtcrime.securesms.migrations.StorageFixLocalUnknownMigrationJob; import org.thoughtcrime.securesms.migrations.StorageServiceMigrationJob; import org.thoughtcrime.securesms.migrations.StorageServiceSystemNameMigrationJob; import org.thoughtcrime.securesms.migrations.StoryViewedReceiptsStateMigrationJob; @@ -259,6 +260,7 @@ public final class JobManagerFactories { put(StickerDayByDayMigrationJob.KEY, new StickerDayByDayMigrationJob.Factory()); put(StickerMyDailyLifeMigrationJob.KEY, new StickerMyDailyLifeMigrationJob.Factory()); put(StorageCapabilityMigrationJob.KEY, new StorageCapabilityMigrationJob.Factory()); + put(StorageFixLocalUnknownMigrationJob.KEY, new StorageFixLocalUnknownMigrationJob.Factory()); put(StorageServiceMigrationJob.KEY, new StorageServiceMigrationJob.Factory()); put(StorageServiceSystemNameMigrationJob.KEY, new StorageServiceSystemNameMigrationJob.Factory()); put(StoryViewedReceiptsStateMigrationJob.KEY, new StoryViewedReceiptsStateMigrationJob.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 a4f4dead9b..7d73b19410 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java @@ -142,9 +142,10 @@ public class ApplicationMigrations { static final int SYNC_KEYS_MIGRATION = 98; static final int SELF_REGISTERTED_STATE = 99; static final int SVR2_ENCLAVE_UPDATE = 100; + static final int STORAGE_LOCAL_UNKNOWNS_FIX = 101; } - public static final int CURRENT_VERSION = 100; + public static final int CURRENT_VERSION = 101; /** * This *must* be called after the {@link JobManager} has been instantiated, but *before* the call @@ -647,6 +648,10 @@ public class ApplicationMigrations { jobs.put(Version.SVR2_ENCLAVE_UPDATE, new Svr2MirrorMigrationJob()); } + if (lastSeenVersion < Version.STORAGE_LOCAL_UNKNOWNS_FIX) { + jobs.put(Version.STORAGE_LOCAL_UNKNOWNS_FIX, new StorageFixLocalUnknownMigrationJob()); + } + return jobs; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageFixLocalUnknownMigrationJob.kt b/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageFixLocalUnknownMigrationJob.kt new file mode 100644 index 0000000000..488395884a --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/StorageFixLocalUnknownMigrationJob.kt @@ -0,0 +1,65 @@ +package org.thoughtcrime.securesms.migrations + +import org.signal.core.util.logging.Log +import org.signal.core.util.withinTransaction +import org.thoughtcrime.securesms.database.SignalDatabase +import org.thoughtcrime.securesms.dependencies.ApplicationDependencies +import org.thoughtcrime.securesms.jobmanager.Job +import org.thoughtcrime.securesms.jobs.MultiDeviceKeysUpdateJob +import org.thoughtcrime.securesms.jobs.StorageSyncJob +import org.thoughtcrime.securesms.keyvalue.SignalStore +import org.thoughtcrime.securesms.util.TextSecurePreferences + +/** + * Remove local unknown storage ids not in local storage service manifest. + */ +internal class StorageFixLocalUnknownMigrationJob( + parameters: Parameters = Parameters.Builder().build() +) : MigrationJob(parameters) { + + companion object { + val TAG = Log.tag(StorageFixLocalUnknownMigrationJob::class.java) + const val KEY = "StorageFixLocalUnknownMigrationJob" + } + + override fun getFactoryKey(): String = KEY + + override fun isUiBlocking(): Boolean = false + + @Suppress("UsePropertyAccessSyntax") + override fun performMigration() { + val localStorageIds = SignalStore.storageService().getManifest().storageIds.toSet() + val unknownLocalIds = SignalDatabase.unknownStorageIds.getAllUnknownIds().toSet() + val danglingLocalUnknownIds = unknownLocalIds - localStorageIds + + if (danglingLocalUnknownIds.isEmpty()) { + return + } + + Log.w(TAG, "Removing ${danglingLocalUnknownIds.size} dangling unknown ids") + + SignalDatabase.rawDatabase.withinTransaction { + SignalDatabase.unknownStorageIds.delete(danglingLocalUnknownIds) + } + + val jobManager = ApplicationDependencies.getJobManager() + + if (TextSecurePreferences.isMultiDevice(context)) { + Log.i(TAG, "Multi-device.") + jobManager.startChain(StorageSyncJob()) + .then(MultiDeviceKeysUpdateJob()) + .enqueue() + } else { + Log.i(TAG, "Single-device.") + jobManager.add(StorageSyncJob()) + } + } + + override fun shouldRetry(e: Exception): Boolean = false + + class Factory : Job.Factory { + override fun create(parameters: Parameters, serializedData: ByteArray?): StorageFixLocalUnknownMigrationJob { + return StorageFixLocalUnknownMigrationJob(parameters) + } + } +}