Skip to content

Commit 982b90d

Browse files
alex-signalcody-signal
authored andcommitted
Add BillingDependencies and shared implementation.
1 parent 36bfd19 commit 982b90d

6 files changed

Lines changed: 67 additions & 10 deletions

File tree

app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ public WebSocketConnection createUnidentifiedWebSocket() {
452452

453453
@Override
454454
public @NonNull BillingApi provideBillingApi() {
455-
return BillingFactory.create(context, RemoteConfig.messageBackups());
455+
return BillingFactory.create(GooglePlayBillingDependencies.INSTANCE, RemoteConfig.messageBackups());
456456
}
457457

458458
@Override
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2024 Signal Messenger, LLC
3+
* SPDX-License-Identifier: AGPL-3.0-only
4+
*/
5+
6+
package org.thoughtcrime.securesms.dependencies
7+
8+
import android.content.Context
9+
import org.signal.core.util.billing.BillingDependencies
10+
11+
/**
12+
* Dependency object for Google Play Billing.
13+
*/
14+
object GooglePlayBillingDependencies : BillingDependencies {
15+
16+
override val context: Context get() = AppDependencies.application
17+
18+
override suspend fun getProductId(): String {
19+
return "backup" // TODO [message-backups] This really shouldn't be hardcoded into the app.
20+
}
21+
22+
override suspend fun getBasePlanId(): String {
23+
return "monthly" // TODO [message-backups] This really shouldn't be hardcoded into the app.
24+
}
25+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package org.signal.billing
22

3-
import android.content.Context
43
import org.signal.core.util.billing.BillingApi
4+
import org.signal.core.util.billing.BillingDependencies
55

66
/**
77
* Website builds do not support google play billing.
88
*/
99
object BillingFactory {
1010
@JvmStatic
11-
fun create(context: Context, isBackupsAvailable: Boolean): BillingApi {
11+
fun create(billingDependencies: BillingDependencies, isBackupsAvailable: Boolean): BillingApi {
1212
return BillingApi.Empty
1313
}
1414
}

billing/src/main/java/org/signal/billing/BillingApiImpl.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
package org.signal.billing
77

88
import android.app.Activity
9-
import android.content.Context
109
import com.android.billingclient.api.BillingClient
1110
import com.android.billingclient.api.BillingClient.BillingResponseCode
1211
import com.android.billingclient.api.BillingClient.ProductType
@@ -37,6 +36,7 @@ import kotlinx.coroutines.flow.update
3736
import kotlinx.coroutines.launch
3837
import kotlinx.coroutines.withContext
3938
import org.signal.core.util.billing.BillingApi
39+
import org.signal.core.util.billing.BillingDependencies
4040
import org.signal.core.util.logging.Log
4141

4242
/**
@@ -46,7 +46,7 @@ import org.signal.core.util.logging.Log
4646
* Care should be taken here to ensure only one instance of this exists at a time.
4747
*/
4848
internal class BillingApiImpl(
49-
context: Context
49+
private val billingDependencies: BillingDependencies
5050
) : BillingApi {
5151

5252
companion object {
@@ -74,7 +74,7 @@ internal class BillingApiImpl(
7474
}
7575
}
7676

77-
private val billingClient: BillingClient = BillingClient.newBuilder(context)
77+
private val billingClient: BillingClient = BillingClient.newBuilder(billingDependencies.context)
7878
.setListener(purchasesUpdatedListener)
7979
.enablePendingPurchases(
8080
PendingPurchasesParams.newBuilder()
@@ -98,6 +98,7 @@ internal class BillingApiImpl(
9898

9999
override suspend fun queryProducts() {
100100
val products = queryProductsInternal()
101+
Log.d(TAG, "Retrieved products with result: $products")
101102
}
102103

103104
override suspend fun queryPurchases() {
@@ -106,6 +107,7 @@ internal class BillingApiImpl(
106107
.build()
107108

108109
val purchases = doOnConnectionReady {
110+
Log.d(TAG, "Querying purchases.")
109111
billingClient.queryPurchasesAsync(param)
110112
}
111113

@@ -143,6 +145,7 @@ internal class BillingApiImpl(
143145

144146
doOnConnectionReady {
145147
withContext(Dispatchers.Main) {
148+
Log.d(TAG, "Launching billing flow.")
146149
billingClient.launchBillingFlow(activity, billingFlowParams)
147150
}
148151
}
@@ -159,7 +162,7 @@ internal class BillingApiImpl(
159162
private suspend fun queryProductsInternal(): ProductDetailsResult {
160163
val productList = listOf(
161164
QueryProductDetailsParams.Product.newBuilder()
162-
.setProductId("") // TODO [message-backups] where does the product id come from?
165+
.setProductId(billingDependencies.getProductId())
163166
.setProductType(ProductType.SUBS)
164167
.build()
165168
)
@@ -170,6 +173,7 @@ internal class BillingApiImpl(
170173

171174
return withContext(Dispatchers.IO) {
172175
doOnConnectionReady {
176+
Log.d(TAG, "Querying product details.")
173177
billingClient.queryProductDetails(params)
174178
}
175179
}

billing/src/main/java/org/signal/billing/BillingFactory.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55

66
package org.signal.billing
77

8-
import android.content.Context
98
import org.signal.core.util.billing.BillingApi
9+
import org.signal.core.util.billing.BillingDependencies
1010

1111
/**
1212
* Play billing factory. Returns empty implementation if message backups are not enabled.
1313
*/
1414
object BillingFactory {
1515
@JvmStatic
16-
fun create(context: Context, isBackupsAvailable: Boolean): BillingApi {
16+
fun create(billingDependencies: BillingDependencies, isBackupsAvailable: Boolean): BillingApi {
1717
return if (isBackupsAvailable) {
18-
BillingApiImpl(context)
18+
BillingApiImpl(billingDependencies)
1919
} else {
2020
BillingApi.Empty
2121
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2024 Signal Messenger, LLC
3+
* SPDX-License-Identifier: AGPL-3.0-only
4+
*/
5+
6+
package org.signal.core.util.billing
7+
8+
import android.content.Context
9+
10+
/**
11+
* Provides a dependency model by which the billing api can request different resources.
12+
*/
13+
interface BillingDependencies {
14+
/**
15+
* Application context
16+
*/
17+
val context: Context
18+
19+
/**
20+
* Get the product id from the donations configuration object.
21+
*/
22+
suspend fun getProductId(): String
23+
24+
/**
25+
* Get the base plan id from the donations configuration object.
26+
*/
27+
suspend fun getBasePlanId(): String
28+
}

0 commit comments

Comments
 (0)