Skip to content

Commit

Permalink
Deprecates observerMode in favor of purchasesAreCompletedBy (#1708)
Browse files Browse the repository at this point in the history
- Adds `PurchasesAreCompletedBy` enum.
- Adds `PurchasesConfiguration.Builder.purchasesAreCompletedBy()`
- Deprecates `PurchasesConfiguration.Builder.observerMode()`, with a
nice `ReplaceWith` action.
- Adds `Purchases.syncAmazonPurchase()`.
- Deprecates `Purchases.syncObserverModeAmazonPurchase`, with a nice
`ReplaceWith` action.
- Deprecates `Purchases.finishTransactions`, with an okay `ReplaceWith`
action.
- Adds API tests for `PurchasesAreCompletedBy`.
- Adds API tests for `purchasesAreCompletedBy()`.
- PaywallsTester, PurchaseTester and the MagicWeather samples use
`purchasesAreCompletedBy()` instead of `observerMode()`.
- Adds some unit tests for `purchasesAreCompletedBy()`.
  • Loading branch information
JayShortway authored Jun 3, 2024
1 parent 61ded49 commit b8bae4a
Show file tree
Hide file tree
Showing 21 changed files with 286 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import com.revenuecat.purchases.models.StoreTransaction;
import com.revenuecat.purchases.models.SubscriptionOption;

import kotlin.Unit;

@SuppressWarnings({"unused"})
final class DeprecatedPurchasesAPI {
static void check(final Purchases purchases,
Expand Down Expand Up @@ -51,6 +53,17 @@ public void onError(@NonNull PurchasesError error, boolean userCancelled) {
purchases.purchaseProduct(activity, storeProduct, makePurchaseListener);
purchases.purchasePackage(activity, packageToPurchase, upgradeInfo, purchaseChangeListener);
purchases.purchasePackage(activity, packageToPurchase, makePurchaseListener);

boolean finishTransactions = purchases.getFinishTransactions();
purchases.setFinishTransactions(true);

purchases.syncObserverModeAmazonPurchase(
storeProduct.getId(),
"receipt-id",
"amazon-user-id",
"EUR",
1.99
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
import com.revenuecat.purchases.CacheFetchPolicy;
import com.revenuecat.purchases.CustomerInfo;
import com.revenuecat.purchases.EntitlementVerificationMode;
import com.revenuecat.purchases.LogLevel;
import com.revenuecat.purchases.Offerings;
import com.revenuecat.purchases.Purchases;
import com.revenuecat.purchases.PurchasesAreCompletedBy;
import com.revenuecat.purchases.PurchasesConfiguration;
import com.revenuecat.purchases.PurchasesError;
import com.revenuecat.purchases.Store;
Expand All @@ -18,13 +18,9 @@
import com.revenuecat.purchases.interfaces.ReceiveCustomerInfoCallback;
import com.revenuecat.purchases.interfaces.SyncAttributesAndOfferingsCallback;
import com.revenuecat.purchases.interfaces.SyncPurchasesCallback;
import com.revenuecat.purchases.models.BillingFeature;

import org.jetbrains.annotations.NotNull;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;

Expand Down Expand Up @@ -125,11 +121,13 @@ static void checkConfiguration(final Context context,
}

static void checkAmazonConfiguration(final Context context,
final ExecutorService executorService) {
final ExecutorService executorService,
final PurchasesAreCompletedBy purchaseCompleter) {
PurchasesConfiguration amazonConfiguration = new AmazonConfiguration.Builder(context, "")
.appUserID("")
.observerMode(true)
.observerMode(false)
.purchasesAreCompletedBy(purchaseCompleter)
.service(executorService)
.diagnosticsEnabled(true)
.entitlementVerificationMode(EntitlementVerificationMode.INFORMATIONAL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,16 @@ private class DeprecatedPurchasesAPI {

Purchases.debugLogsEnabled = false
val debugLogs: Boolean = Purchases.debugLogsEnabled

val finishTransactions: Boolean = purchases.finishTransactions
purchases.finishTransactions = true

val unit: Unit = purchases.syncObserverModeAmazonPurchase(
productID = storeProduct.id,
receiptID = "receipt-id",
amazonUserID = "amazon-user-id",
isoCurrencyCode = "EUR",
price = 1.99,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.revenuecat.purchases.EntitlementVerificationMode
import com.revenuecat.purchases.ExperimentalPreviewRevenueCatPurchasesAPI
import com.revenuecat.purchases.Offerings
import com.revenuecat.purchases.Purchases
import com.revenuecat.purchases.PurchasesAreCompletedBy
import com.revenuecat.purchases.PurchasesConfiguration
import com.revenuecat.purchases.PurchasesError
import com.revenuecat.purchases.Store
Expand Down Expand Up @@ -67,8 +68,8 @@ private class PurchasesAPI {
purchases.getCustomerInfo(receiveCustomerInfoCallback)
purchases.getCustomerInfo(CacheFetchPolicy.CACHED_OR_FETCHED, receiveCustomerInfoCallback)

val finishTransactions: Boolean = purchases.finishTransactions
purchases.finishTransactions = true
val purchasesAreCompletedBy: PurchasesAreCompletedBy = purchases.purchasesAreCompletedBy
purchases.purchasesAreCompletedBy = PurchasesAreCompletedBy.REVENUECAT

val anonymous: Boolean = purchases.isAnonymous

Expand Down Expand Up @@ -177,11 +178,16 @@ private class PurchasesAPI {
LogInResult(customerInfo, created)
}

fun checkAmazonConfiguration(context: Context, executorService: ExecutorService) {
fun checkAmazonConfiguration(
context: Context,
executorService: ExecutorService,
purchaseCompleter: PurchasesAreCompletedBy,
) {
val amazonConfiguration: PurchasesConfiguration = AmazonConfiguration.Builder(context, "")
.appUserID("")
.observerMode(true)
.observerMode(false)
.purchasesAreCompletedBy(purchaseCompleter)
.showInAppMessagesAutomatically(true)
.service(executorService)
.diagnosticsEnabled(true)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.revenuecat.apitester.java;

import com.revenuecat.purchases.PurchasesAreCompletedBy;

@SuppressWarnings({"unused"})
final class PurchasesAreCompletedByAPI {
static void check(final PurchasesAreCompletedBy mode) {
switch (mode) {
case REVENUECAT:
case MY_APP:
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.revenuecat.purchases.ProductType;
import com.revenuecat.purchases.PurchaseParams;
import com.revenuecat.purchases.Purchases;
import com.revenuecat.purchases.PurchasesAreCompletedBy;
import com.revenuecat.purchases.PurchasesConfiguration;
import com.revenuecat.purchases.PurchasesError;
import com.revenuecat.purchases.Store;
Expand All @@ -24,8 +25,8 @@
import com.revenuecat.purchases.interfaces.UpdatedCustomerInfoListener;
import com.revenuecat.purchases.models.BillingFeature;
import com.revenuecat.purchases.models.GoogleProrationMode;
import com.revenuecat.purchases.models.InAppMessageType;
import com.revenuecat.purchases.models.GoogleReplacementMode;
import com.revenuecat.purchases.models.InAppMessageType;
import com.revenuecat.purchases.models.StoreProduct;
import com.revenuecat.purchases.models.StoreTransaction;
import com.revenuecat.purchases.models.SubscriptionOption;
Expand Down Expand Up @@ -146,6 +147,8 @@ static void checkConfiguration(final Context context,
.appUserID("")
.observerMode(true)
.observerMode(false)
.purchasesAreCompletedBy(PurchasesAreCompletedBy.REVENUECAT)
.purchasesAreCompletedBy(PurchasesAreCompletedBy.MY_APP)
.service(executorService)
.diagnosticsEnabled(true)
.entitlementVerificationMode(EntitlementVerificationMode.INFORMATIONAL)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.revenuecat.apitester.kotlin

import com.revenuecat.purchases.PurchasesAreCompletedBy

@Suppress("unused")
private class PurchasesAreCompletedByAPI {
fun check(mode: PurchasesAreCompletedBy) {
when (mode) {
PurchasesAreCompletedBy.REVENUECAT,
PurchasesAreCompletedBy.MY_APP,
-> {
}
}.exhaustive
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.revenuecat.purchases.ProductType
import com.revenuecat.purchases.PurchaseParams
import com.revenuecat.purchases.PurchaseResult
import com.revenuecat.purchases.Purchases
import com.revenuecat.purchases.PurchasesAreCompletedBy
import com.revenuecat.purchases.PurchasesConfiguration
import com.revenuecat.purchases.PurchasesError
import com.revenuecat.purchases.Store
Expand Down Expand Up @@ -191,6 +192,8 @@ private class PurchasesCommonAPI {
.appUserID("")
.observerMode(true)
.observerMode(false)
.purchasesAreCompletedBy(PurchasesAreCompletedBy.REVENUECAT)
.purchasesAreCompletedBy(PurchasesAreCompletedBy.MY_APP)
.showInAppMessagesAutomatically(true)
.service(executorService)
.diagnosticsEnabled(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.revenuecat.sample

import android.app.Application
import com.revenuecat.purchases.Purchases
import com.revenuecat.purchases.PurchasesAreCompletedBy
import com.revenuecat.purchases.PurchasesConfiguration
import com.revenuecat.purchases.amazon.AmazonConfiguration
import com.revenuecat.purchases.interfaces.UpdatedCustomerInfoListener
Expand All @@ -22,7 +23,7 @@ class MainApplication : Application() {
Initialize the RevenueCat Purchases SDK.
- appUserID is nil, so an anonymous ID will be generated automatically by the Purchases SDK. Read more about Identifying Users here: https://docs.revenuecat.com/docs/user-ids
- observerMode is false, so Purchases will automatically handle finishing transactions. Read more about Observer Mode here: https://docs.revenuecat.com/docs/observer-mode
- purchasesAreCompletedBy is set to REVENUECAT, so Purchases will automatically handle finishing transactions. Read more about finishing transactions here: https://docs.revenuecat.com/docs/observer-mode
*/
val builder = when (BuildConfig.STORE) {
"amazon" -> AmazonConfiguration.Builder(this, Constants.AMAZON_API_KEY)
Expand All @@ -31,7 +32,7 @@ class MainApplication : Application() {
}
Purchases.configure(
builder
.observerMode(false)
.purchasesAreCompletedBy(PurchasesAreCompletedBy.REVENUECAT)
.appUserID(null)
.build(),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.revenuecat.sample
import android.app.Application
import com.revenuecat.purchases.LogLevel
import com.revenuecat.purchases.Purchases
import com.revenuecat.purchases.PurchasesAreCompletedBy
import com.revenuecat.purchases.PurchasesConfiguration
import com.revenuecat.purchases.amazon.AmazonConfiguration
import com.revenuecat.sample.data.Constants
Expand All @@ -21,7 +22,7 @@ class MainApplication : Application() {
Initialize the RevenueCat Purchases SDK.
- appUserID is nil, so an anonymous ID will be generated automatically by the Purchases SDK. Read more about Identifying Users here: https://docs.revenuecat.com/docs/user-ids
- observerMode is false, so Purchases will automatically handle finishing transactions. Read more about Observer Mode here: https://docs.revenuecat.com/docs/observer-mode
- purchasesAreCompletedBy is set to REVENUECAT, so Purchases will automatically handle finishing transactions. Read more about finishing transactions here: https://docs.revenuecat.com/docs/observer-mode
*/
val builder = when (BuildConfig.STORE) {
"amazon" -> AmazonConfiguration.Builder(this, Constants.AMAZON_API_KEY)
Expand All @@ -30,7 +31,7 @@ class MainApplication : Application() {
}
Purchases.configure(
builder
.observerMode(false)
.purchasesAreCompletedBy(PurchasesAreCompletedBy.REVENUECAT)
.appUserID(null)
.diagnosticsEnabled(true)
.build(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.revenuecat.paywallstester
import android.app.Application
import com.revenuecat.purchases.LogLevel
import com.revenuecat.purchases.Purchases
import com.revenuecat.purchases.PurchasesAreCompletedBy
import com.revenuecat.purchases.PurchasesConfiguration

class MainApplication : Application() {
Expand All @@ -14,7 +15,7 @@ class MainApplication : Application() {

Purchases.configure(
PurchasesConfiguration.Builder(this, Constants.GOOGLE_API_KEY)
.observerMode(false)
.purchasesAreCompletedBy(PurchasesAreCompletedBy.REVENUECAT)
.appUserID(null)
.diagnosticsEnabled(true)
.build(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import androidx.core.view.children
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.revenuecat.purchases.EntitlementVerificationMode
import com.revenuecat.purchases.LogLevel
import com.revenuecat.purchases.Purchases
import com.revenuecat.purchases.PurchasesAreCompletedBy
import com.revenuecat.purchases.PurchasesConfiguration
import com.revenuecat.purchases.amazon.AmazonConfiguration
import com.revenuecat.purchases_sample.BuildConfig
Expand Down Expand Up @@ -98,12 +100,15 @@ class ConfigureFragment : Fragment() {
}

binding.amazonStoreRadioId.setOnCheckedChangeListener { _, isChecked ->
// Disable observer mode options if Amazon
binding.observerModeCheckbox.isEnabled = !isChecked
// Disable PurchasesAreCompletedBy options if Amazon
with(binding.purchaseCompletionRadioGroup) {
isEnabled = !isChecked
children.forEach { it.isEnabled = !isChecked }
}

// Toggle observer mode off only if Amazon is checked
// Check PurchasesAreCompletedBy.REVENUECAT if Amazon is checked
if (isChecked) {
binding.observerModeCheckbox.isChecked = false
binding.completedByRevenuecatRadioId.isChecked = true
}
}

Expand All @@ -117,7 +122,13 @@ class ConfigureFragment : Fragment() {

val entitlementVerificationMode = EntitlementVerificationMode.values()[verificationModeIndex]
val useAmazonStore = binding.storeRadioGroup.checkedRadioButtonId == R.id.amazon_store_radio_id
val useObserverMode = binding.observerModeCheckbox.isChecked
val purchasesAreCompletedBy = when (binding.purchaseCompletionRadioGroup.checkedRadioButtonId) {
R.id.completed_by_revenuecat_radio_id -> PurchasesAreCompletedBy.REVENUECAT
R.id.completed_by_my_app_radio_id -> PurchasesAreCompletedBy.MY_APP
else -> error(
"Unexpected checkedRadioButtonId: ${binding.purchaseCompletionRadioGroup.checkedRadioButtonId}",
)
}

val application = (requireActivity().application as MainApplication)

Expand All @@ -133,11 +144,11 @@ class ConfigureFragment : Fragment() {
val configuration = configurationBuilder
.diagnosticsEnabled(true)
.entitlementVerificationMode(entitlementVerificationMode)
.observerMode(useObserverMode)
.purchasesAreCompletedBy(purchasesAreCompletedBy)
.build()
Purchases.configure(configuration)

if (useObserverMode) {
if (purchasesAreCompletedBy == PurchasesAreCompletedBy.MY_APP) {
ObserverModeBillingClient.start(application, application.logHandler)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,30 +134,43 @@
</RadioGroup>

<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/observer_mode_label"
android:text="Observer Mode"
android:id="@+id/purchase_completion_label"
android:text="@string/purchases_completed_by"
android:textSize="15sp"
android:layout_marginTop="20dp"
app:layout_constraintTop_toBottomOf="@id/store_label"
app:layout_constraintStart_toStartOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

<CheckBox
android:id="@+id/observer_mode_checkbox"
app:layout_constraintTop_toTopOf="@id/observer_mode_label"
app:layout_constraintBottom_toBottomOf="@id/observer_mode_label"
<RadioGroup
android:id="@+id/purchase_completion_radio_group"
app:layout_constraintTop_toTopOf="@id/purchase_completion_label"
app:layout_constraintBottom_toBottomOf="@id/purchase_completion_label"
app:layout_constraintEnd_toEndOf="parent"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/completed_by_revenuecat_radio_id"
android:text="@string/revenuecat"
android:checked="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RadioButton
android:id="@+id/completed_by_my_app_radio_id"
android:text="@string/my_app"
android:checked="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RadioGroup>

<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/google_unavailable_text_view"
android:text="@string/google_store_is_unavailable"
android:textAlignment="textEnd"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/observer_mode_checkbox"
app:layout_constraintTop_toBottomOf="@id/purchase_completion_radio_group"
app:layout_constraintWidth_percent="0.7"
android:visibility="gone"
tools:visibility="visible"
Expand Down
3 changes: 3 additions & 0 deletions examples/purchase-tester/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<string name="store">Store</string>
<string name="google">Google</string>
<string name="amazon">Amazon</string>
<string name="revenuecat">RevenueCat</string>
<string name="continue_text">Continue</string>
<string name="loving_cat">😻</string>
<string name="logs">Logs</string>
Expand All @@ -21,4 +22,6 @@
<string name="proxy">Proxy</string>
<string name="buy_product">Buy Product</string>
<string name="find_placement">Find Placement</string>
<string name="purchases_completed_by">Purchases are completed by</string>
<string name="my_app">My app</string>
</resources>
Loading

0 comments on commit b8bae4a

Please sign in to comment.