Fix crash loop when writing invalid currency .
This commit is contained in:
parent
71979b34db
commit
cb171092cf
16 changed files with 63 additions and 40 deletions
|
@ -47,6 +47,7 @@ import org.whispersystems.signalservice.api.push.ServiceId.ACI
|
||||||
import org.whispersystems.signalservice.api.push.ServiceId.PNI
|
import org.whispersystems.signalservice.api.push.ServiceId.PNI
|
||||||
import org.whispersystems.signalservice.api.subscriptions.SubscriberId
|
import org.whispersystems.signalservice.api.subscriptions.SubscriberId
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
|
import java.util.Currency
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
@ -253,7 +254,7 @@ class BackupTest {
|
||||||
SignalDatabase.recipients.setProfileName(self.id, ProfileName.fromParts("Peter", "Parker"))
|
SignalDatabase.recipients.setProfileName(self.id, ProfileName.fromParts("Peter", "Parker"))
|
||||||
SignalDatabase.recipients.setProfileAvatar(self.id, "https://example.com/")
|
SignalDatabase.recipients.setProfileAvatar(self.id, "https://example.com/")
|
||||||
|
|
||||||
InAppPaymentsRepository.setSubscriber(InAppPaymentSubscriberRecord(SubscriberId.generate(), "USD", InAppPaymentSubscriberRecord.Type.DONATION, false, InAppPaymentData.PaymentMethodType.UNKNOWN))
|
InAppPaymentsRepository.setSubscriber(InAppPaymentSubscriberRecord(SubscriberId.generate(), Currency.getInstance("USD"), InAppPaymentSubscriberRecord.Type.DONATION, false, InAppPaymentData.PaymentMethodType.UNKNOWN))
|
||||||
SignalStore.donationsValues().setDisplayBadgesOnProfile(false)
|
SignalStore.donationsValues().setDisplayBadgesOnProfile(false)
|
||||||
|
|
||||||
SignalStore.phoneNumberPrivacy().phoneNumberDiscoverabilityMode = PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE
|
SignalStore.phoneNumberPrivacy().phoneNumberDiscoverabilityMode = PhoneNumberPrivacyValues.PhoneNumberDiscoverabilityMode.NOT_DISCOVERABLE
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
import org.thoughtcrime.securesms.testing.assertIs
|
import org.thoughtcrime.securesms.testing.assertIs
|
||||||
import org.thoughtcrime.securesms.testing.assertIsNotNull
|
import org.thoughtcrime.securesms.testing.assertIsNotNull
|
||||||
import org.whispersystems.signalservice.api.subscriptions.SubscriberId
|
import org.whispersystems.signalservice.api.subscriptions.SubscriberId
|
||||||
|
import java.util.Currency
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
class SubscriberIdMigrationJobTest {
|
class SubscriberIdMigrationJobTest {
|
||||||
|
@ -35,7 +36,7 @@ class SubscriberIdMigrationJobTest {
|
||||||
@Test
|
@Test
|
||||||
fun givenUSDSubscriber_whenIRunSubscriberIdMigrationJob_thenIExpectASingleEntry() {
|
fun givenUSDSubscriber_whenIRunSubscriberIdMigrationJob_thenIExpectASingleEntry() {
|
||||||
val subscriberId = SubscriberId.generate()
|
val subscriberId = SubscriberId.generate()
|
||||||
SignalStore.donationsValues().setSubscriberCurrency("USD", InAppPaymentSubscriberRecord.Type.DONATION)
|
SignalStore.donationsValues().setSubscriberCurrency(Currency.getInstance("USD"), InAppPaymentSubscriberRecord.Type.DONATION)
|
||||||
SignalStore.donationsValues().setSubscriber("USD", subscriberId)
|
SignalStore.donationsValues().setSubscriber("USD", subscriberId)
|
||||||
SignalStore.donationsValues().setSubscriptionPaymentSourceType(PaymentSourceType.PayPal)
|
SignalStore.donationsValues().setSubscriptionPaymentSourceType(PaymentSourceType.PayPal)
|
||||||
SignalStore.donationsValues().shouldCancelSubscriptionBeforeNextSubscribeAttempt = true
|
SignalStore.donationsValues().shouldCancelSubscriptionBeforeNextSubscribeAttempt = true
|
||||||
|
@ -48,7 +49,7 @@ class SubscriberIdMigrationJobTest {
|
||||||
actual!!.subscriberId.bytes assertIs subscriberId.bytes
|
actual!!.subscriberId.bytes assertIs subscriberId.bytes
|
||||||
actual.paymentMethodType assertIs InAppPaymentData.PaymentMethodType.PAYPAL
|
actual.paymentMethodType assertIs InAppPaymentData.PaymentMethodType.PAYPAL
|
||||||
actual.requiresCancel assertIs true
|
actual.requiresCancel assertIs true
|
||||||
actual.currencyCode assertIs "USD"
|
actual.currency assertIs Currency.getInstance("USD")
|
||||||
actual.type assertIs InAppPaymentSubscriberRecord.Type.DONATION
|
actual.type assertIs InAppPaymentSubscriberRecord.Type.DONATION
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.whispersystems.signalservice.api.push.UsernameLinkComponents
|
||||||
import org.whispersystems.signalservice.api.storage.StorageRecordProtoUtil.defaultAccountRecord
|
import org.whispersystems.signalservice.api.storage.StorageRecordProtoUtil.defaultAccountRecord
|
||||||
import org.whispersystems.signalservice.api.subscriptions.SubscriberId
|
import org.whispersystems.signalservice.api.subscriptions.SubscriberId
|
||||||
import org.whispersystems.signalservice.api.util.UuidUtil
|
import org.whispersystems.signalservice.api.util.UuidUtil
|
||||||
|
import java.util.Currency
|
||||||
import kotlin.jvm.optionals.getOrNull
|
import kotlin.jvm.optionals.getOrNull
|
||||||
|
|
||||||
object AccountDataProcessor {
|
object AccountDataProcessor {
|
||||||
|
@ -51,7 +52,7 @@ object AccountDataProcessor {
|
||||||
subscriptionManuallyCancelled = InAppPaymentsRepository.isUserManuallyCancelled(InAppPaymentSubscriberRecord.Type.DONATION),
|
subscriptionManuallyCancelled = InAppPaymentsRepository.isUserManuallyCancelled(InAppPaymentSubscriberRecord.Type.DONATION),
|
||||||
username = self.username.getOrNull(),
|
username = self.username.getOrNull(),
|
||||||
subscriberId = subscriber?.subscriberId?.bytes?.toByteString() ?: defaultAccountRecord.subscriberId,
|
subscriberId = subscriber?.subscriberId?.bytes?.toByteString() ?: defaultAccountRecord.subscriberId,
|
||||||
subscriberCurrencyCode = subscriber?.currencyCode ?: defaultAccountRecord.subscriberCurrencyCode,
|
subscriberCurrencyCode = subscriber?.currency?.currencyCode ?: defaultAccountRecord.subscriberCurrencyCode,
|
||||||
accountSettings = AccountData.AccountSettings(
|
accountSettings = AccountData.AccountSettings(
|
||||||
storyViewReceiptsEnabled = SignalStore.storyValues().viewedReceiptsEnabled,
|
storyViewReceiptsEnabled = SignalStore.storyValues().viewedReceiptsEnabled,
|
||||||
typingIndicators = TextSecurePreferences.isTypingIndicatorsEnabled(context),
|
typingIndicators = TextSecurePreferences.isTypingIndicatorsEnabled(context),
|
||||||
|
@ -108,7 +109,7 @@ object AccountDataProcessor {
|
||||||
|
|
||||||
val subscriber = InAppPaymentSubscriberRecord(
|
val subscriber = InAppPaymentSubscriberRecord(
|
||||||
remoteSubscriberId,
|
remoteSubscriberId,
|
||||||
accountData.subscriberCurrencyCode,
|
Currency.getInstance(accountData.subscriberCurrencyCode),
|
||||||
InAppPaymentSubscriberRecord.Type.DONATION,
|
InAppPaymentSubscriberRecord.Type.DONATION,
|
||||||
localSubscriber?.requiresCancel ?: false,
|
localSubscriber?.requiresCancel ?: false,
|
||||||
InAppPaymentsRepository.getLatestPaymentMethodType(InAppPaymentSubscriberRecord.Type.DONATION)
|
InAppPaymentsRepository.getLatestPaymentMethodType(InAppPaymentSubscriberRecord.Type.DONATION)
|
||||||
|
|
|
@ -115,7 +115,7 @@ class RecurringInAppPaymentRepository(private val donationsService: DonationsSer
|
||||||
InAppPaymentsRepository.setSubscriber(
|
InAppPaymentsRepository.setSubscriber(
|
||||||
InAppPaymentSubscriberRecord(
|
InAppPaymentSubscriberRecord(
|
||||||
subscriberId = subscriberId,
|
subscriberId = subscriberId,
|
||||||
currencyCode = SignalStore.donationsValues().getSubscriptionCurrency(subscriberType).currencyCode,
|
currency = SignalStore.donationsValues().getSubscriptionCurrency(subscriberType),
|
||||||
type = subscriberType,
|
type = subscriberType,
|
||||||
requiresCancel = false,
|
requiresCancel = false,
|
||||||
paymentMethodType = InAppPaymentData.PaymentMethodType.UNKNOWN
|
paymentMethodType = InAppPaymentData.PaymentMethodType.UNKNOWN
|
||||||
|
@ -193,7 +193,7 @@ class RecurringInAppPaymentRepository(private val donationsService: DonationsSer
|
||||||
AppDependencies.donationsService.updateSubscriptionLevel(
|
AppDependencies.donationsService.updateSubscriptionLevel(
|
||||||
subscriber.subscriberId,
|
subscriber.subscriberId,
|
||||||
subscriptionLevel,
|
subscriptionLevel,
|
||||||
subscriber.currencyCode,
|
subscriber.currency.currencyCode,
|
||||||
levelUpdateOperation.idempotencyKey.serialize(),
|
levelUpdateOperation.idempotencyKey.serialize(),
|
||||||
subscriberType
|
subscriberType
|
||||||
)
|
)
|
||||||
|
|
|
@ -50,7 +50,7 @@ class SetCurrencyViewModel(
|
||||||
InAppPaymentsRepository.setSubscriber(
|
InAppPaymentsRepository.setSubscriber(
|
||||||
InAppPaymentSubscriberRecord(
|
InAppPaymentSubscriberRecord(
|
||||||
subscriberId = SubscriberId.generate(),
|
subscriberId = SubscriberId.generate(),
|
||||||
currencyCode = currency.currencyCode,
|
currency = currency,
|
||||||
type = inAppPaymentType.requireSubscriberType(),
|
type = inAppPaymentType.requireSubscriberType(),
|
||||||
requiresCancel = false,
|
requiresCancel = false,
|
||||||
paymentMethodType = InAppPaymentData.PaymentMethodType.UNKNOWN
|
paymentMethodType = InAppPaymentData.PaymentMethodType.UNKNOWN
|
||||||
|
|
|
@ -392,7 +392,7 @@ class DonateToSignalViewModel(
|
||||||
if (selectedCurrency !in priceCurrencies) {
|
if (selectedCurrency !in priceCurrencies) {
|
||||||
Log.w(TAG, "Unsupported currency selection. Defaulting to USD. $selectedCurrency isn't supported.")
|
Log.w(TAG, "Unsupported currency selection. Defaulting to USD. $selectedCurrency isn't supported.")
|
||||||
val usd = PlatformCurrencyUtil.USD
|
val usd = PlatformCurrencyUtil.USD
|
||||||
val newSubscriber = InAppPaymentsRepository.getSubscriber(usd, InAppPaymentSubscriberRecord.Type.DONATION) ?: InAppPaymentSubscriberRecord(SubscriberId.generate(), usd.currencyCode, InAppPaymentSubscriberRecord.Type.DONATION, false, InAppPaymentData.PaymentMethodType.UNKNOWN)
|
val newSubscriber = InAppPaymentsRepository.getSubscriber(usd, InAppPaymentSubscriberRecord.Type.DONATION) ?: InAppPaymentSubscriberRecord(SubscriberId.generate(), usd, InAppPaymentSubscriberRecord.Type.DONATION, false, InAppPaymentData.PaymentMethodType.UNKNOWN)
|
||||||
InAppPaymentsRepository.setSubscriber(newSubscriber)
|
InAppPaymentsRepository.setSubscriber(newSubscriber)
|
||||||
subscriptionsRepository.syncAccountRecord().subscribe()
|
subscriptionsRepository.syncAccountRecord().subscribe()
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,7 +240,7 @@ class InternalConversationSettingsFragment : DSLSettingsFragment(
|
||||||
// TODO [alex] - DB on main thread!
|
// TODO [alex] - DB on main thread!
|
||||||
val subscriber: InAppPaymentSubscriberRecord? = InAppPaymentsRepository.getSubscriber(InAppPaymentSubscriberRecord.Type.DONATION)
|
val subscriber: InAppPaymentSubscriberRecord? = InAppPaymentsRepository.getSubscriber(InAppPaymentSubscriberRecord.Type.DONATION)
|
||||||
val summary = if (subscriber != null) {
|
val summary = if (subscriber != null) {
|
||||||
"""currency code: ${subscriber.currencyCode}
|
"""currency code: ${subscriber.currency.currencyCode}
|
||||||
|subscriber id: ${subscriber.subscriberId.serialize()}
|
|subscriber id: ${subscriber.subscriberId.serialize()}
|
||||||
""".trimMargin()
|
""".trimMargin()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.database.model.InAppPaymentSubscriberRecord
|
||||||
import org.thoughtcrime.securesms.database.model.databaseprotos.InAppPaymentData
|
import org.thoughtcrime.securesms.database.model.databaseprotos.InAppPaymentData
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
import org.whispersystems.signalservice.api.subscriptions.SubscriberId
|
import org.whispersystems.signalservice.api.subscriptions.SubscriberId
|
||||||
|
import java.util.Currency
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A table matching up SubscriptionIds to currency codes and type
|
* A table matching up SubscriptionIds to currency codes and type
|
||||||
|
@ -77,7 +78,7 @@ class InAppPaymentSubscriberTable(
|
||||||
* This is a destructive, mutating operation. For setting specific values, prefer the alternative setters available on this table class.
|
* This is a destructive, mutating operation. For setting specific values, prefer the alternative setters available on this table class.
|
||||||
*/
|
*/
|
||||||
fun insertOrReplace(inAppPaymentSubscriberRecord: InAppPaymentSubscriberRecord) {
|
fun insertOrReplace(inAppPaymentSubscriberRecord: InAppPaymentSubscriberRecord) {
|
||||||
Log.i(TAG, "Setting subscriber for currency ${inAppPaymentSubscriberRecord.currencyCode}", Exception(), true)
|
Log.i(TAG, "Setting subscriber for currency ${inAppPaymentSubscriberRecord.currency.currencyCode}", Exception(), true)
|
||||||
|
|
||||||
writableDatabase.withinTransaction { db ->
|
writableDatabase.withinTransaction { db ->
|
||||||
db.insertInto(TABLE_NAME)
|
db.insertInto(TABLE_NAME)
|
||||||
|
@ -85,7 +86,7 @@ class InAppPaymentSubscriberTable(
|
||||||
.run(conflictStrategy = SQLiteDatabase.CONFLICT_REPLACE)
|
.run(conflictStrategy = SQLiteDatabase.CONFLICT_REPLACE)
|
||||||
|
|
||||||
SignalStore.donationsValues().setSubscriberCurrency(
|
SignalStore.donationsValues().setSubscriberCurrency(
|
||||||
inAppPaymentSubscriberRecord.currencyCode,
|
inAppPaymentSubscriberRecord.currency,
|
||||||
inAppPaymentSubscriberRecord.type
|
inAppPaymentSubscriberRecord.type
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -137,7 +138,7 @@ class InAppPaymentSubscriberTable(
|
||||||
override fun serialize(data: InAppPaymentSubscriberRecord): ContentValues {
|
override fun serialize(data: InAppPaymentSubscriberRecord): ContentValues {
|
||||||
return contentValuesOf(
|
return contentValuesOf(
|
||||||
SUBSCRIBER_ID to data.subscriberId.serialize(),
|
SUBSCRIBER_ID to data.subscriberId.serialize(),
|
||||||
CURRENCY_CODE to data.currencyCode.uppercase(),
|
CURRENCY_CODE to data.currency.currencyCode.uppercase(),
|
||||||
TYPE to TypeSerializer.serialize(data.type),
|
TYPE to TypeSerializer.serialize(data.type),
|
||||||
REQUIRES_CANCEL to data.requiresCancel,
|
REQUIRES_CANCEL to data.requiresCancel,
|
||||||
PAYMENT_METHOD_TYPE to data.paymentMethodType.value
|
PAYMENT_METHOD_TYPE to data.paymentMethodType.value
|
||||||
|
@ -145,11 +146,13 @@ class InAppPaymentSubscriberTable(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deserialize(input: Cursor): InAppPaymentSubscriberRecord {
|
override fun deserialize(input: Cursor): InAppPaymentSubscriberRecord {
|
||||||
|
val type = TypeSerializer.deserialize(input.requireInt(TYPE))
|
||||||
|
val currencyCode = input.requireNonNullString(CURRENCY_CODE).takeIf { it.isNotEmpty() }
|
||||||
return InAppPaymentSubscriberRecord(
|
return InAppPaymentSubscriberRecord(
|
||||||
subscriberId = SubscriberId.deserialize(input.requireNonNullString(SUBSCRIBER_ID)),
|
subscriberId = SubscriberId.deserialize(input.requireNonNullString(SUBSCRIBER_ID)),
|
||||||
currencyCode = input.requireNonNullString(CURRENCY_CODE),
|
currency = currencyCode?.let { Currency.getInstance(it) } ?: SignalStore.donationsValues().getSubscriptionCurrency(type),
|
||||||
type = TypeSerializer.deserialize(input.requireInt(TYPE)),
|
type = type,
|
||||||
requiresCancel = input.requireBoolean(REQUIRES_CANCEL),
|
requiresCancel = input.requireBoolean(REQUIRES_CANCEL) || currencyCode.isNullOrBlank(),
|
||||||
paymentMethodType = InAppPaymentData.PaymentMethodType.fromValue(input.requireInt(PAYMENT_METHOD_TYPE)) ?: InAppPaymentData.PaymentMethodType.UNKNOWN
|
paymentMethodType = InAppPaymentData.PaymentMethodType.fromValue(input.requireInt(PAYMENT_METHOD_TYPE)) ?: InAppPaymentData.PaymentMethodType.UNKNOWN
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.thoughtcrime.securesms.database.model
|
||||||
import org.thoughtcrime.securesms.database.InAppPaymentTable
|
import org.thoughtcrime.securesms.database.InAppPaymentTable
|
||||||
import org.thoughtcrime.securesms.database.model.databaseprotos.InAppPaymentData
|
import org.thoughtcrime.securesms.database.model.databaseprotos.InAppPaymentData
|
||||||
import org.whispersystems.signalservice.api.subscriptions.SubscriberId
|
import org.whispersystems.signalservice.api.subscriptions.SubscriberId
|
||||||
|
import java.util.Currency
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a SubscriberId and metadata that can be used for a recurring
|
* Represents a SubscriberId and metadata that can be used for a recurring
|
||||||
|
@ -15,7 +16,7 @@ import org.whispersystems.signalservice.api.subscriptions.SubscriberId
|
||||||
*/
|
*/
|
||||||
data class InAppPaymentSubscriberRecord(
|
data class InAppPaymentSubscriberRecord(
|
||||||
val subscriberId: SubscriberId,
|
val subscriberId: SubscriberId,
|
||||||
val currencyCode: String,
|
val currency: Currency,
|
||||||
val type: Type,
|
val type: Type,
|
||||||
val requiresCancel: Boolean,
|
val requiresCancel: Boolean,
|
||||||
val paymentMethodType: InAppPaymentData.PaymentMethodType
|
val paymentMethodType: InAppPaymentData.PaymentMethodType
|
||||||
|
|
|
@ -164,7 +164,7 @@ class ExternalLaunchDonationJob private constructor(
|
||||||
val updateSubscriptionLevelResponse = AppDependencies.donationsService.updateSubscriptionLevel(
|
val updateSubscriptionLevelResponse = AppDependencies.donationsService.updateSubscriptionLevel(
|
||||||
subscriber.subscriberId,
|
subscriber.subscriberId,
|
||||||
subscriptionLevel,
|
subscriptionLevel,
|
||||||
subscriber.currencyCode,
|
subscriber.currency.currencyCode,
|
||||||
levelUpdateOperation.idempotencyKey.serialize(),
|
levelUpdateOperation.idempotencyKey.serialize(),
|
||||||
subscriber.type
|
subscriber.type
|
||||||
)
|
)
|
||||||
|
|
|
@ -233,7 +233,7 @@ class InAppPaymentAuthCheckJob private constructor(parameters: Parameters) : Bas
|
||||||
val updateLevelResponse = AppDependencies.donationsService.updateSubscriptionLevel(
|
val updateLevelResponse = AppDependencies.donationsService.updateSubscriptionLevel(
|
||||||
subscriber.subscriberId,
|
subscriber.subscriberId,
|
||||||
level,
|
level,
|
||||||
subscriber.currencyCode,
|
subscriber.currency.currencyCode,
|
||||||
updateOperation.idempotencyKey.serialize(),
|
updateOperation.idempotencyKey.serialize(),
|
||||||
subscriber.type
|
subscriber.type
|
||||||
)
|
)
|
||||||
|
|
|
@ -250,7 +250,7 @@ class InAppPaymentKeepAliveJob private constructor(
|
||||||
inAppPaymentData = InAppPaymentData(
|
inAppPaymentData = InAppPaymentData(
|
||||||
badge = badge,
|
badge = badge,
|
||||||
amount = FiatValue(
|
amount = FiatValue(
|
||||||
currencyCode = subscriber.currencyCode,
|
currencyCode = subscriber.currency.currencyCode,
|
||||||
amount = subscription.amount.toDecimalValue()
|
amount = subscription.amount.toDecimalValue()
|
||||||
),
|
),
|
||||||
error = null,
|
error = null,
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription.Cha
|
||||||
import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription.Subscription
|
import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription.Subscription
|
||||||
import org.whispersystems.signalservice.internal.ServiceResponse
|
import org.whispersystems.signalservice.internal.ServiceResponse
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import java.util.Currency
|
||||||
import kotlin.time.Duration.Companion.days
|
import kotlin.time.Duration.Companion.days
|
||||||
import kotlin.time.Duration.Companion.milliseconds
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
@ -288,10 +289,15 @@ class InAppPaymentRecurringContextJob private constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handlePaymentFailure(inAppPayment: InAppPaymentTable.InAppPayment, subscription: Subscription, chargeFailure: ChargeFailure?) {
|
private fun handlePaymentFailure(inAppPayment: InAppPaymentTable.InAppPayment, subscription: Subscription, chargeFailure: ChargeFailure?) {
|
||||||
val subscriber = SignalDatabase.inAppPaymentSubscribers.getBySubscriberId(inAppPayment.subscriberId!!)
|
SignalDatabase.inAppPaymentSubscribers.insertOrReplace(
|
||||||
if (subscriber != null) {
|
InAppPaymentSubscriberRecord(
|
||||||
InAppPaymentsRepository.setShouldCancelSubscriptionBeforeNextSubscribeAttempt(subscriber, true)
|
subscriberId = inAppPayment.subscriberId!!,
|
||||||
}
|
currency = Currency.getInstance(inAppPayment.data.amount!!.currencyCode),
|
||||||
|
type = inAppPayment.type.requireSubscriberType(),
|
||||||
|
requiresCancel = true,
|
||||||
|
paymentMethodType = inAppPayment.data.paymentMethodType
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if (inAppPayment.data.redemption?.keepAlive == true) {
|
if (inAppPayment.data.redemption?.keepAlive == true) {
|
||||||
info("Cancellation occurred during keep-alive. Setting cancellation state.")
|
info("Cancellation occurred during keep-alive. Setting cancellation state.")
|
||||||
|
|
|
@ -245,7 +245,7 @@ internal class DonationsValues internal constructor(store: KeyValueStore) : Sign
|
||||||
} else {
|
} else {
|
||||||
InAppPaymentSubscriberRecord(
|
InAppPaymentSubscriberRecord(
|
||||||
SubscriberId.fromBytes(subscriberIdBytes),
|
SubscriberId.fromBytes(subscriberIdBytes),
|
||||||
currencyCode,
|
currency,
|
||||||
InAppPaymentSubscriberRecord.Type.DONATION,
|
InAppPaymentSubscriberRecord.Type.DONATION,
|
||||||
shouldCancelSubscriptionBeforeNextSubscribeAttempt,
|
shouldCancelSubscriptionBeforeNextSubscribeAttempt,
|
||||||
getSubscriptionPaymentSourceType().toPaymentMethodType()
|
getSubscriptionPaymentSourceType().toPaymentMethodType()
|
||||||
|
@ -253,19 +253,19 @@ internal class DonationsValues internal constructor(store: KeyValueStore) : Sign
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setSubscriberCurrency(currencyCode: String, type: InAppPaymentSubscriberRecord.Type) {
|
fun setSubscriberCurrency(currency: Currency, type: InAppPaymentSubscriberRecord.Type) {
|
||||||
if (type == InAppPaymentSubscriberRecord.Type.DONATION) {
|
if (type == InAppPaymentSubscriberRecord.Type.DONATION) {
|
||||||
store.beginWrite()
|
store.beginWrite()
|
||||||
.putString(KEY_DONATION_SUBSCRIPTION_CURRENCY_CODE, currencyCode)
|
.putString(KEY_DONATION_SUBSCRIPTION_CURRENCY_CODE, currency.currencyCode)
|
||||||
.apply()
|
.apply()
|
||||||
|
|
||||||
recurringDonationCurrencyPublisher.onNext(Currency.getInstance(currencyCode))
|
recurringDonationCurrencyPublisher.onNext(currency)
|
||||||
} else {
|
} else {
|
||||||
store.beginWrite()
|
store.beginWrite()
|
||||||
.putString(KEY_BACKUPS_SUBSCRIPTION_CURRENCY_CODE, currencyCode)
|
.putString(KEY_BACKUPS_SUBSCRIPTION_CURRENCY_CODE, currency.currencyCode)
|
||||||
.apply()
|
.apply()
|
||||||
|
|
||||||
recurringBackupCurrencyPublisher.onNext(Currency.getInstance(currencyCode))
|
recurringBackupCurrencyPublisher.onNext(currency)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ internal class SubscriberIdMigrationJob(
|
||||||
SignalDatabase.inAppPaymentSubscribers.insertOrReplace(
|
SignalDatabase.inAppPaymentSubscribers.insertOrReplace(
|
||||||
InAppPaymentSubscriberRecord(
|
InAppPaymentSubscriberRecord(
|
||||||
subscriber.subscriberId,
|
subscriber.subscriberId,
|
||||||
subscriber.currencyCode,
|
subscriber.currency,
|
||||||
InAppPaymentSubscriberRecord.Type.DONATION,
|
InAppPaymentSubscriberRecord.Type.DONATION,
|
||||||
SignalStore.donationsValues().shouldCancelSubscriptionBeforeNextSubscribeAttempt,
|
SignalStore.donationsValues().shouldCancelSubscriptionBeforeNextSubscribeAttempt,
|
||||||
SignalStore.donationsValues().getSubscriptionPaymentSourceType().toPaymentMethodType()
|
SignalStore.donationsValues().getSubscriptionPaymentSourceType().toPaymentMethodType()
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.database.model.RecipientRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.databaseprotos.InAppPaymentData;
|
import org.thoughtcrime.securesms.database.model.databaseprotos.InAppPaymentData;
|
||||||
import org.thoughtcrime.securesms.groups.GroupId;
|
import org.thoughtcrime.securesms.groups.GroupId;
|
||||||
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
|
import org.thoughtcrime.securesms.keyvalue.PhoneNumberPrivacyValues;
|
||||||
|
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||||
import org.whispersystems.signalservice.api.storage.SignalAccountRecord;
|
import org.whispersystems.signalservice.api.storage.SignalAccountRecord;
|
||||||
|
@ -32,6 +33,7 @@ import org.whispersystems.signalservice.internal.storage.protos.AccountRecord;
|
||||||
import org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState;
|
import org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState;
|
||||||
import org.whispersystems.signalservice.internal.storage.protos.GroupV2Record;
|
import org.whispersystems.signalservice.internal.storage.protos.GroupV2Record;
|
||||||
|
|
||||||
|
import java.util.Currency;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -281,24 +283,32 @@ public final class StorageSyncModels {
|
||||||
if (subscriber == null) {
|
if (subscriber == null) {
|
||||||
return new SignalAccountRecord.Subscriber(null, null);
|
return new SignalAccountRecord.Subscriber(null, null);
|
||||||
} else {
|
} else {
|
||||||
return new SignalAccountRecord.Subscriber(subscriber.getCurrencyCode(), subscriber.getSubscriberId().getBytes());
|
return new SignalAccountRecord.Subscriber(subscriber.getCurrency().getCurrencyCode(), subscriber.getSubscriberId().getBytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO - We need to store the subscriber type.
|
|
||||||
*/
|
|
||||||
public static @Nullable InAppPaymentSubscriberRecord remoteToLocalSubscriber(
|
public static @Nullable InAppPaymentSubscriberRecord remoteToLocalSubscriber(
|
||||||
@NonNull SignalAccountRecord.Subscriber subscriber,
|
@NonNull SignalAccountRecord.Subscriber subscriber,
|
||||||
@NonNull InAppPaymentSubscriberRecord.Type type
|
@NonNull InAppPaymentSubscriberRecord.Type type
|
||||||
) {
|
) {
|
||||||
if (subscriber.getId().isPresent()) {
|
if (subscriber.getId().isPresent()) {
|
||||||
SubscriberId subscriberId = SubscriberId.fromBytes(subscriber.getId().get());
|
SubscriberId subscriberId = SubscriberId.fromBytes(subscriber.getId().get());
|
||||||
InAppPaymentSubscriberRecord localSubscriberRecord = SignalDatabase.inAppPaymentSubscribers().getBySubscriberId(subscriberId);
|
InAppPaymentSubscriberRecord localSubscriberRecord = SignalDatabase.inAppPaymentSubscribers().getBySubscriberId(subscriberId);
|
||||||
boolean requiresCancel = localSubscriberRecord != null && localSubscriberRecord.getRequiresCancel();
|
boolean requiresCancel = localSubscriberRecord != null && localSubscriberRecord.getRequiresCancel();
|
||||||
InAppPaymentData.PaymentMethodType paymentMethodType = localSubscriberRecord != null ? localSubscriberRecord.getPaymentMethodType() : InAppPaymentData.PaymentMethodType.UNKNOWN;
|
InAppPaymentData.PaymentMethodType paymentMethodType = localSubscriberRecord != null ? localSubscriberRecord.getPaymentMethodType() : InAppPaymentData.PaymentMethodType.UNKNOWN;
|
||||||
|
|
||||||
return new InAppPaymentSubscriberRecord(subscriberId, subscriber.getCurrencyCode().get(), type, requiresCancel, paymentMethodType);
|
Currency currency;
|
||||||
|
if (subscriber.getCurrencyCode().isEmpty()) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
currency = Currency.getInstance(subscriber.getCurrencyCode().get());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new InAppPaymentSubscriberRecord(subscriberId, currency, type, requiresCancel, paymentMethodType);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue