From 4dc4f4e6a57cf3f052616a7eafdb226cfcd732c7 Mon Sep 17 00:00:00 2001 From: izzy2lost Date: Sat, 14 Feb 2026 20:04:26 -0500 Subject: [PATCH] fix some crashes --- .gitignore | 2 + android/app/build.gradle.kts | 4 +- .../izzy2lost/x1box/GameLibraryActivity.kt | 63 +++++++++++++------ block/file-posix.c | 16 +++++ 4 files changed, 64 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 3f681d60cc..c6fea61a98 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ Desktop.ini logcat_*.txt hs_err_pid*.log replay_pid*.log +*.aab +*.txt diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index c05aa125a2..bd10cb1637 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -30,8 +30,8 @@ android { minSdk = 26 targetSdk = 36 - versionCode = 1 - versionName = "1.0.0" + versionCode = 2 + versionName = "1.0.1" ndk { abiFilters += listOf("arm64-v8a") diff --git a/android/app/src/main/java/com/izzy2lost/x1box/GameLibraryActivity.kt b/android/app/src/main/java/com/izzy2lost/x1box/GameLibraryActivity.kt index 9ab4edbd5b..cb5a7d0b00 100644 --- a/android/app/src/main/java/com/izzy2lost/x1box/GameLibraryActivity.kt +++ b/android/app/src/main/java/com/izzy2lost/x1box/GameLibraryActivity.kt @@ -4,6 +4,10 @@ import android.content.Intent import android.content.res.Configuration import android.net.Uri import android.os.Bundle +import android.text.SpannableStringBuilder +import android.text.Spanned +import android.text.method.LinkMovementMethod +import android.text.style.ClickableSpan import android.view.LayoutInflater import android.view.View import android.widget.ImageButton @@ -628,29 +632,50 @@ class GameLibraryActivity : AppCompatActivity() { } private fun showAboutDialog() { - val labels = arrayOf( - getString(R.string.library_about_link_source), - getString(R.string.library_about_link_privacy), - getString(R.string.library_about_link_fork), - getString(R.string.library_about_link_license), - getString(R.string.library_about_link_disclaimer) - ) - val urls = arrayOf( - getString(R.string.library_about_url_source), - getString(R.string.library_about_url_privacy), - getString(R.string.library_about_url_fork), - getString(R.string.library_about_url_license), - getString(R.string.library_about_url_disclaimer) + val links = listOf( + getString(R.string.library_about_link_source) to getString(R.string.library_about_url_source), + getString(R.string.library_about_link_privacy) to getString(R.string.library_about_url_privacy), + getString(R.string.library_about_link_fork) to getString(R.string.library_about_url_fork), + getString(R.string.library_about_link_license) to getString(R.string.library_about_url_license), + getString(R.string.library_about_link_disclaimer) to getString(R.string.library_about_url_disclaimer) ) - MaterialAlertDialogBuilder(this) - .setTitle(R.string.library_about_title) - .setMessage(R.string.library_about_message) - .setItems(labels) { _, which -> - openExternalLink(urls[which]) + val message = SpannableStringBuilder().apply { + append(getString(R.string.library_about_message)) + append("\n\n") + links.forEachIndexed { index, pair -> + val label = pair.first + val url = pair.second + append(label) + append('\n') + val start = length + append(url) + setSpan( + object : ClickableSpan() { + override fun onClick(widget: View) { + openExternalLink(url) + } + }, + start, + length, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE + ) + if (index != links.lastIndex) { + append("\n\n") + } } - .setNegativeButton(android.R.string.cancel, null) + } + + val dialog = MaterialAlertDialogBuilder(this) + .setTitle(R.string.library_about_title) + .setMessage(message) + .setPositiveButton(android.R.string.ok, null) .show() + + dialog.findViewById(android.R.id.message)?.apply { + movementMethod = LinkMovementMethod.getInstance() + linksClickable = true + } } private fun openExternalLink(url: String) { diff --git a/block/file-posix.c b/block/file-posix.c index cfda3ee1c4..4a66e18976 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -2525,6 +2525,22 @@ out: static int coroutine_fn raw_thread_pool_submit(ThreadPoolFunc func, void *arg) { +#ifdef __ANDROID__ + /* + * Some Android devices crash in coroutine context switches used by + * thread_pool_submit_co(). Allow forcing synchronous execution for + * raw I/O to avoid that path. Enabled by default on Android, set + * XEMU_ANDROID_INLINE_AIO=0 to restore thread-pool behavior. + */ + static int inline_aio = -1; + if (inline_aio < 0) { + const char *value = getenv("XEMU_ANDROID_INLINE_AIO"); + inline_aio = (!value || value[0] != '0') ? 1 : 0; + } + if (inline_aio) { + return func(arg); + } +#endif return thread_pool_submit_co(func, arg); }