Fix su request auto response

This commit is contained in:
topjohnwu 2020-09-11 03:09:01 -07:00
parent d7f7508fa2
commit b510dc51ac
6 changed files with 74 additions and 77 deletions

View File

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

View File

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

View File

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

View File

@ -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(
} }
if (BiometricHelper.isEnabled) { if (BiometricHelper.isEnabled) {
BiometricDialog { BiometricEvent {
onSuccess { updateState() } onSuccess { updateState() }
}.publish() }.publish()
} else { } else {
@ -130,7 +130,7 @@ class SuperuserViewModel(
} }
if (BiometricHelper.isEnabled) { if (BiometricHelper.isEnabled) {
BiometricDialog { BiometricEvent {
onSuccess { updateState() } onSuccess { updateState() }
}.publish() }.publish()
} else { } else {

View File

@ -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
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,58 +59,41 @@ 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) {
private lateinit var timer: CountDownTimer
fun respond(action: Int) {
timer.cancel()
val pos = selectedItemPosition
timeoutPrefs.edit().putInt(policy.packageName, pos).apply()
respond(action, Config.Value.TIMEOUT_LIST[pos])
// Kill activity after response
DieEvent().publish()
}
fun cancelTimer() {
timer.cancel()
denyText = res.getString(R.string.deny)
}
override fun onStart() {
icon = policy.applicationInfo.loadIcon(pm) icon = policy.applicationInfo.loadIcon(pm)
title = policy.appName title = policy.appName
packageName = policy.packageName packageName = policy.packageName
@ -122,6 +107,22 @@ class SuRequestViewModel(
ShowUIEvent().publish() ShowUIEvent().publish()
} }
private fun respond(action: Int) {
timer.cancel()
val pos = selectedItemPosition
timeoutPrefs.edit().putInt(handler.policy.packageName, pos).apply()
handler.respond(action, Config.Value.TIMEOUT_LIST[pos])
// Kill activity after response
DieEvent().publish()
}
private fun cancelTimer() {
timer.cancel()
denyText = res.getString(R.string.deny)
}
private inner class SuTimer( private inner class SuTimer(
private val millis: Long, private val millis: Long,
interval: Long interval: Long
@ -141,5 +142,3 @@ class SuRequestViewModel(
} }
} }
}