Commit b510dc51 authored by topjohnwu's avatar topjohnwu

Fix su request auto response

parent d7f7508f
...@@ -18,17 +18,16 @@ import java.io.* ...@@ -18,17 +18,16 @@ import java.io.*
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeUnit.SECONDS import java.util.concurrent.TimeUnit.SECONDS
abstract class SuRequestHandler( class SuRequestHandler(
private val packageManager: PackageManager, private val pm: PackageManager,
private val policyDB: PolicyDao private val policyDB: PolicyDao
) : Closeable { ) : Closeable {
private lateinit var output: DataOutputStream private lateinit var output: DataOutputStream
protected lateinit var policy: SuPolicy lateinit var policy: SuPolicy
private set private set
abstract fun onStart() // Return true to indicate undetermined policy, require user interaction
suspend fun start(intent: Intent): Boolean { suspend fun start(intent: Intent): Boolean {
if (!init(intent)) if (!init(intent))
return false return false
...@@ -40,15 +39,14 @@ abstract class SuRequestHandler( ...@@ -40,15 +39,14 @@ abstract class SuRequestHandler(
when (Config.suAutoReponse) { when (Config.suAutoReponse) {
Config.Value.SU_AUTO_DENY -> { Config.Value.SU_AUTO_DENY -> {
respond(SuPolicy.DENY, 0) respond(SuPolicy.DENY, 0)
return true return false
} }
Config.Value.SU_AUTO_ALLOW -> { Config.Value.SU_AUTO_ALLOW -> {
respond(SuPolicy.ALLOW, 0) respond(SuPolicy.ALLOW, 0)
return true return false
} }
} }
onStart()
return true return true
} }
...@@ -82,7 +80,7 @@ abstract class SuRequestHandler( ...@@ -82,7 +80,7 @@ abstract class SuRequestHandler(
val map = async { input.readRequest() }.timedAwait() ?: throw SuRequestError() val map = async { input.readRequest() }.timedAwait() ?: throw SuRequestError()
uid = map["uid"]?.toIntOrNull() ?: throw SuRequestError() uid = map["uid"]?.toIntOrNull() ?: throw SuRequestError()
} }
policy = uid.toPolicy(packageManager) policy = uid.toPolicy(pm)
true true
} catch (e: Exception) { } catch (e: Exception) {
when (e) { when (e) {
......
...@@ -5,7 +5,7 @@ import com.topjohnwu.magisk.arch.BaseUIActivity ...@@ -5,7 +5,7 @@ import com.topjohnwu.magisk.arch.BaseUIActivity
import com.topjohnwu.magisk.arch.ViewEvent import com.topjohnwu.magisk.arch.ViewEvent
import com.topjohnwu.magisk.core.utils.BiometricHelper import com.topjohnwu.magisk.core.utils.BiometricHelper
class BiometricDialog( class BiometricEvent(
builder: Builder.() -> Unit builder: Builder.() -> Unit
) : ViewEvent(), ActivityExecutor { ) : ViewEvent(), ActivityExecutor {
......
...@@ -23,7 +23,7 @@ import com.topjohnwu.magisk.core.tasks.PatchAPK ...@@ -23,7 +23,7 @@ import com.topjohnwu.magisk.core.tasks.PatchAPK
import com.topjohnwu.magisk.data.database.RepoDao import com.topjohnwu.magisk.data.database.RepoDao
import com.topjohnwu.magisk.events.AddHomeIconEvent import com.topjohnwu.magisk.events.AddHomeIconEvent
import com.topjohnwu.magisk.events.RecreateEvent import com.topjohnwu.magisk.events.RecreateEvent
import com.topjohnwu.magisk.events.dialog.BiometricDialog import com.topjohnwu.magisk.events.dialog.BiometricEvent
import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
...@@ -125,7 +125,7 @@ class SettingsViewModel( ...@@ -125,7 +125,7 @@ class SettingsViewModel(
} }
private fun authenticate(callback: () -> Unit) { private fun authenticate(callback: () -> Unit) {
BiometricDialog { BiometricEvent {
// allow the change on success // allow the change on success
onSuccess { callback() } onSuccess { callback() }
}.publish() }.publish()
......
...@@ -16,7 +16,7 @@ import com.topjohnwu.magisk.core.utils.BiometricHelper ...@@ -16,7 +16,7 @@ import com.topjohnwu.magisk.core.utils.BiometricHelper
import com.topjohnwu.magisk.core.utils.currentLocale import com.topjohnwu.magisk.core.utils.currentLocale
import com.topjohnwu.magisk.databinding.ComparableRvItem import com.topjohnwu.magisk.databinding.ComparableRvItem
import com.topjohnwu.magisk.events.SnackbarEvent import com.topjohnwu.magisk.events.SnackbarEvent
import com.topjohnwu.magisk.events.dialog.BiometricDialog import com.topjohnwu.magisk.events.dialog.BiometricEvent
import com.topjohnwu.magisk.events.dialog.SuperuserRevokeDialog import com.topjohnwu.magisk.events.dialog.SuperuserRevokeDialog
import com.topjohnwu.magisk.view.TappableHeadlineItem import com.topjohnwu.magisk.view.TappableHeadlineItem
import com.topjohnwu.magisk.view.TextItem import com.topjohnwu.magisk.view.TextItem
...@@ -86,7 +86,7 @@ class SuperuserViewModel( ...@@ -86,7 +86,7 @@ class SuperuserViewModel(
} }
if (BiometricHelper.isEnabled) { if (BiometricHelper.isEnabled) {
BiometricDialog { BiometricEvent {
onSuccess { updateState() } onSuccess { updateState() }
}.publish() }.publish()
} else { } else {
...@@ -130,7 +130,7 @@ class SuperuserViewModel( ...@@ -130,7 +130,7 @@ class SuperuserViewModel(
} }
if (BiometricHelper.isEnabled) { if (BiometricHelper.isEnabled) {
BiometricDialog { BiometricEvent {
onSuccess { updateState() } onSuccess { updateState() }
}.publish() }.publish()
} else { } else {
......
...@@ -29,7 +29,7 @@ open class SuRequestActivity : BaseUIActivity<SuRequestViewModel, ActivityReques ...@@ -29,7 +29,7 @@ open class SuRequestActivity : BaseUIActivity<SuRequestViewModel, ActivityReques
supportRequestWindowFeature(Window.FEATURE_NO_TITLE) supportRequestWindowFeature(Window.FEATURE_NO_TITLE)
lockOrientation() lockOrientation()
window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, window.setFlags(WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE) WindowManager.LayoutParams.FLAG_SECURE)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
fun showRequest() { fun showRequest() {
......
...@@ -13,12 +13,14 @@ import com.topjohnwu.magisk.R ...@@ -13,12 +13,14 @@ import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.arch.BaseViewModel import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.magiskdb.PolicyDao import com.topjohnwu.magisk.core.magiskdb.PolicyDao
import com.topjohnwu.magisk.core.model.su.SuPolicy
import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW
import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.DENY import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.DENY
import com.topjohnwu.magisk.core.su.SuRequestHandler import com.topjohnwu.magisk.core.su.SuRequestHandler
import com.topjohnwu.magisk.core.utils.BiometricHelper import com.topjohnwu.magisk.core.utils.BiometricHelper
import com.topjohnwu.magisk.events.DieEvent import com.topjohnwu.magisk.events.DieEvent
import com.topjohnwu.magisk.events.ShowUIEvent import com.topjohnwu.magisk.events.ShowUIEvent
import com.topjohnwu.magisk.events.dialog.BiometricEvent
import com.topjohnwu.magisk.ui.superuser.SpinnerRvItem import com.topjohnwu.magisk.ui.superuser.SpinnerRvItem
import com.topjohnwu.magisk.utils.set import com.topjohnwu.magisk.utils.set
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
...@@ -28,7 +30,7 @@ import java.util.concurrent.TimeUnit.SECONDS ...@@ -28,7 +30,7 @@ import java.util.concurrent.TimeUnit.SECONDS
class SuRequestViewModel( class SuRequestViewModel(
private val pm: PackageManager, private val pm: PackageManager,
private val policyDB: PolicyDao, policyDB: PolicyDao,
private val timeoutPrefs: SharedPreferences, private val timeoutPrefs: SharedPreferences,
private val res: Resources private val res: Resources
) : BaseViewModel() { ) : BaseViewModel() {
...@@ -57,89 +59,86 @@ class SuRequestViewModel( ...@@ -57,89 +59,86 @@ class SuRequestViewModel(
setItems(items) setItems(items)
} }
private val handler = Handler() private val handler = SuRequestHandler(pm, policyDB)
private lateinit var timer: CountDownTimer
fun grantPressed() { fun grantPressed() {
handler.cancelTimer() cancelTimer()
if (BiometricHelper.isEnabled) { if (BiometricHelper.isEnabled) {
withView { BiometricEvent {
BiometricHelper.authenticate(this) { onSuccess {
handler.respond(ALLOW) respond(ALLOW)
} }
} }.publish()
} else { } else {
handler.respond(ALLOW) respond(ALLOW)
} }
} }
fun denyPressed() { fun denyPressed() {
handler.respond(DENY) respond(DENY)
} }
fun spinnerTouched(): Boolean { fun spinnerTouched(): Boolean {
handler.cancelTimer() cancelTimer()
return false return false
} }
fun handleRequest(intent: Intent) { fun handleRequest(intent: Intent) {
viewModelScope.launch { viewModelScope.launch {
if (!handler.start(intent)) if (handler.start(intent))
showDialog(handler.policy)
else
DieEvent().publish() DieEvent().publish()
} }
} }
private inner class Handler : SuRequestHandler(pm, policyDB) { private fun showDialog(policy: SuPolicy) {
icon = policy.applicationInfo.loadIcon(pm)
private lateinit var timer: CountDownTimer title = policy.appName
packageName = policy.packageName
fun respond(action: Int) { selectedItemPosition = timeoutPrefs.getInt(policy.packageName, 0)
timer.cancel()
val pos = selectedItemPosition // Set timer
timeoutPrefs.edit().putInt(policy.packageName, pos).apply() val millis = SECONDS.toMillis(Config.suDefaultTimeout.toLong())
respond(action, Config.Value.TIMEOUT_LIST[pos]) timer = SuTimer(millis, 1000).apply { start() }
// Kill activity after response
DieEvent().publish()
}
fun cancelTimer() { // Actually show the UI
timer.cancel() ShowUIEvent().publish()
denyText = res.getString(R.string.deny) }
}
override fun onStart() { private fun respond(action: Int) {
icon = policy.applicationInfo.loadIcon(pm) timer.cancel()
title = policy.appName
packageName = policy.packageName
selectedItemPosition = timeoutPrefs.getInt(policy.packageName, 0)
// Set timer val pos = selectedItemPosition
val millis = SECONDS.toMillis(Config.suDefaultTimeout.toLong()) timeoutPrefs.edit().putInt(handler.policy.packageName, pos).apply()
timer = SuTimer(millis, 1000).apply { start() } handler.respond(action, Config.Value.TIMEOUT_LIST[pos])
// Actually show the UI // Kill activity after response
ShowUIEvent().publish() DieEvent().publish()
} }
private inner class SuTimer( private fun cancelTimer() {
private val millis: Long, timer.cancel()
interval: Long denyText = res.getString(R.string.deny)
) : CountDownTimer(millis, interval) { }
override fun onTick(remains: Long) { private inner class SuTimer(
if (!grantEnabled && remains <= millis - 1000) { private val millis: Long,
grantEnabled = true interval: Long
} ) : CountDownTimer(millis, interval) {
denyText = "${res.getString(R.string.deny)} (${(remains / 1000) + 1})"
}
override fun onFinish() { override fun onTick(remains: Long) {
denyText = res.getString(R.string.deny) if (!grantEnabled && remains <= millis - 1000) {
respond(DENY) grantEnabled = true
} }
denyText = "${res.getString(R.string.deny)} (${(remains / 1000) + 1})"
}
override fun onFinish() {
denyText = res.getString(R.string.deny)
respond(DENY)
} }
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment