mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
hide background while authenticating & other improvements
This commit is contained in:
parent
15d75e5194
commit
5bc9b413d5
4 changed files with 63 additions and 24 deletions
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue