diff --git a/.circleci/config.yml b/.circleci/config.yml index 12ee46f94d..8750294481 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -987,6 +987,9 @@ workflows: build_type: "debug" requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - test: name: test_defaults_bc7_release flavor: "defaults" @@ -994,6 +997,9 @@ workflows: build_type: "release" requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - test: name: test_cec_<< matrix.build_type >> flavor: "customEntitlementComputation" @@ -1003,6 +1009,9 @@ workflows: matrix: parameters: build_type: ["debug", "release"] + # FIXME We only need read access here. + context: + - github-packages-publishing # Special case for defaults BC8 release with kover - test: name: test_defaults_bc8_release @@ -1012,54 +1021,105 @@ workflows: run_kover: true requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - verify-compatibility: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - lint: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - detekt: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - metalava: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - assemble-purchase-tester: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - assemble-paywall-tester-release: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - assemble-rct-tester-release: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - assemble-admob-integration-sample-app: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - test_dokka_hide_internal: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - test-galaxy: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - run-backend-integration-tests: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - record-and-upload-paparazzi-revenuecatui-snapshots: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - run-revenuecatui-ui-tests: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - emerge_purchases_ui_snapshot_tests: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - emerge_size_analysis_tests: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - run-maestro-e2e-tests: requires: - prepare-tests + # FIXME We only need read access here. + context: + - github-packages-publishing - run-integration-tests: requires: - prepare-tests diff --git a/purchases/build.gradle.kts b/purchases/build.gradle.kts index 71b89a2b9f..5432703275 100644 --- a/purchases/build.gradle.kts +++ b/purchases/build.gradle.kts @@ -233,6 +233,7 @@ dependencies { implementation(libs.tink) implementation(libs.playServices.ads.identifier) implementation(libs.coroutines.core) + implementation("com.revenuecat.purchases:purchases-core:0.0.0-rust-SNAPSHOT") "bc8Api"(libs.billing.bc8) "bc7Api"(libs.billing.bc7) diff --git a/purchases/src/defaults/kotlin/com/revenuecat/purchases/NativeHttpClient.kt b/purchases/src/defaults/kotlin/com/revenuecat/purchases/NativeHttpClient.kt new file mode 100644 index 0000000000..980822fcce --- /dev/null +++ b/purchases/src/defaults/kotlin/com/revenuecat/purchases/NativeHttpClient.kt @@ -0,0 +1,25 @@ +package com.revenuecat.purchases + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import uniffi.purchases_core.HttpClient +import uniffi.purchases_core.HttpException +import java.net.URL + +/** + * PoC: Kotlin implementation of the Rust `HttpClient` foreign trait. + * Rust calls `fetch(url)` on this object and awaits the result. + */ +internal class NativeHttpClient : HttpClient { + + override suspend fun fetch(url: String): String { + return withContext(Dispatchers.IO) { + try { + URL(url).readText() + } catch (e: Exception) { + throw HttpException.RequestFailed("${e.javaClass.simpleName}: ${e.message}") + } + } + } + +} diff --git a/purchases/src/defaults/kotlin/com/revenuecat/purchases/Purchases.kt b/purchases/src/defaults/kotlin/com/revenuecat/purchases/Purchases.kt index 4a7f723a39..4bb0fe926c 100644 --- a/purchases/src/defaults/kotlin/com/revenuecat/purchases/Purchases.kt +++ b/purchases/src/defaults/kotlin/com/revenuecat/purchases/Purchases.kt @@ -15,6 +15,9 @@ import com.revenuecat.purchases.common.errorLog import com.revenuecat.purchases.common.events.FeatureEvent import com.revenuecat.purchases.common.infoLog import com.revenuecat.purchases.common.log +import uniffi.purchases_core.add +import uniffi.purchases_core.fetchWithNative +import uniffi.purchases_core.performOperation import com.revenuecat.purchases.customercenter.CustomerCenterListener import com.revenuecat.purchases.deeplinks.DeepLinkParser import com.revenuecat.purchases.interfaces.Callback @@ -43,6 +46,10 @@ import com.revenuecat.purchases.strings.BillingStrings import com.revenuecat.purchases.strings.ConfigureStrings import com.revenuecat.purchases.utils.DefaultIsDebugBuildProvider import com.revenuecat.purchases.virtualcurrencies.VirtualCurrencies +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import uniffi.purchases_core.HttpException +import uniffi.purchases_core.OperationMode import java.net.URL import java.util.Locale @@ -1283,6 +1290,32 @@ public class Purchases internal constructor( public fun configure( configuration: PurchasesConfiguration, ): Purchases { + // Call Rust add() function to verify integration + val rustResult = add(2uL, 3uL) + infoLog { "Rust add(2, 3) = $rustResult" } + GlobalScope.launch { + val successResult = performOperation(OperationMode.SUCCESS) + errorLog { "Operation result in Rust: $successResult" } + try { + val failureResult = performOperation(OperationMode.ERROR) + } catch (e: Exception) { + errorLog(e) { "Error performing operation in Rust" } + } + try { + val timeoutResult = performOperation(OperationMode.TIMEOUT) + } catch (e: Exception) { + errorLog(e) { "Timeout performing operation in Rust" } + } + + // PoC: 2-way communication — Rust calls back into Kotlin via HttpClient + try { + val result = fetchWithNative(NativeHttpClient(), "https://httpbin.org/get") + infoLog { "[Android] Rust round-trip result: $result" } + } catch (e: Exception) { + errorLog(e) { "[Android] Rust round-trip error" } + } + } + if (isConfigured) { if (backingFieldSharedInstance?.purchasesOrchestrator?.currentConfiguration == configuration) { infoLog { ConfigureStrings.INSTANCE_ALREADY_EXISTS_WITH_SAME_CONFIG } diff --git a/settings.gradle.kts b/settings.gradle.kts index 1c1f4f833a..69e676ae7f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -88,6 +88,16 @@ dependencyResolutionManagement { // fallback for the rest of the dependencies mavenCentral() + // GitHub Packages for purchases-core Rust library + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/RevenueCat/purchases-core") + credentials { + username = System.getenv("GITHUB_ACTOR") ?: "" + password = System.getenv("GITHUB_TOKEN") ?: "" + } + } + // Local Samsung IAP SDK AAR flatDir { dirs(samsungIapSdkDir) diff --git a/test-apps/sdksizetesting/settings.gradle.kts b/test-apps/sdksizetesting/settings.gradle.kts index c7b145085d..dc056c7fce 100644 --- a/test-apps/sdksizetesting/settings.gradle.kts +++ b/test-apps/sdksizetesting/settings.gradle.kts @@ -21,6 +21,21 @@ dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { mavenLocal() + // GitHub Packages for purchases-core Rust library (transitive dependency) + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/RevenueCat/purchases-core") + credentials { + username = System.getenv("GITHUB_ACTOR") ?: "" + password = System.getenv("GITHUB_TOKEN") ?: "" + } + content { + // Only fetch purchases-core from GitHub Packages + includeModule("com.revenuecat.purchases", "purchases-core") + includeModule("com.revenuecat.purchases", "purchases-core-android") + includeModule("com.revenuecat.purchases", "purchases-core-jvm") + } + } google { content { // Exclude to make sure we use dependency from mavenLocal