Convert GroupV2RecordProcessor to kotlin.
This commit is contained in:
parent
d5f68130fe
commit
befb433999
3 changed files with 138 additions and 140 deletions
|
@ -369,7 +369,7 @@ class StorageSyncJob private constructor(parameters: Parameters) : BaseJob(param
|
|||
private fun processKnownRecords(context: Context, records: StorageRecordCollection) {
|
||||
ContactRecordProcessor().process(records.contacts, StorageSyncHelper.KEY_GENERATOR)
|
||||
GroupV1RecordProcessor().process(records.gv1, StorageSyncHelper.KEY_GENERATOR)
|
||||
GroupV2RecordProcessor(context).process(records.gv2, StorageSyncHelper.KEY_GENERATOR)
|
||||
GroupV2RecordProcessor().process(records.gv2, StorageSyncHelper.KEY_GENERATOR)
|
||||
AccountRecordProcessor(context, freshSelf()).process(records.account, StorageSyncHelper.KEY_GENERATOR)
|
||||
StoryDistributionListRecordProcessor().process(records.storyDistributionLists, StorageSyncHelper.KEY_GENERATOR)
|
||||
CallLinkRecordProcessor().process(records.callLinkRecords, StorageSyncHelper.KEY_GENERATOR)
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
package org.thoughtcrime.securesms.storage;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
|
||||
import org.thoughtcrime.securesms.database.GroupTable;
|
||||
import org.thoughtcrime.securesms.database.RecipientTable;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.whispersystems.signalservice.api.storage.SignalGroupV2Record;
|
||||
import org.whispersystems.signalservice.internal.storage.protos.GroupV2Record;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class GroupV2RecordProcessor extends DefaultStorageRecordProcessor<SignalGroupV2Record> {
|
||||
|
||||
private static final String TAG = Log.tag(GroupV2RecordProcessor.class);
|
||||
|
||||
private final Context context;
|
||||
private final RecipientTable recipientTable;
|
||||
private final GroupTable groupDatabase;
|
||||
private final Map<GroupId.V2, GroupId.V1> gv1GroupsByExpectedGv2Id;
|
||||
|
||||
public GroupV2RecordProcessor(@NonNull Context context) {
|
||||
this(context, SignalDatabase.recipients(), SignalDatabase.groups());
|
||||
}
|
||||
|
||||
GroupV2RecordProcessor(@NonNull Context context, @NonNull RecipientTable recipientTable, @NonNull GroupTable groupDatabase) {
|
||||
this.context = context;
|
||||
this.recipientTable = recipientTable;
|
||||
this.groupDatabase = groupDatabase;
|
||||
this.gv1GroupsByExpectedGv2Id = groupDatabase.getAllExpectedV2Ids();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInvalid(@NonNull SignalGroupV2Record remote) {
|
||||
return remote.getMasterKeyBytes().length != GroupMasterKey.SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Optional<SignalGroupV2Record> getMatching(@NonNull SignalGroupV2Record record, @NonNull StorageKeyGenerator keyGenerator) {
|
||||
GroupId.V2 groupId = GroupId.v2(record.getMasterKeyOrThrow());
|
||||
|
||||
Optional<RecipientId> recipientId = recipientTable.getByGroupId(groupId);
|
||||
|
||||
return recipientId.map(recipientTable::getRecordForSync)
|
||||
.map(settings -> {
|
||||
if (settings.getSyncExtras().getGroupMasterKey() != null) {
|
||||
return StorageSyncModels.localToRemoteRecord(settings);
|
||||
} else {
|
||||
Log.w(TAG, "No local master key. Assuming it matches remote since the groupIds match. Enqueuing a fetch to fix the bad state.");
|
||||
groupDatabase.fixMissingMasterKey(record.getMasterKeyOrThrow());
|
||||
return StorageSyncModels.localToRemoteRecord(settings, record.getMasterKeyOrThrow());
|
||||
}
|
||||
})
|
||||
.map(r -> r.getGroupV2().get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull SignalGroupV2Record merge(@NonNull SignalGroupV2Record remote, @NonNull SignalGroupV2Record local, @NonNull StorageKeyGenerator keyGenerator) {
|
||||
byte[] unknownFields = remote.serializeUnknownFields();
|
||||
boolean blocked = remote.isBlocked();
|
||||
boolean profileSharing = remote.isProfileSharingEnabled();
|
||||
boolean archived = remote.isArchived();
|
||||
boolean forcedUnread = remote.isForcedUnread();
|
||||
long muteUntil = remote.getMuteUntil();
|
||||
boolean notifyForMentionsWhenMuted = remote.notifyForMentionsWhenMuted();
|
||||
boolean hideStory = remote.shouldHideStory();
|
||||
GroupV2Record.StorySendMode storySendMode = remote.getStorySendMode();
|
||||
|
||||
boolean matchesRemote = doParamsMatch(remote, unknownFields, blocked, profileSharing, archived, forcedUnread, muteUntil, notifyForMentionsWhenMuted, hideStory, storySendMode);
|
||||
boolean matchesLocal = doParamsMatch(local, unknownFields, blocked, profileSharing, archived, forcedUnread, muteUntil, notifyForMentionsWhenMuted, hideStory, storySendMode);
|
||||
|
||||
if (matchesRemote) {
|
||||
return remote;
|
||||
} else if (matchesLocal) {
|
||||
return local;
|
||||
} else {
|
||||
return new SignalGroupV2Record.Builder(keyGenerator.generate(), remote.getMasterKeyBytes(), unknownFields)
|
||||
.setBlocked(blocked)
|
||||
.setProfileSharingEnabled(profileSharing)
|
||||
.setArchived(archived)
|
||||
.setForcedUnread(forcedUnread)
|
||||
.setMuteUntil(muteUntil)
|
||||
.setNotifyForMentionsWhenMuted(notifyForMentionsWhenMuted)
|
||||
.setHideStory(hideStory)
|
||||
.setStorySendMode(storySendMode)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertLocal(@NonNull SignalGroupV2Record record) {
|
||||
recipientTable.applyStorageSyncGroupV2Insert(record);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLocal(@NonNull StorageRecordUpdate<SignalGroupV2Record> update) {
|
||||
recipientTable.applyStorageSyncGroupV2Update(update);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(@NonNull SignalGroupV2Record lhs, @NonNull SignalGroupV2Record rhs) {
|
||||
if (Arrays.equals(lhs.getMasterKeyBytes(), rhs.getMasterKeyBytes())) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doParamsMatch(@NonNull SignalGroupV2Record group,
|
||||
@Nullable byte[] unknownFields,
|
||||
boolean blocked,
|
||||
boolean profileSharing,
|
||||
boolean archived,
|
||||
boolean forcedUnread,
|
||||
long muteUntil,
|
||||
boolean notifyForMentionsWhenMuted,
|
||||
boolean hideStory,
|
||||
@NonNull GroupV2Record.StorySendMode storySendMode)
|
||||
{
|
||||
return Arrays.equals(unknownFields, group.serializeUnknownFields()) &&
|
||||
blocked == group.isBlocked() &&
|
||||
profileSharing == group.isProfileSharingEnabled() &&
|
||||
archived == group.isArchived() &&
|
||||
forcedUnread == group.isForcedUnread() &&
|
||||
muteUntil == group.getMuteUntil() &&
|
||||
notifyForMentionsWhenMuted == group.notifyForMentionsWhenMuted() &&
|
||||
hideStory == group.shouldHideStory() &&
|
||||
storySendMode == group.getStorySendMode();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
package org.thoughtcrime.securesms.storage
|
||||
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.libsignal.zkgroup.groups.GroupMasterKey
|
||||
import org.thoughtcrime.securesms.database.GroupTable
|
||||
import org.thoughtcrime.securesms.database.RecipientTable
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.database.model.RecipientRecord
|
||||
import org.thoughtcrime.securesms.groups.GroupId
|
||||
import org.whispersystems.signalservice.api.storage.SignalGroupV2Record
|
||||
import org.whispersystems.signalservice.api.storage.SignalStorageRecord
|
||||
import org.whispersystems.signalservice.internal.storage.protos.GroupV2Record
|
||||
import java.util.Optional
|
||||
|
||||
class GroupV2RecordProcessor(private val recipientTable: RecipientTable, private val groupDatabase: GroupTable) : DefaultStorageRecordProcessor<SignalGroupV2Record>() {
|
||||
companion object {
|
||||
private val TAG = Log.tag(GroupV2RecordProcessor::class.java)
|
||||
}
|
||||
|
||||
constructor() : this(SignalDatabase.recipients, SignalDatabase.groups)
|
||||
|
||||
override fun isInvalid(remote: SignalGroupV2Record): Boolean {
|
||||
return remote.masterKeyBytes.size != GroupMasterKey.SIZE
|
||||
}
|
||||
|
||||
override fun getMatching(remote: SignalGroupV2Record, keyGenerator: StorageKeyGenerator): Optional<SignalGroupV2Record> {
|
||||
val groupId = GroupId.v2(remote.masterKeyOrThrow)
|
||||
|
||||
val recipientId = recipientTable.getByGroupId(groupId)
|
||||
|
||||
return recipientId
|
||||
.map { recipientTable.getRecordForSync(it)!! }
|
||||
.map { settings: RecipientRecord ->
|
||||
if (settings.syncExtras.groupMasterKey != null) {
|
||||
StorageSyncModels.localToRemoteRecord(settings)
|
||||
} else {
|
||||
Log.w(TAG, "No local master key. Assuming it matches remote since the groupIds match. Enqueuing a fetch to fix the bad state.")
|
||||
groupDatabase.fixMissingMasterKey(remote.masterKeyOrThrow)
|
||||
StorageSyncModels.localToRemoteRecord(settings, remote.masterKeyOrThrow)
|
||||
}
|
||||
}
|
||||
.map { record: SignalStorageRecord -> record.groupV2.get() }
|
||||
}
|
||||
|
||||
override fun merge(remote: SignalGroupV2Record, local: SignalGroupV2Record, keyGenerator: StorageKeyGenerator): SignalGroupV2Record {
|
||||
val unknownFields = remote.serializeUnknownFields()
|
||||
val blocked = remote.isBlocked
|
||||
val profileSharing = remote.isProfileSharingEnabled
|
||||
val archived = remote.isArchived
|
||||
val forcedUnread = remote.isForcedUnread
|
||||
val muteUntil = remote.muteUntil
|
||||
val notifyForMentionsWhenMuted = remote.notifyForMentionsWhenMuted()
|
||||
val hideStory = remote.shouldHideStory()
|
||||
val storySendMode = remote.storySendMode
|
||||
|
||||
val matchesRemote = doParamsMatch(
|
||||
group = remote,
|
||||
unknownFields = unknownFields,
|
||||
blocked = blocked,
|
||||
profileSharing = profileSharing,
|
||||
archived = archived,
|
||||
forcedUnread = forcedUnread,
|
||||
muteUntil = muteUntil,
|
||||
notifyForMentionsWhenMuted = notifyForMentionsWhenMuted,
|
||||
hideStory = hideStory,
|
||||
storySendMode = storySendMode
|
||||
)
|
||||
val matchesLocal = doParamsMatch(
|
||||
group = local,
|
||||
unknownFields = unknownFields,
|
||||
blocked = blocked,
|
||||
profileSharing = profileSharing,
|
||||
archived = archived,
|
||||
forcedUnread = forcedUnread,
|
||||
muteUntil = muteUntil,
|
||||
notifyForMentionsWhenMuted = notifyForMentionsWhenMuted,
|
||||
hideStory = hideStory,
|
||||
storySendMode = storySendMode
|
||||
)
|
||||
|
||||
return if (matchesRemote) {
|
||||
remote
|
||||
} else if (matchesLocal) {
|
||||
local
|
||||
} else {
|
||||
SignalGroupV2Record.Builder(keyGenerator.generate(), remote.masterKeyBytes, unknownFields)
|
||||
.setBlocked(blocked)
|
||||
.setProfileSharingEnabled(profileSharing)
|
||||
.setArchived(archived)
|
||||
.setForcedUnread(forcedUnread)
|
||||
.setMuteUntil(muteUntil)
|
||||
.setNotifyForMentionsWhenMuted(notifyForMentionsWhenMuted)
|
||||
.setHideStory(hideStory)
|
||||
.setStorySendMode(storySendMode)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
override fun insertLocal(record: SignalGroupV2Record) {
|
||||
recipientTable.applyStorageSyncGroupV2Insert(record)
|
||||
}
|
||||
|
||||
override fun updateLocal(update: StorageRecordUpdate<SignalGroupV2Record>) {
|
||||
recipientTable.applyStorageSyncGroupV2Update(update)
|
||||
}
|
||||
|
||||
override fun compare(lhs: SignalGroupV2Record, rhs: SignalGroupV2Record): Int {
|
||||
return if (lhs.masterKeyBytes.contentEquals(rhs.masterKeyBytes)) {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
private fun doParamsMatch(
|
||||
group: SignalGroupV2Record,
|
||||
unknownFields: ByteArray?,
|
||||
blocked: Boolean,
|
||||
profileSharing: Boolean,
|
||||
archived: Boolean,
|
||||
forcedUnread: Boolean,
|
||||
muteUntil: Long,
|
||||
notifyForMentionsWhenMuted: Boolean,
|
||||
hideStory: Boolean,
|
||||
storySendMode: GroupV2Record.StorySendMode
|
||||
): Boolean {
|
||||
return unknownFields.contentEquals(group.serializeUnknownFields()) &&
|
||||
blocked == group.isBlocked &&
|
||||
profileSharing == group.isProfileSharingEnabled &&
|
||||
archived == group.isArchived &&
|
||||
forcedUnread == group.isForcedUnread &&
|
||||
muteUntil == group.muteUntil &&
|
||||
notifyForMentionsWhenMuted == group.notifyForMentionsWhenMuted() &&
|
||||
hideStory == group.shouldHideStory() &&
|
||||
storySendMode == group.storySendMode
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue