Fix storage sync validation crash with local only unknown ids.

This commit is contained in:
Cody Henthorne 2023-12-19 13:55:34 -05:00 committed by Clark Chen
parent 592dfec8db
commit e7c8ecbd31
3 changed files with 73 additions and 1 deletions

View file

@ -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());

View file

@ -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;
}

View file

@ -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<StorageFixLocalUnknownMigrationJob> {
override fun create(parameters: Parameters, serializedData: ByteArray?): StorageFixLocalUnknownMigrationJob {
return StorageFixLocalUnknownMigrationJob(parameters)
}
}
}