diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/App.kt b/mobile/src/main/java/be/mygod/vpnhotspot/App.kt index 3046e8c1..de29da8c 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/App.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/App.kt @@ -7,7 +7,10 @@ import android.app.NotificationManager import android.content.SharedPreferences import android.content.res.Configuration import android.os.Build +import android.os.Handler import android.preference.PreferenceManager +import android.support.annotation.StringRes +import android.widget.Toast class App : Application() { companion object { @@ -36,6 +39,9 @@ class App : Application() { } } + private val handler = Handler() val pref: SharedPreferences by lazy { PreferenceManager.getDefaultSharedPreferences(this) } val dns: String get() = app.pref.getString("service.dns", "8.8.8.8:53") + + fun toast(@StringRes resId: Int) = handler.post { Toast.makeText(app, resId, Toast.LENGTH_SHORT).show() } } diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterFragment.kt b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterFragment.kt index 1682f71e..cac14594 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterFragment.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/RepeaterFragment.kt @@ -97,11 +97,11 @@ class RepeaterFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClickL fun recreate() { clients.clear() val map = HashMap(p2p.associateBy { it.deviceAddress }) - val tethered = (tetheredInterfaces + p2pInterface).filterNotNull() for (neighbour in neighbours) { val client = map.remove(neighbour.lladdr) if (client != null) clients.add(Client(client, neighbour)) - else if (tethered.contains(neighbour.dev)) clients.add(Client(neighbour = neighbour)) + else if (tetheredInterfaces.contains(neighbour.dev) || neighbour.dev == p2pInterface) + clients.add(Client(neighbour = neighbour)) } clients.addAll(map.map { Client(it.value) }) clients.sortWith(compareBy { it.ip }.thenBy { it.mac }) diff --git a/mobile/src/main/java/be/mygod/vpnhotspot/net/IpNeighbourMonitor.kt b/mobile/src/main/java/be/mygod/vpnhotspot/net/IpNeighbourMonitor.kt index 342c8483..e00c4523 100644 --- a/mobile/src/main/java/be/mygod/vpnhotspot/net/IpNeighbourMonitor.kt +++ b/mobile/src/main/java/be/mygod/vpnhotspot/net/IpNeighbourMonitor.kt @@ -1,9 +1,7 @@ package be.mygod.vpnhotspot.net -import android.os.Build import android.os.Handler import android.util.Log -import android.widget.Toast import be.mygod.vpnhotspot.App.Companion.app import be.mygod.vpnhotspot.R import be.mygod.vpnhotspot.debugLog @@ -37,9 +35,7 @@ class IpNeighbourMonitor private constructor() { private fun thread(name: String? = null, start: Boolean = true, isDaemon: Boolean = false, contextClassLoader: ClassLoader? = null, priority: Int = -1, block: () -> Unit): Thread { val thread = kotlin.concurrent.thread(false, isDaemon, contextClassLoader, name, priority, block) - thread.setUncaughtExceptionHandler { _, _ -> - Toast.makeText(app, R.string.noisy_su_failure, Toast.LENGTH_SHORT).show() - } + thread.setUncaughtExceptionHandler { _, _ -> app.toast(R.string.noisy_su_failure) } if (start) thread.start() return thread } @@ -53,18 +49,12 @@ class IpNeighbourMonitor private constructor() { private val handler = Handler() private var updatePosted = false val neighbours = HashMap() - /** - * Using monitor requires using /proc/self/ns/net which would be problematic on Android 6.0+. - * - * Source: https://source.android.com/security/enhancements/enhancements60 - */ private var monitor: Process? = null init { thread(name = TAG + "-input") { - val monitor = (if (Build.VERSION.SDK_INT >= 23) - ProcessBuilder("su", "-c", "ip", "-4", "monitor", "neigh") else - ProcessBuilder("ip", "-4", "monitor", "neigh")) + // monitor may get rejected by SELinux + val monitor = ProcessBuilder("sh", "-c", "ip -4 monitor neigh || su -c ip -4 monitor neigh") .redirectErrorStream(true) .start() this.monitor = monitor @@ -84,8 +74,8 @@ class IpNeighbourMonitor private constructor() { if (changed) postUpdateLocked() } } - Log.w(TAG, if (Build.VERSION.SDK_INT >= 26 && monitor.isAlive) "monitor closed stdout" else - "monitor died unexpectedly") + monitor.waitFor() + if (monitor.exitValue() != 0) app.toast(R.string.noisy_su_failure) } catch (ignore: InterruptedIOException) { } } }