From b29f0ca4d1504cf2d9358ed098bc0e456ec56195 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Thu, 14 Nov 2019 05:42:39 -0500 Subject: [PATCH] Support using BiometricPrompt --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 7 +- .../main/java/com/topjohnwu/magisk/Config.kt | 27 ++-- .../magisk/base/viewmodel/BaseViewModel.kt | 4 +- .../magisk/data/repository/DBConfig.kt | 32 ++--- .../magisk/model/events/ViewEvents.kt | 4 +- .../magisk/ui/settings/SettingsFragment.kt | 21 ++- .../magisk/ui/superuser/SuperuserViewModel.kt | 13 +- .../magisk/ui/surequest/SuRequestActivity.kt | 2 + .../magisk/ui/surequest/SuRequestViewModel.kt | 43 ++----- .../topjohnwu/magisk/utils/BiometricHelper.kt | 60 +++++++++ .../magisk/utils/FingerprintHelper.kt | 121 ------------------ .../view/dialogs/FingerprintAuthDialog.kt | 88 ------------- app/src/main/res/layout/activity_request.xml | 12 +- app/src/main/res/values-ar/strings.xml | 5 - app/src/main/res/values-az/strings.xml | 5 - app/src/main/res/values-bg/strings.xml | 5 - app/src/main/res/values-ca/strings.xml | 5 - app/src/main/res/values-cs/strings.xml | 5 - app/src/main/res/values-de/strings.xml | 5 - app/src/main/res/values-es/strings.xml | 5 - app/src/main/res/values-et/strings.xml | 5 - app/src/main/res/values-fr/strings.xml | 5 - app/src/main/res/values-hi/strings.xml | 5 - app/src/main/res/values-in/strings.xml | 5 - app/src/main/res/values-it/strings.xml | 5 - app/src/main/res/values-ja/strings.xml | 5 - app/src/main/res/values-ko/strings.xml | 5 - app/src/main/res/values-lt/strings.xml | 4 - app/src/main/res/values-mk/strings.xml | 5 - app/src/main/res/values-nb/strings.xml | 5 - app/src/main/res/values-nl/strings.xml | 4 - app/src/main/res/values-pl/strings.xml | 5 - app/src/main/res/values-pt-rBR/strings.xml | 4 - app/src/main/res/values-ro/strings.xml | 5 - app/src/main/res/values-ru/strings.xml | 5 - app/src/main/res/values-sk/strings.xml | 5 - app/src/main/res/values-th/strings.xml | 5 - app/src/main/res/values-tr/strings.xml | 5 - app/src/main/res/values-uk/strings.xml | 5 - app/src/main/res/values-vi/strings.xml | 9 +- app/src/main/res/values-zh-rCN/strings.xml | 5 - app/src/main/res/values-zh-rTW/strings.xml | 5 - app/src/main/res/values/strings.xml | 10 +- app/src/main/res/xml/app_settings.xml | 8 +- .../java/com/topjohnwu/magisk/DynAPK.java | 2 +- stub/src/main/AndroidManifest.xml | 1 + 47 files changed, 146 insertions(+), 456 deletions(-) create mode 100644 app/src/main/java/com/topjohnwu/magisk/utils/BiometricHelper.kt delete mode 100644 app/src/main/java/com/topjohnwu/magisk/utils/FingerprintHelper.kt delete mode 100644 app/src/main/java/com/topjohnwu/magisk/view/dialogs/FingerprintAuthDialog.kt diff --git a/app/build.gradle b/app/build.gradle index 6cd88a0d6..8270643fe 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -120,6 +120,7 @@ dependencies { implementation "androidx.navigation:navigation-fragment-ktx:${vNav}" implementation "androidx.navigation:navigation-ui-ktx:${vNav}" + implementation 'androidx.biometric:biometric:1.0.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha03' implementation 'androidx.preference:preference:1.1.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 32de4b85e..46ed3d6da 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,7 +7,6 @@ - + + + diff --git a/app/src/main/java/com/topjohnwu/magisk/Config.kt b/app/src/main/java/com/topjohnwu/magisk/Config.kt index d065a86be..845521236 100644 --- a/app/src/main/java/com/topjohnwu/magisk/Config.kt +++ b/app/src/main/java/com/topjohnwu/magisk/Config.kt @@ -11,9 +11,8 @@ import com.topjohnwu.magisk.data.repository.DBConfig import com.topjohnwu.magisk.di.Protected import com.topjohnwu.magisk.extensions.get import com.topjohnwu.magisk.extensions.inject -import com.topjohnwu.magisk.extensions.packageName import com.topjohnwu.magisk.model.preference.PreferenceModel -import com.topjohnwu.magisk.utils.FingerprintHelper +import com.topjohnwu.magisk.utils.BiometricHelper import com.topjohnwu.magisk.utils.Utils import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.io.SuFile @@ -32,7 +31,7 @@ object Config : PreferenceModel, DBConfig { const val ROOT_ACCESS = "root_access" const val SU_MULTIUSER_MODE = "multiuser_mode" const val SU_MNT_NS = "mnt_ns" - const val SU_FINGERPRINT = "su_fingerprint" + const val SU_BIOMETRIC = "su_biometric" const val SU_MANAGER = "requester" const val KEYSTORE = "keystore" @@ -127,7 +126,7 @@ object Config : PreferenceModel, 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 suFingerprint by dbSettings(Key.SU_FINGERPRINT, false) + var suBiometric by dbSettings(Key.SU_BIOMETRIC, false) var suManager by dbStrings(Key.SU_MANAGER, "", true) var keyStoreRaw by dbStrings(Key.KEYSTORE, "", true) @@ -135,9 +134,18 @@ object Config : PreferenceModel, DBConfig { val downloadDirectory get() = Utils.ensureDownloadPath(downloadPath) ?: get().getExternalFilesDir(null)!! - fun initialize() = prefs.edit { + private const val SU_FINGERPRINT = "su_fingerprint" + + fun initialize() = prefs.also { + if (it.getBoolean(SU_FINGERPRINT, false)) { + suBiometric = true + } + }.edit { parsePrefs(this) + // Legacy stuff + remove(SU_FINGERPRINT) + // Get actual state putBoolean(Key.COREONLY, Const.MAGISK_DISABLE_FILE.exists()) @@ -145,7 +153,7 @@ object Config : PreferenceModel, DBConfig { putString(Key.ROOT_ACCESS, rootMode.toString()) putString(Key.SU_MNT_NS, suMntNamespaceMode.toString()) putString(Key.SU_MULTIUSER_MODE, suMultiuserMode.toString()) - putBoolean(Key.SU_FINGERPRINT, FingerprintHelper.useFingerprint()) + putBoolean(Key.SU_BIOMETRIC, BiometricHelper.isEnabled) }.also { if (!prefs.contains(Key.UPDATE_CHANNEL)) prefs.edit().putString(Key.UPDATE_CHANNEL, defaultChannel.toString()).apply() @@ -154,7 +162,7 @@ object Config : PreferenceModel, DBConfig { private fun parsePrefs(editor: SharedPreferences.Editor) = editor.apply { val config = SuFile.open("/data/adb", Const.MANAGER_CONFIGS) if (config.exists()) runCatching { - val input = SuFileInputStream(config).buffered() + val input = SuFileInputStream(config) val parser = Xml.newPullParser() parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false) parser.setInput(input, "UTF-8") @@ -205,9 +213,10 @@ object Config : PreferenceModel, DBConfig { fun export() { // Flush prefs to disk prefs.edit().commit() + val context = get(Protected) val xml = File( - "${get(Protected).filesDir.parent}/shared_prefs", - "${packageName}_preferences.xml" + "${context.filesDir.parent}/shared_prefs", + "${context.packageName}_preferences.xml" ) Shell.su("cat $xml > /data/adb/${Const.MANAGER_CONFIGS}").exec() } diff --git a/app/src/main/java/com/topjohnwu/magisk/base/viewmodel/BaseViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/base/viewmodel/BaseViewModel.kt index 987f1bf6d..56338b1ce 100644 --- a/app/src/main/java/com/topjohnwu/magisk/base/viewmodel/BaseViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/base/viewmodel/BaseViewModel.kt @@ -1,6 +1,6 @@ package com.topjohnwu.magisk.base.viewmodel -import android.app.Activity +import com.topjohnwu.magisk.base.BaseActivity import com.topjohnwu.magisk.extensions.doOnSubscribeUi import com.topjohnwu.magisk.model.events.BackPressEvent import com.topjohnwu.magisk.model.events.PermissionEvent @@ -21,7 +21,7 @@ abstract class BaseViewModel( } } - fun withView(action: Activity.() -> Unit) { + fun withView(action: BaseActivity<*, *>.() -> Unit) { ViewActionEvent(action).publish() } diff --git a/app/src/main/java/com/topjohnwu/magisk/data/repository/DBConfig.kt b/app/src/main/java/com/topjohnwu/magisk/data/repository/DBConfig.kt index 1129a18cd..0634ee1e6 100644 --- a/app/src/main/java/com/topjohnwu/magisk/data/repository/DBConfig.kt +++ b/app/src/main/java/com/topjohnwu/magisk/data/repository/DBConfig.kt @@ -29,8 +29,8 @@ interface DBConfig { } class DBSettingsValue( - private val name: String, - private val default: Int + private val name: String, + private val default: Int ) : ReadWriteProperty { private var value: Int? = null @@ -47,29 +47,29 @@ class DBSettingsValue( this.value = value } thisRef.settingsDao.put(name, value) - .subscribeOn(Schedulers.io()) - .subscribe() + .subscribeOn(Schedulers.io()) + .subscribe() } } class DBBoolSettings( - name: String, - default: Boolean + name: String, + default: Boolean ) : ReadWriteProperty { val base = DBSettingsValue(name, if (default) 1 else 0) - override fun getValue(thisRef: DBConfig, property: KProperty<*>): Boolean - = base.getValue(thisRef, property) != 0 + override fun getValue(thisRef: DBConfig, property: KProperty<*>): Boolean = + base.getValue(thisRef, property) != 0 override fun setValue(thisRef: DBConfig, property: KProperty<*>, value: Boolean) = - base.setValue(thisRef, property, if (value) 1 else 0) + base.setValue(thisRef, property, if (value) 1 else 0) } class DBStringsValue( - private val name: String, - private val default: String, - private val sync: Boolean + private val name: String, + private val default: String, + private val sync: Boolean ) : ReadWriteProperty { private var value: String? = null @@ -90,16 +90,16 @@ class DBStringsValue( thisRef.stringDao.delete(name).blockingAwait() } else { thisRef.stringDao.delete(name) - .subscribeOn(Schedulers.io()) - .subscribe() + .subscribeOn(Schedulers.io()) + .subscribe() } } else { if (sync) { thisRef.stringDao.put(name, value).blockingAwait() } else { thisRef.stringDao.put(name, value) - .subscribeOn(Schedulers.io()) - .subscribe() + .subscribeOn(Schedulers.io()) + .subscribe() } } } diff --git a/app/src/main/java/com/topjohnwu/magisk/model/events/ViewEvents.kt b/app/src/main/java/com/topjohnwu/magisk/model/events/ViewEvents.kt index f8e273bd7..ef10c39c5 100644 --- a/app/src/main/java/com/topjohnwu/magisk/model/events/ViewEvents.kt +++ b/app/src/main/java/com/topjohnwu/magisk/model/events/ViewEvents.kt @@ -1,6 +1,6 @@ package com.topjohnwu.magisk.model.events -import android.app.Activity +import com.topjohnwu.magisk.base.BaseActivity import com.topjohnwu.magisk.model.entity.module.Repo import io.reactivex.subjects.PublishSubject @@ -28,7 +28,7 @@ class EnvFixEvent : ViewEvent() class UpdateSafetyNetEvent : ViewEvent() -class ViewActionEvent(val action: Activity.() -> Unit) : ViewEvent() +class ViewActionEvent(val action: BaseActivity<*, *>.() -> Unit) : ViewEvent() class OpenFilePickerEvent : ViewEvent() diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsFragment.kt b/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsFragment.kt index fdcac23a5..88239ff4c 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/settings/SettingsFragment.kt @@ -24,7 +24,6 @@ import com.topjohnwu.magisk.model.entity.internal.Configuration import com.topjohnwu.magisk.model.entity.internal.DownloadSubject import com.topjohnwu.magisk.model.observer.Observer import com.topjohnwu.magisk.utils.* -import com.topjohnwu.magisk.view.dialogs.FingerprintAuthDialog import com.topjohnwu.superuser.Shell import io.reactivex.Completable import org.koin.android.ext.android.inject @@ -61,7 +60,7 @@ class SettingsFragment : BasePreferenceFragment() { multiuserConfig = findPreference(Config.Key.SU_MULTIUSER_MODE)!! nsConfig = findPreference(Config.Key.SU_MNT_NS)!! val reauth = findPreference(Config.Key.SU_REAUTH)!! - val fingerprint = findPreference(Config.Key.SU_FINGERPRINT)!! + val biometric = findPreference(Config.Key.SU_BIOMETRIC)!! val generalCatagory = findPreference("general")!! val magiskCategory = findPreference("magisk")!! val suCategory = findPreference("superuser")!! @@ -88,11 +87,11 @@ class SettingsFragment : BasePreferenceFragment() { suCategory.removePreference(reauth) } - // Disable fingerprint option if not possible - if (!FingerprintHelper.canUseFingerprint()) { - fingerprint.isEnabled = false - fingerprint.isChecked = false - fingerprint.setSummary(R.string.disable_fingerprint) + // Disable biometric option if not possible + if (!BiometricHelper.isSupported) { + biometric.isEnabled = false + biometric.isChecked = false + biometric.setSummary(R.string.no_biometric) } if (Const.USER_ID == 0 && Info.isConnected.value && Shell.rootAccess()) { @@ -208,13 +207,13 @@ class SettingsFragment : BasePreferenceFragment() { override fun onPreferenceTreeClick(preference: Preference): Boolean { when (preference.key) { - Config.Key.SU_FINGERPRINT -> { + Config.Key.SU_BIOMETRIC -> { val checked = (preference as SwitchPreferenceCompat).isChecked preference.isChecked = !checked - FingerprintAuthDialog(requireActivity()) { + BiometricHelper.authenticate(requireActivity()) { preference.isChecked = checked - Config.suFingerprint = checked - }.show() + Config.suBiometric = checked + } } } return true diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt index a8fa02f18..57f24bcc5 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/superuser/SuperuserViewModel.kt @@ -15,11 +15,10 @@ import com.topjohnwu.magisk.model.entity.recycler.PolicyRvItem import com.topjohnwu.magisk.model.events.PolicyEnableEvent import com.topjohnwu.magisk.model.events.PolicyUpdateEvent import com.topjohnwu.magisk.model.events.SnackbarEvent +import com.topjohnwu.magisk.utils.BiometricHelper import com.topjohnwu.magisk.utils.DiffObservableList -import com.topjohnwu.magisk.utils.FingerprintHelper import com.topjohnwu.magisk.utils.RxBus import com.topjohnwu.magisk.view.dialogs.CustomAlertDialog -import com.topjohnwu.magisk.view.dialogs.FingerprintAuthDialog import io.reactivex.Single import io.reactivex.disposables.Disposable import me.tatarka.bindingcollectionadapter2.ItemBinding @@ -83,8 +82,8 @@ class SuperuserViewModel( .add() withView { - if (FingerprintHelper.useFingerprint()) { - FingerprintAuthDialog(this) { updateState() }.show() + if (BiometricHelper.isEnabled) { + BiometricHelper.authenticate(this) { updateState() } } else { CustomAlertDialog(this) .setTitle(R.string.su_revoke_title) @@ -131,12 +130,12 @@ class SuperuserViewModel( .add() } - if (FingerprintHelper.useFingerprint()) { + if (BiometricHelper.isEnabled) { withView { - FingerprintAuthDialog(this, { updateState() }, { + BiometricHelper.authenticate(this, onError = { ignoreNext = item item.isEnabled.toggle() - }).show() + }) { updateState() } } } else { updateState() diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestActivity.kt b/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestActivity.kt index 57d99e5de..2fdac91ab 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestActivity.kt @@ -9,6 +9,7 @@ import com.topjohnwu.magisk.R import com.topjohnwu.magisk.base.BaseActivity import com.topjohnwu.magisk.databinding.ActivityRequestBinding import com.topjohnwu.magisk.model.events.DieEvent +import com.topjohnwu.magisk.model.events.ViewActionEvent import com.topjohnwu.magisk.model.events.ViewEvent import com.topjohnwu.magisk.utils.SuHandler import com.topjohnwu.magisk.utils.SuHandler.REQUEST @@ -56,6 +57,7 @@ open class SuRequestActivity : BaseActivity event.action(this) is DieEvent -> finish() } } diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestViewModel.kt index 20bd9ceea..c9971d738 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/surequest/SuRequestViewModel.kt @@ -5,7 +5,6 @@ import android.content.SharedPreferences import android.content.pm.PackageManager import android.content.res.Resources import android.graphics.drawable.Drawable -import android.hardware.fingerprint.FingerprintManager import android.os.CountDownTimer import com.topjohnwu.magisk.BuildConfig import com.topjohnwu.magisk.Config @@ -19,8 +18,8 @@ import com.topjohnwu.magisk.model.entity.MagiskPolicy import com.topjohnwu.magisk.model.entity.recycler.SpinnerRvItem import com.topjohnwu.magisk.model.entity.toPolicy import com.topjohnwu.magisk.model.events.DieEvent +import com.topjohnwu.magisk.utils.BiometricHelper import com.topjohnwu.magisk.utils.DiffObservableList -import com.topjohnwu.magisk.utils.FingerprintHelper import com.topjohnwu.magisk.utils.KObservableField import com.topjohnwu.magisk.utils.SuConnector import me.tatarka.bindingcollectionadapter2.BindingListViewAdapter @@ -43,7 +42,6 @@ class SuRequestViewModel( val denyText = KObservableField(resources.getString(R.string.deny)) val warningText = KObservableField(resources.getString(R.string.su_warning)) - val canUseFingerprint = KObservableField(FingerprintHelper.useFingerprint()) val selectedItemPosition = KObservableField(0) private val items = DiffObservableList(ComparableRvItem.callback) @@ -68,8 +66,16 @@ class SuRequestViewModel( } fun grantPressed() { - handleAction(MagiskPolicy.ALLOW) - timer.cancel() + cancelTimer() + if (BiometricHelper.isEnabled) { + withView { + BiometricHelper.authenticate(this) { + handleAction(MagiskPolicy.ALLOW) + } + } + } else { + handleAction(MagiskPolicy.ALLOW) + } } fun denyPressed() { @@ -137,13 +143,6 @@ class SuRequestViewModel( } timer.start() cancelTasks.add { cancelTimer() } - - if (canUseFingerprint.value) - runCatching { - val helper = SuFingerprint() - helper.authenticate() - cancelTasks.add { helper.cancel() } - } } private fun handleAction() { @@ -182,24 +181,4 @@ class SuRequestViewModel( } } - private inner class SuFingerprint @Throws(Exception::class) - internal constructor() : FingerprintHelper() { - - override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { - warningText.value = errString - } - - override fun onAuthenticationHelp(helpCode: Int, helpString: CharSequence) { - warningText.value = helpString - } - - override fun onAuthenticationSucceeded(result: FingerprintManager.AuthenticationResult) { - handleAction(MagiskPolicy.ALLOW) - } - - override fun onAuthenticationFailed() { - warningText.value = resources.getString(R.string.auth_fail) - } - } - } diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/BiometricHelper.kt b/app/src/main/java/com/topjohnwu/magisk/utils/BiometricHelper.kt new file mode 100644 index 000000000..ac6c0cfea --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/utils/BiometricHelper.kt @@ -0,0 +1,60 @@ +package com.topjohnwu.magisk.utils + +import androidx.biometric.BiometricManager +import androidx.biometric.BiometricPrompt +import androidx.fragment.app.FragmentActivity +import com.topjohnwu.magisk.Config +import com.topjohnwu.magisk.R +import com.topjohnwu.superuser.internal.UiThreadHandler +import org.koin.core.KoinComponent +import org.koin.core.get + +object BiometricHelper: KoinComponent { + + private val mgr by lazy { BiometricManager.from(get()) } + + val isSupported get() = when (mgr.canAuthenticate()) { + BiometricManager.BIOMETRIC_SUCCESS -> true + else -> false + } + + val isEnabled: Boolean get() { + val enabled = Config.suBiometric + if (enabled && !isSupported) { + Config.suBiometric = false + return false + } + return enabled + } + + fun authenticate( + activity: FragmentActivity, + onError: () -> Unit = {}, + onSuccess: () -> Unit): BiometricPrompt { + val prompt = BiometricPrompt(activity, + { cmd: Runnable -> UiThreadHandler.run(cmd) }, + object : BiometricPrompt.AuthenticationCallback() { + override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { + onError() + } + + override fun onAuthenticationFailed() { + onError() + } + + override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { + onSuccess() + } + } + ) + val info = BiometricPrompt.PromptInfo.Builder() + .setConfirmationRequired(true) + .setDeviceCredentialAllowed(false) + .setTitle(activity.getString(R.string.authenticate)) + .setNegativeButtonText(activity.getString(android.R.string.cancel)) + .build() + prompt.authenticate(info) + return prompt + } + +} diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/FingerprintHelper.kt b/app/src/main/java/com/topjohnwu/magisk/utils/FingerprintHelper.kt deleted file mode 100644 index e174f26f9..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/utils/FingerprintHelper.kt +++ /dev/null @@ -1,121 +0,0 @@ -package com.topjohnwu.magisk.utils - -import android.annotation.TargetApi -import android.app.KeyguardManager -import android.content.Context -import android.hardware.fingerprint.FingerprintManager -import android.os.Build -import android.os.CancellationSignal -import android.security.keystore.KeyGenParameterSpec -import android.security.keystore.KeyProperties -import com.topjohnwu.magisk.Config -import com.topjohnwu.magisk.extensions.get -import com.topjohnwu.magisk.extensions.inject -import java.security.KeyStore -import javax.crypto.Cipher -import javax.crypto.KeyGenerator -import javax.crypto.SecretKey - -@TargetApi(Build.VERSION_CODES.M) -abstract class FingerprintHelper @Throws(Exception::class) -protected constructor() { - - private val manager: FingerprintManager? - private val cipher: Cipher - private var cancel: CancellationSignal? = null - private val context: Context by inject() - - init { - val keyStore = KeyStore.getInstance("AndroidKeyStore") - manager = context.getSystemService(FingerprintManager::class.java) - cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" - + KeyProperties.BLOCK_MODE_CBC + "/" - + KeyProperties.ENCRYPTION_PADDING_PKCS7) - keyStore.load(null) - var key = keyStore.getKey(SU_KEYSTORE_KEY, null) as SecretKey? ?: generateKey() - runCatching { - cipher.init(Cipher.ENCRYPT_MODE, key) - }.onFailure { - // Only happens on Marshmallow - key = generateKey() - cipher.init(Cipher.ENCRYPT_MODE, key) - } - } - - abstract fun onAuthenticationError(errorCode: Int, errString: CharSequence) - - abstract fun onAuthenticationHelp(helpCode: Int, helpString: CharSequence) - - abstract fun onAuthenticationSucceeded(result: FingerprintManager.AuthenticationResult) - - abstract fun onAuthenticationFailed() - - fun authenticate() { - cancel = CancellationSignal() - val cryptoObject = FingerprintManager.CryptoObject(cipher) - manager!!.authenticate(cryptoObject, cancel, 0, Callback(), null) - } - - fun cancel() { - if (cancel != null) - cancel!!.cancel() - } - - @Throws(Exception::class) - private fun generateKey(): SecretKey { - val keygen = KeyGenerator - .getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore") - val builder = KeyGenParameterSpec.Builder( - SU_KEYSTORE_KEY, - KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT) - .setBlockModes(KeyProperties.BLOCK_MODE_CBC) - .setUserAuthenticationRequired(true) - .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7) - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - builder.setInvalidatedByBiometricEnrollment(false) - } - keygen.init(builder.build()) - return keygen.generateKey() - } - - private inner class Callback : FingerprintManager.AuthenticationCallback() { - override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { - this@FingerprintHelper.onAuthenticationError(errorCode, errString) - } - - override fun onAuthenticationHelp(helpCode: Int, helpString: CharSequence) { - this@FingerprintHelper.onAuthenticationHelp(helpCode, helpString) - } - - override fun onAuthenticationSucceeded(result: FingerprintManager.AuthenticationResult) { - this@FingerprintHelper.onAuthenticationSucceeded(result) - } - - override fun onAuthenticationFailed() { - this@FingerprintHelper.onAuthenticationFailed() - } - } - - companion object { - private const val SU_KEYSTORE_KEY = "su_key" - - fun useFingerprint(): Boolean { - var fp = Config.suFingerprint - if (fp && !canUseFingerprint()) { - Config.suFingerprint = false - fp = false - } - return fp - } - - fun canUseFingerprint(context: Context = get()): Boolean { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) - return false - val km = context.getSystemService(KeyguardManager::class.java) - val fm = context.getSystemService(FingerprintManager::class.java) - return km?.isKeyguardSecure ?: false && - fm != null && fm.isHardwareDetected && fm.hasEnrolledFingerprints() - } - } -} diff --git a/app/src/main/java/com/topjohnwu/magisk/view/dialogs/FingerprintAuthDialog.kt b/app/src/main/java/com/topjohnwu/magisk/view/dialogs/FingerprintAuthDialog.kt deleted file mode 100644 index a27d599de..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/view/dialogs/FingerprintAuthDialog.kt +++ /dev/null @@ -1,88 +0,0 @@ -package com.topjohnwu.magisk.view.dialogs - -import android.annotation.TargetApi -import android.app.Activity -import android.graphics.Color -import android.hardware.fingerprint.FingerprintManager -import android.os.Build -import android.view.Gravity -import android.widget.Toast -import androidx.appcompat.app.AlertDialog -import androidx.core.content.ContextCompat -import com.topjohnwu.magisk.R -import com.topjohnwu.magisk.utils.FingerprintHelper -import com.topjohnwu.magisk.utils.Utils - -@TargetApi(Build.VERSION_CODES.M) -class FingerprintAuthDialog(activity: Activity, private val callback: () -> Unit) - : CustomAlertDialog(activity) { - - private var failureCallback: (() -> Unit)? = null - private var helper: DialogFingerprintHelper? = null - - init { - val fingerprint = ContextCompat.getDrawable(activity, R.drawable.ic_fingerprint) - fingerprint?.setBounds(0, 0, Utils.dpInPx(50), Utils.dpInPx(50)) - val theme = activity.theme - val ta = theme.obtainStyledAttributes(intArrayOf(R.attr.imageColorTint)) - fingerprint?.setTint(ta.getColor(0, Color.GRAY)) - ta.recycle() - binding.message.setCompoundDrawables(null, null, null, fingerprint) - binding.message.compoundDrawablePadding = Utils.dpInPx(20) - binding.message.gravity = Gravity.CENTER - setMessage(R.string.auth_fingerprint) - setNegativeButton(android.R.string.cancel) { _, _ -> - helper?.cancel() - failureCallback?.invoke() - } - setOnCancelListener { - helper?.cancel() - failureCallback?.invoke() - } - runCatching { - helper = DialogFingerprintHelper() - } - - } - - constructor(activity: Activity, onSuccess: () -> Unit, onFailure: () -> Unit) - : this(activity, onSuccess) { - failureCallback = onFailure - } - - override fun show(): AlertDialog { - return create().apply { - if (helper == null) { - dismiss() - Utils.toast(R.string.auth_fail, Toast.LENGTH_SHORT) - } else { - helper?.authenticate() - show() - } - } - } - - internal inner class DialogFingerprintHelper @Throws(Exception::class) - constructor() : FingerprintHelper() { - - override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { - binding.message.setTextColor(Color.RED) - binding.message.text = errString - } - - override fun onAuthenticationHelp(helpCode: Int, helpString: CharSequence) { - binding.message.setTextColor(Color.RED) - binding.message.text = helpString - } - - override fun onAuthenticationFailed() { - binding.message.setTextColor(Color.RED) - binding.message.setText(R.string.auth_fail) - } - - override fun onAuthenticationSucceeded(result: FingerprintManager.AuthenticationResult) { - dismiss() - callback() - } - } -} diff --git a/app/src/main/res/layout/activity_request.xml b/app/src/main/res/layout/activity_request.xml index 86257262d..70af73e7d 100644 --- a/app/src/main/res/layout/activity_request.xml +++ b/app/src/main/res/layout/activity_request.xml @@ -129,24 +129,14 @@ - - \ No newline at end of file + diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index e53d65cd8..fbe808ace 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -163,9 +163,6 @@ %1$d ثانية إعادة المصادقة بعد الترقية أعد المصادقة على صلاحيات المستخدم المتميز بعد إجراء ترقيات للتطبيق - استخدام قارئ بصمات الأصابع للسماح بطلبات المستخدم المتميز - تمكين مصادقة البصمة - مصادقة البصمة نمط تعدد المستخدمين مالك الجهاز فقط @@ -182,7 +179,6 @@ تستخدم كافة جلسات العمل للروت مساحة الاسم ذات التركيب العامة سترث جلسات العمل للروت مساحة الأسماء لطالبيها سيكون لكل جلسة عمل للروت مساحة اسم معزولة خاصة بها - لم تُعين بصمات الأصابع أو لا يوجد قارئ بصمات خطأ عند إنشاء مجلد. عليه أن يكون سهلا الوصول إليه من خلال مجلد التخزين للروت و ألا يكون ملفا. @@ -210,7 +206,6 @@ تأكيد لسحب صلاحيات %1$s ? ملاحظة منبثقة بدون - فشل المصادقة PID: %1$d diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index 2dbf1e601..3ca98dcb7 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -151,9 +151,6 @@ %1$d saniyə Yüksəltmədən sonra Yenidən İdentifikasiya et Tətbiq yeniləmələridən sonra superuser icazələrini yenidən identifikasiya et - Barmaq İzi İdentifikasiyasını Aç - Barmaq izi oxuyucunu superuser icazələri üçün işlət - Barmaq izini İdentifikasiya et Çox-istifadəçi modu Yalnız cihaz sahibi Cihaz sahibinin idarəçiliyində @@ -168,7 +165,6 @@ Bütün root sessyaları qlobal qoşma namespace\'dən istifadə edir. Root sessyaları soruşulan namespace\'ləri birindən digərinə keçirəcək. Hər bir root sessyasının ayrılmış namespace\'i olacaq. - Barmaq izi təyin edilməyib ya da dəstəklənmir. Superuser Tələbi @@ -195,7 +191,6 @@ %1$s üçün haqları ləğv etməyi təsdiq edirsiniz? Tost Heçnə - İdentifikasiya xətası PID: %1$d diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 10c8b3378..6c920bd84 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -142,9 +142,6 @@ %1$d секунди Повторно запитване след актуализация Повторно запитване за Superuser достъп след актуализация на приложенията. - Superuser права само с пръстов отпечатък - Използване на сензора за пръстови отпечатъци за разрешаване на Superuser достъп. - Удостоверете с пръстов отпечатък. Потребителски достъп Само собственик @@ -161,7 +158,6 @@ Всички сесии с руут достъп използват глобалното именно пространство. Всички сесии с руут достъп наследяват именното пространство на запитващото приложение. Всички сесии с руут достъп имат собствени именни пространства. - Не са добавени пръстови отпечатъци или устройството не поддържа тази функция. Запитване за Superuser достъп @@ -188,7 +184,6 @@ Потвърждавате ли анулирането на настройките за достъп на %1$s? Toast Без - Неуспешна заверка. Целеви UID: %1$d diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 1de2eb50f..ac9eeaf6e 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -166,9 +166,6 @@ %1$d segons Demanar després d\'una actualització Demanar permisos de superusuari novament si una aplicació és actualitzada o reinstal·lada - Autenticació per Empremta Dactilar - Utilitza el sensor d\'Empremta Dactilar per permetre les sol·licituds de superusuari - Autenticar Emprempta Digital Mode Multiusuari Només Administrador del Dispositiu @@ -185,7 +182,6 @@ Totes les sessions d\'arrel utilitzen el suport Namespace Global Les sessions d\'arrel heretaran les peticiones Namespace Totes les sessions d\'arrel tindran la seva pròpia Namespace - No s\'han establert empremtes dactilars o no existeix el suport del dispositiu Error al crear la carpeta. El directori ha de ser accesible desde el directori arrel i no pot ser un arxiu. @@ -213,7 +209,6 @@ Confirma per revocar drets de %1$s Avís Cap - Autenticació fallida PID: %1$d diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 1c6ff351a..be0a93176 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -154,9 +154,6 @@ %1$d sekund Opětovné ověření po aktualizaci Opětovné ověření oprávnění Superuser po aktualizaci aplikace - Povolit ověřování otisky prstů - Chcete-li povolit požadavky Superuser, použijte snímač otisků prstů - Ověřování otisky prstů Režim více uživatelů Pouze vlastník zařízení @@ -173,7 +170,6 @@ Všechny relace root používají globální připojení jmenného prostoru. Kořenové relace dědí jmenný prostor žadatele. Každá relace root bude mít svůj vlastní izolovaný jmenný prostor. - Nebyly nastaveny žádné otisky prstů ani žádná podpora zařízení. Požadavek Superuser @@ -200,7 +196,6 @@ Smazat záznam ohledně oprávnění pro %1$s? Informační text Žádný - Ověření se nezdařilo PID: %1$d diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 017a84bdd..57aa1e972 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -156,9 +156,6 @@ %1$d Sekunden Nach Aktualisierung erneut authentifizieren Superuser-Zugriff nach App-Aktualisierung erneut abfragen - Aktiviere Authentifizierung durch Fingerabdruck - Fingerabdrucksensor benutzen um Superuser-Anfragen zu erlauben - Authentifiziere Fingerabdruck Mehrbenutzermodus Nur der Gerätebesitzer @@ -175,7 +172,6 @@ Alle Root-Sitzungen benutzen den global angelegten Namespace Root-Sitzungen erben den Namespace des Abfragenden Jede Root-Sitzung hat ihren isolierten Namespace - Keine Fingerabdrücke gespeichert oder keine Geräteunterstützung Superuser-Anfrage @@ -202,7 +198,6 @@ Möchtest du die Rechte für %1$s entziehen? Popup Keine - Authentifizierung fehlgeschlagen PID: %1$d diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 2d3ac095b..5f998c5c3 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -159,9 +159,6 @@ %1$d segundos Re-autenticación Pedir permisos de superusuario nuevamente si una aplicación es actualizada o reinstalada - Autenticación por Huella Dactilar - Utilizar el sensor de Huella Dactilar para permitir las solicitudes de superusuario - Autenticar Huella Dactilar Modo MultiUsuario Sólo Administrador del Dispositivo @@ -178,7 +175,6 @@ Todas las sesiones de root utilizan el soporte Global Namespace Las sesiones de root heredarán las peticiones Namespace Cada sesión root tendrá su propia Namespace - No se establecieron huellas dactilares o no existe soporte del dispositivo Error al crear la carpeta. Debe ser accesible desde el directorio raíz de almacenamiento y no debe ser un archivo. @@ -206,7 +202,6 @@ ¿Confirmar para revocar derechos de %1$s? Aviso Nada - Autenticación fallida PID: %1$d diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index 6c4f3bcde..df63f0b5a 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -162,9 +162,6 @@ %1$d sekundit Taas-autendi peale täiendust Taas-autendi superkasutaja õigused peale rakenduse täiendamist - Luba sõrmejäljega autentimine - Kasuta sõrmejäljelugejat superkasutaja taotluste lubamiseks - Autendi sõrmejälg Mitmikkasutaja režiim Ainult seadme omanik @@ -181,7 +178,6 @@ Kõik juurkasutaja sessioonid kasutavad globaalset monteerimise nimeruumi. Juurkasutaja sessioonid võtavad üle selle taotleja nimeruumi. Iga juurkasutaja sessioon saab oma isoleeritud nimeruumi. - Sõrmejälgi pole määratud või seade pole toetatud. Faili loomisel esines viga. See peab olema ligipääsetav mäluruumi juurkaustast ning ei tohi olla fail. @@ -209,7 +205,6 @@ Kinnitad rakenduse %1$s õiguste eemaldamise? Hüpik Puudub - Autentimine ebaõnnestus PID: %1$d diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 505c1d223..68e27a37d 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -165,9 +165,6 @@ %1$d secondes Authentifier à nouveau après la mise à niveau Authentifier à nouveau les autorisations super‐utilisateur après une mise à jour de l’application - Activer l’authentification par empreinte digitale - Utiliser le lecteur d’empreintes digitales pour autoriser les demandes super‐utilisateur - Authentifier l’empreinte digitale Mode multi‐utilisateur Propriétaire de l’appareil uniquement @@ -184,7 +181,6 @@ Toutes les sessions super‐utilisateur utilisent l’espace de noms global du montage. Les sessions super‐utilisateur hériteront de l’espace de noms de leur demandeur. Chaque session super‐utilisateur aura son propre espace de noms isolé. - Aucune empreinte digitale n’a été définie ou le lecteur d’empreinte n’est pas pris en charge. Erreur lors de la création du dossier. Il doit être accessible depuis le répertoire racine du stockage et ne doit pas être un fichier. @@ -212,7 +208,6 @@ Confirmez‐vous l’annulation des droits pour %1$s ? Toast Aucun - Échec de l’authentification PID : %1$d diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 2b7c04211..b4736fdec 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -162,9 +162,6 @@ %1$d सेकंड्‌स अपग्रेड के बाद फिर से प्रमाणित करें एप्लीकेशन अपग्रेड होने के बाद उत्तम उपयोगकर्ता की अनुमतियों को फिर से प्रमाणित करें - फिंगरप्रिंट प्रमाणीकरण सक्षम करें - उत्तम उपयोगकर्ता के अनुरोधों की अनुमति के लिए फिंगरप्रिंट स्कैनर का उपयोग करें - फिंगरप्रिंट को प्रमाणित करें बहु उपयोगकर्ता मोड केवल डिवाइस का मालिक @@ -181,7 +178,6 @@ सभी रूट सत्र वैश्विक माउंट नेमस्पेस का उपयोग करते हैं. रूट सत्रों को उनके अनुरोधकर्ताओं के नेमस्पेस विरासत में मिलेंगे. प्रत्येक रूट सत्र का अपना अलग नेमस्पेस होगा. - कोई फ़िंगरप्रिंट नहीं सेट किया गया या डिवाइस का समर्थन नहीं है. फोल्डर बनाने में त्रुटि. यह स्टोरेज रूट डायरेक्टरी से एक्सेस होना चाहिए और फाइल नहीं होना चाहिए. @@ -209,7 +205,6 @@ %1$s के अधिकारों को वापस लेने की पुष्टि करें? पॉप-अप नोट कोई नहीं - प्रमाणीकरण विफल हुआ PID: %1$d diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index c53445891..cf36665dc 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -160,9 +160,6 @@ %1$d detik Otentikasi ulang setelah pembaruan Otentikasi ulang izin superuser setelah pembaruan sebuah aplikasi - Aktifkan Otentikasi Sidik Jari - Gunakan pemindai sidik jari untuk mengizinkan permintaan superuser - Otentikasi Sidik Jari Mode Multipengguna Pemilik Perangkat Saja @@ -179,7 +176,6 @@ Semua sesi root menggunakan mount ruang nama global. Sesi root akan mewarisi ruang nama peminta mereka. Setiap sesi root akan memiliki ruang nama tersendiri. - Tidak ada sidik jari diatur atau tidak ada dukungan perangkat. Kesalahan membuat folder. Folder harus dapat diakses dari direktori penyimpanan root dan bukan merupakan file. @@ -207,7 +203,6 @@ Konfirmasi untuk mencabut akses %1$s? Toast Tidak ada - Otentikasi Gagal PID: %1$d diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 473f2f714..b37b534b5 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -164,9 +164,6 @@ %1$d secondi Riautentica dopo aggiornamento Riautentica i permessi Superuser dopo un aggiornamento dell\'app - Abilita autenticazione impronta - Utilizza il sensore di impronte per accettare le richieste Superuser - Conferma impronta Modalità multiutente Solo proprietario del dispositivo @@ -183,7 +180,6 @@ Tutte le sessioni di root erediteranno il namespace globale Le sessioni di root erediteranno il namespace del loro richiedente Ogni sessione di root avrà il suo namespace isolato - Non è presente alcuna impronta o il dispositivo non è supportato Errore durante la creazione della cartella. Deve essere accessibile dalla radice della memoria di archiviazione e non essere un file. @@ -211,7 +207,6 @@ Confermi la revoca dei diritti di %1$s? Toast Nessuno - Autenticatione fallita PID: %1$d diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 76966996f..fd02196b2 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -148,9 +148,6 @@ %1$d秒 アップグレード後の再認証 アプリのアップグレード後にスーパーユーザー権限を再認証します - 指紋認証の有効化 - スーパーユーザー権限のリクエストの許可に指紋認証を使います - 指紋認証 マルチユーザーモード 端末の管理者のみ @@ -167,7 +164,6 @@ すべてのrootセッションがグローバル名前空間を使用します rootセッションはリクエスト者の名前空間を継承します rootセッション毎に分離された名前空間を使用します - 指紋が登録されていないか、お使いの端末でサポートされていません。 スーパーユーザーリクエスト @@ -194,7 +190,6 @@ %1$s の権限を取り消しますか? トースト通知 なし - 認証に失敗しました PID: %1$d diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index f66ad2e3c..5d9f62ef8 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -155,9 +155,6 @@ %1$d초 업데이트 후 재승인 앱 업데이트 후에 슈퍼유저 권한 재승인 - 지문 인식 사용 - 지문 인식으로 슈퍼유저 권한을 허가합니다. - 지문 인식 다중 사용자 모드 기기 소유자만 @@ -174,7 +171,6 @@ 모든 루트 세션이 전역 마운트 이름공간을 사용합니다. 루트 세션은 요청자의 이름공간을 상속합니다. 각각의 루트 세션은 자신만의 독립된 이름공간을 사용합니다. - 지문이 등록되지 않았거나 기기가 지문 인식을 지원하지 않습니다. 슈퍼유저 요청 @@ -201,7 +197,6 @@ 정말 %1$s의 권한을 취소하시겠습니까? 토스트 없음 - 인증 실패 PID: %1$d diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 4484d78a6..b03ba36c1 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -137,8 +137,6 @@ %1$d sekundžių Pakartotinai patvirtinti po atnaujinimo Pakartotinai patvirtinti supervartotojo leidimus po programėlės atnaujinimo - Įgalinti patvirtinimą piršto antspaudu - Naudoti piršto antspaudą supervartotojo leidimo prašymų atsakymui Daugialypio vartotojo režimas Tik įrenginio savininkas @@ -155,7 +153,6 @@ Visos root sesijos naudoja globalią vardų sritį Root sesijos paveldi jos išprašytojo/s vardų sritį Kiekviena root sesija turi savo izoliuotą vardų sritį - Jūsų įrenginyje nebuvo surasta pirštų antspaudų arba jūsų įrenginys neturi pirštų antspaudų skaitytuvo Supervartotojo prašymas @@ -182,7 +179,6 @@ Neleisti %1$s naudotis supervartotojo teisėmis? Išmesti Nėra - Patvirtinimas žlugo Target UID: %1$d diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml index a846ac366..ba525b832 100644 --- a/app/src/main/res/values-mk/strings.xml +++ b/app/src/main/res/values-mk/strings.xml @@ -154,9 +154,6 @@ %1$d секунди Повторна автентикација по надградба Повторна автентикација за супер-корисник дозвола по надградбата на апликацијата - Овозможи автентикација на отпечатоци - Користете скенер за отпечатоци за да дозволите супер-корисник барања - Автентикација на отпечатоци Режим на повеќе корисници Само сопственикот на уредот @@ -173,7 +170,6 @@ Сите рут сесии го користат глобалниот именски простор. Рут сесиите ќе го наследат именскиот простор на нивниот барател. Секоја рут сесија ќе има свој изолиран именски простор. - Нема регистрирано отпечатоци од прсти или уредот не ја поддржува оваа функција. Супер-корисник барање @@ -200,7 +196,6 @@ Дали потврдувате анулирање на поставките за пристап на %1$s? Тост Ниеден - Неуспешна автентикација PID: %1$d diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index c8d884ccf..275141605 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -146,9 +146,6 @@ %1$d sekunder Autentiser på nytt etter oppdateringer after upgrade Autentiser superbruker-tillatelser på nytt etter at en app har blitt oppdatert - Skru på fingeravtrykksautentisering - Bruk fingeravtrykksskanneren for å godkjenne superbruker-forespørsler - Autentiser fingeravtrykk Flerbrukermoduse Kun enhetens eier @@ -165,7 +162,6 @@ Alle root-økter benytter det altdekkende monteringsnavnefeltet. Root-økter vil arve forespørrerens navnefelt. Hver root-økt vil ha sitt eget isolerte navnefelt. - Ingen fingeravtrykk ble gitt, eller så støttes det ikke av enheten. Superbruker-forespørsel @@ -192,7 +188,6 @@ Vil du bekrefte for å oppheve %1$s sine rettigheter? Varselfelt Ingen - Autentisering mislyktes Mål-UID: %1$d diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 2d00fb929..5ee7c6acc 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -132,8 +132,6 @@ %1$d seconden Opnieuw verzoeken na bijwerken Superuser rechten opnieuw opvragen na bijwerken applicatie - Vingerafdruk authenticatie inschakelen - Vingerafdruk gebruiken om superuser verzoeken toe te staan Multi-gebruiker modus Alleen apparaateigenaar @@ -150,7 +148,6 @@ Alle rootsessies gebruiken de globale naamruimte Rootsessies verkrijgen de verzoeker\'s naamruimte Iedere rootsessie heeft een eigen geïsoleerde naamruimte - Geen vingerafdrukken ingesteld, of geen apparaatondersteuning Superuser verzoek @@ -177,7 +174,6 @@ De rechten van %1$s intrekken? Toast Geen - Authenticatie mislukt Doel UID: %1$d diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index a5eaa480a..0bd45c811 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -166,9 +166,6 @@ %1$d sekund Ponowienie uwierzytelnienia po aktualizacji Ponowne uwierzytelnianie uprawnienia superużytkownika po aktualizacji aplikacji - Włącz Uwierzytelnienie Odciskiem Palca - Użyj skanera linii papilarnych, aby zezwolić na żądania supersu - Uwierzytelnianie Odciskiem Palca Tryb Multiusera Tylko Właściciel Urządzenia @@ -185,7 +182,6 @@ Wszystkie sesje root za pomocą globalnej przestrzeni montowań nazw Sesje Root będzie dziedziczyć prośby i nazwy W każdej sesji root będzie miał własną odosobnioną nazwę - Nie ustawiono żadnych odcisków palców lub brak obsługi urządzenia Błąd podczas tworzenia folderu. Musi być dostępny z głównego katalogu pamięci i nie może być plikiem. @@ -213,7 +209,6 @@ Potwierdzasz odwołanie uprawnień %1$s? Powiadomienie Brak - Uwierzytelnienie Nieudane PID: %1$d diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index b69f2f4fe..2ed94706b 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -134,8 +134,6 @@ %1$d segundos Reautenticar após atualizar Reautenticar permissões de superusuário após um app atualizar - Ativar Autenticação de Impressão Digital - Usar escaneador de impressão digital para permitir solicitações de superusuário Modo de Multiusuário Proprietário do Dispositivo Apenas @@ -152,7 +150,6 @@ Todas as sessões root usam montagem de espaço de nome global As sessões root herdarão espaço de nome de seu solicitante Cada sessão root terá seu próprio espaço de nome isolado - Nenhuma impressão digital foi definida ou o dispostivo não tem suporte Solicitação de Superusuário @@ -179,7 +176,6 @@ Revogar os direitos de %1$s? Notificação toast Nenhuma - Falha de Autenticação PID: %1$d diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 2fba59981..545bd4240 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -161,9 +161,6 @@ %1$d secunde Reautentificare după actualizare Reautentifică permisiunile pentru superutilizator după o actualizare a aplicației - Activează autentificarea cu amprenta - Folosește scannerul de amprente pentru a permite solicitările de superutilizator - Autentifică amprenta Mod de multiutilizator Numai proprietarul dispozitivului @@ -180,7 +177,6 @@ Toate sesiunile de root folosesc spațiul de nume global. Sesiunile de root vor moșteni spațiul de nume al solicitantului. Fiecare sesiune de root va avea propriul spațiu de nume izolat. - Nu au fost setate amprente sau scannerul de amprentă lipsește. Eroare la crearea dosarului. Acesta trebuie să fie accesibil din directorul rădăcină al stocării și nu trebuie să fie un fișier. @@ -208,7 +204,6 @@ Confirmi revocarea drepturilor pentru %1$s? Mesaj Nimic - Autentificare eșuată PID: %1$d diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 160bda820..3c723c763 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -167,9 +167,6 @@ %1$d секунд Повторная аутентификация Повторный запрос прав суперпользователя после обновления приложений - Биометрическая аутентификация - Использовать сканер отпечатков пальцев для запросов прав суперпользователя - Подтвердите отпечаток пальца Многопользовательский режим Только владелец @@ -186,7 +183,6 @@ Сессии суперпользователя используют общее пространство имён Сессии суперпользователя наследуют пространство имён запрашивающего Сессии суперпользователя используют изолированные пространства имён - Не поддерживается устройством или не заданы отпечатки Ошибка создания папки. Она должна быть доступна из корневой директории хранилища и не должна быть файлом. @@ -214,7 +210,6 @@ Сбросить настройки для %1$s? Всплывающие уведомления Нет - Ошибка аутентификации PID: %1$d diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index c39bf3cad..c50628129 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -166,9 +166,6 @@ %1$d sekúnd Overenie autentifikácie po upgrade Overí autentifikáciu oprávnení superuser po upgrade aplikácie - Povoliť autentifikáciu odtlačkom prsta - Použite snímač odtlačkov prstov pre povolenie žiadostí superuser - Autentifikovať odtlačok prsta Režim viacerých používateľov Iba majiteľ zariadenia @@ -185,7 +182,6 @@ Všetky relácie root použijú globálny mount namespace Relácie root zdedia namespace od žiadateľa Každá relácia root bude mať vlastný izolovaný namespace - Neboli odoslané žiadne odtlačky prsta alebo ich zariadenie nepodporuje Chyba pri vytváraní priečinka. Musí byť prístupný z koreňového adresára a nemôže to byť súbor. @@ -213,7 +209,6 @@ Potvrdzujete zrušenie práv %1$s? Toast Nič - Autentifikácia zlyhala PID:%1$d diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 066df9c69..c966803f2 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -146,9 +146,6 @@ %1$d วินาที ขอสิทธิ์ใหม่หลังจากอัพเกรด ขอสิทธิ์ superuser ใหม่หลังจากแอปถูกอัพเกรด - ใช้การยืนยันลายนิ้วมือ - ใช้ตัวแสกนลายนิ้วมือเพื่ออนุญาตารขอเข้าถึง superuser - ยืนยันลายนิ้วมือ โหมดผู้ใช้หลายคน เจ้าของอุปกรณ์เท่านั้น @@ -165,7 +162,6 @@ All root sessions use the global mount namespace. Root sessions will inherit their requester\'s namespace. Each root session will have its own isolated namespace. - ไม่มีลายนิ้วมือหรืออุปกรณ์แสกน การขอเข้าถึง Superuser @@ -192,7 +188,6 @@ ยืนยันการลบสิทธิ์ของ %1$s? การเตือน ไม่มี - การยืนยันล้มเหลว UID เป้าหมาย: %1$d diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 1fed35e24..3ec7b2b94 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -166,9 +166,6 @@ %1$d saniye Yükseltmeden sonra yeniden kimlik doğrula Uygulama yükseltmeleri sonrasında yetkili kullanıcı izinlerini yeniden doğrula - Parmak İzi Kimlik Doğrulamayı Etkinleştir - Yetkili kullanıcı isteklerine izin vermek için parmak izi tarayıcısını kullan - Parmak izini doğrula Çok Kullanıcılı Mod Yalnızca Cihaz Sahibi @@ -185,7 +182,6 @@ Tüm kök oturumları genel bağlama ad alanını kullanır Kök oturumları, istekte bulunanın ad alanını devralır Her bir kök oturumunun kendi izole ad alanı olacaktır - Parmak izi ayarlanmadı veya cihaz desteği yok Klasör oluşturma hatası. Depolama kök dizininden erişilebilir olmalı ve bir dosya olmamalıdır. @@ -213,7 +209,6 @@ %1$s hakları geri alınsın mı? Pencere Hiçbiri - Kimlik Doğrulama Başarısız PID: %1$d diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index ae9573824..d445db68c 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -166,9 +166,6 @@ %1$d сек. Повторна автентифікація Перевидача прав суперкористувача після оновлення програм - Автентифікація за відбитком - Використовувати сканер відбитків пальців, щоб надавати дозвіл суперкористувача - Автентифікація за відбитком Багатокористувацький режим Тільки власник @@ -185,7 +182,6 @@ Всі сеанси Суперкористувача використовують глобальний простір імен. Сеанси Суперкористувача наслідують простір імен запитувача. Кожнен сеанс Суперкористувача має власний ізольований простір імен. - Немає відбитків пальця або пристрій не підтримується. Помилка створення папки. Вона повинна бути доступна з кореневої директорії сховища і не повинна бути файлом. @@ -213,7 +209,6 @@ Підтвердити відкликання прав для %1$s? Спливаюче сповіщення Ні - Помилка автентифікації PID: %1$d diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 1b9cef3be..f68e6d5c8 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -141,9 +141,6 @@ %1$d giây Xác thực lại sau khi nâng cấp Xác thực lại quyền superuser sau khi nâng cấp ứng dụng - Bật xác thực vân tay - Sử dụng quét vân tay để cho phép quyền superuser - Xác thực vân tay Chế độ đa người dùng Chỉ chủ sở hữu thiết bị Chủ sở hữu thiết bị được quản lý @@ -158,8 +155,7 @@ Tất cả các phiên root sử dụng không gian tên gắn kết chung. Các phiên root sẽ kế thừa không gian tên của người yêu cầu. Mỗi phiên root sẽ có không gian tên riêng biệt. - Không có dấu vân tay nào được thiết lập hoặc thiết bị không hỗ trợ. - + Yêu cầu Superuser Từ chối @@ -185,8 +181,7 @@ Xác nhận thu hồi quyền của %1$s? Thông báo ngắn Không có - Xác thực thất bại - + Mục UID: %1$d Điều khiển: %1$s diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index e97518fb3..2be863b8b 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -167,9 +167,6 @@ %1$d 秒 更新后重新认证 应用更新后重新认证超级用户权限 - 启用指纹验证 - 使用指纹识别来允许超级用户请求 - 验证指纹 多用户模式 仅设备所有者 @@ -186,7 +183,6 @@ 所有的 ROOT 会话使用全局挂载命名空间 ROOT 会话继承原程序的命名空间 每一个 ROOT 会话使用自己独立的命名空间 - 没有设置指纹或设备不支持 创建文件夹出错。路径需要位于内部存储空间,并且不能有同名文件。 @@ -214,7 +210,6 @@ 确认撤销 %1$s 的权限? 消息提示 - 验证失败 PID: %1$d diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 7225bff86..46361b5ed 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -167,9 +167,6 @@ %1$d 秒 更新後重新驗證 應用程式更新後,重新驗證超級使用者的請求 - 指紋驗證 - 使用指紋辨識器允許超級使用者的請求 - 指紋驗證 多重使用者模式 僅限裝置擁有者 @@ -186,7 +183,6 @@ 所有 Root 工作階段皆使用全域命名空間 所有 Root 工作階段皆繼承原程式的命名空間 所有 Root 工作階段都擁有獨立的命名空間 - 未設定指紋或無指紋感測器 建立資料夾發生錯誤。檔案存放的路徑需要位於內部儲存空間且不能有同樣名稱的檔案。 @@ -214,7 +210,6 @@ 確定撤銷 %1$s 的權限? 快顯通知 - 驗證失敗 PID:%1$d diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5df6c7e97..d9a127161 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -95,7 +95,6 @@ Reboot to apply settings Release notes Repo cache cleared - DTBO was patched! Magisk Manager has patched dtbo.img. Please reboot. Flashing… @@ -116,6 +115,7 @@ Requires Additional Setup Your device needs additional setup for Magisk to work properly. It will download the Magisk setup zip, do you want to proceed now? Running environment setup… + Authenticate General @@ -167,9 +167,9 @@ %1$d seconds Reauthenticate after upgrade Reauthenticate superuser permissions after an application upgrades - Enable Fingerprint Authentication - Use fingerprint scanner to allow superuser requests - Authenticate Fingerprint + Enable Biometric Authentication + Use biometric authentication to allow superuser requests + Unsupported device or no biometric settings are enabled Multiuser Mode Device Owner Only @@ -186,7 +186,6 @@ All root sessions use the global mount namespace Root sessions will inherit their requester\'s namespace Each root session will have its own isolated namespace - No fingerprints were set or no device support Error creating folder. It must be accessible from storage root directory and must not be a file. @@ -214,7 +213,6 @@ Confirm to revoke %1$s rights? Toast None - Authentication Failed PID: %1$d diff --git a/app/src/main/res/xml/app_settings.xml b/app/src/main/res/xml/app_settings.xml index 27345d2d8..44a1ffeb7 100644 --- a/app/src/main/res/xml/app_settings.xml +++ b/app/src/main/res/xml/app_settings.xml @@ -119,9 +119,9 @@ + android:key="su_biometric" + android:title="@string/settings_su_biometric_title" + android:summary="@string/settings_su_biometric_summary" /> - \ No newline at end of file + diff --git a/shared/src/main/java/com/topjohnwu/magisk/DynAPK.java b/shared/src/main/java/com/topjohnwu/magisk/DynAPK.java index 651fd5314..41f9fb906 100644 --- a/shared/src/main/java/com/topjohnwu/magisk/DynAPK.java +++ b/shared/src/main/java/com/topjohnwu/magisk/DynAPK.java @@ -11,7 +11,7 @@ import static android.os.Build.VERSION.SDK_INT; public class DynAPK { - private static final int STUB_VERSION = 5; + private static final int STUB_VERSION = 6; // Indices of the object array private static final int STUB_VERSION_ENTRY = 0; diff --git a/stub/src/main/AndroidManifest.xml b/stub/src/main/AndroidManifest.xml index b04b4dc95..8222e9ca7 100644 --- a/stub/src/main/AndroidManifest.xml +++ b/stub/src/main/AndroidManifest.xml @@ -7,6 +7,7 @@ +