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. 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

View File

@@ -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()

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>