Add better handling for unexpected cancellations.
This commit is contained in:
parent
77f8489e51
commit
588663b3c2
11 changed files with 115 additions and 26 deletions
|
@ -18,7 +18,6 @@ package org.thoughtcrime.securesms;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.StrictMode;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
@ -87,7 +86,6 @@ import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||||
import org.thoughtcrime.securesms.util.AppForegroundObserver;
|
import org.thoughtcrime.securesms.util.AppForegroundObserver;
|
||||||
import org.thoughtcrime.securesms.util.AppStartup;
|
import org.thoughtcrime.securesms.util.AppStartup;
|
||||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||||
import org.thoughtcrime.securesms.util.Environment;
|
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||||
import org.thoughtcrime.securesms.util.SignalLocalMetrics;
|
import org.thoughtcrime.securesms.util.SignalLocalMetrics;
|
||||||
import org.thoughtcrime.securesms.util.SignalUncaughtExceptionHandler;
|
import org.thoughtcrime.securesms.util.SignalUncaughtExceptionHandler;
|
||||||
|
@ -99,7 +97,6 @@ import org.thoughtcrime.securesms.util.dynamiclanguage.DynamicLanguageContextWra
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import io.reactivex.rxjava3.exceptions.OnErrorNotImplementedException;
|
import io.reactivex.rxjava3.exceptions.OnErrorNotImplementedException;
|
||||||
|
@ -221,7 +218,7 @@ public class ApplicationContext extends MultiDexApplication implements AppForegr
|
||||||
ApplicationDependencies.getFrameRateTracker().start();
|
ApplicationDependencies.getFrameRateTracker().start();
|
||||||
ApplicationDependencies.getMegaphoneRepository().onAppForegrounded();
|
ApplicationDependencies.getMegaphoneRepository().onAppForegrounded();
|
||||||
ApplicationDependencies.getDeadlockDetector().start();
|
ApplicationDependencies.getDeadlockDetector().start();
|
||||||
SubscriptionKeepAliveJob.launchSubscriberIdKeepAliveJobIfNecessary();
|
SubscriptionKeepAliveJob.enqueueAndTrackTimeIfNecessary();
|
||||||
|
|
||||||
SignalExecutors.BOUNDED.execute(() -> {
|
SignalExecutors.BOUNDED.execute(() -> {
|
||||||
FeatureFlags.refreshIfNecessary();
|
FeatureFlags.refreshIfNecessary();
|
||||||
|
|
|
@ -40,6 +40,8 @@ data class Badge(
|
||||||
|
|
||||||
fun isExpired(): Boolean = expirationTimestamp < System.currentTimeMillis() && expirationTimestamp > 0
|
fun isExpired(): Boolean = expirationTimestamp < System.currentTimeMillis() && expirationTimestamp > 0
|
||||||
fun isBoost(): Boolean = id == BOOST_BADGE_ID
|
fun isBoost(): Boolean = id == BOOST_BADGE_ID
|
||||||
|
fun isGift(): Boolean = id == GIFT_BADGE_ID
|
||||||
|
fun isSubscription(): Boolean = !isBoost() && !isGift()
|
||||||
|
|
||||||
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
|
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
|
||||||
messageDigest.update(id.toByteArray(Key.CHARSET))
|
messageDigest.update(id.toByteArray(Key.CHARSET))
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.thoughtcrime.securesms.components.settings.app.subscription.errors.Un
|
||||||
import org.thoughtcrime.securesms.components.settings.configure
|
import org.thoughtcrime.securesms.components.settings.configure
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
import org.thoughtcrime.securesms.util.BottomSheetUtil
|
import org.thoughtcrime.securesms.util.BottomSheetUtil
|
||||||
|
import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bottom sheet displaying a fading badge with a notice and action for becoming a subscriber again.
|
* Bottom sheet displaying a fading badge with a notice and action for becoming a subscriber again.
|
||||||
|
@ -30,7 +31,8 @@ class ExpiredBadgeBottomSheetDialogFragment : DSLSettingsBottomSheetFragment(
|
||||||
private fun getConfiguration(): DSLConfiguration {
|
private fun getConfiguration(): DSLConfiguration {
|
||||||
val args = ExpiredBadgeBottomSheetDialogFragmentArgs.fromBundle(requireArguments())
|
val args = ExpiredBadgeBottomSheetDialogFragmentArgs.fromBundle(requireArguments())
|
||||||
val badge: Badge = args.badge
|
val badge: Badge = args.badge
|
||||||
val cancellationReason: UnexpectedSubscriptionCancellation? = UnexpectedSubscriptionCancellation.fromStatus(args.cancelationReason)
|
val cancellationReason = UnexpectedSubscriptionCancellation.fromStatus(args.cancelationReason)
|
||||||
|
val chargeFailure: ActiveSubscription.ChargeFailure? = SignalStore.donationsValues().getUnexpectedSubscriptionCancelationChargeFailure()
|
||||||
val isLikelyASustainer = SignalStore.donationsValues().isLikelyASustainer()
|
val isLikelyASustainer = SignalStore.donationsValues().isLikelyASustainer()
|
||||||
|
|
||||||
val inactive = cancellationReason == UnexpectedSubscriptionCancellation.INACTIVE
|
val inactive = cancellationReason == UnexpectedSubscriptionCancellation.INACTIVE
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.thoughtcrime.securesms.jobs.RemoteConfigRefreshJob
|
||||||
import org.thoughtcrime.securesms.jobs.RetrieveRemoteAnnouncementsJob
|
import org.thoughtcrime.securesms.jobs.RetrieveRemoteAnnouncementsJob
|
||||||
import org.thoughtcrime.securesms.jobs.RotateProfileKeyJob
|
import org.thoughtcrime.securesms.jobs.RotateProfileKeyJob
|
||||||
import org.thoughtcrime.securesms.jobs.StorageForcePushJob
|
import org.thoughtcrime.securesms.jobs.StorageForcePushJob
|
||||||
|
import org.thoughtcrime.securesms.jobs.SubscriptionKeepAliveJob
|
||||||
import org.thoughtcrime.securesms.jobs.SubscriptionReceiptRequestResponseJob
|
import org.thoughtcrime.securesms.jobs.SubscriptionReceiptRequestResponseJob
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
import org.thoughtcrime.securesms.payments.DataExportUtil
|
import org.thoughtcrime.securesms.payments.DataExportUtil
|
||||||
|
@ -401,6 +402,13 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter
|
||||||
enqueueSubscriptionRedemption()
|
enqueueSubscriptionRedemption()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
clickPref(
|
||||||
|
title = DSLSettingsText.from(R.string.preferences__internal_badges_enqueue_keep_alive),
|
||||||
|
onClick = {
|
||||||
|
enqueueSubscriptionKeepAlive()
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
dividerPref()
|
dividerPref()
|
||||||
|
@ -573,6 +581,10 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter
|
||||||
SubscriptionReceiptRequestResponseJob.createSubscriptionContinuationJobChain().enqueue()
|
SubscriptionReceiptRequestResponseJob.createSubscriptionContinuationJobChain().enqueue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun enqueueSubscriptionKeepAlive() {
|
||||||
|
SubscriptionKeepAliveJob.enqueueAndTrackTime(System.currentTimeMillis())
|
||||||
|
}
|
||||||
|
|
||||||
private fun clearCdsHistory() {
|
private fun clearCdsHistory() {
|
||||||
SignalDatabase.cds.clearAll()
|
SignalDatabase.cds.clearAll()
|
||||||
SignalStore.misc().cdsToken = null
|
SignalStore.misc().cdsToken = null
|
||||||
|
|
|
@ -277,9 +277,8 @@ class DonationPaymentRepository(activity: Activity) : StripeApi.PaymentIntentFet
|
||||||
).flatMapCompletable {
|
).flatMapCompletable {
|
||||||
if (it.status == 200 || it.status == 204) {
|
if (it.status == 200 || it.status == 204) {
|
||||||
Log.d(TAG, "Successfully set user subscription to level $subscriptionLevel with response code ${it.status}", true)
|
Log.d(TAG, "Successfully set user subscription to level $subscriptionLevel with response code ${it.status}", true)
|
||||||
SignalStore.donationsValues().clearUserManuallyCancelled()
|
SignalStore.donationsValues().updateLocalStateForLocalSubscribe()
|
||||||
scheduleSyncForAccountRecordChange()
|
scheduleSyncForAccountRecordChange()
|
||||||
SignalStore.donationsValues().clearLevelOperations()
|
|
||||||
LevelUpdate.updateProcessingState(false)
|
LevelUpdate.updateProcessingState(false)
|
||||||
Completable.complete()
|
Completable.complete()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -164,12 +164,7 @@ class SubscribeViewModel(
|
||||||
return Single.just(SignalStore.donationsValues().shouldCancelSubscriptionBeforeNextSubscribeAttempt).flatMapCompletable {
|
return Single.just(SignalStore.donationsValues().shouldCancelSubscriptionBeforeNextSubscribeAttempt).flatMapCompletable {
|
||||||
if (it) {
|
if (it) {
|
||||||
donationPaymentRepository.cancelActiveSubscription().doOnComplete {
|
donationPaymentRepository.cancelActiveSubscription().doOnComplete {
|
||||||
SignalStore.donationsValues().setLastEndOfPeriod(0L)
|
SignalStore.donationsValues().updateLocalStateForManualCancellation()
|
||||||
SignalStore.donationsValues().clearLevelOperations()
|
|
||||||
SignalStore.donationsValues().shouldCancelSubscriptionBeforeNextSubscribeAttempt = false
|
|
||||||
SignalStore.donationsValues().setUnexpectedSubscriptionCancelationChargeFailure(null)
|
|
||||||
SignalStore.donationsValues().unexpectedSubscriptionCancelationReason = null
|
|
||||||
SignalStore.donationsValues().unexpectedSubscriptionCancelationTimestamp = 0L
|
|
||||||
MultiDeviceSubscriptionSyncRequestJob.enqueue()
|
MultiDeviceSubscriptionSyncRequestJob.enqueue()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -183,12 +178,7 @@ class SubscribeViewModel(
|
||||||
disposables += donationPaymentRepository.cancelActiveSubscription().subscribeBy(
|
disposables += donationPaymentRepository.cancelActiveSubscription().subscribeBy(
|
||||||
onComplete = {
|
onComplete = {
|
||||||
eventPublisher.onNext(DonationEvent.SubscriptionCancelled)
|
eventPublisher.onNext(DonationEvent.SubscriptionCancelled)
|
||||||
SignalStore.donationsValues().setLastEndOfPeriod(0L)
|
SignalStore.donationsValues().updateLocalStateForManualCancellation()
|
||||||
SignalStore.donationsValues().clearLevelOperations()
|
|
||||||
SignalStore.donationsValues().markUserManuallyCancelled()
|
|
||||||
SignalStore.donationsValues().setUnexpectedSubscriptionCancelationChargeFailure(null)
|
|
||||||
SignalStore.donationsValues().unexpectedSubscriptionCancelationReason = null
|
|
||||||
SignalStore.donationsValues().unexpectedSubscriptionCancelationTimestamp = 0L
|
|
||||||
refreshActiveSubscription()
|
refreshActiveSubscription()
|
||||||
MultiDeviceSubscriptionSyncRequestJob.enqueue()
|
MultiDeviceSubscriptionSyncRequestJob.enqueue()
|
||||||
donationPaymentRepository.scheduleSyncForAccountRecordChange()
|
donationPaymentRepository.scheduleSyncForAccountRecordChange()
|
||||||
|
|
|
@ -299,6 +299,10 @@ public class RefreshOwnProfileJob extends BaseJob {
|
||||||
Log.d(TAG, "Unexpected expiry due to payment failure.", true);
|
Log.d(TAG, "Unexpected expiry due to payment failure.", true);
|
||||||
isDueToPaymentFailure = true;
|
isDueToPaymentFailure = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (activeSubscription.getChargeFailure() != null) {
|
||||||
|
Log.d(TAG, "Active payment contains a charge failure: " + activeSubscription.getChargeFailure().getCode(), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,6 +324,16 @@ public class RefreshOwnProfileJob extends BaseJob {
|
||||||
|
|
||||||
Log.d(TAG, "Marking boost badge as expired, should notify next time the conversation list is open.", true);
|
Log.d(TAG, "Marking boost badge as expired, should notify next time the conversation list is open.", true);
|
||||||
SignalStore.donationsValues().setExpiredBadge(mostRecentExpiration);
|
SignalStore.donationsValues().setExpiredBadge(mostRecentExpiration);
|
||||||
|
} else {
|
||||||
|
Badge badge = SignalStore.donationsValues().getExpiredBadge();
|
||||||
|
|
||||||
|
if (badge != null && badge.isSubscription() && remoteHasSubscriptionBadges) {
|
||||||
|
Log.d(TAG, "Remote has subscription badges. Clearing local expired subscription badge.", true);
|
||||||
|
SignalStore.donationsValues().setExpiredBadge(null);
|
||||||
|
} else if (badge != null && badge.isBoost() && remoteHasBoostBadges) {
|
||||||
|
Log.d(TAG, "Remote has boost badges. Clearing local expired boost badge.", true);
|
||||||
|
SignalStore.donationsValues().setExpiredBadge(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!remoteHasGiftBadges && localHasGiftBadges) {
|
if (!remoteHasGiftBadges && localHasGiftBadges) {
|
||||||
|
@ -333,6 +347,9 @@ public class RefreshOwnProfileJob extends BaseJob {
|
||||||
|
|
||||||
Log.d(TAG, "Marking gift badge as expired, should notify next time the manage donations screen is open.", true);
|
Log.d(TAG, "Marking gift badge as expired, should notify next time the manage donations screen is open.", true);
|
||||||
SignalStore.donationsValues().setExpiredGiftBadge(mostRecentExpiration);
|
SignalStore.donationsValues().setExpiredGiftBadge(mostRecentExpiration);
|
||||||
|
} else if (remoteHasGiftBadges) {
|
||||||
|
Log.d(TAG, "We have remote gift badges. Clearing local expired gift badge.", true);
|
||||||
|
SignalStore.donationsValues().setExpiredGiftBadge(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean userHasVisibleBadges = badges.stream().anyMatch(SignalServiceProfile.Badge::isVisible);
|
boolean userHasVisibleBadges = badges.stream().anyMatch(SignalServiceProfile.Badge::isVisible);
|
||||||
|
|
|
@ -29,15 +29,19 @@ public class SubscriptionKeepAliveJob extends BaseJob {
|
||||||
private static final String TAG = Log.tag(SubscriptionKeepAliveJob.class);
|
private static final String TAG = Log.tag(SubscriptionKeepAliveJob.class);
|
||||||
private static final long JOB_TIMEOUT = TimeUnit.DAYS.toMillis(3);
|
private static final long JOB_TIMEOUT = TimeUnit.DAYS.toMillis(3);
|
||||||
|
|
||||||
public static void launchSubscriberIdKeepAliveJobIfNecessary() {
|
public static void enqueueAndTrackTimeIfNecessary() {
|
||||||
long nextLaunchTime = SignalStore.donationsValues().getLastKeepAliveLaunchTime() + TimeUnit.DAYS.toMillis(3);
|
long nextLaunchTime = SignalStore.donationsValues().getLastKeepAliveLaunchTime() + TimeUnit.DAYS.toMillis(3);
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
|
||||||
if (nextLaunchTime <= now) {
|
if (nextLaunchTime <= now) {
|
||||||
|
enqueueAndTrackTime(now);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void enqueueAndTrackTime(long now) {
|
||||||
ApplicationDependencies.getJobManager().add(new SubscriptionKeepAliveJob());
|
ApplicationDependencies.getJobManager().add(new SubscriptionKeepAliveJob());
|
||||||
SignalStore.donationsValues().setLastKeepAliveLaunchTime(now);
|
SignalStore.donationsValues().setLastKeepAliveLaunchTime(now);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private SubscriptionKeepAliveJob() {
|
private SubscriptionKeepAliveJob() {
|
||||||
this(new Parameters.Builder()
|
this(new Parameters.Builder()
|
||||||
|
@ -70,6 +74,12 @@ public class SubscriptionKeepAliveJob extends BaseJob {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onRun() throws Exception {
|
protected void onRun() throws Exception {
|
||||||
|
synchronized (SubscriptionReceiptRequestResponseJob.MUTEX) {
|
||||||
|
doRun();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doRun() throws Exception {
|
||||||
Subscriber subscriber = SignalStore.donationsValues().getSubscriber();
|
Subscriber subscriber = SignalStore.donationsValues().getSubscriber();
|
||||||
if (subscriber == null) {
|
if (subscriber == null) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.thoughtcrime.securesms.keyvalue
|
package org.thoughtcrime.securesms.keyvalue
|
||||||
|
|
||||||
|
import androidx.annotation.WorkerThread
|
||||||
import io.reactivex.rxjava3.core.Observable
|
import io.reactivex.rxjava3.core.Observable
|
||||||
import io.reactivex.rxjava3.subjects.BehaviorSubject
|
import io.reactivex.rxjava3.subjects.BehaviorSubject
|
||||||
import io.reactivex.rxjava3.subjects.Subject
|
import io.reactivex.rxjava3.subjects.Subject
|
||||||
|
@ -8,6 +9,7 @@ import org.signal.donations.StripeApi
|
||||||
import org.thoughtcrime.securesms.badges.Badges
|
import org.thoughtcrime.securesms.badges.Badges
|
||||||
import org.thoughtcrime.securesms.badges.models.Badge
|
import org.thoughtcrime.securesms.badges.models.Badge
|
||||||
import org.thoughtcrime.securesms.database.model.databaseprotos.BadgeList
|
import org.thoughtcrime.securesms.database.model.databaseprotos.BadgeList
|
||||||
|
import org.thoughtcrime.securesms.jobs.SubscriptionReceiptRequestResponseJob
|
||||||
import org.thoughtcrime.securesms.payments.currency.CurrencyUtil
|
import org.thoughtcrime.securesms.payments.currency.CurrencyUtil
|
||||||
import org.thoughtcrime.securesms.subscription.LevelUpdateOperation
|
import org.thoughtcrime.securesms.subscription.LevelUpdateOperation
|
||||||
import org.thoughtcrime.securesms.subscription.Subscriber
|
import org.thoughtcrime.securesms.subscription.Subscriber
|
||||||
|
@ -287,4 +289,63 @@ internal class DonationsValues internal constructor(store: KeyValueStore) : Sign
|
||||||
var shouldCancelSubscriptionBeforeNextSubscribeAttempt: Boolean
|
var shouldCancelSubscriptionBeforeNextSubscribeAttempt: Boolean
|
||||||
get() = getBoolean(SHOULD_CANCEL_SUBSCRIPTION_BEFORE_NEXT_SUBSCRIBE_ATTEMPT, false)
|
get() = getBoolean(SHOULD_CANCEL_SUBSCRIPTION_BEFORE_NEXT_SUBSCRIBE_ATTEMPT, false)
|
||||||
set(value) = putBoolean(SHOULD_CANCEL_SUBSCRIPTION_BEFORE_NEXT_SUBSCRIBE_ATTEMPT, value)
|
set(value) = putBoolean(SHOULD_CANCEL_SUBSCRIPTION_BEFORE_NEXT_SUBSCRIBE_ATTEMPT, value)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consolidates a bunch of data clears that should occur whenever a user manually cancels their
|
||||||
|
* subscription:
|
||||||
|
*
|
||||||
|
* 1. Clears keep-alive flag
|
||||||
|
* 1. Clears level operation
|
||||||
|
* 1. Marks the user as manually cancelled
|
||||||
|
* 1. Clears out unexpected cancelation state
|
||||||
|
* 1. Clears expired badge if it is for a subscription
|
||||||
|
*/
|
||||||
|
@WorkerThread
|
||||||
|
fun updateLocalStateForManualCancellation() {
|
||||||
|
synchronized(SubscriptionReceiptRequestResponseJob.MUTEX) {
|
||||||
|
Log.d(TAG, "[updateLocalStateForManualCancellation] Clearing donation values.")
|
||||||
|
|
||||||
|
setLastEndOfPeriod(0L)
|
||||||
|
clearLevelOperations()
|
||||||
|
markUserManuallyCancelled()
|
||||||
|
shouldCancelSubscriptionBeforeNextSubscribeAttempt = false
|
||||||
|
setUnexpectedSubscriptionCancelationChargeFailure(null)
|
||||||
|
unexpectedSubscriptionCancelationReason = null
|
||||||
|
unexpectedSubscriptionCancelationTimestamp = 0L
|
||||||
|
|
||||||
|
val expiredBadge = getExpiredBadge()
|
||||||
|
if (expiredBadge != null && expiredBadge.isSubscription()) {
|
||||||
|
Log.d(TAG, "[updateLocalStateForManualCancellation] Clearing expired badge.")
|
||||||
|
setExpiredBadge(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consolidates a bunch of data clears that should occur whenever a user begins a new subscription:
|
||||||
|
*
|
||||||
|
* 1. Manual cancellation marker
|
||||||
|
* 1. Any set level operations
|
||||||
|
* 1. Unexpected cancelation flags
|
||||||
|
* 1. Expired badge, if it is of a subscription
|
||||||
|
*/
|
||||||
|
@WorkerThread
|
||||||
|
fun updateLocalStateForLocalSubscribe() {
|
||||||
|
synchronized(SubscriptionReceiptRequestResponseJob.MUTEX) {
|
||||||
|
Log.d(TAG, "[updateLocalStateForLocalSubscribe] Clearing donation values.")
|
||||||
|
|
||||||
|
clearUserManuallyCancelled()
|
||||||
|
clearLevelOperations()
|
||||||
|
shouldCancelSubscriptionBeforeNextSubscribeAttempt = false
|
||||||
|
setUnexpectedSubscriptionCancelationChargeFailure(null)
|
||||||
|
unexpectedSubscriptionCancelationReason = null
|
||||||
|
unexpectedSubscriptionCancelationTimestamp = 0L
|
||||||
|
|
||||||
|
val expiredBadge = getExpiredBadge()
|
||||||
|
if (expiredBadge != null && expiredBadge.isSubscription()) {
|
||||||
|
Log.d(TAG, "[updateLocalStateForLocalSubscribe] Clearing expired badge.")
|
||||||
|
setExpiredBadge(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import androidx.annotation.VisibleForTesting;
|
||||||
import com.annimon.stream.Collectors;
|
import com.annimon.stream.Collectors;
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
|
|
||||||
|
import org.signal.core.util.SetUtil;
|
||||||
import org.signal.core.util.logging.Log;
|
import org.signal.core.util.logging.Log;
|
||||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||||
|
@ -22,7 +23,6 @@ import org.thoughtcrime.securesms.payments.Entropy;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.subscription.Subscriber;
|
import org.thoughtcrime.securesms.subscription.Subscriber;
|
||||||
import org.thoughtcrime.securesms.util.Base64;
|
import org.thoughtcrime.securesms.util.Base64;
|
||||||
import org.signal.core.util.SetUtil;
|
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.whispersystems.signalservice.api.storage.SignalAccountRecord;
|
import org.whispersystems.signalservice.api.storage.SignalAccountRecord;
|
||||||
|
@ -160,9 +160,7 @@ public final class StorageSyncHelper {
|
||||||
SignalStore.donationsValues().setDisplayBadgesOnProfile(update.getNew().isDisplayBadgesOnProfile());
|
SignalStore.donationsValues().setDisplayBadgesOnProfile(update.getNew().isDisplayBadgesOnProfile());
|
||||||
|
|
||||||
if (update.getNew().isSubscriptionManuallyCancelled()) {
|
if (update.getNew().isSubscriptionManuallyCancelled()) {
|
||||||
SignalStore.donationsValues().markUserManuallyCancelled();
|
SignalStore.donationsValues().updateLocalStateForManualCancellation();
|
||||||
SignalStore.donationsValues().setUnexpectedSubscriptionCancelationReason(null);
|
|
||||||
SignalStore.donationsValues().setUnexpectedSubscriptionCancelationTimestamp(0L);
|
|
||||||
} else {
|
} else {
|
||||||
SignalStore.donationsValues().clearUserManuallyCancelled();
|
SignalStore.donationsValues().clearUserManuallyCancelled();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2738,6 +2738,7 @@
|
||||||
<string name="preferences__internal_calling_disable_telecom" translatable="false">Disable Telecom integration</string>
|
<string name="preferences__internal_calling_disable_telecom" translatable="false">Disable Telecom integration</string>
|
||||||
<string name="preferences__internal_badges" translatable="false">Badges</string>
|
<string name="preferences__internal_badges" translatable="false">Badges</string>
|
||||||
<string name="preferences__internal_badges_enqueue_redemption" translatable="false">Enqueue redemption.</string>
|
<string name="preferences__internal_badges_enqueue_redemption" translatable="false">Enqueue redemption.</string>
|
||||||
|
<string name="preferences__internal_badges_enqueue_keep_alive" translatable="false">Enqueue keep-alive.</string>
|
||||||
<string name="preferences__internal_release_channel" translatable="false">Release channel</string>
|
<string name="preferences__internal_release_channel" translatable="false">Release channel</string>
|
||||||
<string name="preferences__internal_fetch_release_channel" translatable="false">Fetch release channel</string>
|
<string name="preferences__internal_fetch_release_channel" translatable="false">Fetch release channel</string>
|
||||||
<string name="preferences__internal_release_channel_set_last_version" translatable="false">Set last version seen back 10 versions</string>
|
<string name="preferences__internal_release_channel_set_last_version" translatable="false">Set last version seen back 10 versions</string>
|
||||||
|
|
Loading…
Add table
Reference in a new issue