diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt
index d9c6694f..10f2badc 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/MainActivity.kt
@@ -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() {
diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/account/AccountSelectActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/account/AccountSelectActivity.kt
index 693f0c56..77bbc837 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/ui/account/AccountSelectActivity.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/ui/account/AccountSelectActivity.kt
@@ -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
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/BiometricAuthenticator.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/BiometricAuthenticator.kt
index 6c1f068d..2bc17891 100644
--- a/app/src/main/java/com/lagradost/cloudstream3/utils/BiometricAuthenticator.kt
+++ b/app/src/main/java/com/lagradost/cloudstream3/utils/BiometricAuthenticator.kt
@@ -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()
+ }
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index dc981408..56a78cf1 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -742,11 +742,11 @@
Enable automatic switching of screen orientation based on video orientation
Auto rotate
- Use Fingerprint sensor authentication
+ Fingerprint sensor authentication
Fingerprint authentication succeeded
Fingerprint authentication failed
Unlock CloudStream
- No biometric credentials are enrolled
+ Please add fingerprint or screen lock or disable setting
Please update software and security patches.
Biometric authentication is not supported on this device
biometric_key