From ad652dbaf22f9d8a236cc3e3a43dc27db1d3c43c Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Mon, 2 Jun 2025 10:54:04 -0300 Subject: [PATCH] Backup delete resub flow state fix. --- .../securesms/backup/v2/BackupRepository.kt | 7 ++ .../app/internal/InternalSettingsFragment.kt | 2 - .../jobs/InAppPaymentRecurringContextJob.kt | 5 + .../jobs/InAppPaymentRedemptionJob.kt | 7 +- .../securesms/keyvalue/InAppPaymentValues.kt | 93 ------------------- .../securesms/logsubmit/LogSectionBadges.java | 7 +- 6 files changed, 15 insertions(+), 106 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt index cc665ec18d..d7341536cf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt @@ -1042,6 +1042,13 @@ object BackupRepository { } } + fun enablePaidBackupTier() { + Log.i(TAG, "Setting backup tier to PAID", true) + SignalStore.backup.backupTier = MessageBackupTier.PAID + SignalStore.backup.lastCheckInMillis = System.currentTimeMillis() + SignalStore.backup.lastCheckInSnoozeMillis = 0 + } + /** * Grabs the backup tier for the given ACI. Note that this will set the user's backup * tier to FREE if they are not on PAID, so avoid this method if you don't intend that diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt index fdb96015e7..fe802ea103 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/InternalSettingsFragment.kt @@ -667,8 +667,6 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter clickPref( title = DSLSettingsText.from("Clear keep-alive timestamps"), onClick = { - SignalStore.inAppPayments.subscriptionEndOfPeriodRedemptionStarted = 0L - SignalStore.inAppPayments.subscriptionEndOfPeriodConversionStarted = 0L SignalStore.inAppPayments.setLastEndOfPeriod(0L) Toast.makeText(context, "Cleared", Toast.LENGTH_SHORT).show() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentRecurringContextJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentRecurringContextJob.kt index a7190d88b9..8fe4256dd3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentRecurringContextJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentRecurringContextJob.kt @@ -13,6 +13,7 @@ import org.signal.libsignal.zkgroup.receipts.ReceiptCredential import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialPresentation import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialRequestContext import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialResponse +import org.thoughtcrime.securesms.backup.v2.BackupRepository import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository.requireSubscriberType import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository.toInAppPaymentDataChargeFailure @@ -248,6 +249,10 @@ class InAppPaymentRecurringContextJob private constructor( ).build() ) ) + + if (inAppPayment.type == InAppPaymentType.RECURRING_BACKUP) { + BackupRepository.enablePaidBackupTier() + } } private fun getAndValidateInAppPayment(): Pair { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentRedemptionJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentRedemptionJob.kt index 85e4b66e4b..90b41031f8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentRedemptionJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/InAppPaymentRedemptionJob.kt @@ -8,7 +8,7 @@ package org.thoughtcrime.securesms.jobs import org.signal.core.util.logging.Log import org.signal.donations.InAppPaymentType import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialPresentation -import org.thoughtcrime.securesms.backup.v2.MessageBackupTier +import org.thoughtcrime.securesms.backup.v2.BackupRepository import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository.requireSubscriberType import org.thoughtcrime.securesms.database.InAppPaymentTable @@ -268,10 +268,7 @@ class InAppPaymentRedemptionJob private constructor( ) if (inAppPayment.type == InAppPaymentType.RECURRING_BACKUP) { - Log.i(TAG, "Setting backup tier to PAID", true) - SignalStore.backup.backupTier = MessageBackupTier.PAID - SignalStore.backup.lastCheckInMillis = System.currentTimeMillis() - SignalStore.backup.lastCheckInSnoozeMillis = 0 + BackupRepository.enablePaidBackupTier() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InAppPaymentValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InAppPaymentValues.kt index 6fbed0e61c..01c2b001b0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InAppPaymentValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/InAppPaymentValues.kt @@ -8,8 +8,6 @@ import io.reactivex.rxjava3.subjects.Subject import org.signal.core.util.logging.Log import org.signal.donations.PaymentSourceType import org.signal.donations.StripeApi -import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialPresentation -import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialRequestContext import org.thoughtcrime.securesms.backup.v2.MessageBackupTier import org.thoughtcrime.securesms.badges.Badges import org.thoughtcrime.securesms.badges.models.Badge @@ -70,42 +68,6 @@ class InAppPaymentValues internal constructor(store: KeyValueStore) : SignalStor private const val SUBSCRIPTION_CANCELATION_WATERMARK = "donation.subscription.cancelation.watermark" private const val SHOW_CANT_PROCESS_DIALOG = "show.cant.process.dialog" - /** - * The current request context for subscription. This should be stored until either - * it is successfully converted into a response, the end of period changes, or the user - * manually cancels the subscription. - */ - private const val SUBSCRIPTION_CREDENTIAL_REQUEST = "subscription.credential.request" - - /** - * The current response presentation that can be submitted for a badge. This should be - * stored until it is successfully redeemed, the end of period changes, or the user - * manually cancels their subscription. - */ - private const val SUBSCRIPTION_CREDENTIAL_RECEIPT = "subscription.credential.receipt" - - /** - * Notes the "end of period" time for the latest subscription that we have started - * to get a response presentation for. When this is equal to the latest "end of period" - * it can be assumed that we have a request context that can be safely reused. - */ - private const val SUBSCRIPTION_EOP_STARTED_TO_CONVERT = "subscription.eop.convert" - - /** - * Notes the "end of period" time for the latest subscription that we have started - * to redeem a response presentation for. When this is equal to the latest "end of - * period" it can be assumed that we have a response presentation that we can submit - * to get an active token for. - */ - private const val SUBSCRIPTION_EOP_STARTED_TO_REDEEM = "subscription.eop.redeem" - - /** - * Notes the "end of period" time for the latest subscription that we have successfully - * and fully redeemed a token for. If this is equal to the latest "end of period" it is - * assumed that there is no work to be done. - */ - private const val SUBSCRIPTION_EOP_REDEEMED = "subscription.eop.redeemed" - /** * Notes the type of payment the user utilized for the latest subscription. This is useful * in determining which error messaging they should see if something goes wrong. @@ -154,11 +116,6 @@ class InAppPaymentValues internal constructor(store: KeyValueStore) : SignalStor SUBSCRIPTION_CANCELATION_TIMESTAMP, SUBSCRIPTION_CANCELATION_WATERMARK, SHOW_CANT_PROCESS_DIALOG, - SUBSCRIPTION_CREDENTIAL_REQUEST, - SUBSCRIPTION_CREDENTIAL_RECEIPT, - SUBSCRIPTION_EOP_STARTED_TO_CONVERT, - SUBSCRIPTION_EOP_STARTED_TO_REDEEM, - SUBSCRIPTION_EOP_REDEEMED, SUBSCRIPTION_PAYMENT_SOURCE_TYPE ) @@ -363,15 +320,6 @@ class InAppPaymentValues internal constructor(store: KeyValueStore) : SignalStor return getBoolean(SUBSCRIPTION_REDEMPTION_FAILED, false) } - fun markSubscriptionRedemptionFailed() { - Log.w(TAG, "markSubscriptionRedemptionFailed()", Throwable(), true) - putBoolean(SUBSCRIPTION_REDEMPTION_FAILED, true) - } - - fun clearSubscriptionRedemptionFailed() { - putBoolean(SUBSCRIPTION_REDEMPTION_FAILED, false) - } - @Deprecated("Cancellation status is now stored in InAppPaymentTable") fun setUnexpectedSubscriptionCancelationChargeFailure(chargeFailure: ActiveSubscription.ChargeFailure?) { if (chargeFailure == null) { @@ -439,9 +387,6 @@ class InAppPaymentValues internal constructor(store: KeyValueStore) : SignalStor unexpectedSubscriptionCancelationReason = null unexpectedSubscriptionCancelationTimestamp = 0L - clearSubscriptionRequestCredential() - clearSubscriptionReceiptCredential() - val expiredBadge = getExpiredBadge() if (expiredBadge != null && expiredBadge.isSubscription()) { Log.d(TAG, "[updateLocalStateForManualCancellation] Clearing expired badge.") @@ -483,8 +428,6 @@ class InAppPaymentValues internal constructor(store: KeyValueStore) : SignalStor setUnexpectedSubscriptionCancelationChargeFailure(null) unexpectedSubscriptionCancelationReason = null unexpectedSubscriptionCancelationTimestamp = 0L - refreshSubscriptionRequestCredential() - clearSubscriptionReceiptCredential() val expiredBadge = getExpiredBadge() if (expiredBadge != null && expiredBadge.isSubscription()) { @@ -504,38 +447,6 @@ class InAppPaymentValues internal constructor(store: KeyValueStore) : SignalStor } } - fun refreshSubscriptionRequestCredential() { - putBlob(SUBSCRIPTION_CREDENTIAL_REQUEST, InAppPaymentsRepository.generateRequestCredential().serialize()) - } - - fun setSubscriptionRequestCredential(requestContext: ReceiptCredentialRequestContext) { - putBlob(SUBSCRIPTION_CREDENTIAL_REQUEST, requestContext.serialize()) - } - - fun getSubscriptionRequestCredential(): ReceiptCredentialRequestContext? { - val bytes = getBlob(SUBSCRIPTION_CREDENTIAL_REQUEST, null) ?: return null - - return ReceiptCredentialRequestContext(bytes) - } - - fun clearSubscriptionRequestCredential() { - remove(SUBSCRIPTION_CREDENTIAL_REQUEST) - } - - fun setSubscriptionReceiptCredential(receiptCredentialPresentation: ReceiptCredentialPresentation) { - putBlob(SUBSCRIPTION_CREDENTIAL_RECEIPT, receiptCredentialPresentation.serialize()) - } - - fun getSubscriptionReceiptCredential(): ReceiptCredentialPresentation? { - val bytes = getBlob(SUBSCRIPTION_CREDENTIAL_RECEIPT, null) ?: return null - - return ReceiptCredentialPresentation(bytes) - } - - fun clearSubscriptionReceiptCredential() { - remove(SUBSCRIPTION_CREDENTIAL_RECEIPT) - } - @Deprecated("This information is now stored in InAppPaymentTable") fun setSubscriptionPaymentSourceType(paymentSourceType: PaymentSourceType) { putString(SUBSCRIPTION_PAYMENT_SOURCE_TYPE, paymentSourceType.code) @@ -546,10 +457,6 @@ class InAppPaymentValues internal constructor(store: KeyValueStore) : SignalStor return PaymentSourceType.fromCode(getString(SUBSCRIPTION_PAYMENT_SOURCE_TYPE, null)) } - var subscriptionEndOfPeriodConversionStarted by longValue(SUBSCRIPTION_EOP_STARTED_TO_CONVERT, 0L) - var subscriptionEndOfPeriodRedemptionStarted by longValue(SUBSCRIPTION_EOP_STARTED_TO_REDEEM, 0L) - var subscriptionEndOfPeriodRedeemed by longValue(SUBSCRIPTION_EOP_REDEEMED, 0L) - fun appendToTerminalDonationQueue(terminalDonation: TerminalDonationQueue.TerminalDonation) { synchronized(this) { val pendingBytes = getBlob(DONATION_COMPLETE_QUEUE, null) diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionBadges.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionBadges.java index 5847f2dc60..28da91dff7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionBadges.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionBadges.java @@ -52,15 +52,10 @@ final class LogSectionBadges implements LogSection { .append("ExpiredBadge : ").append(SignalStore.inAppPayments().getExpiredBadge() != null).append("\n") .append("LastKeepAliveLaunchTime : ").append(SignalStore.inAppPayments().getLastKeepAliveLaunchTime()).append("\n") .append("LastEndOfPeriod : ").append(SignalStore.inAppPayments().getLastEndOfPeriod()).append("\n") - .append("SubscriptionEndOfPeriodConversionStarted: ").append(SignalStore.inAppPayments().getSubscriptionEndOfPeriodConversionStarted()).append("\n") - .append("SubscriptionEndOfPeriodRedemptionStarted: ").append(SignalStore.inAppPayments().getSubscriptionEndOfPeriodRedemptionStarted()).append("\n") - .append("SubscriptionEndOfPeriodRedeemed : ").append(SignalStore.inAppPayments().getSubscriptionEndOfPeriodRedeemed()).append("\n") .append("IsUserManuallyCancelledDonation : ").append(SignalStore.inAppPayments().isDonationSubscriptionManuallyCancelled()).append("\n") .append("DisplayBadgesOnProfile : ").append(SignalStore.inAppPayments().getDisplayBadgesOnProfile()).append("\n") .append("SubscriptionRedemptionFailed : ").append(SignalStore.inAppPayments().getSubscriptionRedemptionFailed()).append("\n") - .append("ShouldCancelBeforeNextAttempt : ").append(SignalStore.inAppPayments().getShouldCancelSubscriptionBeforeNextSubscribeAttempt()).append("\n") - .append("Has unconverted request context : ").append(SignalStore.inAppPayments().getSubscriptionRequestCredential() != null).append("\n") - .append("Has unredeemed receipt presentation : ").append(SignalStore.inAppPayments().getSubscriptionReceiptCredential() != null).append("\n"); + .append("ShouldCancelBeforeNextAttempt : ").append(SignalStore.inAppPayments().getShouldCancelSubscriptionBeforeNextSubscribeAttempt()).append("\n"); } }