hide background while authenticating & other improvements

This commit is contained in:
IndusAryan 2024-01-08 15:53:50 +05:30
parent 15d75e5194
commit 5bc9b413d5
4 changed files with 63 additions and 24 deletions

View file

@ -28,6 +28,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.children
import androidx.core.view.isGone
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.core.view.marginStart
import androidx.fragment.app.FragmentActivity
@ -128,6 +129,7 @@ import com.lagradost.cloudstream3.utils.AppUtils.setDefaultFocus
import com.lagradost.cloudstream3.utils.BackupUtils.backup
import com.lagradost.cloudstream3.utils.BackupUtils.setUpBackup
import com.lagradost.cloudstream3.utils.BiometricAuthenticator
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.TAG
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.isTruePhone
import com.lagradost.cloudstream3.utils.BiometricAuthenticator.promptInfo
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
@ -166,7 +168,6 @@ import kotlin.math.absoluteValue
import kotlin.reflect.KClass
import kotlin.system.exitProcess
//https://github.com/videolan/vlc-android/blob/3706c4be2da6800b3d26344fc04fab03ffa4b860/application/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.kt#L1898
//https://wiki.videolan.org/Android_Player_Intents/
@ -285,7 +286,7 @@ var app = Requests(responseParser = object : ResponseParser {
defaultHeaders = mapOf("user-agent" to USER_AGENT)
}
class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
class MainActivity : AppCompatActivity(), ColorPickerDialogListener, BiometricAuthenticator.BiometricAuthCallback {
companion object {
const val TAG = "MAINACT"
const val ANIMATED_OUTLINE : Boolean = false
@ -1161,9 +1162,11 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
val noAccounts = settingsManager.getBoolean(getString(R.string.skip_startup_account_select_key), false) || accounts.count() <= 1
if (isTruePhone() && authEnabled && noAccounts ) {
BiometricAuthenticator.initializeBiometrics(this@MainActivity)
BiometricAuthenticator.initializeBiometrics(this@MainActivity, this)
BiometricAuthenticator.checkBiometricAvailability()
BiometricAuthenticator.biometricPrompt.authenticate(promptInfo)
binding?.navHostFragment?.isInvisible = true // hide background while authenticating
}
// Automatically enable jsdelivr if cant connect to raw.githubusercontent.com
@ -1621,6 +1624,11 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
)
}
override fun onAuthenticationSuccess() { /** Biometric stuff **/
// make background (nav host fragment) visible again
binding?.navHostFragment?.isInvisible = false
}
private var backPressedCallback: OnBackPressedCallback? = null
private fun attachBackPressedCallback() {

View file

@ -24,7 +24,7 @@ import com.lagradost.cloudstream3.utils.DataStoreHelper.selectedKeyIndex
import com.lagradost.cloudstream3.utils.DataStoreHelper.setAccount
import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
class AccountSelectActivity : AppCompatActivity() {
class AccountSelectActivity : AppCompatActivity(), BiometricAuthenticator.BiometricAuthCallback {
lateinit var viewModel: AccountViewModel
@ -43,7 +43,6 @@ class AccountSelectActivity : AppCompatActivity() {
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
val authEnabled = settingsManager.getBoolean(getString(R.string.biometric_enabled_key), false)
val skipStartup = settingsManager.getBoolean(
getString(R.string.skip_startup_account_select_key),
false
@ -54,7 +53,7 @@ class AccountSelectActivity : AppCompatActivity() {
fun askBiometricAuth() {
if (BiometricAuthenticator.isTruePhone() && authEnabled) {
BiometricAuthenticator.initializeBiometrics(this)
BiometricAuthenticator.initializeBiometrics(this@AccountSelectActivity, this)
BiometricAuthenticator.checkBiometricAvailability()
BiometricAuthenticator.biometricPrompt.authenticate(BiometricAuthenticator.promptInfo)
}
@ -179,4 +178,7 @@ class AccountSelectActivity : AppCompatActivity() {
startActivity(mainIntent)
finish() // Finish the account selection activity
}
override fun onAuthenticationSuccess() {
//ask github.com/IndusAryan if confusion occurs
}
}

View file

@ -1,6 +1,8 @@
package com.lagradost.cloudstream3.utils
import android.app.Activity
import android.app.KeyguardManager
import android.content.Context
import android.os.Build
import android.util.Log
import android.widget.Toast
@ -25,8 +27,11 @@ object BiometricAuthenticator {
lateinit var promptInfo: BiometricPrompt.PromptInfo
const val TAG = "cs3Auth"
fun initializeBiometrics(activity: Activity) {
private var authCallback: BiometricAuthCallback? = null
fun initializeBiometrics(activity: Activity, callback: BiometricAuthCallback) {
val executor = ContextCompat.getMainExecutor(activity)
authCallback = callback // to listen success authentication
biometricManager = BiometricManager.from(activity)
biometricPrompt = BiometricPrompt(activity as AppCompatActivity, executor, object : BiometricPrompt.AuthenticationCallback() {
@ -40,6 +45,7 @@ object BiometricAuthenticator {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
Log.d(TAG, "Biometric succeeded.")
unblockMain() //to make background visible after authenticating
}
override fun onAuthenticationFailed() {
@ -50,19 +56,29 @@ object BiometricAuthenticator {
}
})
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("Unlock CloudStream")
//.setSubtitle("Log in using your biometric credential")
//.setNegativeButtonText("Use account password")
.setAllowedAuthenticators(BIOMETRIC_WEAK or BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
.build()
.setTitle("Unlock CloudStream")
//.setSubtitle("Log in using your biometric credential")
//.setNegativeButtonText("Use account password")
.setAllowedAuthenticators(BIOMETRIC_WEAK or BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
.build()
} else if (context?.let { deviceHasPasswordPinLock(it) } == true) {
@Suppress("DEPRECATION")
promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle("Unlock CloudStream")
.setDeviceCredentialAllowed(true)
.build()
}
}
fun checkBiometricAvailability() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// Strong and credential bundle cannot be checked at same time in API < A11 (R)
// Strong and device credential bundle cannot be checked at same time in API < A11 (R)
when (biometricManager.canAuthenticate(BIOMETRIC_WEAK or BIOMETRIC_STRONG or DEVICE_CREDENTIAL)) {
BiometricManager.BIOMETRIC_SUCCESS ->
Log.d(TAG, "App can authenticate.")
@ -74,10 +90,10 @@ object BiometricAuthenticator {
Log.d(TAG, "Biometric authentication is currently unavailable.")
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED ->
showToast(R.string.biometric_not_enrolled, Toast.LENGTH_SHORT)
showToast(R.string.biometric_not_enrolled, Toast.LENGTH_LONG)
BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED ->
showToast(R.string.biometric_update_required, Toast.LENGTH_SHORT)
showToast(R.string.biometric_update_required, Toast.LENGTH_LONG)
BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED ->
showToast(R.string.biometric_unsupported, Toast.LENGTH_SHORT)
@ -92,25 +108,25 @@ object BiometricAuthenticator {
when (biometricManager.canAuthenticate(BIOMETRIC_WEAK or BIOMETRIC_STRONG)) {
BiometricManager.BIOMETRIC_SUCCESS ->
Log.d(TAG, "App can authenticate using biometrics.")
Log.d(TAG, "App can authenticate using biometrics.")
BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE ->
Log.d(TAG, "No biometric features available on this device.")
Log.d(TAG, "No biometric features available on this device.")
BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE ->
Log.e(TAG, "Biometric features are currently unavailable.")
Log.e(TAG, "Biometric features are currently unavailable.")
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED ->
Log.e(TAG, "Biometric features are currently unavailable.")
showToast(R.string.biometric_not_enrolled, Toast.LENGTH_LONG)
BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED ->
showToast(R.string.biometric_update_required, Toast.LENGTH_SHORT)
showToast(R.string.biometric_update_required, Toast.LENGTH_LONG)
BiometricManager.BIOMETRIC_ERROR_UNSUPPORTED ->
showToast(R.string.biometric_unsupported, Toast.LENGTH_SHORT)
showToast(R.string.biometric_unsupported, Toast.LENGTH_SHORT)
BiometricManager.BIOMETRIC_STATUS_UNKNOWN ->
Log.d(TAG, "Unknown error encountered while authenticating fingerprint.")
Log.d(TAG, "Unknown error encountered while authenticating fingerprint.")
}
}
@ -120,4 +136,17 @@ object BiometricAuthenticator {
fun isTruePhone(): Boolean {
return !isTrueTvSettings() && !isTvSettings() && context?.isEmulatorSettings() != true
}
fun unblockMain() {
authCallback?.onAuthenticationSuccess()
}
private fun deviceHasPasswordPinLock(con: Context): Boolean {
val keyManager = con.getSystemService(AppCompatActivity.KEYGUARD_SERVICE) as KeyguardManager
return keyManager.isKeyguardSecure
}
interface BiometricAuthCallback {
fun onAuthenticationSuccess()
}
}

View file

@ -742,11 +742,11 @@
<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="biometric_setting">Use 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">No biometric credentials are enrolled</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>