mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-01-11 15:33:37 +00:00
Do not go through a fragment for auth
This commit is contained in:
parent
678c07fff5
commit
e483d6befe
@ -156,7 +156,12 @@ object Config : PreferenceConfig, DBConfig {
|
||||
var rootMode by dbSettings(Key.ROOT_ACCESS, Value.ROOT_ACCESS_APPS_AND_ADB)
|
||||
var suMntNamespaceMode by dbSettings(Key.SU_MNT_NS, Value.NAMESPACE_MODE_REQUESTER)
|
||||
var suMultiuserMode by dbSettings(Key.SU_MULTIUSER_MODE, Value.MULTIUSER_MODE_OWNER_ONLY)
|
||||
var suBiometric by dbSettings(Key.SU_BIOMETRIC, false)
|
||||
private var suBiometric by dbSettings(Key.SU_BIOMETRIC, false)
|
||||
var userAuth
|
||||
get() = Info.isDeviceSecure && suBiometric
|
||||
set(value) {
|
||||
suBiometric = value
|
||||
}
|
||||
var zygisk by dbSettings(Key.ZYGISK, false)
|
||||
var denyList by BoolDBPropertyNoWrite(Key.DENYLIST, false)
|
||||
var suManager by dbStrings(Key.SU_MANAGER, "", true)
|
||||
|
@ -1,7 +1,9 @@
|
||||
package com.topjohnwu.magisk.core
|
||||
|
||||
import android.app.KeyguardManager
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.topjohnwu.magisk.StubApk
|
||||
import com.topjohnwu.magisk.core.di.AppContext
|
||||
import com.topjohnwu.magisk.core.ktx.getProperty
|
||||
import com.topjohnwu.magisk.core.model.UpdateInfo
|
||||
import com.topjohnwu.magisk.core.repository.NetworkService
|
||||
@ -46,6 +48,9 @@ object Info {
|
||||
|| Config.suMultiuserMode == Config.Value.MULTIUSER_MODE_USER)
|
||||
}
|
||||
|
||||
val isDeviceSecure get() =
|
||||
AppContext.getSystemService(KeyguardManager::class.java).isDeviceSecure
|
||||
|
||||
private fun loadState(): Env {
|
||||
val v = fastCmd("magisk -v").split(":".toRegex())
|
||||
return Env(
|
||||
|
@ -20,6 +20,7 @@ import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.isRunningAsStub
|
||||
import com.topjohnwu.magisk.core.ktx.reflectField
|
||||
import com.topjohnwu.magisk.core.ktx.toast
|
||||
import com.topjohnwu.magisk.core.utils.RequestAuthentication
|
||||
import com.topjohnwu.magisk.core.utils.RequestInstall
|
||||
import com.topjohnwu.magisk.core.wrap
|
||||
|
||||
@ -43,6 +44,12 @@ abstract class BaseActivity : AppCompatActivity() {
|
||||
installCallback = null
|
||||
}
|
||||
|
||||
var authenticateCallback: ((Boolean) -> Unit)? = null
|
||||
val requestAuthenticate = registerForActivityResult(RequestAuthentication()) {
|
||||
authenticateCallback?.invoke(it)
|
||||
authenticateCallback = null
|
||||
}
|
||||
|
||||
private var contentCallback: ContentResultCallback? = null
|
||||
private val getContent = registerForActivityResult(GetContent()) {
|
||||
if (it != null) contentCallback?.onActivityResult(it)
|
||||
|
@ -12,7 +12,6 @@ import com.topjohnwu.magisk.core.data.magiskdb.StringDao
|
||||
import com.topjohnwu.magisk.core.ktx.deviceProtectedContext
|
||||
import com.topjohnwu.magisk.core.repository.LogRepository
|
||||
import com.topjohnwu.magisk.core.repository.NetworkService
|
||||
import com.topjohnwu.magisk.core.utils.BiometricHelper
|
||||
import io.noties.markwon.Markwon
|
||||
import io.noties.markwon.utils.NoCopySpannableFactory
|
||||
|
||||
@ -24,7 +23,6 @@ object ServiceLocator {
|
||||
lateinit var context: Context
|
||||
val deContext by lazy { context.deviceProtectedContext }
|
||||
val timeoutPrefs by lazy { deContext.getSharedPreferences("su_timeout", 0) }
|
||||
val biometrics by lazy { BiometricHelper(context) }
|
||||
|
||||
// Database
|
||||
val policyDB = PolicyDao()
|
||||
|
@ -1,59 +0,0 @@
|
||||
package com.topjohnwu.magisk.core.utils
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.KeyguardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
|
||||
class BiometricHelper(context: Context) {
|
||||
|
||||
private val mgr = context.getSystemService(KeyguardManager::class.java)
|
||||
|
||||
val isSupported get() = mgr.isDeviceSecure
|
||||
|
||||
val isEnabled get() = isSupported && Config.suBiometric
|
||||
|
||||
fun authenticate(
|
||||
activity: FragmentActivity,
|
||||
onError: () -> Unit = {},
|
||||
onSuccess: () -> Unit) {
|
||||
val tag = BiometricFragment::class.java.name
|
||||
val intent = mgr.createConfirmDeviceCredentialIntent(null, null)
|
||||
val fragmentManager = activity.supportFragmentManager
|
||||
var fragment = fragmentManager.findFragmentByTag(tag) as BiometricFragment?
|
||||
if (fragment == null) {
|
||||
fragment = BiometricFragment()
|
||||
fragmentManager.beginTransaction()
|
||||
.add(0, fragment, tag)
|
||||
.commitNow()
|
||||
}
|
||||
fragment.start(intent, onError, onSuccess)
|
||||
}
|
||||
|
||||
class BiometricFragment : Fragment() {
|
||||
private val code = 1
|
||||
private var onError: () -> Unit = {}
|
||||
private var onSuccess: () -> Unit = {}
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (requestCode == code) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
onSuccess()
|
||||
} else {
|
||||
onError()
|
||||
}
|
||||
onError = {}
|
||||
onSuccess = {}
|
||||
}
|
||||
}
|
||||
|
||||
fun start(intent: Intent, onError: () -> Unit, onSuccess: () -> Unit) {
|
||||
this.onError = onError
|
||||
this.onSuccess = onSuccess
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK or Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
|
||||
startActivityForResult(intent, code)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.topjohnwu.magisk.core.utils
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.KeyguardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.activity.result.contract.ActivityResultContract
|
||||
|
||||
class RequestAuthentication: ActivityResultContract<Unit, Boolean>() {
|
||||
|
||||
override fun createIntent(context: Context, input: Unit) =
|
||||
context.getSystemService(KeyguardManager::class.java)
|
||||
.createConfirmDeviceCredentialIntent(null, null)
|
||||
|
||||
override fun parseResult(resultCode: Int, intent: Intent?) =
|
||||
resultCode == Activity.RESULT_OK
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package com.topjohnwu.magisk.events
|
||||
|
||||
import com.topjohnwu.magisk.arch.ActivityExecutor
|
||||
import com.topjohnwu.magisk.arch.UIActivity
|
||||
import com.topjohnwu.magisk.arch.ViewEvent
|
||||
import com.topjohnwu.magisk.core.di.ServiceLocator
|
||||
|
||||
class BiometricEvent(
|
||||
builder: Builder.() -> Unit
|
||||
) : ViewEvent(), ActivityExecutor {
|
||||
|
||||
private var listenerOnFailure: () -> Unit = {}
|
||||
private var listenerOnSuccess: () -> Unit = {}
|
||||
|
||||
init {
|
||||
builder(Builder())
|
||||
}
|
||||
|
||||
override fun invoke(activity: UIActivity<*>) {
|
||||
ServiceLocator.biometrics.authenticate(
|
||||
activity,
|
||||
onError = listenerOnFailure,
|
||||
onSuccess = listenerOnSuccess
|
||||
)
|
||||
}
|
||||
|
||||
inner class Builder internal constructor() {
|
||||
|
||||
fun onFailure(listener: () -> Unit) {
|
||||
listenerOnFailure = listener
|
||||
}
|
||||
|
||||
fun onSuccess(listener: () -> Unit) {
|
||||
listenerOnSuccess = listener
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -51,6 +51,16 @@ class RecreateEvent : ViewEvent(), ActivityExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
class BiometricEvent(
|
||||
private val callback: () -> Unit
|
||||
) : ViewEvent(), ActivityExecutor {
|
||||
|
||||
override fun invoke(activity: UIActivity<*>) {
|
||||
activity.authenticateCallback = { if (it) callback() }
|
||||
activity.requestAuthenticate.launch(Unit)
|
||||
}
|
||||
}
|
||||
|
||||
class GetContentEvent(
|
||||
private val type: String,
|
||||
private val callback: ContentResultCallback
|
||||
|
@ -12,7 +12,6 @@ import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.core.Const
|
||||
import com.topjohnwu.magisk.core.Info
|
||||
import com.topjohnwu.magisk.core.di.ServiceLocator
|
||||
import com.topjohnwu.magisk.core.ktx.activity
|
||||
import com.topjohnwu.magisk.core.tasks.HideAPK
|
||||
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
|
||||
@ -286,14 +285,10 @@ object Tapjack : BaseSettingsItem.Toggle() {
|
||||
object Biometrics : BaseSettingsItem.Toggle() {
|
||||
override val title = R.string.settings_su_biometric_title.asText()
|
||||
override var description = R.string.settings_su_biometric_summary.asText()
|
||||
override var value
|
||||
get() = ServiceLocator.biometrics.isEnabled
|
||||
set(value) {
|
||||
Config.suBiometric = value
|
||||
}
|
||||
override var value by Config::userAuth
|
||||
|
||||
override fun refresh() {
|
||||
isEnabled = ServiceLocator.biometrics.isSupported
|
||||
isEnabled = Info.isDeviceSecure
|
||||
if (!isEnabled) {
|
||||
description = R.string.no_biometric.asText()
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
|
||||
when (item) {
|
||||
DownloadPath -> withExternalRW(andThen)
|
||||
UpdateChecker -> withPostNotificationPermission(andThen)
|
||||
Biometrics -> authenticate(andThen)
|
||||
Biometrics -> BiometricEvent(andThen).publish()
|
||||
Theme -> SettingsFragmentDirections.actionSettingsFragmentToThemeFragment().navigate()
|
||||
DenyListConfig -> SettingsFragmentDirections.actionSettingsFragmentToDenyFragment().navigate()
|
||||
SystemlessHosts -> createHosts()
|
||||
@ -119,13 +119,6 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
private fun authenticate(callback: () -> Unit) {
|
||||
BiometricEvent {
|
||||
// allow the change on success
|
||||
onSuccess { callback() }
|
||||
}.publish()
|
||||
}
|
||||
|
||||
private fun createHosts() {
|
||||
Shell.cmd("add_hosts_module").submit {
|
||||
AppContext.toast(R.string.settings_hosts_toast, Toast.LENGTH_SHORT)
|
||||
|
@ -10,14 +10,18 @@ import androidx.lifecycle.viewModelScope
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.arch.AsyncLoadViewModel
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.core.Info
|
||||
import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao
|
||||
import com.topjohnwu.magisk.core.di.AppContext
|
||||
import com.topjohnwu.magisk.core.di.ServiceLocator
|
||||
import com.topjohnwu.magisk.core.ktx.getLabel
|
||||
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||
import com.topjohnwu.magisk.core.utils.currentLocale
|
||||
import com.topjohnwu.magisk.databinding.*
|
||||
import com.topjohnwu.magisk.databinding.MergeObservableList
|
||||
import com.topjohnwu.magisk.databinding.RvItem
|
||||
import com.topjohnwu.magisk.databinding.bindExtra
|
||||
import com.topjohnwu.magisk.databinding.diffList
|
||||
import com.topjohnwu.magisk.databinding.set
|
||||
import com.topjohnwu.magisk.dialog.SuperuserRevokeDialog
|
||||
import com.topjohnwu.magisk.events.BiometricEvent
|
||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||
@ -113,10 +117,8 @@ class SuperuserViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
if (ServiceLocator.biometrics.isEnabled) {
|
||||
BiometricEvent {
|
||||
onSuccess { updateState() }
|
||||
}.publish()
|
||||
if (Config.userAuth) {
|
||||
BiometricEvent { updateState() }.publish()
|
||||
} else {
|
||||
SuperuserRevokeDialog(item.title) { updateState() }.show()
|
||||
}
|
||||
@ -168,10 +170,8 @@ class SuperuserViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
if (ServiceLocator.biometrics.isEnabled) {
|
||||
BiometricEvent {
|
||||
onSuccess { updateState() }
|
||||
}.publish()
|
||||
if (Config.userAuth) {
|
||||
BiometricEvent { updateState() }.publish()
|
||||
} else {
|
||||
updateState()
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ import com.topjohnwu.magisk.arch.BaseViewModel
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.core.data.magiskdb.PolicyDao
|
||||
import com.topjohnwu.magisk.core.di.AppContext
|
||||
import com.topjohnwu.magisk.core.di.ServiceLocator
|
||||
import com.topjohnwu.magisk.core.ktx.getLabel
|
||||
import com.topjohnwu.magisk.core.ktx.toast
|
||||
import com.topjohnwu.magisk.core.model.su.SuPolicy.Companion.ALLOW
|
||||
@ -77,12 +76,8 @@ class SuRequestViewModel(
|
||||
|
||||
fun grantPressed() {
|
||||
cancelTimer()
|
||||
if (ServiceLocator.biometrics.isEnabled) {
|
||||
BiometricEvent {
|
||||
onSuccess {
|
||||
respond(ALLOW)
|
||||
}
|
||||
}.publish()
|
||||
if (Config.userAuth) {
|
||||
BiometricEvent { respond(ALLOW) }.publish()
|
||||
} else {
|
||||
respond(ALLOW)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user