Add subscriber information to storage service account record.
This commit is contained in:
parent
102f9de06f
commit
6673da0b04
6 changed files with 123 additions and 26 deletions
|
@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
|||
import org.thoughtcrime.securesms.jobs.BoostReceiptRequestResponseJob
|
||||
import org.thoughtcrime.securesms.jobs.SubscriptionReceiptRequestResponseJob
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper
|
||||
import org.thoughtcrime.securesms.subscription.LevelUpdateOperation
|
||||
import org.thoughtcrime.securesms.subscription.Subscriber
|
||||
import org.thoughtcrime.securesms.util.Environment
|
||||
|
@ -99,6 +100,8 @@ class DonationPaymentRepository(activity: Activity) : StripeApi.PaymentIntentFet
|
|||
SignalStore
|
||||
.donationsValues()
|
||||
.setSubscriber(Subscriber(subscriberId, SignalStore.donationsValues().getSubscriptionCurrency().currencyCode))
|
||||
|
||||
StorageSyncHelper.scheduleSyncForDataChange()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import androidx.annotation.Nullable;
|
|||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.subscription.Subscriber;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.storage.SignalAccountRecord;
|
||||
import org.whispersystems.signalservice.api.storage.SignalAccountRecord.PinnedConversation;
|
||||
|
@ -82,6 +83,14 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
|||
payments = local.getPayments();
|
||||
}
|
||||
|
||||
SignalAccountRecord.Subscriber subscriber;
|
||||
|
||||
if (remote.getSubscriber().getId().isPresent()) {
|
||||
subscriber = remote.getSubscriber();
|
||||
} else {
|
||||
subscriber = local.getSubscriber();
|
||||
}
|
||||
|
||||
byte[] unknownFields = remote.serializeUnknownFields();
|
||||
String avatarUrlPath = remote.getAvatarUrlPath().or(local.getAvatarUrlPath()).or("");
|
||||
byte[] profileKey = remote.getProfileKey().or(local.getProfileKey()).orNull();
|
||||
|
@ -99,8 +108,8 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
|||
boolean primarySendsSms = local.isPrimarySendsSms();
|
||||
String e164 = local.getE164();
|
||||
List<String> defaultReactions = remote.getDefaultReactions().size() > 0 ? remote.getDefaultReactions() : local.getDefaultReactions();
|
||||
boolean matchesRemote = doParamsMatch(remote, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, universalExpireTimer, primarySendsSms, e164, defaultReactions);
|
||||
boolean matchesLocal = doParamsMatch(local, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, universalExpireTimer, primarySendsSms, e164, defaultReactions);
|
||||
boolean matchesRemote = doParamsMatch(remote, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, universalExpireTimer, primarySendsSms, e164, defaultReactions, subscriber);
|
||||
boolean matchesLocal = doParamsMatch(local, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, universalExpireTimer, primarySendsSms, e164, defaultReactions, subscriber);
|
||||
|
||||
if (matchesRemote) {
|
||||
return remote;
|
||||
|
@ -129,6 +138,7 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
|||
.setPrimarySendsSms(primarySendsSms)
|
||||
.setE164(e164)
|
||||
.setDefaultReactions(defaultReactions)
|
||||
.setSubscriber(subscriber)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
@ -168,27 +178,29 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
|
|||
int universalExpireTimer,
|
||||
boolean primarySendsSms,
|
||||
String e164,
|
||||
@NonNull List <String> defaultReactions)
|
||||
@NonNull List <String> defaultReactions,
|
||||
@NonNull SignalAccountRecord.Subscriber subscriber)
|
||||
{
|
||||
return Arrays.equals(contact.serializeUnknownFields(), unknownFields) &&
|
||||
Objects.equals(contact.getGivenName().or(""), givenName) &&
|
||||
Objects.equals(contact.getFamilyName().or(""), familyName) &&
|
||||
Objects.equals(contact.getAvatarUrlPath().or(""), avatarUrlPath) &&
|
||||
Objects.equals(contact.getPayments(), payments) &&
|
||||
Objects.equals(contact.getE164(), e164) &&
|
||||
Objects.equals(contact.getDefaultReactions(), defaultReactions) &&
|
||||
Arrays.equals(contact.getProfileKey().orNull(), profileKey) &&
|
||||
contact.isNoteToSelfArchived() == noteToSelfArchived &&
|
||||
contact.isNoteToSelfForcedUnread() == noteToSelfForcedUnread &&
|
||||
contact.isReadReceiptsEnabled() == readReceipts &&
|
||||
contact.isTypingIndicatorsEnabled() == typingIndicators &&
|
||||
contact.isSealedSenderIndicatorsEnabled() == sealedSenderIndicators &&
|
||||
contact.isLinkPreviewsEnabled() == linkPreviewsEnabled &&
|
||||
contact.getPhoneNumberSharingMode() == phoneNumberSharingMode &&
|
||||
contact.isPhoneNumberUnlisted() == unlistedPhoneNumber &&
|
||||
contact.isPreferContactAvatars() == preferContactAvatars &&
|
||||
contact.getUniversalExpireTimer() == universalExpireTimer &&
|
||||
contact.isPrimarySendsSms() == primarySendsSms &&
|
||||
Objects.equals(contact.getPinnedConversations(), pinnedConversations);
|
||||
return Arrays.equals(contact.serializeUnknownFields(), unknownFields) &&
|
||||
Objects.equals(contact.getGivenName().or(""), givenName) &&
|
||||
Objects.equals(contact.getFamilyName().or(""), familyName) &&
|
||||
Objects.equals(contact.getAvatarUrlPath().or(""), avatarUrlPath) &&
|
||||
Objects.equals(contact.getPayments(), payments) &&
|
||||
Objects.equals(contact.getE164(), e164) &&
|
||||
Objects.equals(contact.getDefaultReactions(), defaultReactions) &&
|
||||
Arrays.equals(contact.getProfileKey().orNull(), profileKey) &&
|
||||
contact.isNoteToSelfArchived() == noteToSelfArchived &&
|
||||
contact.isNoteToSelfForcedUnread() == noteToSelfForcedUnread &&
|
||||
contact.isReadReceiptsEnabled() == readReceipts &&
|
||||
contact.isTypingIndicatorsEnabled() == typingIndicators &&
|
||||
contact.isSealedSenderIndicatorsEnabled() == sealedSenderIndicators &&
|
||||
contact.isLinkPreviewsEnabled() == linkPreviewsEnabled &&
|
||||
contact.getPhoneNumberSharingMode() == phoneNumberSharingMode &&
|
||||
contact.isPhoneNumberUnlisted() == unlistedPhoneNumber &&
|
||||
contact.isPreferContactAvatars() == preferContactAvatars &&
|
||||
contact.getUniversalExpireTimer() == universalExpireTimer &&
|
||||
contact.isPrimarySendsSms() == primarySendsSms &&
|
||||
Objects.equals(contact.getPinnedConversations(), pinnedConversations) &&
|
||||
Objects.equals(contact.getSubscriber(), subscriber);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
|
|||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.payments.Entropy;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.subscription.Subscriber;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.SetUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
@ -131,6 +132,7 @@ public final class StorageSyncHelper {
|
|||
.setUniversalExpireTimer(SignalStore.settings().getUniversalExpireTimer())
|
||||
.setE164(TextSecurePreferences.getLocalNumber(context))
|
||||
.setDefaultReactions(SignalStore.emojiValues().getReactions())
|
||||
.setSubscriber(StorageSyncModels.localToRemoteSubscriber(SignalStore.donationsValues().getSubscriber()))
|
||||
.build();
|
||||
|
||||
return SignalStorageRecord.forAccount(account);
|
||||
|
@ -155,6 +157,11 @@ public final class StorageSyncHelper {
|
|||
SignalStore.settings().setUniversalExpireTimer(update.getNew().getUniversalExpireTimer());
|
||||
SignalStore.emojiValues().setReactions(update.getNew().getDefaultReactions());
|
||||
|
||||
Subscriber subscriber = StorageSyncModels.remoteToLocalSubscriber(update.getNew().getSubscriber());
|
||||
if (subscriber != null) {
|
||||
SignalStore.donationsValues().setSubscriber(subscriber);
|
||||
}
|
||||
|
||||
if (fetchProfile && update.getNew().getAvatarUrlPath().isPresent()) {
|
||||
ApplicationDependencies.getJobManager().add(new RetrieveProfileAvatarJob(self, update.getNew().getAvatarUrlPath().get()));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.thoughtcrime.securesms.storage;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
|
@ -10,6 +11,7 @@ import org.thoughtcrime.securesms.database.RecipientDatabase;
|
|||
import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientSettings;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
|
||||
import org.thoughtcrime.securesms.subscription.Subscriber;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.storage.SignalAccountRecord;
|
||||
|
@ -17,12 +19,11 @@ import org.whispersystems.signalservice.api.storage.SignalContactRecord;
|
|||
import org.whispersystems.signalservice.api.storage.SignalGroupV1Record;
|
||||
import org.whispersystems.signalservice.api.storage.SignalGroupV2Record;
|
||||
import org.whispersystems.signalservice.api.storage.SignalStorageRecord;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.api.subscriptions.SubscriberId;
|
||||
import org.whispersystems.signalservice.internal.storage.protos.AccountRecord;
|
||||
import org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class StorageSyncModels {
|
||||
|
||||
|
@ -173,4 +174,19 @@ public final class StorageSyncModels {
|
|||
}
|
||||
}
|
||||
|
||||
public static @NonNull SignalAccountRecord.Subscriber localToRemoteSubscriber(@Nullable Subscriber subscriber) {
|
||||
if (subscriber == null) {
|
||||
return new SignalAccountRecord.Subscriber(null, null);
|
||||
} else {
|
||||
return new SignalAccountRecord.Subscriber(subscriber.getCurrencyCode(), subscriber.getSubscriberId().getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
public static @Nullable Subscriber remoteToLocalSubscriber(@NonNull SignalAccountRecord.Subscriber subscriber) {
|
||||
if (subscriber.getId().isPresent()) {
|
||||
return new Subscriber(SubscriberId.fromBytes(subscriber.getId().get()), subscriber.getCurrencyCode().get());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import org.whispersystems.signalservice.api.push.ACI;
|
|||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.util.OptionalUtil;
|
||||
import org.whispersystems.signalservice.api.util.ProtoUtil;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.storage.protos.AccountRecord;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -34,6 +33,7 @@ public final class SignalAccountRecord implements SignalRecord {
|
|||
private final List<PinnedConversation> pinnedConversations;
|
||||
private final Payments payments;
|
||||
private final List<String> defaultReactions;
|
||||
private final Subscriber subscriber;
|
||||
|
||||
public SignalAccountRecord(StorageId id, AccountRecord proto) {
|
||||
this.id = id;
|
||||
|
@ -47,6 +47,7 @@ public final class SignalAccountRecord implements SignalRecord {
|
|||
this.pinnedConversations = new ArrayList<>(proto.getPinnedConversationsCount());
|
||||
this.payments = new Payments(proto.getPayments().getEnabled(), OptionalUtil.absentIfEmpty(proto.getPayments().getEntropy()));
|
||||
this.defaultReactions = new ArrayList<>(proto.getPreferredReactionEmojiList());
|
||||
this.subscriber = new Subscriber(proto.getSubscriberCurrencyCode(), proto.getSubscriberId().toByteArray());
|
||||
|
||||
for (AccountRecord.PinnedConversation conversation : proto.getPinnedConversationsList()) {
|
||||
pinnedConversations.add(PinnedConversation.fromRemote(conversation));
|
||||
|
@ -153,6 +154,10 @@ public final class SignalAccountRecord implements SignalRecord {
|
|||
diff.add("UnknownFields");
|
||||
}
|
||||
|
||||
if (!Objects.equals(this.getSubscriber(), that.getSubscriber())) {
|
||||
diff.add("Subscriber");
|
||||
}
|
||||
|
||||
return diff.toString();
|
||||
} else {
|
||||
return "Different class. " + getClass().getSimpleName() + " | " + other.getClass().getSimpleName();
|
||||
|
@ -243,6 +248,10 @@ public final class SignalAccountRecord implements SignalRecord {
|
|||
return defaultReactions;
|
||||
}
|
||||
|
||||
public Subscriber getSubscriber() {
|
||||
return subscriber;
|
||||
}
|
||||
|
||||
AccountRecord toProto() {
|
||||
return proto;
|
||||
}
|
||||
|
@ -351,6 +360,42 @@ public final class SignalAccountRecord implements SignalRecord {
|
|||
}
|
||||
}
|
||||
|
||||
public static class Subscriber {
|
||||
private final Optional<String> currencyCode;
|
||||
private final Optional<byte[]> id;
|
||||
|
||||
public Subscriber(String currencyCode, byte[] id) {
|
||||
if (currencyCode != null && id != null && id.length == 32) {
|
||||
this.currencyCode = Optional.of(currencyCode);
|
||||
this.id = Optional.of(id);
|
||||
} else {
|
||||
this.currencyCode = Optional.absent();
|
||||
this.id = Optional.absent();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<String> getCurrencyCode() {
|
||||
return currencyCode;
|
||||
}
|
||||
|
||||
public Optional<byte[]> getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final Subscriber that = (Subscriber) o;
|
||||
return Objects.equals(currencyCode, that.currencyCode) && OptionalUtil.byteArrayEquals(id, that.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(currencyCode, id);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Payments {
|
||||
private static final String TAG = Payments.class.getSimpleName();
|
||||
|
||||
|
@ -518,6 +563,18 @@ public final class SignalAccountRecord implements SignalRecord {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setSubscriber(Subscriber subscriber) {
|
||||
if (subscriber.id.isPresent() && subscriber.currencyCode.isPresent()) {
|
||||
builder.setSubscriberId(ByteString.copyFrom(subscriber.id.get()));
|
||||
builder.setSubscriberCurrencyCode(subscriber.currencyCode.get());
|
||||
} else {
|
||||
builder.clearSubscriberId();
|
||||
builder.clearSubscriberCurrencyCode();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignalAccountRecord build() {
|
||||
AccountRecord proto = builder.build();
|
||||
|
||||
|
|
|
@ -148,4 +148,6 @@ message AccountRecord {
|
|||
bool primarySendsSms = 18;
|
||||
string e164 = 19;
|
||||
repeated string preferredReactionEmoji = 20;
|
||||
bytes subscriberId = 21;
|
||||
string subscriberCurrencyCode = 22;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue