Add BillingDependencies and shared implementation.

This commit is contained in:
Alex Hart 2024-09-05 13:46:55 -03:00 committed by Cody Henthorne
parent 36bfd19bcf
commit 982b90d423
6 changed files with 67 additions and 10 deletions

View file

@ -452,7 +452,7 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider {
@Override
public @NonNull BillingApi provideBillingApi() {
return BillingFactory.create(context, RemoteConfig.messageBackups());
return BillingFactory.create(GooglePlayBillingDependencies.INSTANCE, RemoteConfig.messageBackups());
}
@Override

View file

@ -0,0 +1,25 @@
/*
* Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.dependencies
import android.content.Context
import org.signal.core.util.billing.BillingDependencies
/**
* Dependency object for Google Play Billing.
*/
object GooglePlayBillingDependencies : BillingDependencies {
override val context: Context get() = AppDependencies.application
override suspend fun getProductId(): String {
return "backup" // TODO [message-backups] This really shouldn't be hardcoded into the app.
}
override suspend fun getBasePlanId(): String {
return "monthly" // TODO [message-backups] This really shouldn't be hardcoded into the app.
}
}

View file

@ -1,14 +1,14 @@
package org.signal.billing
import android.content.Context
import org.signal.core.util.billing.BillingApi
import org.signal.core.util.billing.BillingDependencies
/**
* Website builds do not support google play billing.
*/
object BillingFactory {
@JvmStatic
fun create(context: Context, isBackupsAvailable: Boolean): BillingApi {
fun create(billingDependencies: BillingDependencies, isBackupsAvailable: Boolean): BillingApi {
return BillingApi.Empty
}
}

View file

@ -6,7 +6,6 @@
package org.signal.billing
import android.app.Activity
import android.content.Context
import com.android.billingclient.api.BillingClient
import com.android.billingclient.api.BillingClient.BillingResponseCode
import com.android.billingclient.api.BillingClient.ProductType
@ -37,6 +36,7 @@ import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.signal.core.util.billing.BillingApi
import org.signal.core.util.billing.BillingDependencies
import org.signal.core.util.logging.Log
/**
@ -46,7 +46,7 @@ import org.signal.core.util.logging.Log
* Care should be taken here to ensure only one instance of this exists at a time.
*/
internal class BillingApiImpl(
context: Context
private val billingDependencies: BillingDependencies
) : BillingApi {
companion object {
@ -74,7 +74,7 @@ internal class BillingApiImpl(
}
}
private val billingClient: BillingClient = BillingClient.newBuilder(context)
private val billingClient: BillingClient = BillingClient.newBuilder(billingDependencies.context)
.setListener(purchasesUpdatedListener)
.enablePendingPurchases(
PendingPurchasesParams.newBuilder()
@ -98,6 +98,7 @@ internal class BillingApiImpl(
override suspend fun queryProducts() {
val products = queryProductsInternal()
Log.d(TAG, "Retrieved products with result: $products")
}
override suspend fun queryPurchases() {
@ -106,6 +107,7 @@ internal class BillingApiImpl(
.build()
val purchases = doOnConnectionReady {
Log.d(TAG, "Querying purchases.")
billingClient.queryPurchasesAsync(param)
}
@ -143,6 +145,7 @@ internal class BillingApiImpl(
doOnConnectionReady {
withContext(Dispatchers.Main) {
Log.d(TAG, "Launching billing flow.")
billingClient.launchBillingFlow(activity, billingFlowParams)
}
}
@ -159,7 +162,7 @@ internal class BillingApiImpl(
private suspend fun queryProductsInternal(): ProductDetailsResult {
val productList = listOf(
QueryProductDetailsParams.Product.newBuilder()
.setProductId("") // TODO [message-backups] where does the product id come from?
.setProductId(billingDependencies.getProductId())
.setProductType(ProductType.SUBS)
.build()
)
@ -170,6 +173,7 @@ internal class BillingApiImpl(
return withContext(Dispatchers.IO) {
doOnConnectionReady {
Log.d(TAG, "Querying product details.")
billingClient.queryProductDetails(params)
}
}

View file

@ -5,17 +5,17 @@
package org.signal.billing
import android.content.Context
import org.signal.core.util.billing.BillingApi
import org.signal.core.util.billing.BillingDependencies
/**
* Play billing factory. Returns empty implementation if message backups are not enabled.
*/
object BillingFactory {
@JvmStatic
fun create(context: Context, isBackupsAvailable: Boolean): BillingApi {
fun create(billingDependencies: BillingDependencies, isBackupsAvailable: Boolean): BillingApi {
return if (isBackupsAvailable) {
BillingApiImpl(context)
BillingApiImpl(billingDependencies)
} else {
BillingApi.Empty
}

View file

@ -0,0 +1,28 @@
/*
* Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.signal.core.util.billing
import android.content.Context
/**
* Provides a dependency model by which the billing api can request different resources.
*/
interface BillingDependencies {
/**
* Application context
*/
val context: Context
/**
* Get the product id from the donations configuration object.
*/
suspend fun getProductId(): String
/**
* Get the base plan id from the donations configuration object.
*/
suspend fun getBasePlanId(): String
}