Add support for polling ip with root

This commit is contained in:
Mygod
2019-02-17 11:13:51 +08:00
parent 940378857d
commit 662aee51bf
5 changed files with 32 additions and 5 deletions

View File

@@ -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.
- 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.
- Poll with root: Same as Poll but polling is done using a root shell.
## Q & A

View File

@@ -5,6 +5,7 @@ import android.system.OsConstants
import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.DebugHelper
import be.mygod.vpnhotspot.R
import be.mygod.vpnhotspot.util.RootSession
import be.mygod.vpnhotspot.widget.SmartSnackbar
import timber.log.Timber
import java.io.IOException
@@ -17,10 +18,11 @@ import kotlin.concurrent.thread
abstract class IpMonitor : Runnable {
companion object {
const val KEY = "service.ipMonitor"
private val currentMode get() = Mode.valueOf(app.pref.getString(KEY, Mode.Poll.toString()) ?: "")
}
enum class Mode {
Monitor, MonitorRoot, Poll
enum class Mode(val isMonitor: Boolean = false) {
Monitor(true), MonitorRoot(true), Poll, PollRoot
}
private class FlushFailure : RuntimeException()
@@ -66,8 +68,8 @@ abstract class IpMonitor : Runnable {
init {
thread(name = "${javaClass.simpleName}-input") {
val mode = Mode.valueOf(app.pref.getString(KEY, Mode.Poll.toString()) ?: "")
if (mode != Mode.Poll) {
val mode = currentMode
if (mode.isMonitor) {
if (mode != Mode.MonitorRoot) {
// monitor may get rejected by SELinux enforcing
handleProcess(ProcessBuilder("ip", "monitor", monitoredObject))
@@ -85,7 +87,7 @@ abstract class IpMonitor : Runnable {
fun flush() = thread(name = "${javaClass.simpleName}-flush") { run() }
override fun run() {
private fun poll() {
val process = ProcessBuilder("ip", monitoredObject)
.redirectErrorStream(true)
.start()
@@ -101,6 +103,26 @@ abstract class IpMonitor : Runnable {
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() {
destroyed = true
monitor?.destroy()

View File

@@ -100,6 +100,7 @@
<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_poll">轮询</string>
<string name="settings_service_ip_monitor_poll_root">轮询 (root)</string>
<string name="settings_service_upstream">上游网络接口</string>
<string name="settings_service_upstream_auto">自动检测系统 VPN</string>
<string name="settings_service_clean">清理/重新应用路由规则</string>

View File

@@ -26,10 +26,12 @@
<item>@string/settings_service_ip_monitor_monitor</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_root</item>
</string-array>
<string-array name="settings_service_ip_monitor_values">
<item>Monitor</item>
<item>MonitorRoot</item>
<item>Poll</item>
<item>PollRoot</item>
</string-array>
</resources>

View File

@@ -106,6 +106,7 @@
<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_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_auto">Auto detect system VPN</string>
<string name="settings_service_dhcp_workaround">Enable DHCP workaround</string>