From 2ed39e44482026399b40e78ab92b7e86030baf7a Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Wed, 23 Feb 2022 09:00:02 -0400 Subject: [PATCH] Add subscription cancellation step during account deletion. --- .../securesms/delete/DeleteAccountEvent.kt | 6 ++++ .../delete/DeleteAccountFragment.java | 4 +++ .../delete/DeleteAccountProgressDialog.kt | 7 ++++ .../delete/DeleteAccountRepository.java | 33 +++++++++++++++++++ app/src/main/res/values/strings.xml | 2 ++ 5 files changed, 52 insertions(+) diff --git a/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountEvent.kt b/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountEvent.kt index 4f641a3f4..df36a6a19 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountEvent.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountEvent.kt @@ -17,6 +17,8 @@ sealed class DeleteAccountEvent(val type: Type) { object PinDeletionFailed : DeleteAccountEvent(Type.PIN_DELETION_FAILED) + object CancelSubscriptionFailed : DeleteAccountEvent(Type.CANCEL_SUBSCRIPTION_FAILED) + object LeaveGroupsFailed : DeleteAccountEvent(Type.LEAVE_GROUPS_FAILED) object ServerDeletionFailed : DeleteAccountEvent(Type.SERVER_DELETION_FAILED) @@ -25,6 +27,8 @@ sealed class DeleteAccountEvent(val type: Type) { object LeaveGroupsFinished : DeleteAccountEvent(Type.LEAVE_GROUPS_FINISHED) + object CancelingSubscription : DeleteAccountEvent(Type.CANCELING_SUBSCRIPTION) + /** * Progress update for leaving groups * @@ -43,6 +47,8 @@ sealed class DeleteAccountEvent(val type: Type) { CONFIRM_DELETION, LEAVE_GROUPS_FAILED, PIN_DELETION_FAILED, + CANCELING_SUBSCRIPTION, + CANCEL_SUBSCRIPTION_FAILED, SERVER_DELETION_FAILED, LOCAL_DATA_DELETION_FAILED, LEAVE_GROUPS_PROGRESS, diff --git a/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountFragment.java b/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountFragment.java index adac67135..213563dd1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountFragment.java @@ -246,6 +246,7 @@ public class DeleteAccountFragment extends Fragment { case LEAVE_GROUPS_FAILED: case PIN_DELETION_FAILED: case SERVER_DELETION_FAILED: + case CANCEL_SUBSCRIPTION_FAILED: dismissDeletionProgressDialog(); showNetworkDeletionFailedDialog(); break; @@ -260,6 +261,9 @@ public class DeleteAccountFragment extends Fragment { case LEAVE_GROUPS_FINISHED: ensureDeletionProgressDialog(); deletionProgressDialog.presentDeletingAccount(); + case CANCELING_SUBSCRIPTION: + ensureDeletionProgressDialog(); + deletionProgressDialog.presentCancelingSubscription(); break; default: throw new IllegalStateException("Unknown error type: " + deleteAccountEvent); diff --git a/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountProgressDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountProgressDialog.kt index ffb8729b9..0fc5b39a2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountProgressDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountProgressDialog.kt @@ -19,9 +19,16 @@ class DeleteAccountProgressDialog private constructor(private val alertDialog: A val message: TextView = alertDialog.findViewById(R.id.delete_account_progress_dialog_message)!! val progressBar: ProgressBar = alertDialog.findViewById(R.id.delete_account_progress_dialog_spinner)!! + fun presentCancelingSubscription() { + title.setText(R.string.DeleteAccountFragment__deleting_account) + message.setText(R.string.DeleteAccountFragment__canceling_your_subscription) + progressBar.isIndeterminate = true + } + fun presentLeavingGroups(leaveGroupsProgress: DeleteAccountEvent.LeaveGroupsProgress) { title.setText(R.string.DeleteAccountFragment__leaving_groups) message.setText(R.string.DeleteAccountFragment__depending_on_the_number_of_groups) + progressBar.isIndeterminate = false progressBar.max = leaveGroupsProgress.totalCount progressBar.progress = leaveGroupsProgress.leaveCount } diff --git a/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountRepository.java b/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountRepository.java index 3617b6d91..1b1e5af76 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/delete/DeleteAccountRepository.java @@ -12,9 +12,13 @@ import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.SignalDatabase; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.groups.GroupManager; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.pin.KbsEnclaves; +import org.thoughtcrime.securesms.subscription.Subscriber; import org.thoughtcrime.securesms.util.ServiceUtil; import org.whispersystems.signalservice.api.util.PhoneNumberFormatter; +import org.whispersystems.signalservice.internal.EmptyResponse; +import org.whispersystems.signalservice.internal.ServiceResponse; import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException; import java.io.IOException; @@ -42,6 +46,35 @@ class DeleteAccountRepository { void deleteAccount(@NonNull Consumer onDeleteAccountEvent) { SignalExecutors.BOUNDED.execute(() -> { + if (SignalStore.donationsValues().getSubscriber() != null) { + Log.i(TAG, "deleteAccount: attempting to cancel subscription"); + onDeleteAccountEvent.accept(DeleteAccountEvent.CancelingSubscription.INSTANCE); + + Subscriber subscriber = SignalStore.donationsValues().requireSubscriber(); + ServiceResponse cancelSubscriptionResponse = ApplicationDependencies.getDonationsService() + .cancelSubscription(subscriber.getSubscriberId()) + .blockingGet(); + + if (cancelSubscriptionResponse.getExecutionError().isPresent()) { + Log.w(TAG, "deleteAccount: failed attempt to cancel subscription"); + onDeleteAccountEvent.accept(DeleteAccountEvent.CancelSubscriptionFailed.INSTANCE); + return; + } + + switch (cancelSubscriptionResponse.getStatus()) { + case 404: + Log.i(TAG, "deleteAccount: subscription does not exist. Continuing deletion..."); + break; + case 200: + Log.i(TAG, "deleteAccount: successfully cancelled subscription. Continuing deletion..."); + break; + default: + Log.w(TAG, "deleteAccount: an unexpected error occurred. " + cancelSubscriptionResponse.getStatus()); + onDeleteAccountEvent.accept(DeleteAccountEvent.CancelSubscriptionFailed.INSTANCE); + return; + } + } + Log.i(TAG, "deleteAccount: attempting to leave groups..."); int groupsLeft = 0; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 70014fca0..93e61b927 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3442,6 +3442,8 @@ Leaving groups… Deleting account… + + Canceling your subscription… Depending on the number of groups you\'re in, this might take a few minutes