diff --git a/feature/google/src/main/java/com/revenuecat/purchases/google/BillingWrapper.kt b/feature/google/src/main/java/com/revenuecat/purchases/google/BillingWrapper.kt index 6f56608b2d..418d21f63a 100644 --- a/feature/google/src/main/java/com/revenuecat/purchases/google/BillingWrapper.kt +++ b/feature/google/src/main/java/com/revenuecat/purchases/google/BillingWrapper.kt @@ -222,6 +222,9 @@ class BillingWrapper( activity: Activity, params: BillingFlowParams ) { + if (activity.intent == null) { + log(LogIntent.WARNING, BillingStrings.NULL_ACTIVITY_INTENT) + } withConnectedClient { launchBillingFlow(activity, params) .takeIf { billingResult -> billingResult.responseCode != BillingClient.BillingResponseCode.OK } diff --git a/feature/google/src/test/java/com/revenuecat/purchases/google/BillingWrapperTest.kt b/feature/google/src/test/java/com/revenuecat/purchases/google/BillingWrapperTest.kt index 65a48a9a90..7e9005a0f2 100644 --- a/feature/google/src/test/java/com/revenuecat/purchases/google/BillingWrapperTest.kt +++ b/feature/google/src/test/java/com/revenuecat/purchases/google/BillingWrapperTest.kt @@ -2,6 +2,7 @@ package com.revenuecat.purchases.google import android.app.Activity import android.content.Context +import android.content.Intent import android.os.Handler import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.billingclient.api.AcknowledgePurchaseParams @@ -80,6 +81,7 @@ class BillingWrapperTest { private val billingClientOKResult = BillingClient.BillingResponseCode.OK.buildResult() private val appUserId = "jerry" + private var mockActivity = mockk() @Before fun setup() { @@ -145,6 +147,10 @@ class BillingWrapperTest { onConnectedCalled = true } } + + every { + mockActivity.intent + } returns Intent() } @Test @@ -252,11 +258,9 @@ class BillingWrapperTest { val skuDetails = stubSkuDetails(productId = "product_a") - val activity: Activity = mockk() - billingClientStateListener!!.onBillingSetupFinished(BillingClient.BillingResponseCode.OK.buildResult()) wrapper.makePurchaseAsync( - activity, + mockActivity, appUserId, skuDetails.toStoreProduct(), mockReplaceSkuInfo(), @@ -265,7 +269,7 @@ class BillingWrapperTest { verify { mockClient.launchBillingFlow( - eq(activity), + eq(mockActivity), any() ) } @@ -305,12 +309,11 @@ class BillingWrapperTest { @BillingClient.SkuType val skuType = BillingClient.SkuType.SUBS val upgradeInfo = mockReplaceSkuInfo() - val activity: Activity = mockk() val skuDetails = stubSkuDetails(productId = sku, type = skuType) val slot = slot() every { - mockClient.launchBillingFlow(eq(activity), capture(slot)) + mockClient.launchBillingFlow(eq(mockActivity), capture(slot)) } answers { val capturedSkuDetails = skuDetailsSlot.captured @@ -324,7 +327,7 @@ class BillingWrapperTest { billingClientStateListener!!.onBillingSetupFinished(BillingClient.BillingResponseCode.OK.buildResult()) wrapper.makePurchaseAsync( - activity, + mockActivity, appUserId, skuDetails.toStoreProduct(), upgradeInfo, @@ -337,7 +340,7 @@ class BillingWrapperTest { val mockBuilder = setUpForObfuscatedAccountIDTests() wrapper.makePurchaseAsync( - mockk(), + mockActivity, appUserId, stubSkuDetails(productId = "product_a").toStoreProduct(), null, @@ -357,7 +360,7 @@ class BillingWrapperTest { val mockBuilder = setUpForObfuscatedAccountIDTests() wrapper.makePurchaseAsync( - mockk(), + mockActivity, appUserId, stubSkuDetails(productId = "product_a").toStoreProduct(), mockReplaceSkuInfo(), @@ -379,11 +382,10 @@ class BillingWrapperTest { every { mockClient.isReady } returns false - val activity: Activity = mockk() val skuDetails = stubSkuDetails(productId = "product_a") wrapper.makePurchaseAsync( - activity, + mockActivity, appUserId, skuDetails.toStoreProduct(), mockReplaceSkuInfo(), @@ -391,7 +393,7 @@ class BillingWrapperTest { ) verify(exactly = 0) { - mockClient.launchBillingFlow(eq(activity), any()) + mockClient.launchBillingFlow(eq(mockActivity), any()) } every { mockClient.isReady } returns true @@ -399,7 +401,7 @@ class BillingWrapperTest { billingClientStateListener!!.onBillingSetupFinished(BillingClient.BillingResponseCode.OK.buildResult()) verify(exactly = 1) { - mockClient.launchBillingFlow(eq(activity), any()) + mockClient.launchBillingFlow(eq(mockActivity), any()) } } @@ -413,10 +415,8 @@ class BillingWrapperTest { val skuDetails = stubSkuDetails(productId = "product_a") - val activity: Activity = mockk() - wrapper.makePurchaseAsync( - activity, + mockActivity, appUserId, skuDetails.toStoreProduct(), mockReplaceSkuInfo(), @@ -809,11 +809,9 @@ class BillingWrapperTest { val skuDetails = stubSkuDetails(productId = "product_a") - val activity: Activity = mockk() - billingClientStateListener!!.onBillingSetupFinished(BillingClient.BillingResponseCode.OK.buildResult()) wrapper.makePurchaseAsync( - activity, + mockActivity, appUserId, skuDetails.toStoreProduct(), mockReplaceSkuInfo(), diff --git a/strings/src/main/java/com/revenuecat/purchases/strings/BillingStrings.kt b/strings/src/main/java/com/revenuecat/purchases/strings/BillingStrings.kt index 8aa1587f80..0d0403729a 100644 --- a/strings/src/main/java/com/revenuecat/purchases/strings/BillingStrings.kt +++ b/strings/src/main/java/com/revenuecat/purchases/strings/BillingStrings.kt @@ -15,4 +15,6 @@ object BillingStrings { "PurchaseHistoryRecord, but only one will be used." const val BILLING_PURCHASE_MORE_THAN_ONE_SKU = "There's more than one sku in the PurchaseHistoryRecord, " + "but only one will be used." + const val NULL_ACTIVITY_INTENT = "Activity passed into launchBillingFlow has a null intent, which may cause " + + "a crash. See https://github.com/RevenueCat/purchases-android/issues/381 for more information." }