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 <nv@amnezia.org>
This commit is contained in:
vkamn
2026-02-27 17:43:36 +07:00
committed by GitHub
parent 8f7559f01b
commit 9164e38c34
3 changed files with 44 additions and 10 deletions

View File

@@ -75,6 +75,8 @@ private const val OPEN_FILE_ACTION_CODE = 3
private const val CHECK_NOTIFICATION_PERMISSION_ACTION_CODE = 4 private const val CHECK_NOTIFICATION_PERMISSION_ACTION_CODE = 4
private const val PREFS_NOTIFICATION_PERMISSION_ASKED = "NOTIFICATION_PERMISSION_ASKED" 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() { class AmneziaActivity : QtActivity() {
@@ -94,6 +96,8 @@ class AmneziaActivity : QtActivity() {
private var isActivityResumed = false private var isActivityResumed = false
private var hasWindowFocus = false private var hasWindowFocus = false
private val resumeHandler = Handler(Looper.getMainLooper()) private val resumeHandler = Handler(Looper.getMainLooper())
private var pendingOpenFileUri: String? = null
private var openFileDeliveryScheduled = false
private val vpnServiceEventHandler: Handler by lazy(NONE) { private val vpnServiceEventHandler: Handler by lazy(NONE) {
object : Handler(Looper.getMainLooper()) { object : Handler(Looper.getMainLooper()) {
@@ -196,11 +200,18 @@ class AmneziaActivity : QtActivity() {
doBindService() doBindService()
} }
) )
pendingOpenFileUri = savedInstanceState?.getString(KEY_PENDING_OPEN_FILE_URI)
openFileDeliveryScheduled = false
registerBroadcastReceivers() registerBroadcastReceivers()
intent?.let(::processIntent) intent?.let(::processIntent)
runBlocking { vpnProto = proto.await() } 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() { private fun loadLibs() {
listOf( listOf(
"rsapss", "rsapss",
@@ -270,6 +281,7 @@ class AmneziaActivity : QtActivity() {
hasWindowFocus = false hasWindowFocus = false
// Cancel all pending operations when activity stops // Cancel all pending operations when activity stops
resumeHandler.removeCallbacksAndMessages(null) resumeHandler.removeCallbacksAndMessages(null)
openFileDeliveryScheduled = false
Log.d(TAG, "Stop Amnezia activity") Log.d(TAG, "Stop Amnezia activity")
doUnbindService() doUnbindService()
mainScope.launch { mainScope.launch {
@@ -366,6 +378,7 @@ class AmneziaActivity : QtActivity() {
isActivityResumed = false isActivityResumed = false
// Cancel all pending operations when activity pauses // Cancel all pending operations when activity pauses
resumeHandler.removeCallbacksAndMessages(null) resumeHandler.removeCallbacksAndMessages(null)
openFileDeliveryScheduled = false
Log.d(TAG, "Pause Amnezia activity") Log.d(TAG, "Pause Amnezia activity")
} }
@@ -374,6 +387,21 @@ class AmneziaActivity : QtActivity() {
isActivityResumed = true isActivityResumed = true
Log.d(TAG, "Resume Amnezia activity") 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) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
window.decorView.apply { window.decorView.apply {
invalidate() invalidate()
@@ -790,9 +818,13 @@ class AmneziaActivity : QtActivity() {
grantUriPermission(packageName, this, Intent.FLAG_GRANT_READ_URI_PERMISSION) grantUriPermission(packageName, this, Intent.FLAG_GRANT_READ_URI_PERMISSION)
}?.toString() ?: "" }?.toString() ?: ""
Log.v(TAG, "Open file: $uri") Log.v(TAG, "Open file: $uri")
mainScope.launch { if (uri.isNotEmpty()) {
qtInitialized.await() pendingOpenFileUri = uri
QtAndroidController.onFileOpened(uri) } else {
mainScope.launch {
qtInitialized.await()
QtAndroidController.onFileOpened(uri)
}
} }
} }
)) ))

View File

@@ -33,7 +33,10 @@ class TvFilePicker : ComponentActivity() {
return intent return intent
} }
}) { }) {
setResult(RESULT_OK, Intent().apply { data = it }) setResult(RESULT_OK, Intent().apply {
data = it
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
})
finish() finish()
} }

View File

@@ -178,12 +178,11 @@ void SettingsController::backupAppConfig(const QString &fileName)
void SettingsController::restoreAppConfig(const QString &fileName) void SettingsController::restoreAppConfig(const QString &fileName)
{ {
QFile file(fileName); QByteArray data;
if (!SystemController::readFile(fileName, data)) {
file.open(QIODevice::ReadOnly); emit changeSettingsErrorOccurred(tr("Can't open file: %1").arg(fileName));
return;
QByteArray data = file.readAll(); }
restoreAppConfigFromData(data); restoreAppConfigFromData(data);
} }