mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
rewrite and improve biometric authenticator
This commit is contained in:
parent
0f80d9950c
commit
b75441eb3a
6 changed files with 160 additions and 112 deletions
|
@ -113,6 +113,7 @@ import com.lagradost.cloudstream3.ui.result.txt
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchFragment
|
import com.lagradost.cloudstream3.ui.search.SearchFragment
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
|
import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTruePhone
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.updateTv
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.updateTv
|
||||||
|
@ -133,9 +134,8 @@ import com.lagradost.cloudstream3.utils.AppUtils.setDefaultFocus
|
||||||
import com.lagradost.cloudstream3.utils.BackupUtils.backup
|
import com.lagradost.cloudstream3.utils.BackupUtils.backup
|
||||||
import com.lagradost.cloudstream3.utils.BackupUtils.setUpBackup
|
import com.lagradost.cloudstream3.utils.BackupUtils.setUpBackup
|
||||||
import com.lagradost.cloudstream3.utils.BiometricAuthenticator
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator
|
||||||
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.TAG
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.deviceHasPasswordPinLock
|
||||||
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.isTruePhone
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.startBiometricAuthentication
|
||||||
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.promptInfo
|
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
|
||||||
import com.lagradost.cloudstream3.utils.Coroutines.main
|
import com.lagradost.cloudstream3.utils.Coroutines.main
|
||||||
import com.lagradost.cloudstream3.utils.DataStore.getKey
|
import com.lagradost.cloudstream3.utils.DataStore.getKey
|
||||||
|
@ -1194,8 +1194,6 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener, BiometricAu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ActivityMainBinding.bind(newLocalBinding.root) // this may crash
|
ActivityMainBinding.bind(newLocalBinding.root) // this may crash
|
||||||
} else {
|
} else {
|
||||||
val newLocalBinding = ActivityMainBinding.inflate(layoutInflater, null, false)
|
val newLocalBinding = ActivityMainBinding.inflate(layoutInflater, null, false)
|
||||||
|
@ -1214,11 +1212,19 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener, BiometricAu
|
||||||
val noAccounts = settingsManager.getBoolean(getString(R.string.skip_startup_account_select_key), false) || accounts.count() <= 1
|
val noAccounts = settingsManager.getBoolean(getString(R.string.skip_startup_account_select_key), false) || accounts.count() <= 1
|
||||||
|
|
||||||
if (isTruePhone() && authEnabled && noAccounts) {
|
if (isTruePhone() && authEnabled && noAccounts) {
|
||||||
|
if (deviceHasPasswordPinLock(this)) {
|
||||||
|
startBiometricAuthentication(this,
|
||||||
|
R.string.biometric_authentication_title,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
BiometricAuthenticator.initializeBiometrics(this@MainActivity, this)
|
BiometricAuthenticator.biometricPrompt.authenticate(BiometricAuthenticator.promptInfo)
|
||||||
BiometricAuthenticator.checkBiometricAvailability()
|
|
||||||
BiometricAuthenticator.biometricPrompt.authenticate(promptInfo)
|
// hide background while authenticating, Sorry moms & dads 🙏
|
||||||
binding?.navHostFragment?.isInvisible = true // hide background while authenticating
|
binding?.navHostFragment?.isInvisible = true
|
||||||
|
} else {
|
||||||
|
showToast(R.string.phone_not_secured, Toast.LENGTH_LONG)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automatically enable jsdelivr if cant connect to raw.githubusercontent.com
|
// Automatically enable jsdelivr if cant connect to raw.githubusercontent.com
|
||||||
|
@ -1760,7 +1766,8 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener, BiometricAu
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAuthenticationSuccess() { /** Biometric stuff **/
|
/** Biometric stuff **/
|
||||||
|
override fun onAuthenticationSuccess() {
|
||||||
// make background (nav host fragment) visible again
|
// make background (nav host fragment) visible again
|
||||||
binding?.navHostFragment?.isInvisible = false
|
binding?.navHostFragment?.isInvisible = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package com.lagradost.cloudstream3.ui.account
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
|
@ -17,8 +19,11 @@ import com.lagradost.cloudstream3.mvvm.observe
|
||||||
import com.lagradost.cloudstream3.ui.AutofitRecyclerView
|
import com.lagradost.cloudstream3.ui.AutofitRecyclerView
|
||||||
import com.lagradost.cloudstream3.ui.account.AccountAdapter.Companion.VIEW_TYPE_EDIT_ACCOUNT
|
import com.lagradost.cloudstream3.ui.account.AccountAdapter.Companion.VIEW_TYPE_EDIT_ACCOUNT
|
||||||
import com.lagradost.cloudstream3.ui.account.AccountAdapter.Companion.VIEW_TYPE_SELECT_ACCOUNT
|
import com.lagradost.cloudstream3.ui.account.AccountAdapter.Companion.VIEW_TYPE_SELECT_ACCOUNT
|
||||||
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTruePhone
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
||||||
import com.lagradost.cloudstream3.utils.BiometricAuthenticator
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.deviceHasPasswordPinLock
|
||||||
|
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.startBiometricAuthentication
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.accounts
|
import com.lagradost.cloudstream3.utils.DataStoreHelper.accounts
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.selectedKeyIndex
|
import com.lagradost.cloudstream3.utils.DataStoreHelper.selectedKeyIndex
|
||||||
import com.lagradost.cloudstream3.utils.DataStoreHelper.setAccount
|
import com.lagradost.cloudstream3.utils.DataStoreHelper.setAccount
|
||||||
|
@ -43,20 +48,25 @@ class AccountSelectActivity : AppCompatActivity(), BiometricAuthenticator.Biomet
|
||||||
|
|
||||||
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
val authEnabled = settingsManager.getBoolean(getString(R.string.biometric_enabled_key), false)
|
val authEnabled = settingsManager.getBoolean(getString(R.string.biometric_enabled_key), false)
|
||||||
val skipStartup = settingsManager.getBoolean(
|
val skipStartup = settingsManager.getBoolean(getString(R.string.skip_startup_account_select_key), false
|
||||||
getString(R.string.skip_startup_account_select_key),
|
|
||||||
false
|
|
||||||
) || accounts.count() <= 1
|
) || accounts.count() <= 1
|
||||||
|
|
||||||
viewModel = ViewModelProvider(this)[AccountViewModel::class.java]
|
viewModel = ViewModelProvider(this)[AccountViewModel::class.java]
|
||||||
|
|
||||||
fun askBiometricAuth() {
|
fun askBiometricAuth() {
|
||||||
|
|
||||||
if (BiometricAuthenticator.isTruePhone() && authEnabled) {
|
if (isTruePhone() && authEnabled) {
|
||||||
BiometricAuthenticator.initializeBiometrics(this@AccountSelectActivity, this)
|
if (deviceHasPasswordPinLock(this)) {
|
||||||
BiometricAuthenticator.checkBiometricAvailability()
|
startBiometricAuthentication(
|
||||||
|
this,
|
||||||
|
R.string.biometric_authentication_title,
|
||||||
|
false
|
||||||
|
)
|
||||||
BiometricAuthenticator.biometricPrompt.authenticate(BiometricAuthenticator.promptInfo)
|
BiometricAuthenticator.biometricPrompt.authenticate(BiometricAuthenticator.promptInfo)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
showToast(R.string.phone_not_secured, Toast.LENGTH_LONG)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't show account selection if there is only
|
// Don't show account selection if there is only
|
||||||
|
@ -178,7 +188,8 @@ class AccountSelectActivity : AppCompatActivity(), BiometricAuthenticator.Biomet
|
||||||
startActivity(mainIntent)
|
startActivity(mainIntent)
|
||||||
finish() // Finish the account selection activity
|
finish() // Finish the account selection activity
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAuthenticationSuccess() {
|
override fun onAuthenticationSuccess() {
|
||||||
//ask github.com/IndusAryan if confusion occurs
|
Log.i(BiometricAuthenticator.TAG,"Authentication successful in AccountSelectActivity")
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,6 +19,7 @@ import androidx.preference.PreferenceFragmentCompat
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.google.android.material.appbar.AppBarLayout
|
import com.google.android.material.appbar.AppBarLayout
|
||||||
import com.google.android.material.appbar.MaterialToolbar
|
import com.google.android.material.appbar.MaterialToolbar
|
||||||
|
import com.lagradost.cloudstream3.AcraApplication.Companion.context
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.databinding.MainSettingsBinding
|
import com.lagradost.cloudstream3.databinding.MainSettingsBinding
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
|
@ -155,6 +156,11 @@ class SettingsFragment : Fragment() {
|
||||||
return getLayoutInt() == 2
|
return getLayoutInt() == 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// phone exclusive
|
||||||
|
fun isTruePhone(): Boolean {
|
||||||
|
return !isTrueTvSettings() && !isTvSettings() && context?.isEmulatorSettings() != true
|
||||||
|
}
|
||||||
|
|
||||||
private fun Context.isAutoTv(): Boolean {
|
private fun Context.isAutoTv(): Boolean {
|
||||||
val uiModeManager = getSystemService(Context.UI_MODE_SERVICE) as UiModeManager?
|
val uiModeManager = getSystemService(Context.UI_MODE_SERVICE) as UiModeManager?
|
||||||
// AFT = Fire TV
|
// AFT = Fire TV
|
||||||
|
|
|
@ -5,7 +5,7 @@ import android.app.KeyguardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast.LENGTH_SHORT
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.biometric.BiometricManager
|
import androidx.biometric.BiometricManager
|
||||||
import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG
|
import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG
|
||||||
|
@ -13,137 +13,162 @@ import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_WEAK
|
||||||
import androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL
|
import androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL
|
||||||
import androidx.biometric.BiometricPrompt
|
import androidx.biometric.BiometricPrompt
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.lagradost.cloudstream3.AcraApplication.Companion.context
|
|
||||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||||
|
import com.lagradost.cloudstream3.MainActivity
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isEmulatorSettings
|
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueTvSettings
|
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
|
|
||||||
|
|
||||||
object BiometricAuthenticator {
|
object BiometricAuthenticator {
|
||||||
|
|
||||||
|
private const val MAX_FAILED_ATTEMPTS = 3
|
||||||
|
private var failedAttempts = 0
|
||||||
|
const val TAG = "cs3Auth"
|
||||||
|
|
||||||
private lateinit var biometricManager: BiometricManager
|
private lateinit var biometricManager: BiometricManager
|
||||||
lateinit var biometricPrompt: BiometricPrompt
|
lateinit var biometricPrompt: BiometricPrompt
|
||||||
lateinit var promptInfo: BiometricPrompt.PromptInfo
|
lateinit var promptInfo: BiometricPrompt.PromptInfo
|
||||||
const val TAG = "cs3Auth"
|
|
||||||
|
|
||||||
private var authCallback: BiometricAuthCallback? = null
|
var authCallback: BiometricAuthCallback? = null // listen to authentication success
|
||||||
|
|
||||||
fun initializeBiometrics(activity: Activity, callback: BiometricAuthCallback) {
|
private fun initializeBiometrics(activity: Activity) {
|
||||||
val executor = ContextCompat.getMainExecutor(activity)
|
val executor = ContextCompat.getMainExecutor(activity)
|
||||||
authCallback = callback // to listen success authentication
|
|
||||||
biometricManager = BiometricManager.from(activity)
|
biometricManager = BiometricManager.from(activity)
|
||||||
|
|
||||||
biometricPrompt = BiometricPrompt(activity as AppCompatActivity, executor, object : BiometricPrompt.AuthenticationCallback() {
|
if (!::promptInfo.isInitialized) {
|
||||||
|
initBiometricPrompt(
|
||||||
|
activity as AppCompatActivity,
|
||||||
|
R.string.biometric_authentication_title,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
biometricPrompt = BiometricPrompt(
|
||||||
|
activity as AppCompatActivity,
|
||||||
|
executor,
|
||||||
|
object : BiometricPrompt.AuthenticationCallback() {
|
||||||
|
|
||||||
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
|
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
|
||||||
super.onAuthenticationError(errorCode, errString)
|
super.onAuthenticationError(errorCode, errString)
|
||||||
Log.d(TAG, "Authentication error: $errString")
|
showToast("$errString", LENGTH_SHORT)
|
||||||
|
Log.i(TAG, "$errorCode")
|
||||||
activity.finish()
|
activity.finish()
|
||||||
|
failedAttempts++
|
||||||
|
if (failedAttempts >= MAX_FAILED_ATTEMPTS) {
|
||||||
|
failedAttempts = 0
|
||||||
|
activity.finish()
|
||||||
|
} else {
|
||||||
|
failedAttempts = 0
|
||||||
|
MainActivity().finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
||||||
super.onAuthenticationSucceeded(result)
|
super.onAuthenticationSucceeded(result)
|
||||||
Log.d(TAG, "Biometric succeeded.")
|
failedAttempts = 0
|
||||||
unblockMain() //to make background visible after authenticating
|
authCallback?.onAuthenticationSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAuthenticationFailed() {
|
override fun onAuthenticationFailed() {
|
||||||
super.onAuthenticationFailed()
|
super.onAuthenticationFailed()
|
||||||
Log.d(TAG, "Authentication error")
|
failedAttempts++
|
||||||
showToast(R.string.biometric_failed, Toast.LENGTH_SHORT)
|
if (failedAttempts >= MAX_FAILED_ATTEMPTS) {
|
||||||
|
failedAttempts = 0
|
||||||
activity.finish()
|
activity.finish()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initBiometricPrompt(
|
||||||
|
activity: Activity,
|
||||||
|
title: Int,
|
||||||
|
setDeviceCred: Boolean,
|
||||||
|
) {
|
||||||
|
val description = activity.getString(R.string.biometric_prompt_description)
|
||||||
|
if (setDeviceCred) {
|
||||||
|
// For API level > 30, Newer API setAllowedAuthenticators is used
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
|
||||||
|
val authFlag = DEVICE_CREDENTIAL or BIOMETRIC_WEAK or BIOMETRIC_STRONG
|
||||||
promptInfo = BiometricPrompt.PromptInfo.Builder()
|
promptInfo = BiometricPrompt.PromptInfo.Builder()
|
||||||
.setTitle("Unlock CloudStream")
|
.setTitle(activity.getString(title))
|
||||||
//.setSubtitle("Log in using your biometric credential")
|
.setDescription(description)
|
||||||
//.setNegativeButtonText("Use account password")
|
.setAllowedAuthenticators(authFlag)
|
||||||
.setAllowedAuthenticators(BIOMETRIC_WEAK or BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
|
|
||||||
.build()
|
.build()
|
||||||
|
} else {
|
||||||
} else if (context?.let { deviceHasPasswordPinLock(it) } == true) {
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
promptInfo = BiometricPrompt.PromptInfo.Builder()
|
promptInfo = BiometricPrompt.PromptInfo.Builder()
|
||||||
.setTitle("Unlock CloudStream")
|
.setTitle(activity.getString(title))
|
||||||
|
.setDescription(description)
|
||||||
|
.setDeviceCredentialAllowed(true)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// fallback for A12+ when both fingerprint & Face unlock is absent but PIN is set
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
promptInfo = BiometricPrompt.PromptInfo.Builder()
|
||||||
|
.setTitle(activity.getString(title))
|
||||||
|
.setDescription(description)
|
||||||
.setDeviceCredentialAllowed(true)
|
.setDeviceCredentialAllowed(true)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkBiometricAvailability() {
|
private fun isBiometricHardWareAvailable(): Boolean {
|
||||||
|
var result = false
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
when (biometricManager.canAuthenticate(
|
||||||
// Strong and device credential bundle cannot be checked at same time in API < A11 (R)
|
DEVICE_CREDENTIAL or BIOMETRIC_STRONG or BIOMETRIC_WEAK
|
||||||
when (biometricManager.canAuthenticate(BIOMETRIC_WEAK or BIOMETRIC_STRONG or DEVICE_CREDENTIAL)) {
|
)) {
|
||||||
BiometricManager.BIOMETRIC_SUCCESS ->
|
BiometricManager.BIOMETRIC_SUCCESS -> result = true
|
||||||
Log.d(TAG, "App can authenticate.")
|
BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE -> result = false
|
||||||
|
BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE -> result = false
|
||||||
BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE ->
|
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> result = false
|
||||||
Log.d(TAG, "No biometric sensor found.")
|
BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED -> result = true
|
||||||
|
BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED -> result = true
|
||||||
BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE ->
|
BiometricManager.BIOMETRIC_STATUS_UNKNOWN -> result = false
|
||||||
Log.d(TAG, "Biometric authentication is currently unavailable.")
|
}
|
||||||
|
} else {
|
||||||
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED ->
|
@Suppress("DEPRECATION")
|
||||||
showToast(R.string.biometric_not_enrolled, Toast.LENGTH_LONG)
|
when (biometricManager.canAuthenticate()) {
|
||||||
|
BiometricManager.BIOMETRIC_SUCCESS -> result = true
|
||||||
BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED ->
|
BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE -> result = false
|
||||||
showToast(R.string.biometric_update_required, Toast.LENGTH_LONG)
|
BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE -> result = false
|
||||||
|
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> result = false
|
||||||
BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED ->
|
BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED -> result = true
|
||||||
showToast(R.string.biometric_unsupported, Toast.LENGTH_SHORT)
|
BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED -> result = true
|
||||||
|
BiometricManager.BIOMETRIC_STATUS_UNKNOWN -> result = false
|
||||||
BiometricManager.BIOMETRIC_STATUS_UNKNOWN ->
|
|
||||||
Log.e(TAG, "Unknown error encountered while authenticating fingerprint.")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
return result
|
||||||
|
|
||||||
when (biometricManager.canAuthenticate(BIOMETRIC_WEAK or BIOMETRIC_STRONG)) {
|
|
||||||
|
|
||||||
BiometricManager.BIOMETRIC_SUCCESS ->
|
|
||||||
Log.d(TAG, "App can authenticate using biometrics.")
|
|
||||||
|
|
||||||
BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE ->
|
|
||||||
Log.d(TAG, "No biometric features available on this device.")
|
|
||||||
|
|
||||||
BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE ->
|
|
||||||
Log.e(TAG, "Biometric features are currently unavailable.")
|
|
||||||
|
|
||||||
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED ->
|
|
||||||
showToast(R.string.biometric_not_enrolled, Toast.LENGTH_LONG)
|
|
||||||
|
|
||||||
BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED ->
|
|
||||||
showToast(R.string.biometric_update_required, Toast.LENGTH_LONG)
|
|
||||||
|
|
||||||
BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED ->
|
|
||||||
showToast(R.string.biometric_unsupported, Toast.LENGTH_SHORT)
|
|
||||||
|
|
||||||
BiometricManager.BIOMETRIC_STATUS_UNKNOWN ->
|
|
||||||
Log.d(TAG, "Unknown error encountered while authenticating fingerprint.")
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// yes, this feature is phone exclusive
|
// only needed for Android 9 and below
|
||||||
fun isTruePhone(): Boolean {
|
fun deviceHasPasswordPinLock(context: Context?): Boolean {
|
||||||
return !isTrueTvSettings() && !isTvSettings() && context?.isEmulatorSettings() != true
|
val keyMgr =
|
||||||
|
context?.getSystemService(AppCompatActivity.KEYGUARD_SERVICE) as KeyguardManager
|
||||||
|
return keyMgr.isKeyguardSecure
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unblockMain() {
|
fun startBiometricAuthentication(activity: Activity, title: Int, setDeviceCred: Boolean) {
|
||||||
authCallback?.onAuthenticationSuccess()
|
initializeBiometrics(activity)
|
||||||
}
|
|
||||||
|
|
||||||
private fun deviceHasPasswordPinLock(con: Context): Boolean {
|
if (isBiometricHardWareAvailable()) {
|
||||||
val keyManager = con.getSystemService(AppCompatActivity.KEYGUARD_SERVICE) as KeyguardManager
|
authCallback = activity as? BiometricAuthCallback
|
||||||
return keyManager.isKeyguardSecure
|
initBiometricPrompt(activity, title, setDeviceCred)
|
||||||
|
biometricPrompt.authenticate(promptInfo)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (deviceHasPasswordPinLock(activity)) {
|
||||||
|
authCallback = activity as? BiometricAuthCallback
|
||||||
|
initBiometricPrompt(activity, R.string.password_pin_authentication_title, true)
|
||||||
|
biometricPrompt.authenticate(promptInfo)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
showToast(R.string.biometric_unsupported, LENGTH_SHORT)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface BiometricAuthCallback {
|
interface BiometricAuthCallback {
|
||||||
|
|
|
@ -532,7 +532,6 @@ object UIHelper {
|
||||||
WindowInsetsControllerCompat(window, View(this)).show(WindowInsetsCompat.Type.systemBars())
|
WindowInsetsControllerCompat(window, View(this)).show(WindowInsetsCompat.Type.systemBars())
|
||||||
|
|
||||||
} else {*/ /** WINDOW COMPAT IS BUGGY DUE TO FU*KED UP PLAYER AND TRAILERS **/
|
} else {*/ /** WINDOW COMPAT IS BUGGY DUE TO FU*KED UP PLAYER AND TRAILERS **/
|
||||||
Suppress("DEPRECATION")
|
|
||||||
window.decorView.systemUiVisibility =
|
window.decorView.systemUiVisibility =
|
||||||
(View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
|
(View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -745,13 +745,13 @@
|
||||||
<string name="auto_rotate_video_desc">Enable automatic switching of screen orientation based on video orientation</string>
|
<string name="auto_rotate_video_desc">Enable automatic switching of screen orientation based on video orientation</string>
|
||||||
<string name="auto_rotate_video">Auto rotate</string>
|
<string name="auto_rotate_video">Auto rotate</string>
|
||||||
|
|
||||||
|
<!-- For Biometrics -->
|
||||||
|
<string name="biometric_authentication_title">Unlock CloudStream</string>
|
||||||
<string name="biometric_setting">Fingerprint sensor authentication</string>
|
<string name="biometric_setting">Fingerprint sensor authentication</string>
|
||||||
<string name="biometric_success">Fingerprint authentication succeeded</string>
|
|
||||||
<string name="biometric_failed">Fingerprint authentication failed</string>
|
|
||||||
<string name="biometric_prompt_title">Unlock CloudStream</string>
|
|
||||||
<string name="biometric_not_enrolled">Please add fingerprint or screen lock or disable setting</string>
|
|
||||||
<string name="biometric_update_required">Please update software and security patches.</string>
|
|
||||||
<string name="biometric_unsupported">Biometric authentication is not supported on this device</string>
|
|
||||||
<string name="biometric_enabled_key" translatable="false">biometric_key</string>
|
<string name="biometric_enabled_key" translatable="false">biometric_key</string>
|
||||||
|
<string name="password_pin_authentication_title">Password/PIN Authentication</string>
|
||||||
|
<string name="biometric_unsupported">Biometric authentication is not supported on this device</string>
|
||||||
|
<string name="phone_not_secured">Please disable fingerprint authentication if device has no lock.</string>
|
||||||
|
<string name="biometric_prompt_description">This window will close after few failed attempts. You\'ll have to restart the App.</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue