mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-19 00:01:08 +01:00
Fix release channel recipient ID surviving failed backup imports.
This commit is contained in:
committed by
jeffrey-signal
parent
2356bb6da2
commit
5b543c5212
@@ -1218,6 +1218,7 @@ object BackupRepository {
|
||||
}
|
||||
SignalStore.backup.hasInvalidBackupVersion = false
|
||||
|
||||
var transactionSuccessful = false
|
||||
try {
|
||||
// Removing all the data from the various tables is *very* expensive (i.e. can take *several* minutes) if we don't do some pre-work.
|
||||
// SQLite optimizes deletes if there's no foreign keys, triggers, or WHERE clause, so that's the environment we're gonna create.
|
||||
@@ -1406,11 +1407,17 @@ object BackupRepository {
|
||||
stopwatch.split("fk-check")
|
||||
|
||||
SignalDatabase.rawDatabase.setTransactionSuccessful()
|
||||
transactionSuccessful = true
|
||||
} finally {
|
||||
if (SignalDatabase.rawDatabase.inTransaction()) {
|
||||
SignalDatabase.rawDatabase.endTransaction()
|
||||
}
|
||||
|
||||
if (!transactionSuccessful) {
|
||||
Log.w(TAG, "[import] Transaction failed, clearing release channel recipient ID from key-value store.")
|
||||
SignalStore.releaseChannel.clearReleaseChannelRecipientId()
|
||||
}
|
||||
|
||||
Log.d(TAG, "[import] Re-enabling foreign keys...")
|
||||
SignalDatabase.rawDatabase.forceForeignKeyConstraintsEnabled(true)
|
||||
}
|
||||
|
||||
@@ -51,24 +51,31 @@ class CreateReleaseChannelJob private constructor(parameters: Parameters) : Base
|
||||
}
|
||||
|
||||
if (SignalStore.releaseChannel.releaseChannelRecipientId != null) {
|
||||
Log.i(TAG, "Already created Release Channel recipient ${SignalStore.releaseChannel.releaseChannelRecipientId}")
|
||||
val existingId = SignalStore.releaseChannel.releaseChannelRecipientId!!
|
||||
val recipient = Recipient.resolved(existingId)
|
||||
|
||||
val recipient = Recipient.resolved(SignalStore.releaseChannel.releaseChannelRecipientId!!)
|
||||
if (recipient.profileAvatar.isNullOrEmpty() || !SignalStore.releaseChannel.hasUpdatedAvatar) {
|
||||
SignalStore.releaseChannel.hasUpdatedAvatar = true
|
||||
setAvatar(recipient.id)
|
||||
if (recipient.hasServiceId || recipient.hasE164 || recipient.isGroup || recipient.isDistributionList || recipient.isCallLink) {
|
||||
Log.w(TAG, "Release channel recipient $existingId is not a valid release channel recipient (hasServiceId: ${recipient.hasServiceId}, hasE164: ${recipient.hasE164}, isGroup: ${recipient.isGroup}, isDistributionList: ${recipient.isDistributionList}, isCallLink: ${recipient.isCallLink}). Clearing and recreating.")
|
||||
SignalStore.releaseChannel.clearReleaseChannelRecipientId()
|
||||
} else {
|
||||
Log.i(TAG, "Already created Release Channel recipient $existingId")
|
||||
if (recipient.profileAvatar.isNullOrEmpty() || !SignalStore.releaseChannel.hasUpdatedAvatar) {
|
||||
SignalStore.releaseChannel.hasUpdatedAvatar = true
|
||||
setAvatar(recipient.id)
|
||||
}
|
||||
return
|
||||
}
|
||||
} else {
|
||||
val recipients = SignalDatabase.recipients
|
||||
|
||||
val releaseChannelId: RecipientId = recipients.insertReleaseChannelRecipient()
|
||||
SignalStore.releaseChannel.setReleaseChannelRecipientId(releaseChannelId)
|
||||
SignalStore.releaseChannel.hasUpdatedAvatar = true
|
||||
|
||||
recipients.setProfileName(releaseChannelId, ProfileName.asGiven("Signal"))
|
||||
recipients.setMuted(releaseChannelId, Long.MAX_VALUE)
|
||||
setAvatar(releaseChannelId)
|
||||
}
|
||||
|
||||
val recipients = SignalDatabase.recipients
|
||||
|
||||
val releaseChannelId: RecipientId = recipients.insertReleaseChannelRecipient()
|
||||
SignalStore.releaseChannel.setReleaseChannelRecipientId(releaseChannelId)
|
||||
SignalStore.releaseChannel.hasUpdatedAvatar = true
|
||||
|
||||
recipients.setProfileName(releaseChannelId, ProfileName.asGiven("Signal"))
|
||||
recipients.setMuted(releaseChannelId, Long.MAX_VALUE)
|
||||
setAvatar(releaseChannelId)
|
||||
}
|
||||
|
||||
private fun setAvatar(id: RecipientId) {
|
||||
|
||||
@@ -92,6 +92,7 @@ import org.thoughtcrime.securesms.migrations.ProfileSharingUpdateMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.QuoteThumbnailBackfillMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.RebuildMessageSearchIndexMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.RecheckPaymentsMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.ReleaseChannelRecipientFixMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.RecipientSearchMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.ResetArchiveTierMigrationJob;
|
||||
import org.thoughtcrime.securesms.migrations.SelfRegisteredStateMigrationJob;
|
||||
@@ -344,6 +345,7 @@ public final class JobManagerFactories {
|
||||
put(QuoteThumbnailBackfillMigrationJob.KEY, new QuoteThumbnailBackfillMigrationJob.Factory());
|
||||
put(RebuildMessageSearchIndexMigrationJob.KEY, new RebuildMessageSearchIndexMigrationJob.Factory());
|
||||
put(RecheckPaymentsMigrationJob.KEY, new RecheckPaymentsMigrationJob.Factory());
|
||||
put(ReleaseChannelRecipientFixMigrationJob.KEY, new ReleaseChannelRecipientFixMigrationJob.Factory());
|
||||
put(RecipientSearchMigrationJob.KEY, new RecipientSearchMigrationJob.Factory());
|
||||
put(ResetArchiveTierMigrationJob.KEY, new ResetArchiveTierMigrationJob.Factory());
|
||||
put(SelfRegisteredStateMigrationJob.KEY, new SelfRegisteredStateMigrationJob.Factory());
|
||||
|
||||
@@ -33,6 +33,10 @@ class ReleaseChannelValues(store: KeyValueStore) : SignalStoreValues(store) {
|
||||
putString(KEY_RELEASE_CHANNEL_RECIPIENT_ID, id.serialize())
|
||||
}
|
||||
|
||||
fun clearReleaseChannelRecipientId() {
|
||||
store.beginWrite().remove(KEY_RELEASE_CHANNEL_RECIPIENT_ID).apply()
|
||||
}
|
||||
|
||||
var nextScheduledCheck by longValue(KEY_NEXT_SCHEDULED_CHECK, 0)
|
||||
var previousManifestMd5 by blobValue(KEY_PREVIOUS_MANIFEST_MD5, ByteArray(0))
|
||||
var highestVersionNoteReceived by integerValue(KEY_HIGHEST_VERSION_NOTE_RECEIVED, 0)
|
||||
|
||||
@@ -194,9 +194,10 @@ public class ApplicationMigrations {
|
||||
static final int SVR2_ENCLAVE_UPDATE_5 = 150;
|
||||
static final int STICKER_PACK_ADDITION_2 = 151;
|
||||
static final int DELETED_BY_DB_MIGRATION = 152;
|
||||
static final int RELEASE_CHANNEL_RECIPIENT_FIX = 153;
|
||||
}
|
||||
|
||||
public static final int CURRENT_VERSION = 152;
|
||||
public static final int CURRENT_VERSION = 153;
|
||||
|
||||
/**
|
||||
* This *must* be called after the {@link JobManager} has been instantiated, but *before* the call
|
||||
@@ -899,6 +900,10 @@ public class ApplicationMigrations {
|
||||
jobs.put(Version.DELETED_BY_DB_MIGRATION, new DatabaseMigrationJob());
|
||||
}
|
||||
|
||||
if (lastSeenVersion < Version.RELEASE_CHANNEL_RECIPIENT_FIX) {
|
||||
jobs.put(Version.RELEASE_CHANNEL_RECIPIENT_FIX, new ReleaseChannelRecipientFixMigrationJob());
|
||||
}
|
||||
|
||||
return jobs;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2025 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.migrations
|
||||
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.jobmanager.Job
|
||||
import org.thoughtcrime.securesms.jobs.CreateReleaseChannelJob
|
||||
|
||||
/**
|
||||
* In a failed backup flow, the release channel recipient can be incorrectly set. Fix it if that's the case.
|
||||
*/
|
||||
internal class ReleaseChannelRecipientFixMigrationJob private constructor(parameters: Parameters) : MigrationJob(parameters) {
|
||||
|
||||
companion object {
|
||||
const val KEY = "ReleaseChannelRecipientFixMigrationJob"
|
||||
}
|
||||
|
||||
constructor() : this(Parameters.Builder().build())
|
||||
|
||||
override fun isUiBlocking(): Boolean = false
|
||||
|
||||
override fun getFactoryKey(): String = KEY
|
||||
|
||||
override fun performMigration() {
|
||||
AppDependencies.jobManager.add(CreateReleaseChannelJob.create())
|
||||
}
|
||||
|
||||
override fun shouldRetry(e: Exception): Boolean = false
|
||||
|
||||
class Factory : Job.Factory<ReleaseChannelRecipientFixMigrationJob> {
|
||||
override fun create(parameters: Parameters, serializedData: ByteArray?): ReleaseChannelRecipientFixMigrationJob {
|
||||
return ReleaseChannelRecipientFixMigrationJob(parameters)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user