kopia lustrzana https://github.com/ryukoposting/Signal-Android
Prevent KeepAlive Job from alerting user on 409 error.
rodzic
46dd7f8a06
commit
fde1e5ab77
|
@ -28,6 +28,7 @@ public class DonationReceiptRedemptionJob extends BaseJob {
|
||||||
public static final String KEY = "DonationReceiptRedemptionJob";
|
public static final String KEY = "DonationReceiptRedemptionJob";
|
||||||
public static final String INPUT_RECEIPT_CREDENTIAL_PRESENTATION = "data.receipt.credential.presentation";
|
public static final String INPUT_RECEIPT_CREDENTIAL_PRESENTATION = "data.receipt.credential.presentation";
|
||||||
public static final String INPUT_PAYMENT_FAILURE = "data.payment.failure";
|
public static final String INPUT_PAYMENT_FAILURE = "data.payment.failure";
|
||||||
|
public static final String INPUT_KEEP_ALIVE_409 = "data.keep.alive.409";
|
||||||
|
|
||||||
public static DonationReceiptRedemptionJob createJobForSubscription() {
|
public static DonationReceiptRedemptionJob createJobForSubscription() {
|
||||||
return new DonationReceiptRedemptionJob(
|
return new DonationReceiptRedemptionJob(
|
||||||
|
@ -72,6 +73,9 @@ public class DonationReceiptRedemptionJob extends BaseJob {
|
||||||
|
|
||||||
if (inputData != null && inputData.getBooleanOrDefault(INPUT_PAYMENT_FAILURE, false)) {
|
if (inputData != null && inputData.getBooleanOrDefault(INPUT_PAYMENT_FAILURE, false)) {
|
||||||
DonorBadgeNotifications.PaymentFailed.INSTANCE.show(context);
|
DonorBadgeNotifications.PaymentFailed.INSTANCE.show(context);
|
||||||
|
} else if (inputData != null && inputData.getBooleanOrDefault(INPUT_KEEP_ALIVE_409, false)) {
|
||||||
|
Log.i(TAG, "Skipping redemption due to 409 error during keep-alive.");
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
DonorBadgeNotifications.RedemptionFailed.INSTANCE.show(context);
|
DonorBadgeNotifications.RedemptionFailed.INSTANCE.show(context);
|
||||||
}
|
}
|
||||||
|
@ -79,6 +83,7 @@ public class DonationReceiptRedemptionJob extends BaseJob {
|
||||||
if (isForSubscription()) {
|
if (isForSubscription()) {
|
||||||
Log.d(TAG, "Marking subscription failure", true);
|
Log.d(TAG, "Marking subscription failure", true);
|
||||||
SignalStore.donationsValues().markSubscriptionRedemptionFailed();
|
SignalStore.donationsValues().markSubscriptionRedemptionFailed();
|
||||||
|
MultiDeviceSubscriptionSyncRequestJob.enqueue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.whispersystems.signalservice.internal.EmptyResponse;
|
||||||
import org.whispersystems.signalservice.internal.ServiceResponse;
|
import org.whispersystems.signalservice.internal.ServiceResponse;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,8 +96,14 @@ public class SubscriptionKeepAliveJob extends BaseJob {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeSubscription.getActiveSubscription().getEndOfCurrentPeriod() > SignalStore.donationsValues().getLastEndOfPeriod()) {
|
if (activeSubscription.getActiveSubscription().getEndOfCurrentPeriod() > SignalStore.donationsValues().getLastEndOfPeriod()) {
|
||||||
Log.i(TAG, "Last end of period change. Requesting receipt refresh.", true);
|
Log.i(TAG,
|
||||||
SubscriptionReceiptRequestResponseJob.createSubscriptionContinuationJobChain().enqueue();
|
String.format(Locale.US,
|
||||||
|
"Last end of period change. Requesting receipt refresh. (old: %d to new: %d)",
|
||||||
|
SignalStore.donationsValues().getLastEndOfPeriod(),
|
||||||
|
activeSubscription.getActiveSubscription().getEndOfCurrentPeriod()),
|
||||||
|
true);
|
||||||
|
|
||||||
|
SubscriptionReceiptRequestResponseJob.createSubscriptionContinuationJobChain(true).enqueue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,16 +39,18 @@ public class SubscriptionReceiptRequestResponseJob extends BaseJob {
|
||||||
|
|
||||||
public static final String KEY = "SubscriptionReceiptCredentialsSubmissionJob";
|
public static final String KEY = "SubscriptionReceiptCredentialsSubmissionJob";
|
||||||
|
|
||||||
private static final String DATA_REQUEST_BYTES = "data.request.bytes";
|
private static final String DATA_REQUEST_BYTES = "data.request.bytes";
|
||||||
private static final String DATA_SUBSCRIBER_ID = "data.subscriber.id";
|
private static final String DATA_SUBSCRIBER_ID = "data.subscriber.id";
|
||||||
|
private static final String DATA_IS_FOR_KEEP_ALIVE = "data.is.for.keep.alive";
|
||||||
|
|
||||||
public static final Object MUTEX = new Object();
|
public static final Object MUTEX = new Object();
|
||||||
|
|
||||||
private ReceiptCredentialRequestContext requestContext;
|
private ReceiptCredentialRequestContext requestContext;
|
||||||
|
|
||||||
private final SubscriberId subscriberId;
|
private final SubscriberId subscriberId;
|
||||||
|
private final boolean isForKeepAlive;
|
||||||
|
|
||||||
static SubscriptionReceiptRequestResponseJob createJob(SubscriberId subscriberId) {
|
private static SubscriptionReceiptRequestResponseJob createJob(SubscriberId subscriberId, boolean isForKeepAlive) {
|
||||||
return new SubscriptionReceiptRequestResponseJob(
|
return new SubscriptionReceiptRequestResponseJob(
|
||||||
new Parameters
|
new Parameters
|
||||||
.Builder()
|
.Builder()
|
||||||
|
@ -59,13 +61,18 @@ public class SubscriptionReceiptRequestResponseJob extends BaseJob {
|
||||||
.setMaxAttempts(Parameters.UNLIMITED)
|
.setMaxAttempts(Parameters.UNLIMITED)
|
||||||
.build(),
|
.build(),
|
||||||
null,
|
null,
|
||||||
subscriberId
|
subscriberId,
|
||||||
|
isForKeepAlive
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JobManager.Chain createSubscriptionContinuationJobChain() {
|
public static JobManager.Chain createSubscriptionContinuationJobChain() {
|
||||||
|
return createSubscriptionContinuationJobChain(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JobManager.Chain createSubscriptionContinuationJobChain(boolean isForKeepAlive) {
|
||||||
Subscriber subscriber = SignalStore.donationsValues().requireSubscriber();
|
Subscriber subscriber = SignalStore.donationsValues().requireSubscriber();
|
||||||
SubscriptionReceiptRequestResponseJob requestReceiptJob = createJob(subscriber.getSubscriberId());
|
SubscriptionReceiptRequestResponseJob requestReceiptJob = createJob(subscriber.getSubscriberId(), isForKeepAlive);
|
||||||
DonationReceiptRedemptionJob redeemReceiptJob = DonationReceiptRedemptionJob.createJobForSubscription();
|
DonationReceiptRedemptionJob redeemReceiptJob = DonationReceiptRedemptionJob.createJobForSubscription();
|
||||||
RefreshOwnProfileJob refreshOwnProfileJob = RefreshOwnProfileJob.forSubscription();
|
RefreshOwnProfileJob refreshOwnProfileJob = RefreshOwnProfileJob.forSubscription();
|
||||||
|
|
||||||
|
@ -77,16 +84,19 @@ public class SubscriptionReceiptRequestResponseJob extends BaseJob {
|
||||||
|
|
||||||
private SubscriptionReceiptRequestResponseJob(@NonNull Parameters parameters,
|
private SubscriptionReceiptRequestResponseJob(@NonNull Parameters parameters,
|
||||||
@Nullable ReceiptCredentialRequestContext requestContext,
|
@Nullable ReceiptCredentialRequestContext requestContext,
|
||||||
@NonNull SubscriberId subscriberId)
|
@NonNull SubscriberId subscriberId,
|
||||||
|
boolean isForKeepAlive)
|
||||||
{
|
{
|
||||||
super(parameters);
|
super(parameters);
|
||||||
this.requestContext = requestContext;
|
this.requestContext = requestContext;
|
||||||
this.subscriberId = subscriberId;
|
this.subscriberId = subscriberId;
|
||||||
|
this.isForKeepAlive = isForKeepAlive;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull Data serialize() {
|
public @NonNull Data serialize() {
|
||||||
Data.Builder builder = new Data.Builder().putBlobAsString(DATA_SUBSCRIBER_ID, subscriberId.getBytes());
|
Data.Builder builder = new Data.Builder().putBlobAsString(DATA_SUBSCRIBER_ID, subscriberId.getBytes())
|
||||||
|
.putBoolean(DATA_IS_FOR_KEEP_ALIVE, isForKeepAlive);
|
||||||
|
|
||||||
if (requestContext != null) {
|
if (requestContext != null) {
|
||||||
builder.putBlobAsString(DATA_REQUEST_BYTES, requestContext.serialize());
|
builder.putBlobAsString(DATA_REQUEST_BYTES, requestContext.serialize());
|
||||||
|
@ -102,9 +112,6 @@ public class SubscriptionReceiptRequestResponseJob extends BaseJob {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure() {
|
public void onFailure() {
|
||||||
DonorBadgeNotifications.RedemptionFailed.INSTANCE.show(context);
|
|
||||||
SignalStore.donationsValues().markSubscriptionRedemptionFailed();
|
|
||||||
MultiDeviceSubscriptionSyncRequestJob.enqueue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -231,8 +238,8 @@ public class SubscriptionReceiptRequestResponseJob extends BaseJob {
|
||||||
Log.w(TAG, "SubscriberId not found or misformed.", response.getApplicationError().get(), true);
|
Log.w(TAG, "SubscriberId not found or misformed.", response.getApplicationError().get(), true);
|
||||||
throw new Exception(response.getApplicationError().get());
|
throw new Exception(response.getApplicationError().get());
|
||||||
case 409:
|
case 409:
|
||||||
Log.w(TAG, "Latest paid receipt on subscription already redeemed with a different request credential.", response.getApplicationError().get(), true);
|
onAlreadyRedeemed(response);
|
||||||
throw new Exception(response.getApplicationError().get());
|
break;
|
||||||
default:
|
default:
|
||||||
Log.w(TAG, "Encountered a server failure response: " + response.getStatus(), response.getApplicationError().get(), true);
|
Log.w(TAG, "Encountered a server failure response: " + response.getStatus(), response.getApplicationError().get(), true);
|
||||||
throw new RetryableException();
|
throw new RetryableException();
|
||||||
|
@ -245,6 +252,16 @@ public class SubscriptionReceiptRequestResponseJob extends BaseJob {
|
||||||
MultiDeviceSubscriptionSyncRequestJob.enqueue();
|
MultiDeviceSubscriptionSyncRequestJob.enqueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onAlreadyRedeemed(ServiceResponse<ReceiptCredentialResponse> response) throws Exception {
|
||||||
|
if (isForKeepAlive) {
|
||||||
|
Log.i(TAG, "KeepAlive: Latest paid receipt on subscription already redeemed with a different request credential, ignoring.", response.getApplicationError().get(), true);
|
||||||
|
setOutputData(new Data.Builder().putBoolean(DonationReceiptRedemptionJob.INPUT_KEEP_ALIVE_409, true).build());
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "Latest paid receipt on subscription already redeemed with a different request credential.", response.getApplicationError().get(), true);
|
||||||
|
throw new Exception(response.getApplicationError().get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks that the generated Receipt Credential has the following characteristics
|
* Checks that the generated Receipt Credential has the following characteristics
|
||||||
* - level should match the current subscription level and be the same level you signed up for at the time the subscription was last updated
|
* - level should match the current subscription level and be the same level you signed up for at the time the subscription was last updated
|
||||||
|
@ -282,16 +299,17 @@ public class SubscriptionReceiptRequestResponseJob extends BaseJob {
|
||||||
public static class Factory implements Job.Factory<SubscriptionReceiptRequestResponseJob> {
|
public static class Factory implements Job.Factory<SubscriptionReceiptRequestResponseJob> {
|
||||||
@Override
|
@Override
|
||||||
public @NonNull SubscriptionReceiptRequestResponseJob create(@NonNull Parameters parameters, @NonNull Data data) {
|
public @NonNull SubscriptionReceiptRequestResponseJob create(@NonNull Parameters parameters, @NonNull Data data) {
|
||||||
SubscriberId subscriberId = SubscriberId.fromBytes(data.getStringAsBlob(DATA_SUBSCRIBER_ID));
|
SubscriberId subscriberId = SubscriberId.fromBytes(data.getStringAsBlob(DATA_SUBSCRIBER_ID));
|
||||||
|
boolean isForKeepAlive = data.getBooleanOrDefault(DATA_IS_FOR_KEEP_ALIVE, false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (data.hasString(DATA_REQUEST_BYTES)) {
|
if (data.hasString(DATA_REQUEST_BYTES)) {
|
||||||
byte[] blob = data.getStringAsBlob(DATA_REQUEST_BYTES);
|
byte[] blob = data.getStringAsBlob(DATA_REQUEST_BYTES);
|
||||||
ReceiptCredentialRequestContext requestContext = new ReceiptCredentialRequestContext(blob);
|
ReceiptCredentialRequestContext requestContext = new ReceiptCredentialRequestContext(blob);
|
||||||
|
|
||||||
return new SubscriptionReceiptRequestResponseJob(parameters, requestContext, subscriberId);
|
return new SubscriptionReceiptRequestResponseJob(parameters, requestContext, subscriberId, isForKeepAlive);
|
||||||
} else {
|
} else {
|
||||||
return new SubscriptionReceiptRequestResponseJob(parameters, null, subscriberId);
|
return new SubscriptionReceiptRequestResponseJob(parameters, null, subscriberId, isForKeepAlive);
|
||||||
}
|
}
|
||||||
} catch (InvalidInputException e) {
|
} catch (InvalidInputException e) {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
|
|
Ładowanie…
Reference in New Issue