From ae7166a699b6073779c9fc19366f5b29e6ddae32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sun, 17 Mar 2024 01:00:21 +0800 Subject: [PATCH] Add import profile from file --- .../sfa/ui/main/ConfigurationFragment.kt | 13 +++++++++ .../sfa/ui/profile/QRScanActivity.kt | 9 ++++++ .../ui/profileoverride/PerAppProxyActivity.kt | 27 ++++++++++++----- .../res/drawable/ic_baseline_file_open_24.xml | 12 ++++++++ .../main/res/layout/activity_edit_profile.xml | 1 + app/src/main/res/layout/activity_qr_scan.xml | 13 +++++++++ app/src/main/res/layout/activity_vpn_scan.xml | 4 +-- .../res/layout/fragment_configuration.xml | 1 + .../res/layout/fragment_dashboard_groups.xml | 3 ++ app/src/main/res/layout/fragment_log.xml | 1 + app/src/main/res/layout/sheet_add_profile.xml | 29 +++++++++++++++++-- .../main/res/layout/view_dashboard_group.xml | 4 +-- .../res/layout/view_prefenence_screen.xml | 1 + app/src/main/res/values/strings.xml | 1 + 14 files changed, 105 insertions(+), 14 deletions(-) create mode 100644 app/src/main/res/drawable/ic_baseline_file_open_24.xml diff --git a/app/src/main/java/io/nekohasekai/sfa/ui/main/ConfigurationFragment.kt b/app/src/main/java/io/nekohasekai/sfa/ui/main/ConfigurationFragment.kt index 53a903d..5d40991 100644 --- a/app/src/main/java/io/nekohasekai/sfa/ui/main/ConfigurationFragment.kt +++ b/app/src/main/java/io/nekohasekai/sfa/ui/main/ConfigurationFragment.kt @@ -2,10 +2,12 @@ package io.nekohasekai.sfa.ui.main import android.annotation.SuppressLint import android.content.Intent +import android.net.Uri import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.widget.PopupMenu import androidx.core.view.isVisible import androidx.fragment.app.Fragment @@ -84,12 +86,18 @@ class ConfigurationFragment : Fragment() { class AddProfileDialog : BottomSheetDialogFragment(R.layout.sheet_add_profile) { + private val importFromFile = + registerForActivityResult(ActivityResultContracts.GetContent(), ::onImportResult) + private val scanQrCode = registerForActivityResult(QRScanActivity.Contract(), ::onScanResult) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val binding = SheetAddProfileBinding.bind(view) + binding.importFromFile.setOnClickListener { + importFromFile.launch("*/*") + } binding.scanQrCode.setOnClickListener { scanQrCode.launch(null) } @@ -99,6 +107,11 @@ class ConfigurationFragment : Fragment() { } } + private fun onImportResult(result: Uri?) { + dismiss() + (activity as? MainActivity ?: return).onNewIntent(Intent(Intent.ACTION_VIEW, result)) + } + private fun onScanResult(result: Intent?) { dismiss() (activity as? MainActivity ?: return).onNewIntent(result ?: return) diff --git a/app/src/main/java/io/nekohasekai/sfa/ui/profile/QRScanActivity.kt b/app/src/main/java/io/nekohasekai/sfa/ui/profile/QRScanActivity.kt index dbb87af..7d047e0 100644 --- a/app/src/main/java/io/nekohasekai/sfa/ui/profile/QRScanActivity.kt +++ b/app/src/main/java/io/nekohasekai/sfa/ui/profile/QRScanActivity.kt @@ -15,7 +15,9 @@ import androidx.camera.core.CameraSelector import androidx.camera.core.ImageAnalysis import androidx.camera.core.Preview import androidx.camera.lifecycle.ProcessCameraProvider +import androidx.camera.view.PreviewView import androidx.core.content.ContextCompat +import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import io.nekohasekai.libbox.Libbox import io.nekohasekai.sfa.R @@ -36,6 +38,13 @@ class QRScanActivity : AbstractActivity() { setTitle(R.string.profile_add_scan_qr_code) analysisExecutor = Executors.newSingleThreadExecutor() + binding.previewView.implementationMode = PreviewView.ImplementationMode.COMPATIBLE + binding.previewView.previewStreamState.observe(this) { + if (it === PreviewView.StreamState.STREAMING) { + binding.progress.isVisible = false + binding.previewView.implementationMode = PreviewView.ImplementationMode.PERFORMANCE + } + } if (ContextCompat.checkSelfPermission( this, Manifest.permission.CAMERA ) == PackageManager.PERMISSION_GRANTED diff --git a/app/src/main/java/io/nekohasekai/sfa/ui/profileoverride/PerAppProxyActivity.kt b/app/src/main/java/io/nekohasekai/sfa/ui/profileoverride/PerAppProxyActivity.kt index ab70515..2e6f392 100644 --- a/app/src/main/java/io/nekohasekai/sfa/ui/profileoverride/PerAppProxyActivity.kt +++ b/app/src/main/java/io/nekohasekai/sfa/ui/profileoverride/PerAppProxyActivity.kt @@ -30,10 +30,13 @@ import io.nekohasekai.sfa.databinding.ViewAppListItemBinding import io.nekohasekai.sfa.ktx.clipboardText import io.nekohasekai.sfa.ui.shared.AbstractActivity import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File +import java.util.concurrent.atomic.AtomicInteger import java.util.zip.ZipFile class PerAppProxyActivity : AbstractActivity() { @@ -530,18 +533,26 @@ class PerAppProxyActivity : AbstractActivity() { ).setView(binding.root).setCancelable(false).create() progress.show() lifecycleScope.launch { - val foundApps = withContext(Dispatchers.IO) { + val startTime = System.currentTimeMillis() + val foundApps = withContext(Dispatchers.Default) { mutableMapOf().also { foundApps -> - currentPackages.forEachIndexed { index, it -> - if (scanChinaPackage(it.packageName)) { - foundApps[it.packageName] = it + val progressInt = AtomicInteger() + currentPackages.map { it -> + async { + if (scanChinaPackage(it.packageName)) { + foundApps[it.packageName] = it + } + runOnUiThread { + binding.progress.progress = progressInt.addAndGet(1) + } } - withContext(Dispatchers.Main) { - binding.progress.progress = index + 1 - } - } + }.awaitAll() } } + Log.d( + "PerAppProxyActivity", + "Scan China apps took ${(System.currentTimeMillis() - startTime).toDouble() / 1000}s" + ) withContext(Dispatchers.Main) { progress.dismiss() if (foundApps.isEmpty()) { diff --git a/app/src/main/res/drawable/ic_baseline_file_open_24.xml b/app/src/main/res/drawable/ic_baseline_file_open_24.xml new file mode 100644 index 0000000..86307ea --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_file_open_24.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/app/src/main/res/layout/activity_edit_profile.xml b/app/src/main/res/layout/activity_edit_profile.xml index 17061f0..3110b63 100644 --- a/app/src/main/res/layout/activity_edit_profile.xml +++ b/app/src/main/res/layout/activity_edit_profile.xml @@ -28,6 +28,7 @@ android:id="@+id/profileLayout" android:layout_width="match_parent" android:layout_height="match_parent" + android:clipChildren="false" android:clipToPadding="false" android:orientation="vertical" android:padding="16dp" diff --git a/app/src/main/res/layout/activity_qr_scan.xml b/app/src/main/res/layout/activity_qr_scan.xml index aec26cd..e596e12 100644 --- a/app/src/main/res/layout/activity_qr_scan.xml +++ b/app/src/main/res/layout/activity_qr_scan.xml @@ -8,6 +8,19 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_vpn_scan.xml b/app/src/main/res/layout/activity_vpn_scan.xml index b6430c6..5b3d7f4 100644 --- a/app/src/main/res/layout/activity_vpn_scan.xml +++ b/app/src/main/res/layout/activity_vpn_scan.xml @@ -4,7 +4,6 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - diff --git a/app/src/main/res/layout/fragment_configuration.xml b/app/src/main/res/layout/fragment_configuration.xml index 600e764..af149c5 100644 --- a/app/src/main/res/layout/fragment_configuration.xml +++ b/app/src/main/res/layout/fragment_configuration.xml @@ -24,6 +24,7 @@ android:id="@+id/profileList" android:layout_width="match_parent" android:layout_height="match_parent" + android:clipChildren="false" android:clipToPadding="false" android:padding="16dp" android:scrollbars="vertical" /> diff --git a/app/src/main/res/layout/fragment_dashboard_groups.xml b/app/src/main/res/layout/fragment_dashboard_groups.xml index 2290090..29e9935 100644 --- a/app/src/main/res/layout/fragment_dashboard_groups.xml +++ b/app/src/main/res/layout/fragment_dashboard_groups.xml @@ -14,6 +14,9 @@ diff --git a/app/src/main/res/layout/fragment_log.xml b/app/src/main/res/layout/fragment_log.xml index aa00187..2efc797 100644 --- a/app/src/main/res/layout/fragment_log.xml +++ b/app/src/main/res/layout/fragment_log.xml @@ -23,6 +23,7 @@ android:id="@+id/logView" android:layout_width="match_parent" android:layout_height="match_parent" + android:clipChildren="false" android:clipToPadding="false" android:padding="16dp" android:visibility="gone" /> diff --git a/app/src/main/res/layout/sheet_add_profile.xml b/app/src/main/res/layout/sheet_add_profile.xml index d7e1e2e..beda7c1 100644 --- a/app/src/main/res/layout/sheet_add_profile.xml +++ b/app/src/main/res/layout/sheet_add_profile.xml @@ -15,6 +15,31 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> + + + + + + + + + @@ -57,7 +82,7 @@ diff --git a/app/src/main/res/layout/view_dashboard_group.xml b/app/src/main/res/layout/view_dashboard_group.xml index 6e03459..1b12613 100644 --- a/app/src/main/res/layout/view_dashboard_group.xml +++ b/app/src/main/res/layout/view_dashboard_group.xml @@ -6,8 +6,8 @@ android:clipChildren="false" android:clipToPadding="false" android:layout_height="wrap_content" - android:orientation="vertical" - android:padding="16dp"> + android:layout_marginBottom="16dp" + android:orientation="vertical"> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e5e0324..a8ac831 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -41,6 +41,7 @@ Create New Import + Import from file Scan QR code Front camera MLKit analyzer