Fix billing bugs

This commit is contained in:
max-klaus 2021-03-06 14:22:22 +03:00
parent 8c029663b7
commit 136542f0dd
4 changed files with 41 additions and 24 deletions

View file

@ -6,6 +6,7 @@ import android.content.Intent;
import android.net.Uri;
import android.widget.Toast;
import com.android.billingclient.api.AccountIdentifiers;
import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.Purchase;
@ -76,6 +77,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
return billingManager;
}
@Override
protected void execImpl(@NonNull final InAppPurchaseTaskType taskType, @NonNull final InAppCommand runnable) {
billingManager = new BillingManager(ctx, BASE64_ENCODED_PUBLIC_KEY, new BillingManager.BillingUpdatesListener() {
@ -125,7 +127,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
}
billingManager.querySkuDetailsAsync(BillingClient.SkuType.INAPP, skuInApps, new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(BillingResult billingResult, final List<SkuDetails> skuDetailsListInApps) {
public void onSkuDetailsResponse(@NonNull BillingResult billingResult, final List<SkuDetails> skuDetailsListInApps) {
// Is it a failure?
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
logError("Failed to query inapps sku details: " + billingResult.getResponseCode());
@ -152,7 +154,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
billingManager.querySkuDetailsAsync(BillingClient.SkuType.SUBS, skuSubscriptions, new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(BillingResult billingResult, final List<SkuDetails> skuDetailsListSubscriptions) {
public void onSkuDetailsResponse(@NonNull BillingResult billingResult, final List<SkuDetails> skuDetailsListSubscriptions) {
// Is it a failure?
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
logError("Failed to query subscriptipons sku details: " + billingResult.getResponseCode());
@ -321,7 +323,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
}
@Override
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> skuDetailsList) {
public void onSkuDetailsResponse(@NonNull BillingResult billingResult, List<SkuDetails> skuDetailsList) {
logDebug("Query sku details finished.");
@ -442,8 +444,8 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
if (liveUpdatesPurchases.size() > 0) {
List<String> tokensSent = Arrays.asList(settings.BILLING_PURCHASE_TOKENS_SENT.get().split(";"));
for (Purchase purchase : liveUpdatesPurchases) {
if (needRestoreUserInfo(settings)) {
restoreUserInfo(settings, purchase);
if (needRestoreUserInfo()) {
restoreUserInfo(purchase);
}
if (!tokensSent.contains(purchase.getSku())) {
tokensToSend.add(purchase);
@ -458,29 +460,34 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
}
};
private void restoreUserInfo(OsmandSettings settings, Purchase purchase) {
boolean restored = restoreUserInfoFromString(settings, purchase.getDeveloperPayload());
private void restoreUserInfo(Purchase purchase) {
boolean restored = restoreUserInfoFromString(purchase.getDeveloperPayload());
if (!restored) {
restoreUserInfoFromString(settings, purchase.getAccountIdentifiers().getObfuscatedAccountId());
AccountIdentifiers accountIdentifiers = purchase.getAccountIdentifiers();
if (accountIdentifiers != null) {
restoreUserInfoFromString(accountIdentifiers.getObfuscatedAccountId());
}
}
}
private boolean restoreUserInfoFromString(OsmandSettings settings, String userInfo) {
private boolean restoreUserInfoFromString(String userInfo) {
if (Algorithms.isEmpty(userInfo)) {
return false;
}
OsmandSettings settings = ctx.getSettings();
String[] arr = userInfo.split(" ");
if (arr.length > 0 && !Algorithms.isEmpty(settings.BILLING_USER_ID.get())) {
if (arr.length > 0) {
settings.BILLING_USER_ID.set(arr[0]);
}
if (arr.length > 1 && !Algorithms.isEmpty(settings.BILLING_USER_TOKEN.get())) {
if (arr.length > 1) {
token = arr[1];
settings.BILLING_USER_TOKEN.set(token);
}
return needRestoreUserInfo(settings);
return needRestoreUserInfo();
}
private boolean needRestoreUserInfo(OsmandSettings settings) {
private boolean needRestoreUserInfo() {
OsmandSettings settings = ctx.getSettings();
return Algorithms.isEmpty(settings.BILLING_USER_ID.get()) || Algorithms.isEmpty(settings.BILLING_USER_TOKEN.get());
}
@ -539,7 +546,8 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
}
}
protected InAppCommand getPurchaseLiveUpdatesCommand(final WeakReference<Activity> activity, final String sku) {
@Override
protected InAppCommand getPurchaseLiveUpdatesCommand(final WeakReference<Activity> activity, final String sku, final String userInfo) {
return new InAppCommand() {
@Override
public void run(InAppPurchaseHelper helper) {
@ -549,9 +557,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
if (AndroidUtils.isActivityNotDestroyed(a) && skuDetails != null) {
BillingManager billingManager = getBillingManager();
if (billingManager != null) {
OsmandSettings settings = ctx.getSettings();
String userCredential = settings.BILLING_USER_ID.get() + " " + settings.BILLING_USER_TOKEN.get();
billingManager.setObfuscatedAccountId(userCredential);
billingManager.setObfuscatedAccountId(userInfo);
billingManager.initiatePurchaseFlow(a, skuDetails);
} else {
throw new IllegalStateException("BillingManager disposed");
@ -568,6 +574,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
};
}
@Override
protected InAppCommand getRequestInventoryCommand() {
return new InAppCommand() {
@Override

View file

@ -276,7 +276,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
}
}
protected InAppCommand getPurchaseLiveUpdatesCommand(final WeakReference<Activity> activity, final String sku, final String payload) {
protected InAppCommand getPurchaseLiveUpdatesCommand(final WeakReference<Activity> activity, final String sku, final String userInfo) {
return new InAppCommand() {
@Override
public void run(InAppPurchaseHelper helper) {
@ -285,7 +285,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
ProductInfo productInfo = getProductInfo(sku);
if (AndroidUtils.isActivityNotDestroyed(a) && productInfo != null) {
IapRequestHelper.createPurchaseIntent(getIapClient(), sku,
IapClient.PriceType.IN_APP_SUBSCRIPTION, payload, new IapApiCallback<PurchaseIntentResult>() {
IapClient.PriceType.IN_APP_SUBSCRIPTION, userInfo, new IapApiCallback<PurchaseIntentResult>() {
@Override
public void onSuccess(PurchaseIntentResult result) {
if (result == null) {

View file

@ -8,6 +8,9 @@ import android.os.AsyncTask;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.AndroidNetworkUtils;
import net.osmand.AndroidNetworkUtils.OnRequestResultListener;
import net.osmand.AndroidNetworkUtils.OnRequestsResultListener;
@ -40,9 +43,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public abstract class InAppPurchaseHelper {
// Debug tag, for logging
protected static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(InAppPurchaseHelper.class);
@ -364,7 +364,8 @@ public abstract class InAppPurchaseHelper {
notifyDismissProgress(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES);
if (!Algorithms.isEmpty(userId) && !Algorithms.isEmpty(token)) {
logDebug("Launching purchase flow for live updates subscription for userId=" + userId);
exec(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, getPurchaseLiveUpdatesCommand(activity, sku));
final String userInfo = userId + " " + token;
exec(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, getPurchaseLiveUpdatesCommand(activity, sku, userInfo));
} else {
notifyError(InAppPurchaseTaskType.PURCHASE_LIVE_UPDATES, "Empty userId");
stop(true);
@ -373,7 +374,7 @@ public abstract class InAppPurchaseHelper {
}
protected abstract InAppCommand getPurchaseLiveUpdatesCommand(final WeakReference<Activity> activity,
final String sku) throws UnsupportedOperationException;
final String sku, final String userInfo) throws UnsupportedOperationException;
@SuppressLint("StaticFieldLeak")
private class RequestInventoryTask extends AsyncTask<Void, Void, String[]> {

View file

@ -58,7 +58,9 @@ public class BillingManager implements PurchasesUpdatedListener {
// Public key for verifying signature, in base64 encoding
private String mSignatureBase64;
private String mObfuscatedAccountId;
private String mObfuscatedProfileId;
private final BillingUpdatesListener mBillingUpdatesListener;
private final List<Purchase> mPurchases = new ArrayList<>();
@ -151,6 +153,9 @@ public class BillingManager implements PurchasesUpdatedListener {
if (!TextUtils.isEmpty(mObfuscatedAccountId)) {
paramsBuilder.setObfuscatedAccountId(mObfuscatedAccountId);
}
if (!TextUtils.isEmpty(mObfuscatedProfileId)) {
paramsBuilder.setObfuscatedProfileId(mObfuscatedProfileId);
}
if (oldSku != null && purchaseToken != null) {
paramsBuilder.setOldSku(oldSku, purchaseToken);
}
@ -405,6 +410,10 @@ public class BillingManager implements PurchasesUpdatedListener {
mObfuscatedAccountId = obfuscatedAccountId;
}
public void setObfuscatedProfileId(String obfuscatedProfileId) {
mObfuscatedProfileId = obfuscatedProfileId;
}
private void executeServiceRequest(Runnable runnable) {
if (mIsServiceConnected) {
runnable.run();