Optimize and improve SettingsManager
This commit is contained in:
@@ -7,7 +7,6 @@ import androidx.work.WorkManager
|
||||
import com.tencent.mmkv.MMKV
|
||||
import com.v2ray.ang.AppConfig.ANG_PACKAGE
|
||||
import com.v2ray.ang.handler.SettingsManager
|
||||
import com.v2ray.ang.util.Utils
|
||||
|
||||
class AngApplication : MultiDexApplication() {
|
||||
companion object {
|
||||
@@ -36,7 +35,7 @@ class AngApplication : MultiDexApplication() {
|
||||
|
||||
MMKV.initialize(this)
|
||||
|
||||
Utils.setNightMode()
|
||||
SettingsManager.setNightMode()
|
||||
// Initialize WorkManager with the custom configuration
|
||||
WorkManager.initialize(this, workManagerConfiguration)
|
||||
|
||||
|
||||
@@ -4,12 +4,14 @@ import android.content.Context
|
||||
import android.content.res.AssetManager
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.AppConfig.ANG_PACKAGE
|
||||
import com.v2ray.ang.AppConfig.GEOIP_PRIVATE
|
||||
import com.v2ray.ang.AppConfig.GEOSITE_PRIVATE
|
||||
import com.v2ray.ang.AppConfig.TAG_DIRECT
|
||||
import com.v2ray.ang.dto.EConfigType
|
||||
import com.v2ray.ang.dto.Language
|
||||
import com.v2ray.ang.dto.ProfileItem
|
||||
import com.v2ray.ang.dto.RoutingType
|
||||
import com.v2ray.ang.dto.RulesetItem
|
||||
@@ -18,10 +20,10 @@ import com.v2ray.ang.handler.MmkvManager.decodeServerConfig
|
||||
import com.v2ray.ang.handler.MmkvManager.decodeServerList
|
||||
import com.v2ray.ang.util.JsonUtil
|
||||
import com.v2ray.ang.util.Utils
|
||||
import com.v2ray.ang.util.Utils.parseInt
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.util.Collections
|
||||
import java.util.Locale
|
||||
|
||||
object SettingsManager {
|
||||
|
||||
@@ -173,7 +175,7 @@ object SettingsManager {
|
||||
}
|
||||
|
||||
fun getSocksPort(): Int {
|
||||
return parseInt(MmkvManager.decodeSettingsString(AppConfig.PREF_SOCKS_PORT), AppConfig.PORT_SOCKS.toInt())
|
||||
return Utils.parseInt(MmkvManager.decodeSettingsString(AppConfig.PREF_SOCKS_PORT), AppConfig.PORT_SOCKS.toInt())
|
||||
}
|
||||
|
||||
fun getHttpPort(): Int {
|
||||
@@ -205,4 +207,75 @@ object SettingsManager {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* get domestic dns servers from preference
|
||||
*/
|
||||
fun getDomesticDnsServers(): List<String> {
|
||||
val domesticDns =
|
||||
MmkvManager.decodeSettingsString(AppConfig.PREF_DOMESTIC_DNS) ?: AppConfig.DNS_DIRECT
|
||||
val ret = domesticDns.split(",").filter { Utils.isPureIpAddress(it) || Utils.isCoreDNSAddress(it) }
|
||||
if (ret.isEmpty()) {
|
||||
return listOf(AppConfig.DNS_DIRECT)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* get remote dns servers from preference
|
||||
*/
|
||||
fun getRemoteDnsServers(): List<String> {
|
||||
val remoteDns =
|
||||
MmkvManager.decodeSettingsString(AppConfig.PREF_REMOTE_DNS) ?: AppConfig.DNS_PROXY
|
||||
val ret = remoteDns.split(",").filter { Utils.isPureIpAddress(it) || Utils.isCoreDNSAddress(it) }
|
||||
if (ret.isEmpty()) {
|
||||
return listOf(AppConfig.DNS_PROXY)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* get vpn dns servers from preference
|
||||
*/
|
||||
fun getVpnDnsServers(): List<String> {
|
||||
val vpnDns = MmkvManager.decodeSettingsString(AppConfig.PREF_VPN_DNS) ?: AppConfig.DNS_VPN
|
||||
return vpnDns.split(",").filter { Utils.isPureIpAddress(it) }
|
||||
// allow empty, in that case dns will use system default
|
||||
}
|
||||
|
||||
|
||||
fun getDelayTestUrl(second: Boolean = false): String {
|
||||
return if (second) {
|
||||
AppConfig.DelayTestUrl2
|
||||
} else {
|
||||
MmkvManager.decodeSettingsString(AppConfig.PREF_DELAY_TEST_URL)
|
||||
?: AppConfig.DelayTestUrl
|
||||
}
|
||||
}
|
||||
|
||||
fun getLocale(): Locale {
|
||||
val langCode =
|
||||
MmkvManager.decodeSettingsString(AppConfig.PREF_LANGUAGE) ?: Language.AUTO.code
|
||||
val language = Language.fromCode(langCode)
|
||||
|
||||
return when (language) {
|
||||
Language.AUTO -> Utils.getSysLocale()
|
||||
Language.ENGLISH -> Locale.ENGLISH
|
||||
Language.CHINA -> Locale.CHINA
|
||||
Language.TRADITIONAL_CHINESE -> Locale.TRADITIONAL_CHINESE
|
||||
Language.VIETNAMESE -> Locale("vi")
|
||||
Language.RUSSIAN -> Locale("ru")
|
||||
Language.PERSIAN -> Locale("fa")
|
||||
Language.BANGLA -> Locale("bn")
|
||||
Language.BAKHTIARI -> Locale("bqi", "IR")
|
||||
}
|
||||
}
|
||||
|
||||
fun setNightMode() {
|
||||
when (MmkvManager.decodeSettingsString(AppConfig.PREF_UI_MODE_NIGHT, "0")) {
|
||||
"0" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
||||
"1" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
|
||||
"2" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,7 +271,7 @@ object V2rayConfigManager {
|
||||
}
|
||||
|
||||
// DNS inbound对象
|
||||
val remoteDns = Utils.getRemoteDnsServers()
|
||||
val remoteDns = SettingsManager.getRemoteDnsServers()
|
||||
if (v2rayConfig.inbounds.none { e -> e.protocol == "dokodemo-door" && e.tag == "dns-in" }) {
|
||||
val dnsInboundSettings = V2rayConfig.InboundBean.InSettingsBean(
|
||||
address = if (Utils.isPureIpAddress(remoteDns.first())) remoteDns.first() else AppConfig.DNS_PROXY,
|
||||
@@ -329,7 +329,7 @@ object V2rayConfigManager {
|
||||
val servers = ArrayList<Any>()
|
||||
|
||||
//remote Dns
|
||||
val remoteDns = Utils.getRemoteDnsServers()
|
||||
val remoteDns = SettingsManager.getRemoteDnsServers()
|
||||
val proxyDomain = userRule2Domain(TAG_PROXY)
|
||||
remoteDns.forEach {
|
||||
servers.add(it)
|
||||
@@ -344,7 +344,7 @@ object V2rayConfigManager {
|
||||
}
|
||||
|
||||
// domestic DNS
|
||||
val domesticDns = Utils.getDomesticDnsServers()
|
||||
val domesticDns = SettingsManager.getDomesticDnsServers()
|
||||
val directDomain = userRule2Domain(TAG_DIRECT)
|
||||
val isCnRoutingMode = directDomain.contains(GEOSITE_CN)
|
||||
val geoipCn = arrayListOf(GEOIP_CN)
|
||||
|
||||
@@ -6,8 +6,8 @@ import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.v2ray.ang.handler.SettingsManager
|
||||
import com.v2ray.ang.util.MyContextWrapper
|
||||
import com.v2ray.ang.util.Utils
|
||||
import java.lang.ref.SoftReference
|
||||
|
||||
class V2RayProxyOnlyService : Service(), ServiceControl {
|
||||
@@ -49,7 +49,7 @@ class V2RayProxyOnlyService : Service(), ServiceControl {
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
override fun attachBaseContext(newBase: Context?) {
|
||||
val context = newBase?.let {
|
||||
MyContextWrapper.wrap(newBase, Utils.getLocale())
|
||||
MyContextWrapper.wrap(newBase, SettingsManager.getLocale())
|
||||
}
|
||||
super.attachBaseContext(context)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.v2ray.ang.dto.EConfigType
|
||||
import com.v2ray.ang.dto.ProfileItem
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.handler.SettingsManager
|
||||
import com.v2ray.ang.handler.V2rayConfigManager
|
||||
import com.v2ray.ang.util.MessageUtil
|
||||
import com.v2ray.ang.util.PluginUtil
|
||||
@@ -176,14 +177,14 @@ object V2RayServiceManager {
|
||||
var errstr = ""
|
||||
if (v2rayPoint.isRunning) {
|
||||
try {
|
||||
time = v2rayPoint.measureDelay(Utils.getDelayTestUrl())
|
||||
time = v2rayPoint.measureDelay(SettingsManager.getDelayTestUrl())
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, "measureV2rayDelay: $e")
|
||||
errstr = e.message?.substringAfter("\":") ?: "empty message"
|
||||
}
|
||||
if (time == -1L) {
|
||||
try {
|
||||
time = v2rayPoint.measureDelay(Utils.getDelayTestUrl(true))
|
||||
time = v2rayPoint.measureDelay(SettingsManager.getDelayTestUrl(true))
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, "measureV2rayDelay: $e")
|
||||
errstr = e.message?.substringAfter("\":") ?: "empty message"
|
||||
|
||||
@@ -133,7 +133,7 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
override fun attachBaseContext(newBase: Context?) {
|
||||
val context = newBase?.let {
|
||||
MyContextWrapper.wrap(newBase, Utils.getLocale())
|
||||
MyContextWrapper.wrap(newBase, SettingsManager.getLocale())
|
||||
}
|
||||
super.attachBaseContext(context)
|
||||
}
|
||||
@@ -182,7 +182,7 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
||||
// if (MmkvManager.decodeSettingsBool(AppConfig.PREF_LOCAL_DNS_ENABLED) == true) {
|
||||
// builder.addDnsServer(PRIVATE_VLAN4_ROUTER)
|
||||
// } else {
|
||||
Utils.getVpnDnsServers()
|
||||
SettingsManager.getVpnDnsServers()
|
||||
.forEach {
|
||||
if (Utils.isPureIpAddress(it)) {
|
||||
builder.addDnsServer(it)
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.view.MenuItem
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.WindowCompat
|
||||
import com.v2ray.ang.handler.SettingsManager
|
||||
import com.v2ray.ang.util.MyContextWrapper
|
||||
import com.v2ray.ang.util.Utils
|
||||
|
||||
@@ -34,6 +35,6 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
override fun attachBaseContext(newBase: Context?) {
|
||||
super.attachBaseContext(MyContextWrapper.wrap(newBase ?: return, Utils.getLocale()))
|
||||
super.attachBaseContext(MyContextWrapper.wrap(newBase ?: return, SettingsManager.getLocale()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.util.Log
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.extension.responseLength
|
||||
import com.v2ray.ang.handler.SettingsManager
|
||||
import kotlinx.coroutines.isActive
|
||||
import libv2ray.Libv2ray
|
||||
import java.io.IOException
|
||||
@@ -35,7 +36,7 @@ object SpeedtestUtil {
|
||||
|
||||
fun realPing(config: String): Long {
|
||||
return try {
|
||||
Libv2ray.measureOutboundDelay(config, Utils.getDelayTestUrl())
|
||||
Libv2ray.measureOutboundDelay(config, SettingsManager.getDelayTestUrl())
|
||||
} catch (e: Exception) {
|
||||
Log.d(AppConfig.ANG_PACKAGE, "realPing: $e")
|
||||
-1L
|
||||
@@ -98,7 +99,7 @@ object SpeedtestUtil {
|
||||
var result: String
|
||||
var elapsed = -1L
|
||||
|
||||
val conn = HttpUtil.createProxyConnection(Utils.getDelayTestUrl(), port, 30000, 30000) ?: return Pair(elapsed, "")
|
||||
val conn = HttpUtil.createProxyConnection(SettingsManager.getDelayTestUrl(), port, 30000, 30000) ?: return Pair(elapsed, "")
|
||||
try {
|
||||
val start = SystemClock.elapsedRealtime()
|
||||
val code = conn.responseCode
|
||||
|
||||
@@ -15,14 +15,11 @@ import android.util.Base64
|
||||
import android.util.Log
|
||||
import android.util.Patterns
|
||||
import android.webkit.URLUtil
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.net.toUri
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.AppConfig.ANG_PACKAGE
|
||||
import com.v2ray.ang.AppConfig.LOOPBACK
|
||||
import com.v2ray.ang.dto.Language
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import java.io.IOException
|
||||
import java.net.ServerSocket
|
||||
import java.net.URLDecoder
|
||||
@@ -126,37 +123,6 @@ object Utils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get remote dns servers from preference
|
||||
*/
|
||||
fun getRemoteDnsServers(): List<String> {
|
||||
val remoteDns =
|
||||
MmkvManager.decodeSettingsString(AppConfig.PREF_REMOTE_DNS) ?: AppConfig.DNS_PROXY
|
||||
val ret = remoteDns.split(",").filter { isPureIpAddress(it) || isCoreDNSAddress(it) }
|
||||
if (ret.isEmpty()) {
|
||||
return listOf(AppConfig.DNS_PROXY)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
fun getVpnDnsServers(): List<String> {
|
||||
val vpnDns = MmkvManager.decodeSettingsString(AppConfig.PREF_VPN_DNS) ?: AppConfig.DNS_VPN
|
||||
return vpnDns.split(",").filter { isPureIpAddress(it) }
|
||||
// allow empty, in that case dns will use system default
|
||||
}
|
||||
|
||||
/**
|
||||
* get remote dns servers from preference
|
||||
*/
|
||||
fun getDomesticDnsServers(): List<String> {
|
||||
val domesticDns =
|
||||
MmkvManager.decodeSettingsString(AppConfig.PREF_DOMESTIC_DNS) ?: AppConfig.DNS_DIRECT
|
||||
val ret = domesticDns.split(",").filter { isPureIpAddress(it) || isCoreDNSAddress(it) }
|
||||
if (ret.isEmpty()) {
|
||||
return listOf(AppConfig.DNS_DIRECT)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* is ip address
|
||||
@@ -224,7 +190,7 @@ object Utils {
|
||||
return regV6.matches(addr)
|
||||
}
|
||||
|
||||
private fun isCoreDNSAddress(s: String): Boolean {
|
||||
fun isCoreDNSAddress(s: String): Boolean {
|
||||
return s.startsWith("https")
|
||||
|| s.startsWith("tcp")
|
||||
|| s.startsWith("quic")
|
||||
@@ -327,15 +293,6 @@ object Utils {
|
||||
return context.resources.configuration.uiMode and UI_MODE_NIGHT_MASK != UI_MODE_NIGHT_NO
|
||||
}
|
||||
|
||||
|
||||
fun setNightMode() {
|
||||
when (MmkvManager.decodeSettingsString(AppConfig.PREF_UI_MODE_NIGHT, "0")) {
|
||||
"0" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
||||
"1" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
|
||||
"2" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
||||
}
|
||||
}
|
||||
|
||||
fun getIpv6Address(address: String?): String {
|
||||
if (address == null) {
|
||||
return ""
|
||||
@@ -347,26 +304,7 @@ object Utils {
|
||||
}
|
||||
}
|
||||
|
||||
fun getLocale(): Locale {
|
||||
val langCode =
|
||||
MmkvManager.decodeSettingsString(AppConfig.PREF_LANGUAGE) ?: Language.AUTO.code
|
||||
val language = Language.fromCode(langCode)
|
||||
|
||||
return when (language) {
|
||||
Language.AUTO -> getSysLocale()
|
||||
Language.ENGLISH -> Locale.ENGLISH
|
||||
Language.CHINA -> Locale.CHINA
|
||||
Language.TRADITIONAL_CHINESE -> Locale.TRADITIONAL_CHINESE
|
||||
Language.VIETNAMESE -> Locale("vi")
|
||||
Language.RUSSIAN -> Locale("ru")
|
||||
Language.PERSIAN -> Locale("fa")
|
||||
Language.BANGLA -> Locale("bn")
|
||||
Language.BAKHTIARI -> Locale("bqi", "IR")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun getSysLocale(): Locale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
fun getSysLocale(): Locale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
LocaleList.getDefault()[0]
|
||||
} else {
|
||||
Locale.getDefault()
|
||||
@@ -385,15 +323,6 @@ object Utils {
|
||||
fun isTv(context: Context): Boolean =
|
||||
context.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
|
||||
|
||||
fun getDelayTestUrl(second: Boolean = false): String {
|
||||
return if (second) {
|
||||
AppConfig.DelayTestUrl2
|
||||
} else {
|
||||
MmkvManager.decodeSettingsString(AppConfig.PREF_DELAY_TEST_URL)
|
||||
?: AppConfig.DelayTestUrl
|
||||
}
|
||||
}
|
||||
|
||||
fun findFreePort(ports: List<Int>): Int {
|
||||
for (port in ports) {
|
||||
try {
|
||||
|
||||
@@ -7,7 +7,7 @@ import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.util.Utils
|
||||
import com.v2ray.ang.handler.SettingsManager
|
||||
|
||||
class SettingsViewModel(application: Application) : AndroidViewModel(application),
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
@@ -83,7 +83,7 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
|
||||
// }
|
||||
}
|
||||
if (key == AppConfig.PREF_UI_MODE_NIGHT) {
|
||||
Utils.setNightMode()
|
||||
SettingsManager.setNightMode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user