diff --git a/app/src/main/java/com/kunzisoft/keepass/biometric/DeviceUnlockCryptoPrompt.kt b/app/src/main/java/com/kunzisoft/keepass/biometric/DeviceUnlockCryptoPrompt.kt index ca5be5bc7..b154dce8d 100644 --- a/app/src/main/java/com/kunzisoft/keepass/biometric/DeviceUnlockCryptoPrompt.kt +++ b/app/src/main/java/com/kunzisoft/keepass/biometric/DeviceUnlockCryptoPrompt.kt @@ -10,7 +10,11 @@ data class DeviceUnlockCryptoPrompt( @StringRes var descriptionId: Int? = null, var isDeviceCredentialOperation: Boolean, var isBiometricOperation: Boolean -) +) { + fun isOldCredentialOperation(): Boolean { + return !isBiometricOperation && isDeviceCredentialOperation + } +} enum class DeviceUnlockCryptoPromptType { CREDENTIAL_ENCRYPTION, CREDENTIAL_DECRYPTION diff --git a/app/src/main/java/com/kunzisoft/keepass/services/DatabaseTaskNotificationService.kt b/app/src/main/java/com/kunzisoft/keepass/services/DatabaseTaskNotificationService.kt index ead63ff14..9d6c0baf3 100644 --- a/app/src/main/java/com/kunzisoft/keepass/services/DatabaseTaskNotificationService.kt +++ b/app/src/main/java/com/kunzisoft/keepass/services/DatabaseTaskNotificationService.kt @@ -31,7 +31,6 @@ import androidx.annotation.StringRes import androidx.media.app.NotificationCompat import com.kunzisoft.keepass.R import com.kunzisoft.keepass.activities.GroupActivity -import com.kunzisoft.keepass.app.AppLifecycleObserver import com.kunzisoft.keepass.app.database.CipherDatabaseAction import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction import com.kunzisoft.keepass.database.ContextualDatabase @@ -626,16 +625,6 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress intent?.removeExtra(NEW_ELEMENT_KEY) } - override fun onCreate() { - super.onCreate() - AppLifecycleObserver.lockBackgroundEvent = true - } - - override fun onDestroy() { - super.onDestroy() - AppLifecycleObserver.lockBackgroundEvent = false - } - /** * Execute action with a coroutine */ diff --git a/app/src/main/java/com/kunzisoft/keepass/services/LockNotificationService.kt b/app/src/main/java/com/kunzisoft/keepass/services/LockNotificationService.kt index 5118fc203..10372dce0 100644 --- a/app/src/main/java/com/kunzisoft/keepass/services/LockNotificationService.kt +++ b/app/src/main/java/com/kunzisoft/keepass/services/LockNotificationService.kt @@ -21,6 +21,7 @@ package com.kunzisoft.keepass.services import android.content.Intent import androidx.core.app.ServiceCompat +import com.kunzisoft.keepass.app.AppLifecycleObserver import com.kunzisoft.keepass.timeout.TimeoutHelper import com.kunzisoft.keepass.utils.LockReceiver import com.kunzisoft.keepass.utils.registerLockReceiver @@ -35,6 +36,7 @@ abstract class LockNotificationService : NotificationService() { protected open fun actionOnLock() { // Stop the service in all cases ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE) + AppLifecycleObserver.lockBackgroundEvent = false stopSelf() } diff --git a/app/src/main/java/com/kunzisoft/keepass/viewmodels/DeviceUnlockViewModel.kt b/app/src/main/java/com/kunzisoft/keepass/viewmodels/DeviceUnlockViewModel.kt index b0f2d2a98..ff4046b13 100644 --- a/app/src/main/java/com/kunzisoft/keepass/viewmodels/DeviceUnlockViewModel.kt +++ b/app/src/main/java/com/kunzisoft/keepass/viewmodels/DeviceUnlockViewModel.kt @@ -161,19 +161,28 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat checkUnlockAvailability(databaseUri) } - fun disconnect() { + private fun showPendingIfNecessary() { + // Reassign prompt state to open again if necessary + if (cryptoPrompt?.isOldCredentialOperation() != true + && uiState.value.cryptoPromptState == DeviceUnlockPromptMode.IDLE_SHOW) { + cryptoPromptShowPending = true + } + } + + private fun disconnectDatabase() { this.databaseUri = null cipherDatabaseListener?.let { cipherDatabaseAction.unregisterDatabaseListener(it) } - // Reassign prompt state to open again if necessary - if (uiState.value.cryptoPromptState == DeviceUnlockPromptMode.IDLE_SHOW) { - cryptoPromptShowPending = true - } clear() changeMode(DeviceUnlockMode.BIOMETRIC_UNAVAILABLE) } + fun disconnect() { + showPendingIfNecessary() + disconnectDatabase() + } + fun databaseFileLoaded(databaseUri: Uri?) { // To get device credential unlock result, only if same database uri if (databaseUri != null @@ -182,7 +191,7 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat connect(databaseUri) } } else { - disconnect() + disconnectDatabase() } } @@ -319,11 +328,14 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat autoOpen: Boolean = false ) { this@DeviceUnlockViewModel.cryptoPrompt = cryptoPrompt - if (autoOpen && PreferencesUtil.isAdvancedUnlockPromptAutoOpenEnable(getApplication())) + if (cryptoPromptShowPending + || (autoOpen && PreferencesUtil.isAdvancedUnlockPromptAutoOpenEnable(getApplication()))) showPrompt() } fun showPrompt() { + AppLifecycleObserver.lockBackgroundEvent = true + isAutoOpenBiometricPromptAllowed = false cryptoPromptShowPending = false _uiState.update { currentState -> currentState.copy( @@ -333,7 +345,6 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat } fun promptShown() { - isAutoOpenBiometricPromptAllowed = false _uiState.update { currentState -> currentState.copy( cryptoPromptState = DeviceUnlockPromptMode.IDLE_SHOW @@ -378,7 +389,6 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat onPromptRequested( cryptoPrompt, autoOpen = isAutoOpenBiometricPromptAllowed - || cryptoPromptShowPending ) } ?: setException(Exception("AdvancedUnlockManager not initialized")) } catch (e: Exception) { @@ -420,7 +430,7 @@ class DeviceUnlockViewModel(application: Application): AndroidViewModel(applicat } fun clear(checkOperation: Boolean = false) { - if (!checkOperation || cryptoPrompt?.isDeviceCredentialOperation != true) { + if (!checkOperation || cryptoPrompt?.isOldCredentialOperation() != true) { cryptoPrompt = null deviceUnlockManager = null }