Skip to content

Commit

Permalink
Create GPBC Wrapper Interface
Browse files Browse the repository at this point in the history
Summary:
In order to clean up the in-app purchase auto-logging code and adhere to best coding practices, we should create an interface that both billing client wrappers implement.

We can now use this interface to call a generic billing client in ```InAppPurchaseAutoLogger``` or anywhere else in the FBSDK for that matter.

Reviewed By: jjiang10

Differential Revision: D62037255

fbshipit-source-id: 126e57dec5f2d9156f77d9b09678a5c2d2ed4ba0
  • Loading branch information
maxalbrightmeta authored and facebook-github-bot committed Sep 6, 2024
1 parent ba13aba commit f598208
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,34 +30,25 @@ object InAppPurchaseAutoLogger {
if (failedToCreateWrapper.get()) {
return
}

var billingClientWrapper: InAppPurchaseBillingClientWrapper? = null
if (billingClientVersion == V2_V4) {
val billingClientWrapper =
billingClientWrapper =
InAppPurchaseBillingClientWrapperV2V4.getOrCreateInstance(context)
if (billingClientWrapper == null) {
failedToCreateWrapper.set(true)
return
}
if (InAppPurchaseLoggerManager.eligibleQueryPurchaseHistory()) {
billingClientWrapper.queryPurchaseHistory(INAPP) {
logPurchase(V2_V4)
}
} else {
billingClientWrapper.queryPurchase(INAPP) {
logPurchase(V2_V4)
}
}
} else if (billingClientVersion == V5_Plus) {
val billingClientWrapper =
billingClientWrapper =
InAppPurchaseBillingClientWrapperV5V7.getOrCreateInstance(context)
if (billingClientWrapper == null) {
failedToCreateWrapper.set(true)
return
}
if (billingClientWrapper == null) {
failedToCreateWrapper.set(true)
return
}
if (InAppPurchaseLoggerManager.eligibleQueryPurchaseHistory()) {
billingClientWrapper.queryPurchaseHistory(INAPP) {
logPurchase(billingClientVersion)
}
if (InAppPurchaseLoggerManager.eligibleQueryPurchaseHistory()) {
billingClientWrapper.queryPurchaseHistoryAsync(INAPP) { logPurchase(V5_Plus) }
} else {
billingClientWrapper.queryPurchasesAsync(INAPP) { logPurchase(V5_Plus) }
} else {
billingClientWrapper.queryPurchases(INAPP) {
logPurchase(billingClientVersion)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.facebook.appevents.iap

interface InAppPurchaseBillingClientWrapper {
val billingClient: Any
fun queryPurchases(productType: InAppPurchaseUtils.IAPProductType, runnable: Runnable)
fun queryPurchaseHistory(productType: InAppPurchaseUtils.IAPProductType, runnable: Runnable)
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ import org.json.JSONObject
class InAppPurchaseBillingClientWrapperV2V4
private constructor(
private val packageName: String,
private val billingClient: Any,
override val billingClient: Any,
private val billingClientClazz: Class<*>,
private val purchaseResultClazz: Class<*>,
private val purchaseClazz: Class<*>,
Expand All @@ -74,26 +74,34 @@ private constructor(
private val querySkuDetailsAsyncMethod: Method,
private val queryPurchaseHistoryAsyncMethod: Method,
private val inAppPurchaseSkuDetailsWrapper: InAppPurchaseSkuDetailsWrapper
) {
) : InAppPurchaseBillingClientWrapper {
private val historyPurchaseSet: MutableSet<String?> = CopyOnWriteArraySet()
fun queryPurchaseHistory(
skuType: InAppPurchaseUtils.IAPProductType,
queryPurchaseHistoryRunnable: Runnable
override fun queryPurchaseHistory(
productType: InAppPurchaseUtils.IAPProductType,
runnable: Runnable
) {
queryPurchaseHistoryAsync(skuType.type) {
queryPurchaseHistoryAsync(productType.type) {
querySkuDetailsAsync(
skuType.type,
productType.type,
ArrayList(historyPurchaseSet),
queryPurchaseHistoryRunnable
runnable
)
}
}

fun queryPurchase(skuType: InAppPurchaseUtils.IAPProductType, querySkuRunnable: Runnable) {
override fun queryPurchases(
productType: InAppPurchaseUtils.IAPProductType,
runnable: Runnable
) {
// TODO (T67568885): support subs
val queryPurchaseRunnable = Runnable {
val purchaseResult =
invokeMethod(billingClientClazz, queryPurchasesMethod, billingClient, skuType.type)
invokeMethod(
billingClientClazz,
queryPurchasesMethod,
billingClient,
productType.type
)
val purchaseObjects =
invokeMethod(purchaseResultClazz, getPurchaseListMethod, purchaseResult) as? List<*>
try {
Expand All @@ -114,7 +122,7 @@ private constructor(
purchaseDetailsMap[skuID] = purchaseJson
}
}
querySkuDetailsAsync(skuType.type, skuIDs, querySkuRunnable)
querySkuDetailsAsync(productType.type, skuIDs, runnable)
}
} catch (je: JSONException) {
/* swallow */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ import org.json.JSONObject
class InAppPurchaseBillingClientWrapperV5V7
private constructor(
private val packageName: String,
private val billingClient: Any,
override val billingClient: Any,
private val billingClientClazz: Class<*>,
private val purchaseClazz: Class<*>,
private val productDetailsClazz: Class<*>,
Expand Down Expand Up @@ -113,7 +113,7 @@ private constructor(

private val billingClientStartConnectionMethod: Method,
private val billingResultGetResponseCodeMethod: Method
) {
) : InAppPurchaseBillingClientWrapper {

@AutoHandleExceptions
inner class ListenerWrapper(private var wrapperArgs: Array<Any>?) : InvocationHandler {
Expand Down Expand Up @@ -262,15 +262,15 @@ private constructor(
)
}

fun queryPurchasesAsync(
override fun queryPurchases(
productType: InAppPurchaseUtils.IAPProductType,
loggingRunnable: Runnable
runnable: Runnable
) {
val runnableQuery = Runnable {
val listenerObj = Proxy.newProxyInstance(
purchasesResponseListenerClazz.classLoader,
arrayOf(purchasesResponseListenerClazz),
ListenerWrapper(arrayOf(productType, loggingRunnable))
ListenerWrapper(arrayOf(productType, runnable))
)
invokeMethod(
billingClientClazz,
Expand All @@ -283,14 +283,14 @@ private constructor(
executeServiceRequest(runnableQuery)
}

fun queryPurchaseHistoryAsync(
productType: InAppPurchaseUtils.IAPProductType, loggingRunnable: Runnable
override fun queryPurchaseHistory(
productType: InAppPurchaseUtils.IAPProductType, runnable: Runnable
) {
val runnableQuery = Runnable {
val listenerObj = Proxy.newProxyInstance(
purchaseHistoryResponseListenerClazz.classLoader,
arrayOf(purchaseHistoryResponseListenerClazz),
ListenerWrapper(arrayOf(productType, loggingRunnable))
ListenerWrapper(arrayOf(productType, runnable))
)
invokeMethod(
billingClientClazz,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class InAppPurchaseAutoLoggerTest : FacebookPowerMockTestCase() {
PowerMockito.doAnswer { null }
.`when`(InAppPurchaseUtils::class.java, "getClass", any())
whenever(
mockBillingClientWrapperV5Plus.queryPurchaseHistoryAsync(
mockBillingClientWrapperV5Plus.queryPurchaseHistory(
any(),
any()
)
Expand Down Expand Up @@ -149,7 +149,7 @@ class InAppPurchaseAutoLoggerTest : FacebookPowerMockTestCase() {
logPurchaseCallTimes++
Unit
}
whenever(mockBillingClientWrapperV2_V4.queryPurchase(any(), any())).thenAnswer {
whenever(mockBillingClientWrapperV2_V4.queryPurchases(any(), any())).thenAnswer {
runnable = it.getArgument(1) as Runnable
Unit
}
Expand Down Expand Up @@ -179,7 +179,7 @@ class InAppPurchaseAutoLoggerTest : FacebookPowerMockTestCase() {
Unit
}
whenever(
mockBillingClientWrapperV5Plus.queryPurchaseHistoryAsync(
mockBillingClientWrapperV5Plus.queryPurchaseHistory(
any(),
any()
)
Expand Down Expand Up @@ -214,7 +214,7 @@ class InAppPurchaseAutoLoggerTest : FacebookPowerMockTestCase() {
Unit
}
whenever(
mockBillingClientWrapperV5Plus.queryPurchasesAsync(
mockBillingClientWrapperV5Plus.queryPurchases(
any(),
any()
)
Expand Down

0 comments on commit f598208

Please sign in to comment.