1 package org
.asamk
.signal
.manager
.syncStorage
;
3 import org
.asamk
.signal
.manager
.api
.PhoneNumberSharingMode
;
4 import org
.asamk
.signal
.manager
.api
.TrustLevel
;
5 import org
.asamk
.signal
.manager
.storage
.configuration
.ConfigurationStore
;
6 import org
.asamk
.signal
.manager
.storage
.groups
.GroupInfoV1
;
7 import org
.asamk
.signal
.manager
.storage
.groups
.GroupInfoV2
;
8 import org
.asamk
.signal
.manager
.storage
.identities
.IdentityInfo
;
9 import org
.asamk
.signal
.manager
.storage
.recipients
.Recipient
;
10 import org
.whispersystems
.signalservice
.api
.push
.UsernameLinkComponents
;
11 import org
.whispersystems
.signalservice
.api
.storage
.SignalAccountRecord
;
12 import org
.whispersystems
.signalservice
.api
.storage
.SignalContactRecord
;
13 import org
.whispersystems
.signalservice
.api
.storage
.SignalGroupV1Record
;
14 import org
.whispersystems
.signalservice
.api
.storage
.SignalGroupV2Record
;
15 import org
.whispersystems
.signalservice
.api
.storage
.SignalStorageRecord
;
16 import org
.whispersystems
.signalservice
.api
.util
.UuidUtil
;
17 import org
.whispersystems
.signalservice
.internal
.storage
.protos
.AccountRecord
;
18 import org
.whispersystems
.signalservice
.internal
.storage
.protos
.AccountRecord
.UsernameLink
;
19 import org
.whispersystems
.signalservice
.internal
.storage
.protos
.ContactRecord
;
20 import org
.whispersystems
.signalservice
.internal
.storage
.protos
.ContactRecord
.IdentityState
;
22 import java
.util
.Optional
;
24 import okio
.ByteString
;
26 public final class StorageSyncModels
{
28 private StorageSyncModels() {
31 public static AccountRecord
.PhoneNumberSharingMode
localToRemote(PhoneNumberSharingMode phoneNumberPhoneNumberSharingMode
) {
32 return switch (phoneNumberPhoneNumberSharingMode
) {
33 case EVERYBODY
-> AccountRecord
.PhoneNumberSharingMode
.EVERYBODY
;
34 case CONTACTS
, NOBODY
-> AccountRecord
.PhoneNumberSharingMode
.NOBODY
;
38 public static PhoneNumberSharingMode
remoteToLocal(AccountRecord
.PhoneNumberSharingMode phoneNumberPhoneNumberSharingMode
) {
39 return switch (phoneNumberPhoneNumberSharingMode
) {
40 case EVERYBODY
-> PhoneNumberSharingMode
.EVERYBODY
;
41 case UNKNOWN
, NOBODY
-> PhoneNumberSharingMode
.NOBODY
;
45 public static SignalStorageRecord
localToRemoteRecord(
46 ConfigurationStore configStore
,
48 UsernameLinkComponents usernameLinkComponents
,
51 final var builder
= new SignalAccountRecord
.Builder(rawStorageId
, self
.getStorageRecord());
52 if (self
.getProfileKey() != null) {
53 builder
.setProfileKey(self
.getProfileKey().serialize());
55 if (self
.getProfile() != null) {
56 builder
.setGivenName(self
.getProfile().getGivenName())
57 .setFamilyName(self
.getProfile().getFamilyName())
58 .setAvatarUrlPath(self
.getProfile().getAvatarUrlPath());
60 builder
.setTypingIndicatorsEnabled(Optional
.ofNullable(configStore
.getTypingIndicators()).orElse(true))
61 .setReadReceiptsEnabled(Optional
.ofNullable(configStore
.getReadReceipts()).orElse(true))
62 .setSealedSenderIndicatorsEnabled(Optional
.ofNullable(configStore
.getUnidentifiedDeliveryIndicators())
64 .setLinkPreviewsEnabled(Optional
.ofNullable(configStore
.getLinkPreviews()).orElse(true))
65 .setUnlistedPhoneNumber(Optional
.ofNullable(configStore
.getPhoneNumberUnlisted()).orElse(true))
66 .setPhoneNumberSharingMode(localToRemote(Optional
.ofNullable(configStore
.getPhoneNumberSharingMode())
67 .orElse(PhoneNumberSharingMode
.EVERYBODY
)))
68 .setE164(self
.getAddress().number().orElse(""))
69 .setUsername(self
.getAddress().username().orElse(null));
70 if (usernameLinkComponents
!= null) {
71 final var linkColor
= configStore
.getUsernameLinkColor();
72 builder
.setUsernameLink(new UsernameLink
.Builder().entropy(ByteString
.of(usernameLinkComponents
.getEntropy()))
73 .serverId(UuidUtil
.toByteString(usernameLinkComponents
.getServerId()))
74 .color(linkColor
== null ? UsernameLink
.Color
.UNKNOWN
: UsernameLink
.Color
.valueOf(linkColor
))
78 return SignalStorageRecord
.forAccount(builder
.build());
81 public static SignalStorageRecord
localToRemoteRecord(
82 Recipient recipient
, IdentityInfo identity
, byte[] rawStorageId
84 final var address
= recipient
.getAddress();
85 final var builder
= new SignalContactRecord
.Builder(rawStorageId
,
86 address
.aci().orElse(null),
87 recipient
.getStorageRecord()).setE164(address
.number().orElse(null))
88 .setPni(address
.pni().orElse(null))
89 .setUsername(address
.username().orElse(null))
90 .setProfileKey(recipient
.getProfileKey() == null ?
null : recipient
.getProfileKey().serialize());
91 if (recipient
.getProfile() != null) {
92 builder
.setProfileGivenName(recipient
.getProfile().getGivenName())
93 .setProfileFamilyName(recipient
.getProfile().getFamilyName());
95 if (recipient
.getContact() != null) {
96 builder
.setSystemGivenName(recipient
.getContact().givenName())
97 .setSystemFamilyName((recipient
.getContact().familyName()))
98 .setBlocked(recipient
.getContact().isBlocked())
99 .setProfileSharingEnabled(recipient
.getContact().isProfileSharingEnabled())
100 .setArchived(recipient
.getContact().isArchived())
101 .setHidden(recipient
.getContact().isHidden());
103 if (identity
!= null) {
104 builder
.setIdentityKey(identity
.getIdentityKey().serialize())
105 .setIdentityState(localToRemote(identity
.getTrustLevel()));
107 return SignalStorageRecord
.forContact(builder
.build());
110 public static SignalStorageRecord
localToRemoteRecord(
111 GroupInfoV1 group
, byte[] rawStorageId
113 final var builder
= new SignalGroupV1Record
.Builder(rawStorageId
,
114 group
.getGroupId().serialize(),
115 group
.getStorageRecord());
116 builder
.setBlocked(group
.isBlocked()).setArchived(group
.archived
);
117 return SignalStorageRecord
.forGroupV1(builder
.build());
120 public static SignalStorageRecord
localToRemoteRecord(
121 GroupInfoV2 group
, byte[] rawStorageId
123 final var builder
= new SignalGroupV2Record
.Builder(rawStorageId
,
124 group
.getMasterKey(),
125 group
.getStorageRecord());
126 builder
.setBlocked(group
.isBlocked());
127 return SignalStorageRecord
.forGroupV2(builder
.build());
130 public static TrustLevel
remoteToLocal(ContactRecord
.IdentityState identityState
) {
131 return switch (identityState
) {
132 case DEFAULT
-> TrustLevel
.TRUSTED_UNVERIFIED
;
133 case UNVERIFIED
-> TrustLevel
.UNTRUSTED
;
134 case VERIFIED
-> TrustLevel
.TRUSTED_VERIFIED
;
138 private static IdentityState
localToRemote(TrustLevel local
) {
139 return switch (local
) {
140 case TRUSTED_VERIFIED
-> IdentityState
.VERIFIED
;
141 case UNTRUSTED
-> IdentityState
.UNVERIFIED
;
142 default -> IdentityState
.DEFAULT
;