Skip to content

Commit c005d99

Browse files
Fix IAP payment card switching issue (#3649)
Co-authored-by: Marvin W <git@larma.de>
1 parent 28b3cb9 commit c005d99

3 files changed

Lines changed: 73 additions & 5 deletions

File tree

‎vending-app/src/main/java/org/microg/vending/billing/core/ui/UIParser.kt‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,10 @@ private fun parseAction(action: Action?, result: BAction): Boolean {
9898
}
9999
action.viewClickAction?.let { viewClickAction ->
100100
if (viewClickAction.uiInfo != null) {
101-
result.uiInfo = parseUIInfo(viewClickAction.uiInfo!!)
101+
val parsedUiInfo = parseUIInfo(viewClickAction.uiInfo!!)
102+
if (parsedUiInfo.uiType != UIType.UNKNOWN) {
103+
result.uiInfo = parsedUiInfo
104+
}
102105
}
103106
return parseAction(viewClickAction.action, result)
104107
}
@@ -676,4 +679,4 @@ private fun extractPurchaseItemFromScreens(
676679
)
677680
}
678681
return mapOf<String, Any>("RESPONSE_CODE" to 0, "DEBUG_MESSAGE" to "") to null
679-
}
682+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2026 microG Project Team
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.microg.vending.billing.ui.logic
7+
8+
internal class BillingScreenHistory {
9+
private companion object {
10+
const val MAX_SIZE = 32
11+
}
12+
13+
private val screenIds = mutableListOf<String>()
14+
15+
fun recordTransition(fromScreenId: String?, toScreenId: String?): Boolean {
16+
if (fromScreenId == null || toScreenId == null || fromScreenId == toScreenId) return false
17+
18+
val targetIndex = screenIds.lastIndexOf(toScreenId)
19+
if (targetIndex >= 0) {
20+
screenIds.subList(targetIndex, screenIds.size).clear()
21+
return true
22+
}
23+
24+
if (screenIds.lastOrNull() == fromScreenId) return false
25+
screenIds.add(fromScreenId)
26+
if (screenIds.size > MAX_SIZE) screenIds.removeAt(0)
27+
return true
28+
}
29+
30+
fun popPrevious(currentScreenId: String?, isAvailable: (String) -> Boolean): String? {
31+
while (screenIds.isNotEmpty()) {
32+
val screenId = screenIds.removeAt(screenIds.lastIndex)
33+
if (screenId != currentScreenId && isAvailable(screenId)) return screenId
34+
}
35+
return null
36+
}
37+
}

‎vending-app/src/main/java/org/microg/vending/billing/ui/logic/InAppBillingViewModel.kt‎

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ class InAppBillingViewModel : ViewModel() {
7575
)
7676
)
7777
private lateinit var lastBuyFlowResult: BuyFlowResult
78+
private val screenHistory = BillingScreenHistory()
79+
private var currentScreenId: String? = null
7880

7981
private fun finishWithResult(result: Bundle) {
8082
viewModelScope.launch {
@@ -268,14 +270,36 @@ class InAppBillingViewModel : ViewModel() {
268270
}
269271
}
270272

273+
UIType.BILLING_PROFILE_SCREEN_ABANDON -> {
274+
if (showPreviousScreen()) return
275+
finishWithResult(billingUiViewState.result)
276+
}
277+
271278
else -> finishWithResult(billingUiViewState.result)
272279
}
273280
}
274281
}
275282
}
276283

277-
private fun showScreen(screenId: String): Boolean {
284+
private fun showPreviousScreen(): Boolean {
285+
val previousScreenId = screenHistory.popPrevious(
286+
currentScreenId,
287+
billingUiViewState.screenMap::containsKey
288+
)
289+
return previousScreenId != null && showScreen(
290+
previousScreenId,
291+
recordHistory = false
292+
)
293+
}
294+
295+
private fun showScreen(
296+
screenId: String,
297+
recordHistory: Boolean = true
298+
): Boolean {
299+
val previousScreenId = currentScreenId
278300
val showScreen = billingUiViewState.screenMap[screenId] ?: return false
301+
if (recordHistory) screenHistory.recordTransition(previousScreenId, screenId)
302+
currentScreenId = screenId
279303
billingUiViewState = billingUiViewState.copy(
280304
showScreen = showScreen,
281305
visible = true
@@ -300,11 +324,15 @@ class InAppBillingViewModel : ViewModel() {
300324
}
301325
val action = buyFlowResult.acquireResult?.action ?: return failAction()
302326
val screenMap = buyFlowResult.acquireResult.screenMap
303-
val showScreen = screenMap[action.screenId] ?: return failAction()
327+
val targetScreenId = action.screenId ?: return failAction()
328+
val showScreen = screenMap[targetScreenId] ?: return failAction()
304329
if (Log.isLoggable(TAG, Log.DEBUG)) Log.d(TAG, "handleAcquireResult, showScreen:$showScreen result:${buyFlowResult.acquireResult}")
305330
if (action.type != ActionType.SHOW) return failAction()
306331
lastBuyFlowResult = buyFlowResult
332+
val previousScreenId = currentScreenId
307333
billingUiViewState.screenMap.putAll(screenMap)
334+
screenHistory.recordTransition(previousScreenId, targetScreenId)
335+
currentScreenId = targetScreenId
308336
billingUiViewState = billingUiViewState.copy(
309337
showScreen = showScreen,
310338
result = buyFlowResult.result,
@@ -400,4 +428,4 @@ class InAppBillingViewModel : ViewModel() {
400428
resultBundle(BillingClient.BillingResponseCode.USER_CANCELED, "")
401429
finishWithResult(result)
402430
}
403-
}
431+
}

0 commit comments

Comments
 (0)