Add support for polling ip with root
This commit is contained in:
@@ -77,6 +77,7 @@ Default settings are picked to suit general use cases and maximize compatibility
|
|||||||
but might still be bugged on devices heavily modified by OEM and/or carriers. Sometimes auto fallbacks to Poll.
|
but might still be bugged on devices heavily modified by OEM and/or carriers. Sometimes auto fallbacks to Poll.
|
||||||
- Poll: (default) Update network information manually every second. Least battery efficient but it should work on most
|
- Poll: (default) Update network information manually every second. Least battery efficient but it should work on most
|
||||||
devices. Recommended to switch to other modes if possible.
|
devices. Recommended to switch to other modes if possible.
|
||||||
|
- Poll with root: Same as Poll but polling is done using a root shell.
|
||||||
|
|
||||||
|
|
||||||
## Q & A
|
## Q & A
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.system.OsConstants
|
|||||||
import be.mygod.vpnhotspot.App.Companion.app
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import be.mygod.vpnhotspot.DebugHelper
|
import be.mygod.vpnhotspot.DebugHelper
|
||||||
import be.mygod.vpnhotspot.R
|
import be.mygod.vpnhotspot.R
|
||||||
|
import be.mygod.vpnhotspot.util.RootSession
|
||||||
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
@@ -17,10 +18,11 @@ import kotlin.concurrent.thread
|
|||||||
abstract class IpMonitor : Runnable {
|
abstract class IpMonitor : Runnable {
|
||||||
companion object {
|
companion object {
|
||||||
const val KEY = "service.ipMonitor"
|
const val KEY = "service.ipMonitor"
|
||||||
|
private val currentMode get() = Mode.valueOf(app.pref.getString(KEY, Mode.Poll.toString()) ?: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class Mode {
|
enum class Mode(val isMonitor: Boolean = false) {
|
||||||
Monitor, MonitorRoot, Poll
|
Monitor(true), MonitorRoot(true), Poll, PollRoot
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FlushFailure : RuntimeException()
|
private class FlushFailure : RuntimeException()
|
||||||
@@ -66,8 +68,8 @@ abstract class IpMonitor : Runnable {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
thread(name = "${javaClass.simpleName}-input") {
|
thread(name = "${javaClass.simpleName}-input") {
|
||||||
val mode = Mode.valueOf(app.pref.getString(KEY, Mode.Poll.toString()) ?: "")
|
val mode = currentMode
|
||||||
if (mode != Mode.Poll) {
|
if (mode.isMonitor) {
|
||||||
if (mode != Mode.MonitorRoot) {
|
if (mode != Mode.MonitorRoot) {
|
||||||
// monitor may get rejected by SELinux enforcing
|
// monitor may get rejected by SELinux enforcing
|
||||||
handleProcess(ProcessBuilder("ip", "monitor", monitoredObject))
|
handleProcess(ProcessBuilder("ip", "monitor", monitoredObject))
|
||||||
@@ -85,7 +87,7 @@ abstract class IpMonitor : Runnable {
|
|||||||
|
|
||||||
fun flush() = thread(name = "${javaClass.simpleName}-flush") { run() }
|
fun flush() = thread(name = "${javaClass.simpleName}-flush") { run() }
|
||||||
|
|
||||||
override fun run() {
|
private fun poll() {
|
||||||
val process = ProcessBuilder("ip", monitoredObject)
|
val process = ProcessBuilder("ip", monitoredObject)
|
||||||
.redirectErrorStream(true)
|
.redirectErrorStream(true)
|
||||||
.start()
|
.start()
|
||||||
@@ -101,6 +103,26 @@ abstract class IpMonitor : Runnable {
|
|||||||
process.inputStream.bufferedReader().useLines(this::processLines)
|
process.inputStream.bufferedReader().useLines(this::processLines)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
if (currentMode == Mode.Poll) try {
|
||||||
|
return poll()
|
||||||
|
} catch (e: IOException) {
|
||||||
|
DebugHelper.logEvent("ip_poll_failure")
|
||||||
|
Timber.d(e)
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
val command = "ip $monitoredObject"
|
||||||
|
RootSession.use {
|
||||||
|
val result = it.execQuiet(command)
|
||||||
|
RootSession.checkOutput(command, result, false)
|
||||||
|
processLines(result.out.asSequence())
|
||||||
|
}
|
||||||
|
} catch (e: RuntimeException) {
|
||||||
|
DebugHelper.logEvent("ip_su_poll_failure")
|
||||||
|
Timber.w(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun destroy() {
|
fun destroy() {
|
||||||
destroyed = true
|
destroyed = true
|
||||||
monitor?.destroy()
|
monitor?.destroy()
|
||||||
|
|||||||
@@ -100,6 +100,7 @@
|
|||||||
<string name="settings_service_ip_monitor_monitor">Netlink 监听</string>
|
<string name="settings_service_ip_monitor_monitor">Netlink 监听</string>
|
||||||
<string name="settings_service_ip_monitor_monitor_root">Netlink 监听 (root)</string>
|
<string name="settings_service_ip_monitor_monitor_root">Netlink 监听 (root)</string>
|
||||||
<string name="settings_service_ip_monitor_poll">轮询</string>
|
<string name="settings_service_ip_monitor_poll">轮询</string>
|
||||||
|
<string name="settings_service_ip_monitor_poll_root">轮询 (root)</string>
|
||||||
<string name="settings_service_upstream">上游网络接口</string>
|
<string name="settings_service_upstream">上游网络接口</string>
|
||||||
<string name="settings_service_upstream_auto">自动检测系统 VPN</string>
|
<string name="settings_service_upstream_auto">自动检测系统 VPN</string>
|
||||||
<string name="settings_service_clean">清理/重新应用路由规则</string>
|
<string name="settings_service_clean">清理/重新应用路由规则</string>
|
||||||
|
|||||||
@@ -26,10 +26,12 @@
|
|||||||
<item>@string/settings_service_ip_monitor_monitor</item>
|
<item>@string/settings_service_ip_monitor_monitor</item>
|
||||||
<item>@string/settings_service_ip_monitor_monitor_root</item>
|
<item>@string/settings_service_ip_monitor_monitor_root</item>
|
||||||
<item>@string/settings_service_ip_monitor_poll</item>
|
<item>@string/settings_service_ip_monitor_poll</item>
|
||||||
|
<item>@string/settings_service_ip_monitor_poll_root</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="settings_service_ip_monitor_values">
|
<string-array name="settings_service_ip_monitor_values">
|
||||||
<item>Monitor</item>
|
<item>Monitor</item>
|
||||||
<item>MonitorRoot</item>
|
<item>MonitorRoot</item>
|
||||||
<item>Poll</item>
|
<item>Poll</item>
|
||||||
|
<item>PollRoot</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -106,6 +106,7 @@
|
|||||||
<string name="settings_service_ip_monitor_monitor">Netlink monitor</string>
|
<string name="settings_service_ip_monitor_monitor">Netlink monitor</string>
|
||||||
<string name="settings_service_ip_monitor_monitor_root">Netlink monitor with root</string>
|
<string name="settings_service_ip_monitor_monitor_root">Netlink monitor with root</string>
|
||||||
<string name="settings_service_ip_monitor_poll">Poll</string>
|
<string name="settings_service_ip_monitor_poll">Poll</string>
|
||||||
|
<string name="settings_service_ip_monitor_poll_root">Poll with root</string>
|
||||||
<string name="settings_service_upstream">Upstream network interface</string>
|
<string name="settings_service_upstream">Upstream network interface</string>
|
||||||
<string name="settings_service_upstream_auto">Auto detect system VPN</string>
|
<string name="settings_service_upstream_auto">Auto detect system VPN</string>
|
||||||
<string name="settings_service_dhcp_workaround">Enable DHCP workaround</string>
|
<string name="settings_service_dhcp_workaround">Enable DHCP workaround</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user