mirror of
https://github.com/2dust/v2rayNG.git
synced 2026-10-29 06:31:54 +00:00
Clarify boot auto-connect and link system VPN settings (#6179)
* Clarify device-boot connection and link system VPN settings * Match Bakhtiari system spelling in VPN settings strings
This commit is contained in:
1 parent
f4f992eb9b
commit
5bfcdf90ec
12 files changed
+145
-21
No files matched your search
@@ -1,7 +1,10 @@
|
|||||||
package com.v2ray.ang.ui.settings
|
package com.v2ray.ang.ui.settings
|
||||||
|
|
||||||
|
import android.content.ActivityNotFoundException
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.provider.Settings
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@@ -24,10 +27,14 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.res.stringArrayResource
|
import androidx.compose.ui.res.stringArrayResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import com.v2ray.ang.AppConfig
|
import com.v2ray.ang.AppConfig
|
||||||
import com.v2ray.ang.AppConfig.VPN
|
import com.v2ray.ang.AppConfig.VPN
|
||||||
import com.v2ray.ang.R
|
import com.v2ray.ang.R
|
||||||
|
import com.v2ray.ang.extension.toastError
|
||||||
import com.v2ray.ang.handler.AppLocaleManager
|
import com.v2ray.ang.handler.AppLocaleManager
|
||||||
import com.v2ray.ang.handler.MmkvManager
|
import com.v2ray.ang.handler.MmkvManager
|
||||||
import com.v2ray.ang.handler.MmkvManager.rememberMmkvBool
|
import com.v2ray.ang.handler.MmkvManager.rememberMmkvBool
|
||||||
@@ -44,7 +51,9 @@ import com.v2ray.ang.ui.compose.SettingsMenuItem
|
|||||||
import com.v2ray.ang.ui.compose.SettingsSwitchItem
|
import com.v2ray.ang.ui.compose.SettingsSwitchItem
|
||||||
import com.v2ray.ang.ui.compose.ThemeManager
|
import com.v2ray.ang.ui.compose.ThemeManager
|
||||||
import com.v2ray.ang.ui.compose.verticalScrollbar
|
import com.v2ray.ang.ui.compose.verticalScrollbar
|
||||||
|
import com.v2ray.ang.util.LogUtil
|
||||||
import com.v2ray.ang.util.Utils
|
import com.v2ray.ang.util.Utils
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class SettingsActivity : BaseComponentActivity() {
|
class SettingsActivity : BaseComponentActivity() {
|
||||||
|
|
||||||
@@ -52,6 +61,26 @@ class SettingsActivity : BaseComponentActivity() {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.RESUMED) {
|
||||||
|
viewModel.refreshSystemVpnSettingsAvailability()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openSystemVpnSettings() {
|
||||||
|
try {
|
||||||
|
startActivity(Intent(Settings.ACTION_VPN_SETTINGS))
|
||||||
|
} catch (error: ActivityNotFoundException) {
|
||||||
|
reportSystemVpnSettingsFailure(error)
|
||||||
|
} catch (error: SecurityException) {
|
||||||
|
reportSystemVpnSettingsFailure(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reportSystemVpnSettingsFailure(error: RuntimeException) {
|
||||||
|
LogUtil.e(AppConfig.TAG, "Cannot open system VPN settings", error)
|
||||||
|
toastError(R.string.toast_system_vpn_settings_unavailable)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -59,7 +88,8 @@ class SettingsActivity : BaseComponentActivity() {
|
|||||||
SettingsScreen(
|
SettingsScreen(
|
||||||
viewModel = viewModel,
|
viewModel = viewModel,
|
||||||
onBackClick = { finish() },
|
onBackClick = { finish() },
|
||||||
onModeHelpClicked = { Utils.openUri(this, AppConfig.APP_WIKI_MODE) }
|
onModeHelpClicked = { Utils.openUri(this, AppConfig.APP_WIKI_MODE) },
|
||||||
|
onSystemVpnSettingsClicked = ::openSystemVpnSettings
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,10 +99,12 @@ class SettingsActivity : BaseComponentActivity() {
|
|||||||
fun SettingsScreen(
|
fun SettingsScreen(
|
||||||
viewModel: SettingsViewModel,
|
viewModel: SettingsViewModel,
|
||||||
onBackClick: () -> Unit,
|
onBackClick: () -> Unit,
|
||||||
onModeHelpClicked: () -> Unit
|
onModeHelpClicked: () -> Unit,
|
||||||
|
onSystemVpnSettingsClicked: () -> Unit
|
||||||
) {
|
) {
|
||||||
val scrollState = rememberScrollState()
|
val scrollState = rememberScrollState()
|
||||||
val isLoading by viewModel.isLoading.collectAsStateWithLifecycle()
|
val isLoading by viewModel.isLoading.collectAsStateWithLifecycle()
|
||||||
|
val systemVpnSettingsAvailable by viewModel.systemVpnSettingsAvailable.collectAsStateWithLifecycle()
|
||||||
var uiSettingsExpanded by rememberSaveable { mutableStateOf(true) }
|
var uiSettingsExpanded by rememberSaveable { mutableStateOf(true) }
|
||||||
var vpnSettingsExpanded by rememberSaveable { mutableStateOf(true) }
|
var vpnSettingsExpanded by rememberSaveable { mutableStateOf(true) }
|
||||||
var coreSettingsExpanded by rememberSaveable { mutableStateOf(true) }
|
var coreSettingsExpanded by rememberSaveable { mutableStateOf(true) }
|
||||||
@@ -612,6 +644,13 @@ fun SettingsScreen(
|
|||||||
checked = isBooted,
|
checked = isBooted,
|
||||||
onCheckedChange = { isBooted = it }
|
onCheckedChange = { isBooted = it }
|
||||||
)
|
)
|
||||||
|
if (systemVpnSettingsAvailable) {
|
||||||
|
SettingsMenuItem(
|
||||||
|
title = stringResource(R.string.title_system_vpn_settings),
|
||||||
|
subtitle = stringResource(R.string.summary_system_vpn_settings),
|
||||||
|
onClick = onSystemVpnSettingsClicked
|
||||||
|
)
|
||||||
|
}
|
||||||
SettingsEditItem(
|
SettingsEditItem(
|
||||||
title = stringResource(R.string.title_pref_delay_test_url),
|
title = stringResource(R.string.title_pref_delay_test_url),
|
||||||
value = delayTestUrl,
|
value = delayTestUrl,
|
||||||
|
|||||||
@@ -1,15 +1,29 @@
|
|||||||
package com.v2ray.ang.ui.settings
|
package com.v2ray.ang.ui.settings
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.content.Intent
|
||||||
|
import android.provider.Settings
|
||||||
import com.v2ray.ang.AppConfig
|
import com.v2ray.ang.AppConfig
|
||||||
import com.v2ray.ang.R
|
import com.v2ray.ang.R
|
||||||
import com.v2ray.ang.root.RootManager
|
import com.v2ray.ang.root.RootManager
|
||||||
import com.v2ray.ang.ui.base.BaseViewModel
|
import com.v2ray.ang.ui.base.BaseViewModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
class SettingsViewModel(application: Application) : BaseViewModel(application) {
|
class SettingsViewModel(application: Application) : BaseViewModel(application) {
|
||||||
|
|
||||||
|
private val _systemVpnSettingsAvailable = MutableStateFlow(false)
|
||||||
|
val systemVpnSettingsAvailable = _systemVpnSettingsAvailable.asStateFlow()
|
||||||
|
|
||||||
|
suspend fun refreshSystemVpnSettingsAvailability() {
|
||||||
|
_systemVpnSettingsAvailable.value = withContext(Dispatchers.IO) {
|
||||||
|
// Android exposes the VPN page, not a direct link to the Always-on VPN switch.
|
||||||
|
Intent(Settings.ACTION_VPN_SETTINGS).resolveActivity(getApplication<Application>().packageManager) != null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks for root access and requests it if necessary.
|
* Checks for root access and requests it if necessary.
|
||||||
* Updates [isLoading] during the process.
|
* Updates [isLoading] during the process.
|
||||||
@@ -56,4 +70,4 @@ class SettingsViewModel(application: Application) : BaseViewModel(application) {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,8 +172,11 @@
|
|||||||
<string name="title_vpn_settings">إعدادات VPN</string>
|
<string name="title_vpn_settings">إعدادات VPN</string>
|
||||||
<string name="title_pref_per_app_proxy">الوكيل لكل تطبيق</string>
|
<string name="title_pref_per_app_proxy">الوكيل لكل تطبيق</string>
|
||||||
<string name="summary_pref_per_app_proxy">عام: تستخدم التطبيقات المحددة الوكيل، وتتصل التطبيقات غير المحددة مباشرة؛\nوضع التجاوز: تتصل التطبيقات المحددة مباشرة، وتستخدم التطبيقات غير المحددة الوكيل.\nيتوفر في القائمة خيار لتحديد التطبيقات التي ستستخدم الوكيل تلقائيًا.</string>
|
<string name="summary_pref_per_app_proxy">عام: تستخدم التطبيقات المحددة الوكيل، وتتصل التطبيقات غير المحددة مباشرة؛\nوضع التجاوز: تتصل التطبيقات المحددة مباشرة، وتستخدم التطبيقات غير المحددة الوكيل.\nيتوفر في القائمة خيار لتحديد التطبيقات التي ستستخدم الوكيل تلقائيًا.</string>
|
||||||
<string name="title_pref_is_booted">الاتصال تلقائياً عند بدء التشغيل</string>
|
<string name="title_pref_is_booted">الاتصال بعد إقلاع الجهاز</string>
|
||||||
<string name="summary_pref_is_booted">الاتصال تلقائياً بالخادم المحدد عند بدء التشغيل؛ قد لا تنجح المحاولة</string>
|
<string name="summary_pref_is_booted">الاتصال تلقائياً بالخادم المحدد بعد إقلاع الجهاز. قد يقيّد Android بدء التشغيل في الخلفية.</string>
|
||||||
|
<string name="title_system_vpn_settings">إعدادات VPN للنظام</string>
|
||||||
|
<string name="summary_system_vpn_settings">فتح إعدادات VPN في Android لإعداد VPN الدائم، إذا كان الجهاز يدعمه.</string>
|
||||||
|
<string name="toast_system_vpn_settings_unavailable">إعدادات VPN للنظام غير متاحة.</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="subscription_updater_job_tips">ستعمل المهمة في الخلفية، وسيُعرض تقدمها في الإشعار.</string>
|
<string name="subscription_updater_job_tips">ستعمل المهمة في الخلفية، وسيُعرض تقدمها في الإشعار.</string>
|
||||||
|
|||||||
@@ -172,8 +172,11 @@
|
|||||||
<string name="title_vpn_settings">VPN সেটিংস</string>
|
<string name="title_vpn_settings">VPN সেটিংস</string>
|
||||||
<string name="title_pref_per_app_proxy">প্রতি-অ্যাপ প্রক্সি</string>
|
<string name="title_pref_per_app_proxy">প্রতি-অ্যাপ প্রক্সি</string>
|
||||||
<string name="summary_pref_per_app_proxy">সাধারণ: নির্বাচিত অ্যাপ প্রক্সি ব্যবহার করে, অনির্বাচিত অ্যাপ সরাসরি সংযুক্ত হয়;\nবাইপাস মোড: নির্বাচিত অ্যাপ সরাসরি সংযুক্ত হয়, অনির্বাচিত অ্যাপ প্রক্সি ব্যবহার করে।\nযেসব অ্যাপ প্রক্সি ব্যবহার করবে, সেগুলি স্বয়ংক্রিয়ভাবে নির্বাচনের বিকল্পটি মেনুতে আছে।</string>
|
<string name="summary_pref_per_app_proxy">সাধারণ: নির্বাচিত অ্যাপ প্রক্সি ব্যবহার করে, অনির্বাচিত অ্যাপ সরাসরি সংযুক্ত হয়;\nবাইপাস মোড: নির্বাচিত অ্যাপ সরাসরি সংযুক্ত হয়, অনির্বাচিত অ্যাপ প্রক্সি ব্যবহার করে।\nযেসব অ্যাপ প্রক্সি ব্যবহার করবে, সেগুলি স্বয়ংক্রিয়ভাবে নির্বাচনের বিকল্পটি মেনুতে আছে।</string>
|
||||||
<string name="title_pref_is_booted">চালুর সময় স্বয়ংক্রিয় সংযোগ</string>
|
<string name="title_pref_is_booted">ডিভাইস চালু হওয়ার পর সংযোগ</string>
|
||||||
<string name="summary_pref_is_booted">চালুর সময় নির্বাচিত সার্ভারে স্বয়ংক্রিয়ভাবে সংযোগ করে; সংযোগ ব্যর্থ হতে পারে</string>
|
<string name="summary_pref_is_booted">ডিভাইস চালু হওয়ার পর নির্বাচিত সার্ভারে স্বয়ংক্রিয়ভাবে সংযোগ করুন। Android ব্যাকগ্রাউন্ডে চালু হওয়া সীমিত করতে পারে।</string>
|
||||||
|
<string name="title_system_vpn_settings">সিস্টেমের VPN সেটিংস</string>
|
||||||
|
<string name="summary_system_vpn_settings">ডিভাইসে সমর্থিত হলে সর্বদা চালু VPN কনফিগার করতে Android-এর VPN সেটিংস খুলুন।</string>
|
||||||
|
<string name="toast_system_vpn_settings_unavailable">সিস্টেমের VPN সেটিংস উপলভ্য নয়।</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="subscription_updater_job_tips">কাজটি ব্যাকগ্রাউন্ডে চলবে এবং অগ্রগতির তথ্য বিজ্ঞপ্তিতে দেখানো হবে।</string>
|
<string name="subscription_updater_job_tips">কাজটি ব্যাকগ্রাউন্ডে চলবে এবং অগ্রগতির তথ্য বিজ্ঞপ্তিতে দেখানো হবে।</string>
|
||||||
|
|||||||
@@ -172,8 +172,11 @@
|
|||||||
<string name="title_vpn_settings">سامووا VPN</string>
|
<string name="title_vpn_settings">سامووا VPN</string>
|
||||||
<string name="title_pref_per_app_proxy">پروکسی و ری برنومه</string>
|
<string name="title_pref_per_app_proxy">پروکسی و ری برنومه</string>
|
||||||
<string name="summary_pref_per_app_proxy">پوی وولاتی: برنومه پسند وابیڌه وا ی پروکسی منپیز ابۊ، برنومه پسند نوابیڌه موستقیمن منپیز ابۊ.\nحالت دور زیڌن: برنومه پسند وابیڌه موستقیمن منپیز ابۊ، برنومه پسند نوابیڌه وا ی پروکسی منپیز ابۊ.\nپسند خوتکار برنومه یلی ک وا ی پروکسی منپیز ابۊن من نومگه امکووݩ پذیر هڌ.</string>
|
<string name="summary_pref_per_app_proxy">پوی وولاتی: برنومه پسند وابیڌه وا ی پروکسی منپیز ابۊ، برنومه پسند نوابیڌه موستقیمن منپیز ابۊ.\nحالت دور زیڌن: برنومه پسند وابیڌه موستقیمن منپیز ابۊ، برنومه پسند نوابیڌه وا ی پروکسی منپیز ابۊ.\nپسند خوتکار برنومه یلی ک وا ی پروکسی منپیز ابۊن من نومگه امکووݩ پذیر هڌ.</string>
|
||||||
<string name="title_pref_is_booted">منپیز خوتکار مجال ره ونی</string>
|
<string name="title_pref_is_booted">منپیز بئڌ ره وندن دسگا</string>
|
||||||
<string name="summary_pref_is_booted">مجال ره وندن، خوساخوس و سرور پسند بیڌه منپیز ابۊ که گاشڌ نا مووفق بۊ.</string>
|
<string name="summary_pref_is_booted">بئڌ ره وندن دسگا، خوساخوس و سرور پسند بیڌه منپیز ابۊ. Android گاشڌ ره وندن من پس زمینه ن مئدۊد کونه.</string>
|
||||||
|
<string name="title_system_vpn_settings">سامووا VPN سیستوم</string>
|
||||||
|
<string name="summary_system_vpn_settings">سامووا VPN من Android ن وا کۊنین سی ساموو کردن VPN همیشه ره وست، ٱر دسگا زس پشتیبانی اکونه.</string>
|
||||||
|
<string name="toast_system_vpn_settings_unavailable">سامووا VPN سیستوم من دسرس نین.</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="subscription_updater_job_tips">وزیفه من پس زمینه کار اکونه وو ایلاعات پؽشرفت من اعلان نشووݩ داڌه ابۊ.</string>
|
<string name="subscription_updater_job_tips">وزیفه من پس زمینه کار اکونه وو ایلاعات پؽشرفت من اعلان نشووݩ داڌه ابۊ.</string>
|
||||||
|
|||||||
@@ -172,8 +172,11 @@
|
|||||||
<string name="title_vpn_settings">تنظیمات VPN</string>
|
<string name="title_vpn_settings">تنظیمات VPN</string>
|
||||||
<string name="title_pref_per_app_proxy">پروکسی به تفکیک برنامه</string>
|
<string name="title_pref_per_app_proxy">پروکسی به تفکیک برنامه</string>
|
||||||
<string name="summary_pref_per_app_proxy">حالت عادی: برنامههای انتخابشده از پروکسی استفاده میکنند و برنامههای انتخابنشده مستقیماً متصل میشوند؛\nحالت دور زدن: برنامههای انتخابشده مستقیماً متصل میشوند و برنامههای انتخابنشده از پروکسی استفاده میکنند.\nگزینهٔ انتخاب خودکار برنامههایی که باید از پروکسی استفاده کنند در منو قرار دارد.</string>
|
<string name="summary_pref_per_app_proxy">حالت عادی: برنامههای انتخابشده از پروکسی استفاده میکنند و برنامههای انتخابنشده مستقیماً متصل میشوند؛\nحالت دور زدن: برنامههای انتخابشده مستقیماً متصل میشوند و برنامههای انتخابنشده از پروکسی استفاده میکنند.\nگزینهٔ انتخاب خودکار برنامههایی که باید از پروکسی استفاده کنند در منو قرار دارد.</string>
|
||||||
<string name="title_pref_is_booted">اتصال خودکار هنگام راه اندازی</string>
|
<string name="title_pref_is_booted">اتصال پس از راهاندازی دستگاه</string>
|
||||||
<string name="summary_pref_is_booted">هنگام راه اندازی به طور خودکار به سرور انتخابی متصل می شود که ممکن است ناموفق باشد.</string>
|
<string name="summary_pref_is_booted">پس از راهاندازی دستگاه، بهطور خودکار به سرور انتخابشده متصل شود. ممکن است Android اجرای پسزمینه را محدود کند.</string>
|
||||||
|
<string name="title_system_vpn_settings">تنظیمات VPN سیستم</string>
|
||||||
|
<string name="summary_system_vpn_settings">تنظیمات VPN در Android را برای پیکربندی VPN همیشهروشن باز کنید، اگر دستگاه از آن پشتیبانی میکند.</string>
|
||||||
|
<string name="toast_system_vpn_settings_unavailable">تنظیمات VPN سیستم در دسترس نیست.</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="subscription_updater_job_tips">این کار در پسزمینه اجرا میشود و پیشرفت آن در اعلان نمایش داده خواهد شد.</string>
|
<string name="subscription_updater_job_tips">این کار در پسزمینه اجرا میشود و پیشرفت آن در اعلان نمایش داده خواهد شد.</string>
|
||||||
|
|||||||
@@ -172,8 +172,11 @@
|
|||||||
<string name="title_vpn_settings">Настройки VPN</string>
|
<string name="title_vpn_settings">Настройки VPN</string>
|
||||||
<string name="title_pref_per_app_proxy">Прокси для выбранных приложений</string>
|
<string name="title_pref_per_app_proxy">Прокси для выбранных приложений</string>
|
||||||
<string name="summary_pref_per_app_proxy">Основной: выбранное приложение соединяется через прокси, не выбранное — напрямую;\nРежим обхода: выбранное приложение соединяется напрямую, не выбранное — через прокси.\nВ меню можно автоматически выбрать приложения, которые должны использовать прокси.</string>
|
<string name="summary_pref_per_app_proxy">Основной: выбранное приложение соединяется через прокси, не выбранное — напрямую;\nРежим обхода: выбранное приложение соединяется напрямую, не выбранное — через прокси.\nВ меню можно автоматически выбрать приложения, которые должны использовать прокси.</string>
|
||||||
<string name="title_pref_is_booted">Автоподключение при запуске</string>
|
<string name="title_pref_is_booted">Подключаться после загрузки устройства</string>
|
||||||
<string name="summary_pref_is_booted">Автоматически подключаться к выбранному серверу при запуске приложения (может оказаться неудачным)</string>
|
<string name="summary_pref_is_booted">Автоматически подключаться к выбранному серверу после загрузки устройства. Android может ограничивать запуск в фоне.</string>
|
||||||
|
<string name="title_system_vpn_settings">Системные настройки VPN</string>
|
||||||
|
<string name="summary_system_vpn_settings">Открыть настройки VPN в Android для включения постоянного VPN-подключения, если устройство его поддерживает.</string>
|
||||||
|
<string name="toast_system_vpn_settings_unavailable">Системные настройки VPN недоступны.</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="subscription_updater_job_tips">Задача будет выполняться в фоновом режиме, информация о ходе выполнения будет отображаться в уведомлении.</string>
|
<string name="subscription_updater_job_tips">Задача будет выполняться в фоновом режиме, информация о ходе выполнения будет отображаться в уведомлении.</string>
|
||||||
|
|||||||
@@ -172,8 +172,11 @@
|
|||||||
<string name="title_vpn_settings">Cài đặt VPN</string>
|
<string name="title_vpn_settings">Cài đặt VPN</string>
|
||||||
<string name="title_pref_per_app_proxy">Proxy theo từng ứng dụng</string>
|
<string name="title_pref_per_app_proxy">Proxy theo từng ứng dụng</string>
|
||||||
<string name="summary_pref_per_app_proxy">Thông thường: ứng dụng đã chọn dùng proxy, ứng dụng chưa chọn kết nối trực tiếp;\nChế độ bỏ qua: ứng dụng đã chọn kết nối trực tiếp, ứng dụng chưa chọn dùng proxy.\nTrong trình đơn có tùy chọn tự động chọn các ứng dụng sẽ dùng proxy.</string>
|
<string name="summary_pref_per_app_proxy">Thông thường: ứng dụng đã chọn dùng proxy, ứng dụng chưa chọn kết nối trực tiếp;\nChế độ bỏ qua: ứng dụng đã chọn kết nối trực tiếp, ứng dụng chưa chọn dùng proxy.\nTrong trình đơn có tùy chọn tự động chọn các ứng dụng sẽ dùng proxy.</string>
|
||||||
<string name="title_pref_is_booted">Tự động kết nối khi khởi động</string>
|
<string name="title_pref_is_booted">Kết nối sau khi thiết bị khởi động</string>
|
||||||
<string name="summary_pref_is_booted">Tự động kết nối với máy chủ đã chọn khi khởi động; thao tác này có thể không thành công</string>
|
<string name="summary_pref_is_booted">Tự động kết nối với máy chủ đã chọn sau khi thiết bị khởi động. Android có thể hạn chế khởi chạy trong nền.</string>
|
||||||
|
<string name="title_system_vpn_settings">Cài đặt VPN hệ thống</string>
|
||||||
|
<string name="summary_system_vpn_settings">Mở cài đặt VPN của Android để cấu hình VPN luôn bật, nếu thiết bị này hỗ trợ.</string>
|
||||||
|
<string name="toast_system_vpn_settings_unavailable">Không có cài đặt VPN hệ thống.</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="subscription_updater_job_tips">Tác vụ sẽ chạy trong nền và thông tin tiến độ sẽ hiển thị trong thông báo.</string>
|
<string name="subscription_updater_job_tips">Tác vụ sẽ chạy trong nền và thông tin tiến độ sẽ hiển thị trong thông báo.</string>
|
||||||
|
|||||||
@@ -172,8 +172,11 @@
|
|||||||
<string name="title_vpn_settings">VPN 设置</string>
|
<string name="title_vpn_settings">VPN 设置</string>
|
||||||
<string name="title_pref_per_app_proxy">分应用代理</string>
|
<string name="title_pref_per_app_proxy">分应用代理</string>
|
||||||
<string name="summary_pref_per_app_proxy">常规:勾选的应用使用代理,未勾选的应用直连;\n绕行模式:勾选的应用直连,未勾选的应用使用代理。\n菜单中可自动选择需要使用代理的应用。</string>
|
<string name="summary_pref_per_app_proxy">常规:勾选的应用使用代理,未勾选的应用直连;\n绕行模式:勾选的应用直连,未勾选的应用使用代理。\n菜单中可自动选择需要使用代理的应用。</string>
|
||||||
<string name="title_pref_is_booted">开机时自动连接</string>
|
<string name="title_pref_is_booted">设备启动后自动连接</string>
|
||||||
<string name="summary_pref_is_booted">开机时自动连接选择的服务器,可能会不成功</string>
|
<string name="summary_pref_is_booted">设备启动后自动连接到所选服务器。Android 可能会限制后台启动。</string>
|
||||||
|
<string name="title_system_vpn_settings">系统 VPN 设置</string>
|
||||||
|
<string name="summary_system_vpn_settings">打开 Android VPN 设置,配置始终开启的 VPN(如果此设备支持)。</string>
|
||||||
|
<string name="toast_system_vpn_settings_unavailable">系统 VPN 设置不可用。</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="subscription_updater_job_tips">任务将在后台运行,在通知中会显示进度信息</string>
|
<string name="subscription_updater_job_tips">任务将在后台运行,在通知中会显示进度信息</string>
|
||||||
|
|||||||
@@ -172,8 +172,11 @@
|
|||||||
<string name="title_vpn_settings">VPN 設定</string>
|
<string name="title_vpn_settings">VPN 設定</string>
|
||||||
<string name="title_pref_per_app_proxy">個別應用程式代理</string>
|
<string name="title_pref_per_app_proxy">個別應用程式代理</string>
|
||||||
<string name="summary_pref_per_app_proxy">一般:已勾選的應用程式使用代理,未勾選的應用程式直接連線;\n繞行模式:已勾選的應用程式直接連線,未勾選的應用程式使用代理。\n選單中可自動選取需要使用代理的應用程式。</string>
|
<string name="summary_pref_per_app_proxy">一般:已勾選的應用程式使用代理,未勾選的應用程式直接連線;\n繞行模式:已勾選的應用程式直接連線,未勾選的應用程式使用代理。\n選單中可自動選取需要使用代理的應用程式。</string>
|
||||||
<string name="title_pref_is_booted">開機時自動連線</string>
|
<string name="title_pref_is_booted">裝置開機後自動連線</string>
|
||||||
<string name="summary_pref_is_booted">開機時自動連線選擇的伺服器,可能會不成功</string>
|
<string name="summary_pref_is_booted">裝置開機後自動連線至所選伺服器。Android 可能會限制背景啟動。</string>
|
||||||
|
<string name="title_system_vpn_settings">系統 VPN 設定</string>
|
||||||
|
<string name="summary_system_vpn_settings">開啟 Android VPN 設定,設定永遠開啟的 VPN(若此裝置支援)。</string>
|
||||||
|
<string name="toast_system_vpn_settings_unavailable">系統 VPN 設定無法使用。</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="subscription_updater_job_tips">任務將在背景執行,通知中會顯示進度資訊。</string>
|
<string name="subscription_updater_job_tips">任務將在背景執行,通知中會顯示進度資訊。</string>
|
||||||
|
|||||||
@@ -172,8 +172,11 @@
|
|||||||
<string name="title_vpn_settings">VPN Settings</string>
|
<string name="title_vpn_settings">VPN Settings</string>
|
||||||
<string name="title_pref_per_app_proxy">Per-app proxy</string>
|
<string name="title_pref_per_app_proxy">Per-app proxy</string>
|
||||||
<string name="summary_pref_per_app_proxy">General: checked apps use the proxy, and unchecked apps connect directly;\nBypass mode: checked apps connect directly, and unchecked apps use the proxy.\nThe option to automatically select apps that should use the proxy is in the menu.</string>
|
<string name="summary_pref_per_app_proxy">General: checked apps use the proxy, and unchecked apps connect directly;\nBypass mode: checked apps connect directly, and unchecked apps use the proxy.\nThe option to automatically select apps that should use the proxy is in the menu.</string>
|
||||||
<string name="title_pref_is_booted">Auto connect at startup</string>
|
<string name="title_pref_is_booted">Connect after device boot</string>
|
||||||
<string name="summary_pref_is_booted">Automatically connects to the selected server at startup, which may be unsuccessful</string>
|
<string name="summary_pref_is_booted">Automatically connect to the selected server after the device starts. Android may restrict background starts.</string>
|
||||||
|
<string name="title_system_vpn_settings">System VPN settings</string>
|
||||||
|
<string name="summary_system_vpn_settings">Open Android VPN settings to configure Always-on VPN, if supported by this device.</string>
|
||||||
|
<string name="toast_system_vpn_settings_unavailable">System VPN settings are unavailable.</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="subscription_updater_job_tips">The task will run in the background, and progress information will be displayed in the notification.</string>
|
<string name="subscription_updater_job_tips">The task will run in the background, and progress information will be displayed in the notification.</string>
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.v2ray.ang.ui.settings
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.ComponentName
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.provider.Settings
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertFalse
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
import org.mockito.Mockito.mockConstruction
|
||||||
|
import org.mockito.kotlin.mock
|
||||||
|
import org.mockito.kotlin.whenever
|
||||||
|
|
||||||
|
class SettingsViewModelTest {
|
||||||
|
@Test
|
||||||
|
fun vpnSettingsVisibilityFollowsActivityAvailability() = runBlocking(Dispatchers.IO) {
|
||||||
|
val packageManager = mock<PackageManager>()
|
||||||
|
val application = mock<Application>()
|
||||||
|
whenever(application.packageManager).thenReturn(packageManager)
|
||||||
|
var activity: ComponentName? = null
|
||||||
|
|
||||||
|
mockConstruction(Intent::class.java) { intent, context ->
|
||||||
|
assertEquals(listOf(Settings.ACTION_VPN_SETTINGS), context.arguments())
|
||||||
|
whenever(intent.resolveActivity(packageManager)).thenAnswer { activity }
|
||||||
|
}.use {
|
||||||
|
val viewModel = SettingsViewModel(application)
|
||||||
|
assertFalse(viewModel.systemVpnSettingsAvailable.value)
|
||||||
|
viewModel.refreshSystemVpnSettingsAvailability()
|
||||||
|
assertFalse(viewModel.systemVpnSettingsAvailable.value)
|
||||||
|
|
||||||
|
activity = mock<ComponentName>()
|
||||||
|
viewModel.refreshSystemVpnSettingsAvailability()
|
||||||
|
assertTrue(viewModel.systemVpnSettingsAvailable.value)
|
||||||
|
|
||||||
|
activity = null
|
||||||
|
viewModel.refreshSystemVpnSettingsAvailability()
|
||||||
|
assertFalse(viewModel.systemVpnSettingsAvailable.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user