diff --git a/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingCreateAlternativeBillingOnlyTokenCallback.aidl b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingCreateAlternativeBillingOnlyTokenCallback.aidl new file mode 100644 index 0000000000..76da286a27 --- /dev/null +++ b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingCreateAlternativeBillingOnlyTokenCallback.aidl @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2024 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ +package com.android.vending.billing; + +import android.os.Bundle; + +interface IInAppBillingCreateAlternativeBillingOnlyTokenCallback { + /** + * @param bundle a Bundle with the following keys: + * "RESPONSE_CODE" - Integer + * "DEBUG_MESSAGE" - String + * "CREATE_ALTERNATIVE_BILLING_ONLY_REPORTING_DETAILS" - String with JSON encoded reporting details with the following keys: + * "externalTransactionToken" - String used to report a transaction made via alternative billing + */ + void callback(in Bundle bundle); +} \ No newline at end of file diff --git a/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingCreateExternalPaymentReportingDetailsCallback.aidl b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingCreateExternalPaymentReportingDetailsCallback.aidl new file mode 100644 index 0000000000..5c21ab0460 --- /dev/null +++ b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingCreateExternalPaymentReportingDetailsCallback.aidl @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2024 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ +package com.android.vending.billing; + +import android.os.Bundle; + +interface IInAppBillingCreateExternalPaymentReportingDetailsCallback { + /** + * @param bundle a Bundle with the following keys: + * "RESPONSE_CODE" - Integer + * "DEBUG_MESSAGE" - String + */ + void callback(in Bundle bundle); +} \ No newline at end of file diff --git a/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingDelegateToBackendCallback.aidl b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingDelegateToBackendCallback.aidl new file mode 100644 index 0000000000..a7a5c0b409 --- /dev/null +++ b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingDelegateToBackendCallback.aidl @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2024 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ +package com.android.vending.billing; + +import android.os.Bundle; + +interface IInAppBillingDelegateToBackendCallback { + +} \ No newline at end of file diff --git a/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingGetAlternativeBillingOnlyDialogIntentCallback.aidl b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingGetAlternativeBillingOnlyDialogIntentCallback.aidl new file mode 100644 index 0000000000..d05e99bbd4 --- /dev/null +++ b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingGetAlternativeBillingOnlyDialogIntentCallback.aidl @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2024 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ +package com.android.vending.billing; + +import android.os.Bundle; + +interface IInAppBillingGetAlternativeBillingOnlyDialogIntentCallback { + /** + * @param bundle a Bundle with the following keys: + * "RESPONSE_CODE" - Integer + * "DEBUG_MESSAGE" - String + * "ALTERNATIVE_BILLING_ONLY_DIALOG_INTENT" - PendingIntent + */ + void callback(in Bundle bundle); +} \ No newline at end of file diff --git a/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingGetBillingConfigCallback.aidl b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingGetBillingConfigCallback.aidl new file mode 100644 index 0000000000..37f54c6439 --- /dev/null +++ b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingGetBillingConfigCallback.aidl @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2023 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ +package com.android.vending.billing; + +import android.os.Bundle; + +interface IInAppBillingGetBillingConfigCallback { + /** + * @param bundle a Bundle with the following keys: + * "BILLING_CONFIG" - String with JSON encoded billing config with following keys: + * "countryCode" - String with customer's country code (ISO-3166-1 alpha2) + */ + void callback(in Bundle bundle); +} \ No newline at end of file diff --git a/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingGetExternalPaymentDialogIntentCallback.aidl b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingGetExternalPaymentDialogIntentCallback.aidl new file mode 100644 index 0000000000..be5e178141 --- /dev/null +++ b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingGetExternalPaymentDialogIntentCallback.aidl @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2024 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ +package com.android.vending.billing; + +import android.os.Bundle; + +interface IInAppBillingGetExternalPaymentDialogIntentCallback { + /** + * @param bundle a Bundle with the following keys: + * "RESPONSE_CODE" - Integer + * "DEBUG_MESSAGE" - String + * "EXTERNAL_PAYMENT_DIALOG_INTENT" - PendingIntent + */ + void callback(in Bundle bundle); +} \ No newline at end of file diff --git a/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingIsAlternativeBillingOnlyAvailableCallback.aidl b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingIsAlternativeBillingOnlyAvailableCallback.aidl new file mode 100644 index 0000000000..c2f552bfd6 --- /dev/null +++ b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingIsAlternativeBillingOnlyAvailableCallback.aidl @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2024 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ +package com.android.vending.billing; + +import android.os.Bundle; + +interface IInAppBillingIsAlternativeBillingOnlyAvailableCallback { + /** + * @param bundle a Bundle with the following keys: + * "RESPONSE_CODE" - Integer + * "DEBUG_MESSAGE" - String + */ + void callback(in Bundle bundle); +} \ No newline at end of file diff --git a/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingIsExternalPaymentAvailableCallback.aidl b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingIsExternalPaymentAvailableCallback.aidl new file mode 100644 index 0000000000..18a73b0476 --- /dev/null +++ b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingIsExternalPaymentAvailableCallback.aidl @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2024 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ +package com.android.vending.billing; + +import android.os.Bundle; + +interface IInAppBillingIsExternalPaymentAvailableCallback { + /** + * @param bundle a Bundle with the following keys: + * "RESPONSE_CODE" - Integer + * "DEBUG_MESSAGE" - String + */ + void callback(in Bundle bundle); +} \ No newline at end of file diff --git a/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl index 0342932f83..7c9861ca7b 100644 --- a/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl +++ b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl @@ -1,6 +1,16 @@ package com.android.vending.billing; import android.os.Bundle; +import com.android.vending.billing.IInAppBillingServiceCallback; +import com.android.vending.billing.IInAppBillingCreateAlternativeBillingOnlyTokenCallback; +import com.android.vending.billing.IInAppBillingCreateExternalPaymentReportingDetailsCallback; +import com.android.vending.billing.IInAppBillingDelegateToBackendCallback; +import com.android.vending.billing.IInAppBillingGetAlternativeBillingOnlyDialogIntentCallback; +import com.android.vending.billing.IInAppBillingGetBillingConfigCallback; +import com.android.vending.billing.IInAppBillingGetExternalPaymentDialogIntentCallback; +import com.android.vending.billing.IInAppBillingIsAlternativeBillingOnlyAvailableCallback; +import com.android.vending.billing.IInAppBillingIsExternalPaymentAvailableCallback; + /** * InAppBillingService is the service that provides in-app billing version 3 and beyond. @@ -363,8 +373,72 @@ interface IInAppBillingService { * "KEY_DIMEN_BOTTOM" - Integer * "KEY_CATEGORY_IDS" - ArrayList * "playBillingLibraryVersion" - String + * @param callback callback that is invoked with the result, see IInAppBillingServiceCallback.aidl for details + */ + void showInAppMessages(int apiVersion, String packageName, in Bundle extraParams, IInAppBillingServiceCallback callback) = 1200; + + /** + * @param apiVersion billing API version that the app is using, must be 18 or later + * @param packageName package name of the calling app + * @param extraParams a Bundle with the following optional keys: + * "playBillingLibraryVersion" - String + * @param callback callback that is invoked with the result, see IInAppBillingGetBillingConfigCallback.aidl for details + */ + void getBillingConfig(int apiVersion, String packageName, in Bundle extraParams, IInAppBillingGetBillingConfigCallback callback) = 1300; + + /** + * @param apiVersion billing API version that the app is using, must be 21 or later + * @param packageName package name of the calling app + * @param extraParams a Bundle with the following optional keys: + * "playBillingLibraryVersion" - String + * @param callback callback that is invoked with the result, see IInAppBillingIsAlternativeBillingOnlyAvailableCallback.aidl for details + */ + void isAlternativeBillingOnlyAvailable(int apiVersion, String packageName, in Bundle extraParams, IInAppBillingIsAlternativeBillingOnlyAvailableCallback callback) = 1400; + + /** + * @param apiVersion billing API version that the app is using, must be 21 or later + * @param packageName package name of the calling app + * @param extraParams a Bundle with the following optional keys: + * "playBillingLibraryVersion" - String + * @param callback callback that is invoked with the result, see IInAppBillingCreateAlternativeBillingOnlyTokenCallback.aidl for details + */ + void createAlternativeBillingOnlyToken(int apiVersion, String packageName, in Bundle extraParams, IInAppBillingCreateAlternativeBillingOnlyTokenCallback callback) = 1500; + + /** + * @param apiVersion billing API version that the app is using, must be 21 or later + * @param packageName package name of the calling app + * @param extraParams a Bundle with the following optional keys: + * "playBillingLibraryVersion" - String + * @param callback callback that is invoked with the result, see IInAppBillingGetAlternativeBillingOnlyDialogIntentCallback.aidl for details + */ + void getAlternativeBillingOnlyDialogIntent(int apiVersion, String packageName, in Bundle extraParams, IInAppBillingGetAlternativeBillingOnlyDialogIntentCallback callback) = 1600; + + /** + * @param apiVersion billing API version that the app is using, must be 22 or later + * @param packageName package name of the calling app + * @param extraParams a Bundle with the following optional keys: + * "playBillingLibraryVersion" - String + * @param callback callback that is invoked with the result, see IInAppBillingIsExternalPaymentAvailableCallback.aidl for details + */ + void isExternalOfferAvailable(int apiVersion, String packageName, in Bundle extraParams, IInAppBillingIsExternalPaymentAvailableCallback callback) = 1700; + + /** + * @param apiVersion billing API version that the app is using, must be 22 or later + * @param packageName package name of the calling app + * @param extraParams a Bundle with the following optional keys: + * "playBillingLibraryVersion" - String + * @param callback callback that is invoked with the result, see IInAppBillingCreateExternalPaymentReportingDetailsCallback.aidl for details + */ + void createExternalOfferReportingDetails(int apiVersion, String packageName, in Bundle extraParams, IInAppBillingCreateExternalPaymentReportingDetailsCallback callback) = 1800; + + /** + * @param apiVersion billing API version that the app is using, must be 22 or later + * @param packageName package name of the calling app + * @param extraParams a Bundle with the following optional keys: + * "playBillingLibraryVersion" - String + * @param callback callback that is invoked with the result, see IInAppBillingGetExternalPaymentDialogIntentCallback.aidl for details */ -// void showInAppMessages(int apiVersion, String packageName, in Bundle extraParams, IInAppBillingServiceCallback callback) = 1200; + void showExternalOfferInformationDialog(int apiVersion, String packageName, in Bundle extraParams, IInAppBillingGetExternalPaymentDialogIntentCallback callback) = 1900; -// void r(String packageName, Bundle arg2, eql arg3) = 1300; + void delegateToBackend(in Bundle bundle, IInAppBillingDelegateToBackendCallback callback) = 2000; } \ No newline at end of file diff --git a/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingServiceCallback.aidl b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingServiceCallback.aidl new file mode 100644 index 0000000000..4432bc8bce --- /dev/null +++ b/vending-app/src/main/aidl/com/android/vending/billing/IInAppBillingServiceCallback.aidl @@ -0,0 +1,15 @@ +/* + * SPDX-FileCopyrightText: 2024 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ +package com.android.vending.billing; + +import android.os.Bundle; + +interface IInAppBillingServiceCallback { + /** + * @param bundle a Bundle with the following keys: + * "KEY_LAUNCH_INTENT" - PendingIntent + */ + void callback(in Bundle bundle); +} \ No newline at end of file diff --git a/vending-app/src/main/java/org/microg/vending/billing/InAppBillingServiceImpl.kt b/vending-app/src/main/java/org/microg/vending/billing/InAppBillingServiceImpl.kt index 5803da0d47..2d3d0311f4 100644 --- a/vending-app/src/main/java/org/microg/vending/billing/InAppBillingServiceImpl.kt +++ b/vending-app/src/main/java/org/microg/vending/billing/InAppBillingServiceImpl.kt @@ -18,7 +18,16 @@ import androidx.core.os.bundleOf import com.android.billingclient.api.BillingClient.BillingResponseCode import com.android.billingclient.api.BillingClient.ProductType import com.android.vending.VendingPreferences +import com.android.vending.billing.IInAppBillingCreateAlternativeBillingOnlyTokenCallback +import com.android.vending.billing.IInAppBillingCreateExternalPaymentReportingDetailsCallback +import com.android.vending.billing.IInAppBillingDelegateToBackendCallback +import com.android.vending.billing.IInAppBillingGetAlternativeBillingOnlyDialogIntentCallback +import com.android.vending.billing.IInAppBillingGetBillingConfigCallback +import com.android.vending.billing.IInAppBillingGetExternalPaymentDialogIntentCallback +import com.android.vending.billing.IInAppBillingIsAlternativeBillingOnlyAvailableCallback +import com.android.vending.billing.IInAppBillingIsExternalPaymentAvailableCallback import com.android.vending.billing.IInAppBillingService +import com.android.vending.billing.IInAppBillingServiceCallback import org.microg.vending.billing.ui.InAppBillingHostActivity import org.microg.vending.billing.ui.logic.BuyFlowResult import com.google.android.gms.droidguard.DroidGuardClient @@ -26,8 +35,10 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking +import org.json.JSONObject import org.microg.gms.utils.toHexString import org.microg.vending.billing.core.* +import java.util.Locale private class BuyFlowCacheEntry( var packageName: String, @@ -179,7 +190,7 @@ class InAppBillingServiceImpl(private val context: Context) : IInAppBillingServi Log.w(TAG, "isBillingSupported: Billing is disabled") return resultBundle(BillingResponseCode.BILLING_UNAVAILABLE, "Billing is disabled") } - if (apiVersion < 3 || apiVersion > 17) { + if (apiVersion < 3) { return resultBundle(BillingResponseCode.BILLING_UNAVAILABLE, "Client does not support the requesting billing API.") } if (extraParams != null && apiVersion < 7) { @@ -626,4 +637,73 @@ class InAppBillingServiceImpl(private val context: Context) : IInAppBillingServi return resultBundle(BillingResponseCode.BILLING_UNAVAILABLE, "Not yet implemented") } + override fun showInAppMessages(apiVersion: Int, packageName: String?, extraParams: Bundle?, callback: IInAppBillingServiceCallback?) { + Log.d(TAG, "showInAppMessages Not yet implemented") + } + + override fun getBillingConfig(apiVersion: Int, packageName: String?, bundle: Bundle?, callback: IInAppBillingGetBillingConfigCallback) { + Log.d(TAG, "getBillingConfig apiVersion:$apiVersion packageName:$packageName bundle:$bundle") + val result = resultBundle(BillingResponseCode.OK, "", bundleOf( + "BILLING_CONFIG" to JSONObject().apply { put("countryCode", Locale.getDefault().country) }.toString() + )) + callback.callback(result) + } + + override fun isAlternativeBillingOnlyAvailable( + apiVersion: Int, + packageName: String?, + extraParams: Bundle?, + callback: IInAppBillingIsAlternativeBillingOnlyAvailableCallback? + ) { + Log.d(TAG, "isAlternativeBillingOnlyAvailable Not yet implemented") + } + + override fun createAlternativeBillingOnlyToken( + apiVersion: Int, + packageName: String?, + extraParams: Bundle?, + callback: IInAppBillingCreateAlternativeBillingOnlyTokenCallback? + ) { + Log.d(TAG, "createAlternativeBillingOnlyToken Not yet implemented") + } + + override fun getAlternativeBillingOnlyDialogIntent( + apiVersion: Int, + packageName: String?, + extraParams: Bundle?, + callback: IInAppBillingGetAlternativeBillingOnlyDialogIntentCallback? + ) { + Log.d(TAG, "getAlternativeBillingOnlyDialogIntent Not yet implemented") + } + + override fun isExternalOfferAvailable( + apiVersion: Int, + packageName: String?, + extraParams: Bundle?, + callback: IInAppBillingIsExternalPaymentAvailableCallback? + ) { + Log.d(TAG, "isExternalOfferAvailable Not yet implemented") + } + + override fun createExternalOfferReportingDetails( + apiVersion: Int, + packageName: String?, + extraParams: Bundle?, + callback: IInAppBillingCreateExternalPaymentReportingDetailsCallback? + ) { + Log.d(TAG, "createExternalOfferReportingDetails Not yet implemented") + } + + override fun showExternalOfferInformationDialog( + apiVersion: Int, + packageName: String?, + extraParams: Bundle?, + callback: IInAppBillingGetExternalPaymentDialogIntentCallback? + ) { + Log.d(TAG, "showExternalOfferInformationDialog Not yet implemented") + } + + override fun delegateToBackend(bundle: Bundle?, callback: IInAppBillingDelegateToBackendCallback?) { + Log.d(TAG, "delegateToBackend Not yet implemented") + } } \ No newline at end of file diff --git a/vending-app/src/main/java/org/microg/vending/billing/core/HttpClient.kt b/vending-app/src/main/java/org/microg/vending/billing/core/HttpClient.kt index 18d2ba55b6..9835e0e8db 100644 --- a/vending-app/src/main/java/org/microg/vending/billing/core/HttpClient.kt +++ b/vending-app/src/main/java/org/microg/vending/billing/core/HttpClient.kt @@ -14,7 +14,7 @@ import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException import kotlin.coroutines.suspendCoroutine -private const val POST_TIMEOUT = 15000 +private const val POST_TIMEOUT = 8000 class HttpClient(context: Context) { private val requestQueue = singleInstanceOf { Volley.newRequestQueue(context.applicationContext) }