Add 60 seconds timeout to RootSession
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
package be.mygod.vpnhotspot.util
|
package be.mygod.vpnhotspot.util
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.core.os.postDelayed
|
||||||
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import com.crashlytics.android.Crashlytics
|
import com.crashlytics.android.Crashlytics
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -8,27 +10,41 @@ import java.util.concurrent.locks.ReentrantLock
|
|||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.concurrent.withLock
|
import kotlin.concurrent.withLock
|
||||||
|
|
||||||
class RootSession {
|
class RootSession : AutoCloseable {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "RootSession"
|
private const val TAG = "RootSession"
|
||||||
const val INIT_CHECKPOINT = "$TAG initialized successfully"
|
private const val INIT_CHECKPOINT = "$TAG initialized successfully"
|
||||||
|
|
||||||
private val monitor = ReentrantLock()
|
private val monitor = ReentrantLock()
|
||||||
|
private fun onUnlock() {
|
||||||
|
if (monitor.holdCount == 1) instance?.startTimeout()
|
||||||
|
}
|
||||||
|
private fun unlock() {
|
||||||
|
onUnlock()
|
||||||
|
monitor.unlock()
|
||||||
|
}
|
||||||
|
|
||||||
private var instance: RootSession? = null
|
private var instance: RootSession? = null
|
||||||
private fun ensureInstance(): RootSession {
|
private fun ensureInstance(): RootSession {
|
||||||
var instance = instance
|
var instance = instance
|
||||||
if (instance == null) instance = RootSession().also { RootSession.instance = it }
|
if (instance == null || !instance.isAlive) instance = RootSession().also { RootSession.instance = it }
|
||||||
return instance
|
return instance
|
||||||
}
|
}
|
||||||
fun <T> use(operation: (RootSession) -> T) = monitor.withLock { operation(ensureInstance()) }
|
fun <T> use(operation: (RootSession) -> T) = monitor.withLock {
|
||||||
|
val instance = ensureInstance()
|
||||||
|
instance.haltTimeout()
|
||||||
|
operation(instance).also { onUnlock() }
|
||||||
|
}
|
||||||
fun beginTransaction(): Transaction {
|
fun beginTransaction(): Transaction {
|
||||||
monitor.lock()
|
monitor.lock()
|
||||||
return try {
|
val instance = try {
|
||||||
ensureInstance()
|
ensureInstance()
|
||||||
} catch (e: RuntimeException) {
|
} catch (e: RuntimeException) {
|
||||||
monitor.unlock()
|
unlock()
|
||||||
throw e
|
throw e
|
||||||
}.Transaction()
|
}
|
||||||
|
instance.haltTimeout()
|
||||||
|
return instance.Transaction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +69,14 @@ class RootSession {
|
|||||||
checkOutput("echo", result, result.out.joinToString("\n").trim() != INIT_CHECKPOINT)
|
checkOutput("echo", result, result.out.joinToString("\n").trim() != INIT_CHECKPOINT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val isAlive get() = shell.isAlive
|
||||||
|
override fun close() {
|
||||||
|
shell.close()
|
||||||
|
if (instance == this) instance = null
|
||||||
|
}
|
||||||
|
private fun startTimeout() = app.handler.postDelayed(60 * 1000, this) { monitor.withLock { close() } }
|
||||||
|
private fun haltTimeout() = app.handler.removeCallbacksAndMessages(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Don't care about the results, but still sync.
|
* Don't care about the results, but still sync.
|
||||||
*/
|
*/
|
||||||
@@ -91,7 +115,7 @@ class RootSession {
|
|||||||
}
|
}
|
||||||
fun execQuiet(command: String) = this@RootSession.execQuiet(command)
|
fun execQuiet(command: String) = this@RootSession.execQuiet(command)
|
||||||
|
|
||||||
fun commit() = monitor.unlock()
|
fun commit() = unlock()
|
||||||
|
|
||||||
fun revert() {
|
fun revert() {
|
||||||
if (revertCommands.isEmpty()) return
|
if (revertCommands.isEmpty()) return
|
||||||
@@ -99,9 +123,10 @@ class RootSession {
|
|||||||
monitor.lock()
|
monitor.lock()
|
||||||
ensureInstance()
|
ensureInstance()
|
||||||
}
|
}
|
||||||
|
shell.haltTimeout()
|
||||||
revertCommands.forEach { shell.submit(it) }
|
revertCommands.forEach { shell.submit(it) }
|
||||||
revertCommands.clear()
|
revertCommands.clear()
|
||||||
monitor.unlock() // commit
|
unlock() // commit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user