From 9164e38c34b08c9d7231fc7135f89aac166cd6ef Mon Sep 17 00:00:00 2001 From: vkamn Date: Fri, 27 Feb 2026 17:43:36 +0700 Subject: [PATCH] fix: restore backup android (#2291) * fix: fixed restore backup on android * chore: add resume helper for android * chore: add ResumeHelper.runWhenActive call after all native android dialogs * fix: add permission for tv file picker * fix: add file picker handler in kotlin --------- Co-authored-by: NickVs2015 --- .../src/org/amnezia/vpn/AmneziaActivity.kt | 38 +++++++++++++++++-- .../src/org/amnezia/vpn/TvFilePicker.kt | 5 ++- client/ui/controllers/settingsController.cpp | 11 +++--- 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/client/android/src/org/amnezia/vpn/AmneziaActivity.kt b/client/android/src/org/amnezia/vpn/AmneziaActivity.kt index ffe327528..293f21eaf 100644 --- a/client/android/src/org/amnezia/vpn/AmneziaActivity.kt +++ b/client/android/src/org/amnezia/vpn/AmneziaActivity.kt @@ -75,6 +75,8 @@ private const val OPEN_FILE_ACTION_CODE = 3 private const val CHECK_NOTIFICATION_PERMISSION_ACTION_CODE = 4 private const val PREFS_NOTIFICATION_PERMISSION_ASKED = "NOTIFICATION_PERMISSION_ASKED" +private const val OPEN_FILE_AFTER_RESUME_DELAY_MS = 400L +private const val KEY_PENDING_OPEN_FILE_URI = "pending_open_file_uri" class AmneziaActivity : QtActivity() { @@ -94,6 +96,8 @@ class AmneziaActivity : QtActivity() { private var isActivityResumed = false private var hasWindowFocus = false private val resumeHandler = Handler(Looper.getMainLooper()) + private var pendingOpenFileUri: String? = null + private var openFileDeliveryScheduled = false private val vpnServiceEventHandler: Handler by lazy(NONE) { object : Handler(Looper.getMainLooper()) { @@ -196,11 +200,18 @@ class AmneziaActivity : QtActivity() { doBindService() } ) + pendingOpenFileUri = savedInstanceState?.getString(KEY_PENDING_OPEN_FILE_URI) + openFileDeliveryScheduled = false registerBroadcastReceivers() intent?.let(::processIntent) runBlocking { vpnProto = proto.await() } } + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + pendingOpenFileUri?.let { outState.putString(KEY_PENDING_OPEN_FILE_URI, it) } + } + private fun loadLibs() { listOf( "rsapss", @@ -270,6 +281,7 @@ class AmneziaActivity : QtActivity() { hasWindowFocus = false // Cancel all pending operations when activity stops resumeHandler.removeCallbacksAndMessages(null) + openFileDeliveryScheduled = false Log.d(TAG, "Stop Amnezia activity") doUnbindService() mainScope.launch { @@ -366,6 +378,7 @@ class AmneziaActivity : QtActivity() { isActivityResumed = false // Cancel all pending operations when activity pauses resumeHandler.removeCallbacksAndMessages(null) + openFileDeliveryScheduled = false Log.d(TAG, "Pause Amnezia activity") } @@ -374,6 +387,21 @@ class AmneziaActivity : QtActivity() { isActivityResumed = true Log.d(TAG, "Resume Amnezia activity") + if (pendingOpenFileUri != null && !openFileDeliveryScheduled) { + val uri = pendingOpenFileUri!! + openFileDeliveryScheduled = true + resumeHandler.postDelayed({ + if (!isFinishing && !isDestroyed) { + pendingOpenFileUri = null + openFileDeliveryScheduled = false + mainScope.launch { + qtInitialized.await() + QtAndroidController.onFileOpened(uri) + } + } + }, OPEN_FILE_AFTER_RESUME_DELAY_MS) + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { window.decorView.apply { invalidate() @@ -790,9 +818,13 @@ class AmneziaActivity : QtActivity() { grantUriPermission(packageName, this, Intent.FLAG_GRANT_READ_URI_PERMISSION) }?.toString() ?: "" Log.v(TAG, "Open file: $uri") - mainScope.launch { - qtInitialized.await() - QtAndroidController.onFileOpened(uri) + if (uri.isNotEmpty()) { + pendingOpenFileUri = uri + } else { + mainScope.launch { + qtInitialized.await() + QtAndroidController.onFileOpened(uri) + } } } )) diff --git a/client/android/src/org/amnezia/vpn/TvFilePicker.kt b/client/android/src/org/amnezia/vpn/TvFilePicker.kt index 33f4355f4..a3c7ec8af 100644 --- a/client/android/src/org/amnezia/vpn/TvFilePicker.kt +++ b/client/android/src/org/amnezia/vpn/TvFilePicker.kt @@ -33,7 +33,10 @@ class TvFilePicker : ComponentActivity() { return intent } }) { - setResult(RESULT_OK, Intent().apply { data = it }) + setResult(RESULT_OK, Intent().apply { + data = it + addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + }) finish() } diff --git a/client/ui/controllers/settingsController.cpp b/client/ui/controllers/settingsController.cpp index 6a3726828..8b456f3a6 100644 --- a/client/ui/controllers/settingsController.cpp +++ b/client/ui/controllers/settingsController.cpp @@ -178,12 +178,11 @@ void SettingsController::backupAppConfig(const QString &fileName) void SettingsController::restoreAppConfig(const QString &fileName) { - QFile file(fileName); - - file.open(QIODevice::ReadOnly); - - QByteArray data = file.readAll(); - + QByteArray data; + if (!SystemController::readFile(fileName, data)) { + emit changeSettingsErrorOccurred(tr("Can't open file: %1").arg(fileName)); + return; + } restoreAppConfigFromData(data); }