From 6f7458395ddd56e0865c77435ee75df642d2993b Mon Sep 17 00:00:00 2001 From: proletarius101 Date: Wed, 17 Nov 2021 16:34:46 +0000 Subject: [PATCH] update userland to v2.8.3 --- metadata/tech.ula.yml | 50 ++-- metadata/tech.ula/disable-gms-billing.patch | 252 ++++++++++++++++++++ 2 files changed, 276 insertions(+), 26 deletions(-) create mode 100644 metadata/tech.ula/disable-gms-billing.patch diff --git a/metadata/tech.ula.yml b/metadata/tech.ula.yml index 0dd95d8526..64e97a6cc7 100644 --- a/metadata/tech.ula.yml +++ b/metadata/tech.ula.yml @@ -8,30 +8,6 @@ IssueTracker: https://github.com/CypherpunkArmory/UserLAnd/issues Changelog: https://github.com/CypherpunkArmory/UserLAnd/releases AutoName: UserLAnd -Description: |- - UserLAnd provides the easiest way to run GNU/Linux Distros on Android. - - Features: - * Run full linux distros or specific applications on top of Android. - * Install and uninstall like a regular app. - * No root required. - - There are two ways to use UserLAnd - - Using single-click apps: - * Click an app. - * Fill out the required information. - * You're good to go! - Using user-defined custom sessions: - - * Define a session - This describes what filesystem you are going to use, and - what kind of service you want to use when connecting to it (ssh or vnc). - * Define a filesystem - This describes what distribution of Linux you want to - install. - * Once defined, just tap on the session to start up. This will download - necessary assets, setup the filesystem, start the server, and connect to it. - This will take several minutes for the first start up, but will be quicker - afterwards. RepoType: git Repo: https://github.com/CypherpunkArmory/UserLAnd @@ -232,6 +208,28 @@ Builds: - echo "tracepotHttpsEndpoint=\"\"" >> tracepot.properties - sed -i -e 's/versionCode vcode/versionCode $$VERCODE$$/' build.gradle + - versionName: 2.8.3 + versionCode: 7438725 + commit: v2.8.3 + subdir: app + patch: + - disable-gms-billing.patch + gradle: + - yes + prebuild: + - echo "tracepotHttpsEndpoint=\"\"" >> tracepot.properties + - sed -i -e 's/versionCode vcode/versionCode $$VERCODE$$/' build.gradle + - sed -i -e '/com.google.firebase/d' -e '/firebaseCrashlytics/d' -e '/com.google.android.play/d' + -e '/com.google.gms/d' -e '/com.google.android.gms/d' -e '/billingclient/d' + build.gradle + - sed -i -e "s/buildConfigField 'boolean', 'ENABLE_PLAY_SERVICES', 'true'/buildConfigField + 'boolean', 'ENABLE_PLAY_SERVICES', 'false'/" build.gradle + buildjni: + - ../termux-app/terminal-emulator/src/main/jni + ndk: r21b + preassemble: + - androidDependencies + MaintainerNotes: |- We can't enable AUM since 2.5.14, versionCode is generated at build time and depends on the actual date. Actual versionCode is copied from the upstream release. @@ -240,5 +238,5 @@ MaintainerNotes: |- AutoUpdateMode: None UpdateCheckMode: None -CurrentVersion: 2.7.2 -CurrentVersionCode: 2927098 +CurrentVersion: 2.8.3 +CurrentVersionCode: 7438725 diff --git a/metadata/tech.ula/disable-gms-billing.patch b/metadata/tech.ula/disable-gms-billing.patch new file mode 100644 index 0000000000..86a9e76b72 --- /dev/null +++ b/metadata/tech.ula/disable-gms-billing.patch @@ -0,0 +1,252 @@ +diff --git a/app/src/main/java/tech/ula/MainActivity.kt b/app/src/main/java/tech/ula/MainActivity.kt +index ee2daa7..93209aa 100644 +--- a/app/src/main/java/tech/ula/MainActivity.kt ++++ b/app/src/main/java/tech/ula/MainActivity.kt +@@ -83,7 +83,7 @@ class MainActivity : AppCompatActivity(), SessionListFragment.SessionSelection, + } + + val billingManager by lazy { +- BillingManager(this, contributionPrompter.onEntitledSubPurchases, contributionPrompter.onEntitledInAppPurchases, contributionPrompter.onPurchase, contributionPrompter.onSubscriptionSupportedChecked) ++ BillingManager(this, contributionPrompter.onSubscriptionSupportedChecked) + } + + private val contributionPrompter by lazy { +@@ -735,4 +735,4 @@ class MainActivity : AppCompatActivity(), SessionListFragment.SessionSelection, + else -> true + } + } +-} +\ No newline at end of file ++} +diff --git a/app/src/main/java/tech/ula/utils/BillingManager.kt b/app/src/main/java/tech/ula/utils/BillingManager.kt +index 5e44366..f725d9a 100644 +--- a/app/src/main/java/tech/ula/utils/BillingManager.kt ++++ b/app/src/main/java/tech/ula/utils/BillingManager.kt +@@ -2,17 +2,6 @@ package tech.ula.utils + + import android.app.Activity + import android.util.Log +-import com.android.billingclient.api.AcknowledgePurchaseParams +-import com.android.billingclient.api.BillingClient +-import com.android.billingclient.api.BillingClient.BillingResponseCode +-import com.android.billingclient.api.BillingClient.FeatureType +-import com.android.billingclient.api.BillingClientStateListener +-import com.android.billingclient.api.BillingFlowParams +-import com.android.billingclient.api.BillingResult +-import com.android.billingclient.api.Purchase +-import com.android.billingclient.api.PurchasesUpdatedListener +-import com.android.billingclient.api.SkuDetails +-import com.android.billingclient.api.SkuDetailsParams + import java.util.* // ktlint-disable no-wildcard-imports + import kotlin.collections.HashMap + +@@ -25,58 +14,11 @@ import kotlin.collections.HashMap + */ + class BillingManager( + private val activity: Activity, +- private val onEntitledSubPurchases: (List) -> Unit, +- private val onEntitledInAppPurchases: (List) -> Unit, +- private val onPurchase: (Purchase) -> Unit, + private val onSubscriptionSupportedChecked: (Boolean) -> Unit + ) { + +- private val purchasesUpdatedListener = PurchasesUpdatedListener { billingResult, purchases -> +- when (billingResult.responseCode) { +- BillingResponseCode.OK -> { +- purchases?.let { +- for (purchase in purchases) { +- when (purchase.purchaseState) { +- Purchase.PurchaseState.PURCHASED -> { +- onPurchase(purchase) +- if (!purchase.isAcknowledged) { +- val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() +- .setPurchaseToken(purchase.purchaseToken) +- .build() +- billingClient.acknowledgePurchase(acknowledgePurchaseParams) { billingResult -> +- log("acknowledgePurchase(), billingResult=$billingResult") +- } +- } +- } +- Purchase.PurchaseState.PENDING -> { +- // Here you can confirm to the user that they've started the pending +- // purchase, and to complete it, they should follow instructions that +- // are given to them. You can also choose to remind the user in the +- // future to complete the purchase if you detect that it is still +- // pending. +- } +- } +- } +- } +- log("onPurchasesUpdated(), $purchases") +- } +- BillingResponseCode.USER_CANCELED -> log("onPurchasesUpdated() - user cancelled the purchase flow - skipping") +- else -> log("onPurchasesUpdated() got unknown resultCode: ${billingResult.responseCode}") +- } +- } +- +- private val skuDetailsMap = HashMap() +- +- private val billingClient: BillingClient = BillingClient.newBuilder(activity) +- .enablePendingPurchases() +- .setListener(purchasesUpdatedListener) +- .build() +- + private var isBillingServiceConnected = false + +- val populateSkus: (List) -> Unit = { +- it.forEach { skuDetailsMap.put(it.sku, it) } +- } + private fun handlePopulateSkuError(code: Int, message: String) { + log("Error trying to populate skus. code: $code message: $message") + } +@@ -84,102 +26,27 @@ class BillingManager( + init { + startServiceConnection { + onSubscriptionSupportedChecked(isSubscriptionPurchaseSupported()) +- querySubPurchases() +- queryInAppPurchases() +- querySubscriptionSkuDetails(listOf(Sku.US1_MONTHLY, Sku.US5_MONTHLY, Sku.US10_MONTHLY, Sku.US20_MONTHLY, Sku.US1_YEARLY, Sku.US5_YEARLY, Sku.US10_YEARLY, Sku.US20_YEARLY), populateSkus, ::handlePopulateSkuError) +- queryInAppSkuDetails(listOf(Sku.US1_ONETIME, Sku.US5_ONETIME, Sku.US10_ONETIME, Sku.US20_ONETIME), populateSkus, ::handlePopulateSkuError) + } + } + + fun querySubPurchases() { +- if (isSubscriptionPurchaseSupported()) { +- val purchasesResult = billingClient.queryPurchases(BillingClient.SkuType.SUBS) +- if (purchasesResult.responseCode == BillingResponseCode.OK) { +- onEntitledSubPurchases(Collections.unmodifiableList(purchasesResult.purchasesList)) +- } else { +- log("Error trying to query purchases: $purchasesResult") +- } +- } + } + + fun queryInAppPurchases() { +- val purchasesResult = billingClient.queryPurchases(BillingClient.SkuType.INAPP) +- if (purchasesResult.responseCode == BillingResponseCode.OK) { +- onEntitledInAppPurchases(Collections.unmodifiableList(purchasesResult.purchasesList)) +- } else { +- log("Error trying to query purchases: $purchasesResult") +- } + } + + fun startPurchaseFlow(productId: String) { +- val sku = skuDetailsMap.get(productId) +- if (sku != null) { +- startServiceConnection { +- val flowParams = BillingFlowParams.newBuilder().setSkuDetails(sku).build() +- val billingResult = billingClient.launchBillingFlow(activity, flowParams) +- log("startPurchaseFlow(...), billingResult=$billingResult") +- } +- } + } + + fun destroy() { + log("destroy()") +- if (billingClient.isReady) { +- billingClient.endConnection() +- } + } + + private fun startServiceConnection(task: () -> Unit) { +- if (isBillingServiceConnected) { +- task() +- } else { +- billingClient.startConnection(object : BillingClientStateListener { +- override fun onBillingSetupFinished(billingResult: BillingResult) { +- log("onBillingSetupFinished(...), billingResult=$billingResult") +- if (billingResult.responseCode == BillingResponseCode.OK) { +- isBillingServiceConnected = true +- task() +- } +- } +- +- override fun onBillingServiceDisconnected() { +- log("onBillingServiceDisconnected()") +- isBillingServiceConnected = false +- // Try to restart the connection on the next request to +- // Google Play by calling the startConnection() method. +- } +- }) +- } +- } +- +- private fun querySubscriptionSkuDetails(skus: List, onSuccess: (List) -> Unit, onError: (code: Int, message: String) -> Unit) { +- val params = SkuDetailsParams.newBuilder().setSkusList(skus).setType(BillingClient.SkuType.SUBS) +- billingClient.querySkuDetailsAsync(params.build()) { billingResult, skuDetailsList -> +- if (billingResult.responseCode == BillingResponseCode.OK && skuDetailsList != null) { +- onSuccess(skuDetailsList) +- } else { +- onError(billingResult.responseCode, billingResult.debugMessage) +- } +- } +- } +- +- private fun queryInAppSkuDetails(skus: List, onSuccess: (List) -> Unit, onError: (code: Int, message: String) -> Unit) { +- val params = SkuDetailsParams.newBuilder().setSkusList(skus).setType(BillingClient.SkuType.INAPP) +- billingClient.querySkuDetailsAsync(params.build()) { billingResult, skuDetailsList -> +- if (billingResult.responseCode == BillingResponseCode.OK && skuDetailsList != null) { +- onSuccess(skuDetailsList) +- } else { +- onError(billingResult.responseCode, billingResult.debugMessage) +- } +- } + } + + private fun isSubscriptionPurchaseSupported(): Boolean { +- val response = billingClient.isFeatureSupported(FeatureType.SUBSCRIPTIONS) +- if (response.responseCode != BillingResponseCode.OK) { +- log("isSubscriptionPurchaseSupported(), not supported, error response: $response") +- } +- return response.responseCode == BillingResponseCode.OK ++ return false + } + + private fun log(message: String) { +diff --git a/app/src/main/java/tech/ula/utils/UserPrompter.kt b/app/src/main/java/tech/ula/utils/UserPrompter.kt +index b61a5a3..1e0aae4 100644 +--- a/app/src/main/java/tech/ula/utils/UserPrompter.kt ++++ b/app/src/main/java/tech/ula/utils/UserPrompter.kt +@@ -11,7 +11,6 @@ import android.widget.SeekBar + import android.widget.TextView + import android.widget.Toast + import androidx.annotation.StringRes +-import com.android.billingclient.api.Purchase + import tech.ula.MainActivity + import tech.ula.R + +@@ -358,34 +357,6 @@ class ContributionPrompter(private val activity: MainActivity, private val viewG + subscriptionSupported = it + } + +- val onEntitledSubPurchases: (List) -> Unit = { +- processSubPurchases(it) +- } +- +- val onEntitledInAppPurchases: (List) -> Unit = { +- processInAppPurchases(it) +- } +- +- val onPurchase: (Purchase) -> Unit = { +- processPurchase(it) +- } +- +- private fun processSubPurchases(purchases: List) { +- setHasMadeSubPurchase(!purchases.isEmpty()) +- } +- +- private fun processInAppPurchases(purchases: List) { +- setHasMadeInAppPurchase(!purchases.isEmpty()) +- } +- +- private fun processPurchase(purchase: Purchase) { +- if (purchase.sku.endsWith("onetime")) +- setHasMadeInAppPurchase(true) +- else +- setHasMadeSubPurchase(true) +- Toast.makeText(savedActivity, "Thanks for your contribution", Toast.LENGTH_LONG).show() +- } +- + override val initialPrompt: Int + get() = R.string.contribution_primary + override val initialPosBtnText: Int