From 224daaf17b81f519743c60cec0d8cb1a136ddbb1 Mon Sep 17 00:00:00 2001 From: Sayed Date: Mon, 19 Jun 2023 11:52:10 +0100 Subject: [PATCH] Add basic API replacements to V5 migration --- .../digitalgoods/BillingResultMerger.java | 5 +- .../digitalgoods/ConnectedBillingWrapper.java | 31 ++--- .../digitalgoods/GetDetailsCall.java | 18 +-- .../playbilling/digitalgoods/ItemDetails.java | 37 +++--- .../playbilling/provider/BillingWrapper.java | 25 ++-- .../provider/MockBillingWrapper.java | 81 ++++++------ .../playbilling/provider/PaymentActivity.java | 22 ++-- .../provider/PlayBillingWrapper.java | 121 +++++++++++------- 8 files changed, 188 insertions(+), 152 deletions(-) diff --git a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/BillingResultMerger.java b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/BillingResultMerger.java index 464d55e6..b0f02a46 100644 --- a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/BillingResultMerger.java +++ b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/BillingResultMerger.java @@ -15,6 +15,7 @@ package com.google.androidbrowserhelper.playbilling.digitalgoods; import com.android.billingclient.api.BillingClient; +import com.android.billingclient.api.BillingClient.ProductType; import com.android.billingclient.api.BillingClient.SkuType; import com.android.billingclient.api.BillingResult; @@ -26,8 +27,8 @@ /** * Play Billing SKUs are split into purchases and subscriptions. This isn't a distinction that * exists in the Digital Goods API, but since SKU ids are unique across both product types, we can - * just call methods that take a skuType twice, once with {@link SkuType#INAPP} and once with - * {@link SkuType#SUBS}. This class exists to combine the results of those calls. + * just call methods that take a ProductType twice, once with {@link ProductType#INAPP} and once with + * {@link ProductType#SUBS}. This class exists to combine the results of those calls. * * Although the Play Billing methods are asynchronous, their callbacks (which will call * {@link #setInAppResult} and {@link #setSubsResult}) should both take place on the UI thread, so diff --git a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/ConnectedBillingWrapper.java b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/ConnectedBillingWrapper.java index 84081872..be6659a4 100644 --- a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/ConnectedBillingWrapper.java +++ b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/ConnectedBillingWrapper.java @@ -21,11 +21,12 @@ import com.android.billingclient.api.BillingClientStateListener; import com.android.billingclient.api.BillingResult; import com.android.billingclient.api.ConsumeResponseListener; -import com.android.billingclient.api.PriceChangeConfirmationListener; +import com.android.billingclient.api.ProductDetails; +import com.android.billingclient.api.ProductDetailsResponseListener; import com.android.billingclient.api.PurchaseHistoryResponseListener; import com.android.billingclient.api.PurchasesResponseListener; +import com.android.billingclient.api.QueryProductDetailsParams.Product; import com.android.billingclient.api.SkuDetails; -import com.android.billingclient.api.SkuDetailsResponseListener; import com.google.androidbrowserhelper.playbilling.provider.BillingWrapper; import com.google.androidbrowserhelper.playbilling.provider.MethodData; @@ -34,7 +35,7 @@ /** * A wrapper around {@link BillingWrapper} that ensures it is connected before calling - * {@link #querySkuDetails}, {@link #acknowledge} or {@link #consume}. + * {@link #queryProductDetails}, {@link #acknowledge} or {@link #consume}. */ public class ConnectedBillingWrapper implements BillingWrapper { private final BillingWrapper mInner; @@ -90,19 +91,19 @@ public void connect(BillingClientStateListener callback) { } @Override - public void querySkuDetails(@BillingClient.SkuType String skuType, List skus, - SkuDetailsResponseListener callback) { - execute(() -> mInner.querySkuDetails(skuType, skus, callback)); + public void queryProductDetails(@BillingClient.ProductType String productType, List productsIds, + ProductDetailsResponseListener callback) { + execute(() -> mInner.queryProductDetails(productType, productsIds, callback)); } @Override - public void queryPurchases(String skuType, PurchasesResponseListener callback) { - execute(() -> mInner.queryPurchases(skuType, callback)); + public void queryPurchases(String productType, PurchasesResponseListener callback) { + execute(() -> mInner.queryPurchases(productType, callback)); } @Override - public void queryPurchaseHistory(String skuType, PurchaseHistoryResponseListener callback) { - execute(() -> mInner.queryPurchaseHistory(skuType, callback)); + public void queryPurchaseHistory(String productType, PurchaseHistoryResponseListener callback) { + execute(() -> mInner.queryPurchaseHistory(productType, callback)); } @Override @@ -116,15 +117,15 @@ public void consume(String token, ConsumeResponseListener callback) { } @Override - public boolean launchPaymentFlow(Activity activity, SkuDetails sku, MethodData data) { + public boolean launchPaymentFlow(Activity activity, ProductDetails productDetails, MethodData data) { throw new IllegalStateException( - "EnsuredConnectionBillingWrapper doesn't handle launch Payment flow"); + "EnsuredConnectionBillingWrapper doesn't handle launch Payment flow"); } @Override - public void launchPriceChangeConfirmationFlow(Activity activity, SkuDetails sku, - PriceChangeConfirmationListener listener) { + public void launchPriceChangeConfirmationFlow(Activity activity, ProductDetails productDetails, + ProductDetailsResponseListener listener) { throw new IllegalStateException("EnsuredConnectionBillingWrapper doesn't handle the " + - "price change confirmation flow"); + "price change confirmation flow"); } } diff --git a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/GetDetailsCall.java b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/GetDetailsCall.java index 95ef94a2..d7e83d32 100644 --- a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/GetDetailsCall.java +++ b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/GetDetailsCall.java @@ -18,8 +18,9 @@ import android.os.Parcelable; import com.android.billingclient.api.BillingClient; +import com.android.billingclient.api.BillingClient.ProductType; import com.android.billingclient.api.BillingResult; -import com.android.billingclient.api.SkuDetails; +import com.android.billingclient.api.ProductDetails; import com.google.androidbrowserhelper.playbilling.provider.BillingWrapper; import java.util.Arrays; @@ -27,7 +28,6 @@ import androidx.annotation.Nullable; -import static com.google.androidbrowserhelper.playbilling.digitalgoods.DigitalGoodsConverter.toChromiumResponseCode; /** * A class for parsing Digital Goods API calls from the browser and converting them into a format @@ -52,7 +52,7 @@ private GetDetailsCall(List itemIds, DigitalGoodsCallback callback) { /** Creates this class from a {@link Bundle}, returns {@code null} if the Bundle is invalid. **/ @Nullable public static GetDetailsCall create(@Nullable Bundle args, - @Nullable DigitalGoodsCallback callback) { + @Nullable DigitalGoodsCallback callback) { if (args == null || callback == null) return null; String[] itemIds = args.getStringArray(PARAM_GET_DETAILS_ITEM_IDS); @@ -62,7 +62,7 @@ public static GetDetailsCall create(@Nullable Bundle args, } /** Calls the callback provided in the constructor with serialized forms of the parameters. */ - private void respond(BillingResult result, @Nullable List detailsList) { + private void respond(BillingResult result, @Nullable List detailsList) { Logging.logGetDetailsResponse(result); Parcelable[] parcelables = new Parcelable[0]; @@ -70,14 +70,14 @@ private void respond(BillingResult result, @Nullable List detailsLis parcelables = new Parcelable[detailsList.size()]; int index = 0; - for (SkuDetails details : detailsList) { + for (ProductDetails details : detailsList) { parcelables[index++] = ItemDetails.create(details).toBundle(); } } Bundle args = new Bundle(); args.putInt(RESPONSE_GET_DETAILS_RESPONSE_CODE, - DigitalGoodsConverter.toChromiumResponseCode(result)); + DigitalGoodsConverter.toChromiumResponseCode(result)); args.putParcelableArray(RESPONSE_GET_DETAILS_DETAILS_LIST, parcelables); mCallback.run(RESPONSE_GET_DETAILS, args); } @@ -86,10 +86,10 @@ private void respond(BillingResult result, @Nullable List detailsLis public void call(BillingWrapper billing) { Logging.logGetDetailsCall(mItemIds); - BillingResultMerger merger = new BillingResultMerger<>(this::respond); + BillingResultMerger merger = new BillingResultMerger<>(this::respond); - billing.querySkuDetails(BillingClient.SkuType.INAPP, mItemIds, merger::setInAppResult); - billing.querySkuDetails(BillingClient.SkuType.SUBS, mItemIds, merger::setSubsResult); + billing.queryProductDetails(BillingClient.ProductType.INAPP, mItemIds, merger::setInAppResult); + billing.queryProductDetails(BillingClient.ProductType.SUBS, mItemIds, merger::setSubsResult); } /** Creates a Bundle that can be used with {@link #create}. For testing. */ diff --git a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/ItemDetails.java b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/ItemDetails.java index 512ee303..7a2f8290 100644 --- a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/ItemDetails.java +++ b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/digitalgoods/ItemDetails.java @@ -16,6 +16,7 @@ import android.os.Bundle; +import com.android.billingclient.api.ProductDetails; import com.android.billingclient.api.SkuDetails; /** @@ -57,10 +58,10 @@ public class ItemDetails { public final int introductoryPriceCycles; private ItemDetails(String id, String title, String description, String currency, String value, - String type, String iconUrl, String subscriptionPeriod, - String freeTrialPeriod, String introductoryPricePeriod, - String introductoryPriceCurrency, String introductoryPriceValue, - int introductoryPriceCycles) { + String type, String iconUrl, String subscriptionPeriod, + String freeTrialPeriod, String introductoryPricePeriod, + String introductoryPriceCurrency, String introductoryPriceValue, + int introductoryPriceCycles) { this.id = id; this.title = title; this.description = description; @@ -79,19 +80,19 @@ private ItemDetails(String id, String title, String description, String currency /** * Creates this class from a Play Billing {@link SkuDetails}. */ - public static ItemDetails create(SkuDetails skuDetails) { + public static ItemDetails create(ProductDetails skuDetails) { return new ItemDetails( - skuDetails.getSku(), - skuDetails.getTitle(), - skuDetails.getDescription(), - skuDetails.getPriceCurrencyCode(), - toPrice(skuDetails.getPriceAmountMicros()), - skuDetails.getType(), skuDetails.getIconUrl(), skuDetails.getSubscriptionPeriod(), - skuDetails.getFreeTrialPeriod(), - skuDetails.getIntroductoryPricePeriod(), - skuDetails.getPriceCurrencyCode(), - toPrice(skuDetails.getIntroductoryPriceAmountMicros()), - skuDetails.getIntroductoryPriceCycles()); + skuDetails.getProductId(), + skuDetails.getTitle(), + skuDetails.getDescription(), + skuDetails.getOneTimePurchaseOfferDetails().getPriceCurrencyCode(), + toPrice(skuDetails.getOneTimePurchaseOfferDetails().getPriceAmountMicros()), + skuDetails.getProductType(), skuDetails.getIconUrl(), skuDetails.getSubscriptionPeriod(), + skuDetails.getFreeTrialPeriod(), + skuDetails.getIntroductoryPricePeriod(), + skuDetails.getPriceCurrencyCode(), + toPrice(skuDetails.getIntroductoryPriceAmountMicros()), + skuDetails.getIntroductoryPriceCycles()); } /** @@ -114,8 +115,8 @@ public static ItemDetails create(Bundle bundle) { int introductoryPriceCycles = bundle.getInt(KEY_INTRO_CYCLES); return new ItemDetails(id, title, description, currency, value, type, iconUrl, - subscriptionPeriod, freeTrialPeriod, introductoryPricePeriod, - introductoryPriceCurrency, introductoryPriceValue, introductoryPriceCycles); + subscriptionPeriod, freeTrialPeriod, introductoryPricePeriod, + introductoryPriceCurrency, introductoryPriceValue, introductoryPriceCycles); } /** diff --git a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/BillingWrapper.java b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/BillingWrapper.java index 6d71630d..2f830883 100644 --- a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/BillingWrapper.java +++ b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/BillingWrapper.java @@ -21,12 +21,11 @@ import com.android.billingclient.api.BillingClientStateListener; import com.android.billingclient.api.BillingResult; import com.android.billingclient.api.ConsumeResponseListener; -import com.android.billingclient.api.PriceChangeConfirmationListener; +import com.android.billingclient.api.ProductDetails; +import com.android.billingclient.api.ProductDetailsResponseListener; import com.android.billingclient.api.PurchaseHistoryResponseListener; import com.android.billingclient.api.PurchasesResponseListener; -import com.android.billingclient.api.SkuDetails; -import com.android.billingclient.api.SkuDetailsResponseListener; -import com.google.androidbrowserhelper.playbilling.digitalgoods.ConnectedBillingWrapper; +import com.android.billingclient.api.QueryProductDetailsParams.Product; import java.util.List; @@ -47,21 +46,21 @@ interface Listener { void connect(BillingClientStateListener callback); /** - * Get {@link SkuDetails} objects for the provided SKUs. + * Get {@link ProductDetails} objects for the provided products. */ - void querySkuDetails(@BillingClient.SkuType String skuType, List skus, - SkuDetailsResponseListener callback); + void queryProductDetails(@BillingClient.ProductType String productType, List productsIds, + ProductDetailsResponseListener callback); /** * Returns details for currently owned items. */ - void queryPurchases(@BillingClient.SkuType String skuType, PurchasesResponseListener callback); + void queryPurchases(@BillingClient.ProductType String productType, PurchasesResponseListener callback); /** * Returns details for all previously purchased items. */ - void queryPurchaseHistory(@BillingClient.SkuType String skuType, - PurchaseHistoryResponseListener callback); + void queryPurchaseHistory(@BillingClient.ProductType String skuType, + PurchaseHistoryResponseListener callback); /** * Acknowledges that a purchase has occured. @@ -77,12 +76,12 @@ void queryPurchaseHistory(@BillingClient.SkuType String skuType, * Launches the Payment Flow. If it returns {@code true}, * {@link Listener#onPurchaseFlowComplete} should be called. */ - boolean launchPaymentFlow(Activity activity, SkuDetails sku, MethodData methodData); + boolean launchPaymentFlow(Activity activity, ProductDetails productDetails, MethodData methodData); /** * Launches the price change confirmation flow. */ - void launchPriceChangeConfirmationFlow(Activity activity, SkuDetails sku, - PriceChangeConfirmationListener listener); + void launchPriceChangeConfirmationFlow(Activity activity, ProductDetails productDetails, + ProductDetailsResponseListener listener); } diff --git a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/MockBillingWrapper.java b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/MockBillingWrapper.java index 7dd2c3a5..62e3380f 100644 --- a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/MockBillingWrapper.java +++ b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/MockBillingWrapper.java @@ -23,10 +23,13 @@ import com.android.billingclient.api.BillingResult; import com.android.billingclient.api.ConsumeResponseListener; import com.android.billingclient.api.PriceChangeConfirmationListener; +import com.android.billingclient.api.ProductDetails; +import com.android.billingclient.api.ProductDetailsResponseListener; import com.android.billingclient.api.Purchase; import com.android.billingclient.api.PurchaseHistoryRecord; import com.android.billingclient.api.PurchaseHistoryResponseListener; import com.android.billingclient.api.PurchasesResponseListener; +import com.android.billingclient.api.QueryProductDetailsParams.Product; import com.android.billingclient.api.SkuDetails; import com.android.billingclient.api.SkuDetailsResponseListener; @@ -47,19 +50,19 @@ public class MockBillingWrapper implements BillingWrapper { private boolean mPaymentFlowSuccessful; private InvocationTracker - mAcknowledgeInvocation = new InvocationTracker<>(); + mAcknowledgeInvocation = new InvocationTracker<>(); private InvocationTracker - mConsumeInvocation = new InvocationTracker<>(); + mConsumeInvocation = new InvocationTracker<>(); - private MultiSkuTypeInvocationTracker, SkuDetailsResponseListener> - mQuerySkuDetailsInvocation = new MultiSkuTypeInvocationTracker<>(); + private MultiSkuTypeInvocationTracker, ProductDetailsResponseListener> + mQuerySkuDetailsInvocation = new MultiSkuTypeInvocationTracker<>(); private MultiSkuTypeInvocationTracker - mQueryPurchasesInvocation = new MultiSkuTypeInvocationTracker<>(); + mQueryPurchasesInvocation = new MultiSkuTypeInvocationTracker<>(); private MultiSkuTypeInvocationTracker - mQueryPurchaseHistoryInvocation = new MultiSkuTypeInvocationTracker<>(); + mQueryPurchaseHistoryInvocation = new MultiSkuTypeInvocationTracker<>(); - private InvocationTracker - mPriceChangeConfirmationFlow = new InvocationTracker<>(); + private InvocationTracker + mPriceChangeConfirmationFlow = new InvocationTracker<>(); private Intent mPlayBillingFlowLaunchIntent; @@ -73,19 +76,19 @@ public void connect(BillingClientStateListener callback) { } @Override - public void querySkuDetails(@BillingClient.SkuType String skuType, List skus, - SkuDetailsResponseListener callback) { - mQuerySkuDetailsInvocation.call(skuType, skus, callback); + public void queryProductDetails(@BillingClient.ProductType String productType, List productsIds, + ProductDetailsResponseListener callback) { + mQuerySkuDetailsInvocation.call(productType, productsIds, callback); } @Override - public void queryPurchases(String skuType, PurchasesResponseListener callback) { - mQueryPurchasesInvocation.call(skuType, null, callback); + public void queryPurchases(String productType, PurchasesResponseListener callback) { + mQueryPurchasesInvocation.call(productType, null, callback); } @Override - public void queryPurchaseHistory(String skuType, PurchaseHistoryResponseListener callback) { - mQueryPurchaseHistoryInvocation.call(skuType, null, callback); + public void queryPurchaseHistory(String productType, PurchaseHistoryResponseListener callback) { + mQueryPurchaseHistoryInvocation.call(productType, null, callback); } @Override @@ -99,64 +102,64 @@ public void consume(String token, ConsumeResponseListener callback) { } @Override - public boolean launchPaymentFlow(Activity activity, SkuDetails sku, MethodData data) { + public boolean launchPaymentFlow(Activity activity, ProductDetails productDetails, MethodData data) { mPlayBillingFlowLaunchIntent = activity.getIntent(); mLaunchPaymentFlowLatch.countDown(); return mPaymentFlowSuccessful; } @Override - public void launchPriceChangeConfirmationFlow(Activity activity, SkuDetails sku, - PriceChangeConfirmationListener listener) { - mPriceChangeConfirmationFlow.call(sku, listener); + public void launchPriceChangeConfirmationFlow(Activity activity, ProductDetails productDetails, + ProductDetailsResponseListener listener) { + mPriceChangeConfirmationFlow.call(productDetails, listener); } public void triggerConnected() { mConnectionStateListener.onBillingSetupFinished( - toResult(BillingClient.BillingResponseCode.OK)); + toResult(BillingClient.BillingResponseCode.OK)); } public void triggerDisconnected() { mConnectionStateListener.onBillingServiceDisconnected(); } - public void triggerOnGotSkuDetails(List skuDetails) { - triggerOnGotInAppSkuDetails(skuDetails); + public void triggerOnGotSkuDetails(List productDetails) { + triggerOnGotInAppSkuDetails(productDetails); triggerOnGotSubsSkuDetails(Collections.emptyList()); } - public void triggerOnGotInAppSkuDetails(List skuDetails) { + public void triggerOnGotInAppSkuDetails(List skuDetails) { triggerOnGotInAppSkuDetails(BillingClient.BillingResponseCode.OK, skuDetails); } - public void triggerOnGotInAppSkuDetails(int responseCode, List skuDetails) { - mQuerySkuDetailsInvocation.getCallback(BillingClient.SkuType.INAPP) - .onSkuDetailsResponse(toResult(responseCode), skuDetails); + public void triggerOnGotInAppSkuDetails(int responseCode, List productDetails) { + mQuerySkuDetailsInvocation.getCallback(BillingClient.ProductType.INAPP) + .onProductDetailsResponse(toResult(responseCode), productDetails); } - public void triggerOnGotSubsSkuDetails(List skuDetails) { - triggerOnGotSubsSkuDetails(BillingClient.BillingResponseCode.OK, skuDetails); + public void triggerOnGotSubsSkuDetails(List productDetails) { + triggerOnGotSubsSkuDetails(BillingClient.BillingResponseCode.OK, productDetails); } - public void triggerOnGotSubsSkuDetails(int responseCode, List skuDetails) { - mQuerySkuDetailsInvocation.getCallback(BillingClient.SkuType.SUBS) - .onSkuDetailsResponse(toResult(responseCode), skuDetails); + public void triggerOnGotSubsSkuDetails(int responseCode, List productDetails) { + mQuerySkuDetailsInvocation.getCallback(BillingClient.ProductType.SUBS) + .onProductDetailsResponse(toResult(responseCode), productDetails); } public void triggerOnGotInAppPurchaseDetails(List details) { - mQueryPurchasesInvocation.getCallback(BillingClient.SkuType.INAPP) - .onQueryPurchasesResponse(toResult(BillingClient.BillingResponseCode.OK), details); + mQueryPurchasesInvocation.getCallback(BillingClient.ProductType.INAPP) + .onQueryPurchasesResponse(toResult(BillingClient.BillingResponseCode.OK), details); } public void triggerOnGotSubsPurchaseDetails(List details) { - mQueryPurchasesInvocation.getCallback(BillingClient.SkuType.SUBS) - .onQueryPurchasesResponse(toResult(BillingClient.BillingResponseCode.OK), details); + mQueryPurchasesInvocation.getCallback(BillingClient.ProductType.SUBS) + .onQueryPurchasesResponse(toResult(BillingClient.BillingResponseCode.OK), details); } public void triggerOnPurchaseHistoryResponse(String skuType, - List records) { + List records) { mQueryPurchaseHistoryInvocation.getCallback(skuType) - .onPurchaseHistoryResponse(toResult(BillingClient.BillingResponseCode.OK), records); + .onPurchaseHistoryResponse(toResult(BillingClient.BillingResponseCode.OK), records); } public void triggerAcknowledge(int responseCode) { @@ -173,7 +176,7 @@ public void triggerOnPurchasesUpdated() { public void triggerOnPriceChangeConfirmationResult() { mPriceChangeConfirmationFlow.getCallback().onPriceChangeConfirmationResult( - toResult(BillingClient.BillingResponseCode.OK)); + toResult(BillingClient.BillingResponseCode.OK)); } public boolean waitForConnect() throws InterruptedException { @@ -239,6 +242,6 @@ private static boolean wait(CountDownLatch latch) throws InterruptedException { } private static BillingResult toResult(int responseCode) { - return BillingResult.newBuilder().setResponseCode(responseCode).build(); + return BillingResult.newBuilder().setResponseCode(responseCode).build(); } } diff --git a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/PaymentActivity.java b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/PaymentActivity.java index aaea2ce8..a1899fd4 100644 --- a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/PaymentActivity.java +++ b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/PaymentActivity.java @@ -25,7 +25,7 @@ import com.android.billingclient.api.BillingClientStateListener; import com.android.billingclient.api.BillingFlowParams; import com.android.billingclient.api.BillingResult; -import com.android.billingclient.api.SkuDetails; +import com.android.billingclient.api.ProductDetails; import com.google.androidbrowserhelper.playbilling.digitalgoods.BillingResultMerger; import java.util.Collections; @@ -74,9 +74,9 @@ public void onCreate(@Nullable Bundle savedInstanceState) { */ Integer prorationMode = mMethodData.prorationMode; if (prorationMode != null - && prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION) { + && prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION) { fail("This proration mode is currently disabled. Check " + - "chromeos.dev/publish/pwa-play-billing for more info"); + "chromeos.dev/publish/pwa-play-billing for more info"); return; } @@ -99,20 +99,20 @@ public void onDisconnected() { } public void onConnected() { - BillingResultMerger merger = new BillingResultMerger<>(this::onSkusQueried); + BillingResultMerger merger = new BillingResultMerger<>(this::onSkusQueried); List ids = Collections.singletonList(mMethodData.sku); - mWrapper.querySkuDetails(BillingClient.SkuType.INAPP, ids, merger::setInAppResult); - mWrapper.querySkuDetails(BillingClient.SkuType.SUBS, ids, merger::setSubsResult); + mWrapper.queryProductDetails(BillingClient.ProductType.INAPP, ids, merger::setInAppResult); + mWrapper.queryProductDetails(BillingClient.ProductType.SUBS, ids, merger::setSubsResult); } - private void onSkusQueried(BillingResult result, List skus) { + private void onSkusQueried(BillingResult result, List skus) { if (skus == null || skus.isEmpty()) { fail("Play Billing returned did not find SKU."); return; } - SkuDetails sku = skus.get(0); + ProductDetails sku = skus.get(0); if (mMethodData.isPriceChangeConfirmation) { launchPriceChangeConfirmationFlow(sku); @@ -121,8 +121,8 @@ private void onSkusQueried(BillingResult result, List skus) { } } - private void launchPriceChangeConfirmationFlow(SkuDetails sku) { - mWrapper.launchPriceChangeConfirmationFlow(this, sku, result -> { + private void launchPriceChangeConfirmationFlow(ProductDetails productDetails) { + mWrapper.launchPriceChangeConfirmationFlow(this, productDetails, (result, productDetailsList) -> { if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) { setResultAndFinish(PaymentResult.priceChangeSuccess()); } else { @@ -131,7 +131,7 @@ private void launchPriceChangeConfirmationFlow(SkuDetails sku) { }); } - private void launchPaymentFlow(SkuDetails sku) { + private void launchPaymentFlow(ProductDetails sku) { if (mWrapper.launchPaymentFlow(this, sku, mMethodData)) return; diff --git a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/PlayBillingWrapper.java b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/PlayBillingWrapper.java index 3ea9bf6d..bd69b93c 100644 --- a/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/PlayBillingWrapper.java +++ b/playbilling/src/main/java/com/google/androidbrowserhelper/playbilling/provider/PlayBillingWrapper.java @@ -22,21 +22,32 @@ import com.android.billingclient.api.AcknowledgePurchaseParams; import com.android.billingclient.api.AcknowledgePurchaseResponseListener; import com.android.billingclient.api.BillingClient; +import com.android.billingclient.api.BillingClient.ProductType; import com.android.billingclient.api.BillingClientStateListener; import com.android.billingclient.api.BillingFlowParams; +import com.android.billingclient.api.BillingFlowParams.ProductDetailsParams; import com.android.billingclient.api.BillingResult; import com.android.billingclient.api.ConsumeParams; import com.android.billingclient.api.ConsumeResponseListener; import com.android.billingclient.api.PriceChangeConfirmationListener; import com.android.billingclient.api.PriceChangeFlowParams; +import com.android.billingclient.api.ProductDetails; +import com.android.billingclient.api.ProductDetailsResponseListener; import com.android.billingclient.api.Purchase; import com.android.billingclient.api.PurchaseHistoryResponseListener; import com.android.billingclient.api.PurchasesResponseListener; import com.android.billingclient.api.PurchasesUpdatedListener; +import com.android.billingclient.api.QueryProductDetailsParams; +import com.android.billingclient.api.QueryProductDetailsParams.Product; +import com.android.billingclient.api.QueryPurchaseHistoryParams; +import com.android.billingclient.api.QueryPurchasesParams; import com.android.billingclient.api.SkuDetails; import com.android.billingclient.api.SkuDetailsParams; import com.android.billingclient.api.SkuDetailsResponseListener; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; /** @@ -47,26 +58,26 @@ public class PlayBillingWrapper implements BillingWrapper { private final BillingClient mClient; private final PurchasesUpdatedListener mPurchaseUpdateListener = - new PurchasesUpdatedListener() { - @Override - public void onPurchasesUpdated(BillingResult billingResult, @Nullable List list) { - Logging.logPurchasesUpdate(billingResult, list); - - if (list == null || list.size() == 0) { - mListener.onPurchaseFlowComplete(billingResult, ""); - } else { - mListener.onPurchaseFlowComplete(billingResult, list.get(0).getPurchaseToken()); + new PurchasesUpdatedListener() { + @Override + public void onPurchasesUpdated(BillingResult billingResult, @Nullable List list) { + Logging.logPurchasesUpdate(billingResult, list); + + if (list == null || list.size() == 0) { + mListener.onPurchaseFlowComplete(billingResult, ""); + } else { + mListener.onPurchaseFlowComplete(billingResult, list.get(0).getPurchaseToken()); + } } - } - }; + }; public PlayBillingWrapper(Context context, Listener listener) { mListener = listener; mClient = BillingClient - .newBuilder(context) - .setListener(mPurchaseUpdateListener) - .enablePendingPurchases() - .build(); + .newBuilder(context) + .setListener(mPurchaseUpdateListener) + .enablePendingPurchases() + .build(); } @Override @@ -75,34 +86,34 @@ public void connect(BillingClientStateListener callback) { } @Override - public void querySkuDetails(@BillingClient.SkuType String skuType, List skus, - SkuDetailsResponseListener callback) { - SkuDetailsParams params = SkuDetailsParams - .newBuilder() - .setSkusList(skus) - .setType(skuType) - .build(); - - mClient.querySkuDetailsAsync(params, callback); + public void queryProductDetails(@BillingClient.ProductType String productType, List productsIds, + ProductDetailsResponseListener callback) { + QueryProductDetailsParams params = QueryProductDetailsParams + .newBuilder() + .setProductList(buildProductList(productType, productsIds)) + .build(); + + mClient.queryProductDetailsAsync(params, callback); } @Override - public void queryPurchases(@BillingClient.SkuType String skuType, - PurchasesResponseListener callback) { - mClient.queryPurchasesAsync(skuType, callback); + public void queryPurchases(@BillingClient.ProductType String productType, + PurchasesResponseListener callback) { + mClient.queryPurchasesAsync(QueryPurchasesParams.newBuilder().setProductType(productType).build(), callback); } @Override - public void queryPurchaseHistory(String skuType, PurchaseHistoryResponseListener callback) { - mClient.queryPurchaseHistoryAsync(skuType, callback); + public void queryPurchaseHistory(@BillingClient.ProductType String productType, PurchaseHistoryResponseListener callback) { + mClient.queryPurchaseHistoryAsync( + QueryPurchaseHistoryParams.newBuilder().setProductType(productType).build(), callback); } @Override public void acknowledge(String token, AcknowledgePurchaseResponseListener callback) { AcknowledgePurchaseParams params = AcknowledgePurchaseParams - .newBuilder() - .setPurchaseToken(token) - .build(); + .newBuilder() + .setPurchaseToken(token) + .build(); mClient.acknowledgePurchase(params, callback); } @@ -110,26 +121,34 @@ public void acknowledge(String token, AcknowledgePurchaseResponseListener callba @Override public void consume(String token, ConsumeResponseListener callback) { ConsumeParams params = ConsumeParams - .newBuilder() - .setPurchaseToken(token) - .build(); + .newBuilder() + .setPurchaseToken(token) + .build(); mClient.consumeAsync(params, callback); } @Override - public boolean launchPaymentFlow(Activity activity, SkuDetails sku, MethodData methodData) { + public boolean launchPaymentFlow(Activity activity, ProductDetails productDetails, MethodData methodData) { BillingFlowParams.SubscriptionUpdateParams.Builder subUpdateParamsBuilder = BillingFlowParams.SubscriptionUpdateParams.newBuilder(); BillingFlowParams.Builder builder = BillingFlowParams.newBuilder(); - builder.setSkuDetails(sku); + List productDetailsParamsList = Collections.singletonList( + ProductDetailsParams.newBuilder() + .setProductDetails(productDetails) + .build() + ); + builder.setProductDetailsParamsList(productDetailsParamsList); + + if (methodData.purchaseToken != null) { + subUpdateParamsBuilder.setOldPurchaseToken(methodData.purchaseToken); + } if (methodData.prorationMode != null) { - subUpdateParamsBuilder.setReplaceSkusProrationMode(methodData.prorationMode); + subUpdateParamsBuilder.setReplaceProrationMode(methodData.prorationMode); } - if (methodData.purchaseToken != null) { - subUpdateParamsBuilder.setOldSkuPurchaseToken(methodData.purchaseToken); + if (methodData.purchaseToken != null || methodData.prorationMode != null) { builder.setSubscriptionUpdateParams(subUpdateParamsBuilder.build()); } @@ -141,12 +160,24 @@ public boolean launchPaymentFlow(Activity activity, SkuDetails sku, MethodData m } @Override - public void launchPriceChangeConfirmationFlow(Activity activity, SkuDetails sku, - PriceChangeConfirmationListener listener) { + public void launchPriceChangeConfirmationFlow(Activity activity, ProductDetails productDetails, + ProductDetailsResponseListener listener) { + PriceChangeFlowParams params = PriceChangeFlowParams - .newBuilder() - .setSkuDetails(sku) - .build(); + .newBuilder() + .setSkuDetails(productDetails) + .build(); mClient.launchPriceChangeConfirmationFlow(activity, params, listener); } + + private List buildProductList(@ProductType String productType, List ids){ + List products = new ArrayList<>(); + for (String id : ids) { + products.add(Product.newBuilder() + .setProductId(id) + .setProductType(productType) + .build()); + } + return products; + } }