mirror of
https://github.com/MatsuriDayo/NekoBoxForAndroid.git
synced 2025-12-21 16:30:06 +08:00
set url test concurrency
This commit is contained in:
parent
01a5e45237
commit
82557554b3
@ -155,6 +155,7 @@ object DataStore : OnPreferenceDataStoreChangeListener {
|
|||||||
var requireTransproxy by configurationStore.boolean(Key.REQUIRE_TRANSPROXY)
|
var requireTransproxy by configurationStore.boolean(Key.REQUIRE_TRANSPROXY)
|
||||||
var transproxyMode by configurationStore.stringToInt(Key.TRANSPROXY_MODE)
|
var transproxyMode by configurationStore.stringToInt(Key.TRANSPROXY_MODE)
|
||||||
var connectionTestURL by configurationStore.string(Key.CONNECTION_TEST_URL) { CONNECTION_TEST_URL }
|
var connectionTestURL by configurationStore.string(Key.CONNECTION_TEST_URL) { CONNECTION_TEST_URL }
|
||||||
|
var connectionTestConcurrent by configurationStore.int("connectionTestConcurrent") { 5 }
|
||||||
var alwaysShowAddress by configurationStore.boolean(Key.ALWAYS_SHOW_ADDRESS)
|
var alwaysShowAddress by configurationStore.boolean(Key.ALWAYS_SHOW_ADDRESS)
|
||||||
|
|
||||||
var tunImplementation by configurationStore.stringToInt(Key.TUN_IMPLEMENTATION) { TunImplementation.SYSTEM }
|
var tunImplementation by configurationStore.stringToInt(Key.TUN_IMPLEMENTATION) { TunImplementation.SYSTEM }
|
||||||
|
|||||||
@ -517,9 +517,6 @@ class ConfigurationFragment @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
R.id.action_connection_icmp_ping -> {
|
|
||||||
pingTest(true)
|
|
||||||
}
|
|
||||||
R.id.action_connection_tcp_ping -> {
|
R.id.action_connection_tcp_ping -> {
|
||||||
pingTest(false)
|
pingTest(false)
|
||||||
}
|
}
|
||||||
@ -611,6 +608,7 @@ class ConfigurationFragment @JvmOverloads constructor(
|
|||||||
if (DataStore.serviceState.started) SagerNet.stopService()
|
if (DataStore.serviceState.started) SagerNet.stopService()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
@Suppress("EXPERIMENTAL_API_USAGE")
|
@Suppress("EXPERIMENTAL_API_USAGE")
|
||||||
fun pingTest(icmpPing: Boolean) {
|
fun pingTest(icmpPing: Boolean) {
|
||||||
val test = TestDialog()
|
val test = TestDialog()
|
||||||
@ -625,8 +623,11 @@ class ConfigurationFragment @JvmOverloads constructor(
|
|||||||
val profilesUnfiltered = SagerDatabase.proxyDao.getByGroup(group.id)
|
val profilesUnfiltered = SagerDatabase.proxyDao.getByGroup(group.id)
|
||||||
test.proxyN = profilesUnfiltered.size
|
test.proxyN = profilesUnfiltered.size
|
||||||
val profiles = ConcurrentLinkedQueue(profilesUnfiltered)
|
val profiles = ConcurrentLinkedQueue(profilesUnfiltered)
|
||||||
val testPool = newFixedThreadPoolContext(5, "Connection test pool")
|
val testPool = newFixedThreadPoolContext(
|
||||||
repeat(5) {
|
DataStore.connectionTestConcurrent,
|
||||||
|
"Connection test pool"
|
||||||
|
)
|
||||||
|
repeat(DataStore.connectionTestConcurrent) {
|
||||||
testJobs.add(launch(testPool) {
|
testJobs.add(launch(testPool) {
|
||||||
while (isActive) {
|
while (isActive) {
|
||||||
val profile = profiles.poll() ?: break
|
val profile = profiles.poll() ?: break
|
||||||
@ -764,7 +765,7 @@ class ConfigurationFragment @JvmOverloads constructor(
|
|||||||
val profiles = ConcurrentLinkedQueue(profilesUnfiltered)
|
val profiles = ConcurrentLinkedQueue(profilesUnfiltered)
|
||||||
val urlTest = UrlTest() // note: this is NOT in bg process
|
val urlTest = UrlTest() // note: this is NOT in bg process
|
||||||
|
|
||||||
repeat(5) {
|
repeat(DataStore.connectionTestConcurrent) {
|
||||||
testJobs.add(launch {
|
testJobs.add(launch {
|
||||||
while (isActive) {
|
while (isActive) {
|
||||||
val profile = profiles.poll() ?: break
|
val profile = profiles.poll() ?: break
|
||||||
|
|||||||
@ -25,7 +25,7 @@ constructor(
|
|||||||
) : EditTextPreference(context, attrs, defStyleAttr, defStyleRes) {
|
) : EditTextPreference(context, attrs, defStyleAttr, defStyleRes) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
dialogLayoutResource = R.layout.layout_link_dialog
|
dialogLayoutResource = R.layout.layout_urltest_preference_dialog
|
||||||
|
|
||||||
setOnBindEditTextListener {
|
setOnBindEditTextListener {
|
||||||
val linkLayout = it.rootView.findViewById<TextInputLayout>(R.id.input_layout)
|
val linkLayout = it.rootView.findViewById<TextInputLayout>(R.id.input_layout)
|
||||||
|
|||||||
@ -1,71 +0,0 @@
|
|||||||
package io.nekohasekai.sagernet.widget
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.util.AttributeSet
|
|
||||||
import androidx.core.content.res.TypedArrayUtils
|
|
||||||
import androidx.core.widget.addTextChangedListener
|
|
||||||
import androidx.preference.EditTextPreference
|
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
|
||||||
import io.nekohasekai.sagernet.R
|
|
||||||
import io.nekohasekai.sagernet.ktx.app
|
|
||||||
import io.nekohasekai.sagernet.ktx.readableMessage
|
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
|
||||||
|
|
||||||
class LinkPreference
|
|
||||||
@JvmOverloads
|
|
||||||
constructor(
|
|
||||||
context: Context,
|
|
||||||
attrs: AttributeSet? = null,
|
|
||||||
defStyleAttr: Int = TypedArrayUtils.getAttr(
|
|
||||||
context, R.attr.editTextPreferenceStyle,
|
|
||||||
android.R.attr.editTextPreferenceStyle
|
|
||||||
),
|
|
||||||
defStyleRes: Int = 0
|
|
||||||
) : EditTextPreference(context, attrs, defStyleAttr, defStyleRes) {
|
|
||||||
|
|
||||||
// var defaultValue: String? = null
|
|
||||||
|
|
||||||
init {
|
|
||||||
dialogLayoutResource = R.layout.layout_link_dialog
|
|
||||||
|
|
||||||
setOnBindEditTextListener {
|
|
||||||
val linkLayout = it.rootView.findViewById<TextInputLayout>(R.id.input_layout)
|
|
||||||
fun validate() {
|
|
||||||
val link = it.text
|
|
||||||
if (link.isBlank()) {
|
|
||||||
linkLayout.isErrorEnabled = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
val url = link.toString().toHttpUrl()
|
|
||||||
if ("http".equals(url.scheme, true)) {
|
|
||||||
linkLayout.error = app.getString(R.string.cleartext_http_warning)
|
|
||||||
linkLayout.isErrorEnabled = true
|
|
||||||
} else {
|
|
||||||
linkLayout.isErrorEnabled = false
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
linkLayout.error = e.readableMessage
|
|
||||||
linkLayout.isErrorEnabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
validate()
|
|
||||||
it.addTextChangedListener {
|
|
||||||
validate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setOnPreferenceChangeListener { _, newValue ->
|
|
||||||
if ((newValue as String).isBlank()) {
|
|
||||||
// text = defaultValue
|
|
||||||
false
|
|
||||||
} else try {
|
|
||||||
newValue.toHttpUrl()
|
|
||||||
true
|
|
||||||
} catch (ignored: Exception) {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
47
app/src/main/java/moe/matsuri/nb4a/ui/UrlTestPreference.kt
Normal file
47
app/src/main/java/moe/matsuri/nb4a/ui/UrlTestPreference.kt
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package moe.matsuri.nb4a.ui
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.widget.EditText
|
||||||
|
import androidx.core.content.res.TypedArrayUtils
|
||||||
|
import androidx.preference.EditTextPreference
|
||||||
|
import io.nekohasekai.sagernet.R
|
||||||
|
import io.nekohasekai.sagernet.database.DataStore
|
||||||
|
|
||||||
|
class UrlTestPreference
|
||||||
|
@JvmOverloads
|
||||||
|
constructor(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet? = null,
|
||||||
|
defStyleAttr: Int = TypedArrayUtils.getAttr(
|
||||||
|
context, R.attr.editTextPreferenceStyle,
|
||||||
|
android.R.attr.editTextPreferenceStyle
|
||||||
|
),
|
||||||
|
defStyleRes: Int = 0
|
||||||
|
) : EditTextPreference(context, attrs, defStyleAttr, defStyleRes) {
|
||||||
|
|
||||||
|
var concurrent: EditText? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
dialogLayoutResource = R.layout.layout_urltest_preference_dialog
|
||||||
|
|
||||||
|
setOnBindEditTextListener {
|
||||||
|
concurrent = it.rootView.findViewById(R.id.edit_concurrent)
|
||||||
|
concurrent?.apply {
|
||||||
|
setText(DataStore.connectionTestConcurrent.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setOnPreferenceChangeListener { _, _ ->
|
||||||
|
concurrent?.apply {
|
||||||
|
var newConcurrent = text?.toString()?.toIntOrNull()
|
||||||
|
if (newConcurrent == null || newConcurrent <= 0) {
|
||||||
|
newConcurrent = 5
|
||||||
|
}
|
||||||
|
DataStore.connectionTestConcurrent = newConcurrent
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -10,18 +10,6 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@android:id/message"
|
|
||||||
style="?android:attr/textAppearanceSmall"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="24dp"
|
|
||||||
android:layout_marginLeft="24dp"
|
|
||||||
android:layout_marginEnd="24dp"
|
|
||||||
android:layout_marginRight="24dp"
|
|
||||||
android:layout_marginBottom="48dp"
|
|
||||||
android:textColor="?android:attr/textColorSecondary" />
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/input_layout"
|
android:id="@+id/input_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -41,6 +29,30 @@
|
|||||||
android:paddingTop="12dp"
|
android:paddingTop="12dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:typeface="monospace" />
|
android:typeface="monospace" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="?android:attr/textAppearanceSmall"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/test_concurrency"
|
||||||
|
android:textColor="?android:attr/textColorSecondary" />
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/edit_concurrent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:inputType="number"
|
||||||
|
android:minHeight="48dp"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:typeface="monospace" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
@ -93,10 +93,6 @@
|
|||||||
android:id="@+id/action_connection_test"
|
android:id="@+id/action_connection_test"
|
||||||
android:title="@string/connection_test">
|
android:title="@string/connection_test">
|
||||||
<menu>
|
<menu>
|
||||||
<item
|
|
||||||
android:id="@+id/action_connection_icmp_ping"
|
|
||||||
android:title="@string/connection_test_icmp_ping"
|
|
||||||
android:visible="false" />
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_connection_tcp_ping"
|
android:id="@+id/action_connection_tcp_ping"
|
||||||
android:title="@string/connection_test_tcp_ping" />
|
android:title="@string/connection_test_tcp_ping" />
|
||||||
|
|||||||
@ -471,4 +471,7 @@
|
|||||||
<string name="reset_connections">重置连接</string>
|
<string name="reset_connections">重置连接</string>
|
||||||
<string name="remove_duplicate">删除重复的服务器</string>
|
<string name="remove_duplicate">删除重复的服务器</string>
|
||||||
<string name="tls_camouflage_settings">TLS 伪装设置</string>
|
<string name="tls_camouflage_settings">TLS 伪装设置</string>
|
||||||
|
<string name="mtu_help">长按设置项以设置自定义 MTU。</string>
|
||||||
|
<string name="log_level_help">长按设置项以设置缓冲区大小。</string>
|
||||||
|
<string name="test_concurrency">测试并发</string>
|
||||||
</resources>
|
</resources>
|
||||||
@ -514,5 +514,6 @@ Anyone can write advanced plugins, which can control NekoBox. please download an
|
|||||||
<string name="mtu_help">Long press the preference to set custom MTU.</string>
|
<string name="mtu_help">Long press the preference to set custom MTU.</string>
|
||||||
<string name="log_level_help">Long press the preference to set the buffer size.</string>
|
<string name="log_level_help">Long press the preference to set the buffer size.</string>
|
||||||
<string name="tls_camouflage_settings">TLS Camouflage Settings</string>
|
<string name="tls_camouflage_settings">TLS Camouflage Settings</string>
|
||||||
|
<string name="test_concurrency">Test concurrency</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@ -215,7 +215,7 @@
|
|||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory app:title="@string/cag_misc">
|
<PreferenceCategory app:title="@string/cag_misc">
|
||||||
<EditTextPreference
|
<moe.matsuri.nb4a.ui.UrlTestPreference
|
||||||
app:defaultValue="http://cp.cloudflare.com/"
|
app:defaultValue="http://cp.cloudflare.com/"
|
||||||
app:icon="@drawable/ic_baseline_cast_connected_24"
|
app:icon="@drawable/ic_baseline_cast_connected_24"
|
||||||
app:key="connectionTestURL"
|
app:key="connectionTestURL"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user