diff options
Diffstat (limited to 'ui/src/main/java/com/wireguard/android/preference/ZipExporterPreference.kt')
-rw-r--r-- | ui/src/main/java/com/wireguard/android/preference/ZipExporterPreference.kt | 83 |
1 files changed, 38 insertions, 45 deletions
diff --git a/ui/src/main/java/com/wireguard/android/preference/ZipExporterPreference.kt b/ui/src/main/java/com/wireguard/android/preference/ZipExporterPreference.kt index fe8d39a3..c1eaa9f6 100644 --- a/ui/src/main/java/com/wireguard/android/preference/ZipExporterPreference.kt +++ b/ui/src/main/java/com/wireguard/android/preference/ZipExporterPreference.kt @@ -13,13 +13,18 @@ import androidx.preference.Preference import com.google.android.material.snackbar.Snackbar import com.wireguard.android.Application import com.wireguard.android.R -import com.wireguard.android.model.ObservableTunnel +import com.wireguard.android.util.AdminKnobs import com.wireguard.android.util.BiometricAuthenticator import com.wireguard.android.util.DownloadsFileSaver -import com.wireguard.android.util.AdminKnobs import com.wireguard.android.util.ErrorMessages import com.wireguard.android.util.FragmentUtils -import java9.util.concurrent.CompletableFuture +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import java.nio.charset.StandardCharsets import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream @@ -29,52 +34,40 @@ import java.util.zip.ZipOutputStream */ class ZipExporterPreference(context: Context, attrs: AttributeSet?) : Preference(context, attrs) { private var exportedFilePath: String? = null - private fun exportZip() { - Application.getTunnelManager().tunnels.thenAccept(this::exportZip) - } - - private fun exportZip(tunnels: List<ObservableTunnel>) { - val futureConfigs = tunnels.map { it.configAsync.toCompletableFuture() }.toTypedArray() - if (futureConfigs.isEmpty()) { - exportZipComplete(null, IllegalArgumentException( - context.getString(R.string.no_tunnels_error))) - return - } - CompletableFuture.allOf(*futureConfigs) - .whenComplete { _, exception -> - Application.getAsyncWorker().supplyAsync { - if (exception != null) throw exception - val outputFile = DownloadsFileSaver.save(context, "wireguard-export.zip", "application/zip", true) - try { - ZipOutputStream(outputFile.outputStream).use { zip -> - for (i in futureConfigs.indices) { - zip.putNextEntry(ZipEntry(tunnels[i].name + ".conf")) - zip.write(futureConfigs[i].getNow(null)!!.toWgQuickString().toByteArray(StandardCharsets.UTF_8)) - } - zip.closeEntry() + GlobalScope.launch(Dispatchers.Main.immediate) { + val tunnels = Application.getTunnelManager().getTunnels() + try { + exportedFilePath = withContext(Dispatchers.IO) { + val configs = tunnels.map { async(SupervisorJob()) { it.getConfigAsync() } }.awaitAll() + if (configs.isEmpty()) { + throw IllegalArgumentException(context.getString(R.string.no_tunnels_error)) + } + val outputFile = DownloadsFileSaver.save(context, "wireguard-export.zip", "application/zip", true) + try { + ZipOutputStream(outputFile.outputStream).use { zip -> + for (i in configs.indices) { + zip.putNextEntry(ZipEntry(tunnels[i].name + ".conf")) + zip.write(configs[i].toWgQuickString().toByteArray(StandardCharsets.UTF_8)) } - } catch (e: Exception) { - outputFile.delete() - throw e + zip.closeEntry() } - outputFile.fileName - }.whenComplete(this::exportZipComplete) + } catch (e: Throwable) { + outputFile.delete() + throw e + } + outputFile.fileName } - } - - private fun exportZipComplete(filePath: String?, throwable: Throwable?) { - if (throwable != null) { - val error = ErrorMessages[throwable] - val message = context.getString(R.string.zip_export_error, error) - Log.e(TAG, message, throwable) - Snackbar.make( - FragmentUtils.getPrefActivity(this).findViewById(android.R.id.content), - message, Snackbar.LENGTH_LONG).show() - isEnabled = true - } else { - exportedFilePath = filePath - notifyChanged() + notifyChanged() + } catch (e: Throwable) { + val error = ErrorMessages[e] + val message = context.getString(R.string.zip_export_error, error) + Log.e(TAG, message, e) + Snackbar.make( + FragmentUtils.getPrefActivity(this@ZipExporterPreference).findViewById(android.R.id.content), + message, Snackbar.LENGTH_LONG).show() + isEnabled = true + } } } |