mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-05-24 09:08:46 +01:00
Sync release note channel settings with storage service.
This commit is contained in:
committed by
jeffrey-signal
parent
9f608337f1
commit
6eea4ba937
@@ -4028,6 +4028,11 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
fun rotateStorageId(recipientId: RecipientId, logFailure: Boolean = false) {
|
||||
val selfId = Recipient.self().id
|
||||
|
||||
if (recipientId != selfId && recipientId == SignalStore.releaseChannel.releaseChannelRecipientId) {
|
||||
// Release channel info is stored on the account record (self)
|
||||
rotateStorageId(selfId)
|
||||
}
|
||||
|
||||
val values = ContentValues(1).apply {
|
||||
put(STORAGE_SERVICE_ID, Base64.encodeWithPadding(StorageSyncHelper.generateKey()))
|
||||
}
|
||||
|
||||
@@ -1622,6 +1622,8 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
||||
Log.w(TAG, "Failed to parse serviceId!")
|
||||
null
|
||||
}
|
||||
} else if (pinned.releaseNotes != null) {
|
||||
SignalStore.releaseChannel.releaseChannelRecipientId?.let { Recipient.resolved(it) }
|
||||
} else if (pinned.legacyGroupId != null) {
|
||||
try {
|
||||
Recipient.externalGroupExact(GroupId.v1(pinned.legacyGroupId!!.toByteArray()))
|
||||
@@ -1657,6 +1659,10 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
||||
notifyConversationListListeners()
|
||||
}
|
||||
|
||||
fun applyStorageSyncReleaseChannelUpdate(recipientId: RecipientId, archived: Boolean, forcedUnread: Boolean) {
|
||||
applyStorageSyncUpdate(recipientId, archived, forcedUnread, isGroup = false)
|
||||
}
|
||||
|
||||
private fun applyStorageSyncUpdate(recipientId: RecipientId, archived: Boolean, forcedUnread: Boolean, isGroup: Boolean) {
|
||||
val values = ContentValues()
|
||||
values.put(ARCHIVED, if (archived) 1 else 0)
|
||||
|
||||
@@ -199,9 +199,10 @@ public class ApplicationMigrations {
|
||||
static final int COLLAPSED_EVENTS = 155;
|
||||
static final int COLLAPSED_EVENTS_2 = 156;
|
||||
static final int KEY_TRANSPARENCY = 157;
|
||||
static final int RELEASE_NOTES_CHAT_SYNC = 158;
|
||||
}
|
||||
|
||||
public static final int CURRENT_VERSION = 157;
|
||||
public static final int CURRENT_VERSION = 158;
|
||||
|
||||
/**
|
||||
* This *must* be called after the {@link JobManager} has been instantiated, but *before* the call
|
||||
@@ -924,6 +925,10 @@ public class ApplicationMigrations {
|
||||
jobs.put(Version.KEY_TRANSPARENCY, new ResetKeyTransparencyMigrationJob());
|
||||
}
|
||||
|
||||
if (lastSeenVersion < Version.RELEASE_NOTES_CHAT_SYNC) {
|
||||
jobs.put(Version.RELEASE_NOTES_CHAT_SYNC, new AccountRecordMigrationJob());
|
||||
}
|
||||
|
||||
return jobs;
|
||||
}
|
||||
|
||||
|
||||
@@ -140,6 +140,10 @@ class AccountRecordProcessor(
|
||||
backupTier = local.proto.backupTier ?: remote.proto.backupTier
|
||||
automaticKeyVerificationDisabled = remote.proto.automaticKeyVerificationDisabled
|
||||
hasSeenAdminDeleteEducationDialog = remote.proto.hasSeenAdminDeleteEducationDialog
|
||||
releaseNotesChatArchived = remote.proto.releaseNotesChatArchived
|
||||
releaseNotesChatMutedUntilTimestamp = remote.proto.releaseNotesChatMutedUntilTimestamp
|
||||
releaseNotesChatBlocked = remote.proto.releaseNotesChatBlocked
|
||||
releaseNotesChatMarkedUnread = remote.proto.releaseNotesChatMarkedUnread
|
||||
|
||||
safeSetPayments(payments?.enabled == true, payments?.entropy?.toByteArray())
|
||||
safeSetSubscriber(donationSubscriberId, donationSubscriberCurrencyCode)
|
||||
|
||||
@@ -139,6 +139,8 @@ object StorageSyncHelper {
|
||||
|
||||
val storageId = selfRecord?.storageId ?: self.storageId
|
||||
|
||||
val releaseChannelRecord: RecipientRecord? = SignalStore.releaseChannel.releaseChannelRecipientId?.let { SignalDatabase.recipients.getRecordForSync(it) }
|
||||
|
||||
val accountRecord = SignalAccountRecord.newBuilder(selfRecord?.syncExtras?.storageProto).apply {
|
||||
profileKey = self.profileKey?.toByteString() ?: ByteString.EMPTY
|
||||
givenName = self.profileName.givenName
|
||||
@@ -197,6 +199,13 @@ object StorageSyncHelper {
|
||||
safeSetPayments(SignalStore.payments.mobileCoinPaymentsEnabled(), Optional.ofNullable(SignalStore.payments.paymentsEntropy).map { obj: Entropy -> obj.bytes }.orElse(null))
|
||||
automaticKeyVerificationDisabled = !SignalStore.settings.automaticVerificationEnabled
|
||||
hasSeenAdminDeleteEducationDialog = SignalStore.uiHints.hasSeenAdminDeleteEducationDialog()
|
||||
|
||||
if (releaseChannelRecord != null) {
|
||||
releaseNotesChatArchived = releaseChannelRecord.syncExtras.isArchived == true
|
||||
releaseNotesChatMutedUntilTimestamp = releaseChannelRecord.muteUntil
|
||||
releaseNotesChatBlocked = releaseChannelRecord.isBlocked == true
|
||||
releaseNotesChatMarkedUnread = releaseChannelRecord.syncExtras.isForcedUnread == true
|
||||
}
|
||||
}
|
||||
|
||||
return accountRecord.toSignalAccountRecord(StorageId.forAccount(storageId)).toSignalStorageRecord()
|
||||
@@ -308,6 +317,13 @@ object StorageSyncHelper {
|
||||
SignalStore.misc.usernameQrCodeColorScheme = StorageSyncModels.remoteToLocalUsernameColor(update.new.proto.usernameLink!!.color)
|
||||
}
|
||||
|
||||
SignalStore.releaseChannel.releaseChannelRecipientId?.let { releaseChannelId ->
|
||||
SignalDatabase.recipients.setBlocked(releaseChannelId, update.new.proto.releaseNotesChatBlocked)
|
||||
SignalDatabase.recipients.setMuted(releaseChannelId, update.new.proto.releaseNotesChatMutedUntilTimestamp)
|
||||
SignalDatabase.threads.applyStorageSyncReleaseChannelUpdate(releaseChannelId, update.new.proto.releaseNotesChatArchived, update.new.proto.releaseNotesChatMarkedUnread)
|
||||
Recipient.live(releaseChannelId).refresh()
|
||||
}
|
||||
|
||||
if (update.new.proto.notificationProfileManualOverride != null) {
|
||||
if (update.new.proto.notificationProfileManualOverride!!.enabled != null) {
|
||||
Log.i(TAG, "Found a remote enabled notification override")
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.thoughtcrime.securesms.database.model.databaseprotos.InAppPaymentData
|
||||
import org.thoughtcrime.securesms.groups.BadGroupIdException
|
||||
import org.thoughtcrime.securesms.groups.GroupId
|
||||
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
@@ -123,13 +124,17 @@ object StorageSyncModels {
|
||||
|
||||
@JvmStatic
|
||||
fun localToRemotePinnedConversations(records: List<RecipientRecord>): List<AccountRecord.PinnedConversation> {
|
||||
val releaseChannelId = SignalStore.releaseChannel.releaseChannelRecipientId
|
||||
return records
|
||||
.filter { it.recipientType == RecipientType.GV1 || it.recipientType == RecipientType.GV2 || it.registered == RecipientTable.RegisteredState.REGISTERED }
|
||||
.map { localToRemotePinnedConversation(it) }
|
||||
.filter { it.recipientType == RecipientType.GV1 || it.recipientType == RecipientType.GV2 || it.registered == RecipientTable.RegisteredState.REGISTERED || it.id == releaseChannelId }
|
||||
.map { localToRemotePinnedConversation(it, releaseChannelId) }
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
private fun localToRemotePinnedConversation(settings: RecipientRecord): AccountRecord.PinnedConversation {
|
||||
private fun localToRemotePinnedConversation(settings: RecipientRecord, releaseChannelId: RecipientId?): AccountRecord.PinnedConversation {
|
||||
if (settings.id == releaseChannelId) {
|
||||
return AccountRecord.PinnedConversation(releaseNotes = AccountRecord.PinnedConversation.ReleaseNotes())
|
||||
}
|
||||
return when (settings.recipientType) {
|
||||
RecipientType.INDIVIDUAL -> {
|
||||
AccountRecord.PinnedConversation(
|
||||
|
||||
@@ -33,7 +33,7 @@ class StorageServicePlugin : Plugin {
|
||||
|
||||
if (record.proto.account != null) {
|
||||
row += "Account"
|
||||
row += record.proto.account.toString()
|
||||
row += record.proto.account.toString().prettyPrintProto()
|
||||
} else if (record.proto.contact != null) {
|
||||
row += "Contact"
|
||||
row += record.proto.toString()
|
||||
@@ -77,3 +77,55 @@ class StorageServicePlugin : Plugin {
|
||||
const val PATH = "/storage"
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.prettyPrintProto(): String {
|
||||
val out = StringBuilder(length + length / 4)
|
||||
var indent = 0
|
||||
var compactDepth = 0
|
||||
fun newline() {
|
||||
out.append('\n').append(" ".repeat(indent))
|
||||
}
|
||||
var i = 0
|
||||
while (i < length) {
|
||||
val c = this[i]
|
||||
when (c) {
|
||||
'{', '[' -> {
|
||||
val compact = c == '[' && this.regionMatches(i + 1, "hex", 0, 3, ignoreCase = true)
|
||||
if (compact) {
|
||||
compactDepth++
|
||||
out.append(c)
|
||||
} else {
|
||||
indent++
|
||||
out.append(c)
|
||||
newline()
|
||||
}
|
||||
}
|
||||
'}', ']' -> {
|
||||
if (compactDepth > 0 && c == ']') {
|
||||
compactDepth--
|
||||
out.append(c)
|
||||
} else {
|
||||
indent = (indent - 1).coerceAtLeast(0)
|
||||
val opener = if (c == '}') '{' else '['
|
||||
while (out.isNotEmpty() && (out.last() == ' ' || out.last() == '\n')) {
|
||||
out.deleteCharAt(out.length - 1)
|
||||
}
|
||||
if (out.isNotEmpty() && out.last() == opener) {
|
||||
out.append(c)
|
||||
} else {
|
||||
newline()
|
||||
out.append(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
',' -> {
|
||||
out.append(c)
|
||||
if (compactDepth == 0) newline()
|
||||
}
|
||||
' ' -> if (out.isNotEmpty() && out.last() != '\n' && out.last() != ' ') out.append(c)
|
||||
else -> out.append(c)
|
||||
}
|
||||
i++
|
||||
}
|
||||
return out.toString()
|
||||
}
|
||||
|
||||
@@ -195,10 +195,13 @@ message AccountRecord {
|
||||
bytes serviceIdBinary = 3; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI)
|
||||
}
|
||||
|
||||
message ReleaseNotes {}
|
||||
|
||||
oneof identifier {
|
||||
Contact contact = 1;
|
||||
bytes legacyGroupId = 3;
|
||||
bytes groupMasterKey = 4;
|
||||
Contact contact = 1;
|
||||
bytes legacyGroupId = 3;
|
||||
bytes groupMasterKey = 4;
|
||||
ReleaseNotes releaseNotes = 5;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,6 +301,10 @@ message AccountRecord {
|
||||
bool notificationProfileSyncDisabled = 45;
|
||||
bool automaticKeyVerificationDisabled = 46;
|
||||
bool hasSeenAdminDeleteEducationDialog = 47;
|
||||
bool releaseNotesChatArchived = 48;
|
||||
uint64 releaseNotesChatMutedUntilTimestamp = 49;
|
||||
bool releaseNotesChatBlocked = 50;
|
||||
bool releaseNotesChatMarkedUnread = 51;
|
||||
}
|
||||
|
||||
message StoryDistributionListRecord {
|
||||
|
||||
Reference in New Issue
Block a user