From 0158c84de72f9a363d57ebe7880f96f7468bc6d1 Mon Sep 17 00:00:00 2001 From: Davinci9196 Date: Thu, 26 Mar 2026 15:03:41 +0800 Subject: [PATCH 1/2] Fix crash caused by resuming cancelled coroutine in fetchSelfPlayer --- .../kotlin/org/microg/gms/games/extensions.kt | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/play-services-core/src/main/kotlin/org/microg/gms/games/extensions.kt b/play-services-core/src/main/kotlin/org/microg/gms/games/extensions.kt index 215328957c..ced8f413d1 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/games/extensions.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/games/extensions.kt @@ -1,4 +1,4 @@ -/* +/* * SPDX-FileCopyrightText: 2023 microG Project Team * SPDX-License-Identifier: Apache-2.0 */ @@ -51,6 +51,7 @@ import org.microg.gms.utils.singleInstanceOf import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException import kotlin.coroutines.suspendCoroutine +import kotlinx.coroutines.suspendCancellableCoroutine const val SERVICE_GAMES_LITE = "oauth2:https://www.googleapis.com/auth/games_lite" @@ -336,19 +337,19 @@ suspend fun fetchSelfPlayer( context: Context, authToken: String, queue: RequestQueue = singleInstanceOf { Volley.newRequestQueue(context.applicationContext) } -) = suspendCoroutine { continuation -> - queue.add( - object : JsonObjectRequest( - "https://www.googleapis.com/games/v1/players/me", - { continuation.resume(it) }, - { continuation.resumeWithException(it) }) { - override fun getHeaders(): MutableMap { - return mutableMapOf( - "Authorization" to "OAuth $authToken" - ) - } +) = suspendCancellableCoroutine { continuation -> + val request = object : JsonObjectRequest( + "https://www.googleapis.com/games/v1/players/me", + { if (continuation.isActive) continuation.resume(it) }, + { if (continuation.isActive) continuation.resumeWithException(it) }) { + override fun getHeaders(): MutableMap { + return mutableMapOf( + "Authorization" to "OAuth $authToken" + ) } - ) + } + continuation.invokeOnCancellation { request.cancel() } + queue.add(request) } suspend fun requestGameToken( From 56d8f42e92d060ae33172897cbccf3e76e035271 Mon Sep 17 00:00:00 2001 From: Davinci9196 Date: Thu, 26 Mar 2026 15:29:27 +0800 Subject: [PATCH 2/2] add try/catch --- .../kotlin/org/microg/gms/games/GamesService.kt | 13 +++++++++---- .../org/microg/gms/games/GamesSignInActivity.kt | 11 ++++++++--- .../main/kotlin/org/microg/gms/games/extensions.kt | 12 ++++++++++-- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/play-services-core/src/main/kotlin/org/microg/gms/games/GamesService.kt b/play-services-core/src/main/kotlin/org/microg/gms/games/GamesService.kt index cd30a1675b..e29c2c0ee4 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/games/GamesService.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/games/GamesService.kt @@ -1,4 +1,4 @@ -/* +/* * SPDX-FileCopyrightText: 2023 microG Project Team * SPDX-License-Identifier: Apache-2.0 */ @@ -115,8 +115,13 @@ class GamesService : BaseService(TAG, GmsService.GAMES) { return@launchWhenStarted sendSignInRequired(account) } - if (!performGamesSignIn(this@GamesService, packageName, account, scopes = scopes)) { - Log.d(TAG, "performGamesSignIn fail, sign in required") + try { + if (!performGamesSignIn(this@GamesService, packageName, account, scopes = scopes)) { + Log.d(TAG, "performGamesSignIn fail, sign in required") + return@launchWhenStarted sendSignInRequired(account) + } + } catch (e: Exception) { + Log.w(TAG, "performGamesSignIn exception, sign in required", e) return@launchWhenStarted sendSignInRequired(account) } @@ -793,4 +798,4 @@ class GamesServiceImpl(val context: Context, override val lifecycle: Lifecycle, override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean = warnOnTransactionIssues(code, reply, flags, TAG) { super.onTransact(code, data, reply, flags) } -} \ No newline at end of file +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/games/GamesSignInActivity.kt b/play-services-core/src/main/kotlin/org/microg/gms/games/GamesSignInActivity.kt index 4319e97e01..9179044560 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/games/GamesSignInActivity.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/games/GamesSignInActivity.kt @@ -1,4 +1,4 @@ -/* +/* * SPDX-FileCopyrightText: 2023 microG Project Team * SPDX-License-Identifier: Apache-2.0 */ @@ -81,7 +81,12 @@ class GamesSignInActivity : AppCompatActivity() { ?.getParcelable("googleSignInAccount")?.account if (account != null) { lifecycleScope.launchWhenStarted { - signIn(account) + try { + signIn(account) + } catch (e: Exception) { + Log.w(TAG, "signIn failed", e) + finish() + } } return } @@ -89,4 +94,4 @@ class GamesSignInActivity : AppCompatActivity() { finish() } } -} \ No newline at end of file +} diff --git a/play-services-core/src/main/kotlin/org/microg/gms/games/extensions.kt b/play-services-core/src/main/kotlin/org/microg/gms/games/extensions.kt index ced8f413d1..510126ae45 100644 --- a/play-services-core/src/main/kotlin/org/microg/gms/games/extensions.kt +++ b/play-services-core/src/main/kotlin/org/microg/gms/games/extensions.kt @@ -309,13 +309,21 @@ suspend fun performGamesSignIn( fetchSelfPlayer(context, authResponse.auth, queue) } catch (e : Exception){ requestGameToken(context, account, scopes, authManager.isPermitted)?.let { - fetchSelfPlayer(context, it, queue) + try { + fetchSelfPlayer(context, it, queue) + } catch (e: Exception) { + return false + } } ?: return false } } 403 -> { requestGameToken(context, account, scopes, authManager.isPermitted)?.let { - fetchSelfPlayer(context, it, queue) + try { + fetchSelfPlayer(context, it, queue) + } catch (e: Exception) { + return false + } } ?: return false } else -> throw e