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 .setSystemNickname(recipient
.getContact().nickName())
99 .setBlocked(recipient
.getContact().isBlocked())
100 .setProfileSharingEnabled(recipient
.getContact().isProfileSharingEnabled())
101 .setMuteUntil(recipient
.getContact().muteUntil())
102 .setHideStory(recipient
.getContact().hideStory())
103 .setUnregisteredTimestamp(recipient
.getContact().unregisteredTimestamp() == null
105 : recipient
.getContact().unregisteredTimestamp())
106 .setArchived(recipient
.getContact().isArchived())
107 .setHidden(recipient
.getContact().isHidden());
109 if (identity
!= null) {
110 builder
.setIdentityKey(identity
.getIdentityKey().serialize())
111 .setIdentityState(localToRemote(identity
.getTrustLevel()));
113 return SignalStorageRecord
.forContact(builder
.build());
116 public static SignalStorageRecord
localToRemoteRecord(
117 GroupInfoV1 group
, byte[] rawStorageId
119 final var builder
= new SignalGroupV1Record
.Builder(rawStorageId
,
120 group
.getGroupId().serialize(),
121 group
.getStorageRecord());
122 builder
.setBlocked(group
.isBlocked()).setArchived(group
.archived
);
123 return SignalStorageRecord
.forGroupV1(builder
.build());
126 public static SignalStorageRecord
localToRemoteRecord(
127 GroupInfoV2 group
, byte[] rawStorageId
129 final var builder
= new SignalGroupV2Record
.Builder(rawStorageId
,
130 group
.getMasterKey(),
131 group
.getStorageRecord());
132 builder
.setBlocked(group
.isBlocked());
133 return SignalStorageRecord
.forGroupV2(builder
.build());
136 public static TrustLevel
remoteToLocal(ContactRecord
.IdentityState identityState
) {
137 return switch (identityState
) {
138 case DEFAULT
-> TrustLevel
.TRUSTED_UNVERIFIED
;
139 case UNVERIFIED
-> TrustLevel
.UNTRUSTED
;
140 case VERIFIED
-> TrustLevel
.TRUSTED_VERIFIED
;
144 private static IdentityState
localToRemote(TrustLevel local
) {
145 return switch (local
) {
146 case TRUSTED_VERIFIED
-> IdentityState
.VERIFIED
;
147 case UNTRUSTED
-> IdentityState
.UNVERIFIED
;
148 default -> IdentityState
.DEFAULT
;