mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Add advanced unlock timeout
This commit is contained in:
@@ -35,6 +35,7 @@ import androidx.biometric.BiometricPrompt
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.app.database.CipherDatabaseAction
|
||||
import com.kunzisoft.keepass.notifications.AdvancedUnlockNotificationService
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.view.AdvancedUnlockInfoView
|
||||
|
||||
@@ -190,6 +191,7 @@ class AdvancedUnlockedManager(var context: FragmentActivity,
|
||||
Mode.STORE_CREDENTIAL -> {
|
||||
// newly store the entered password in encrypted way
|
||||
biometricUnlockDatabaseHelper?.encryptData(passwordView?.text.toString())
|
||||
AdvancedUnlockNotificationService.startServiceForTimeout(context)
|
||||
}
|
||||
Mode.EXTRACT_CREDENTIAL -> {
|
||||
// retrieve the encrypted value from preferences
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package com.kunzisoft.keepass.notifications
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Binder
|
||||
import android.os.IBinder
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.app.database.CipherDatabaseEntity
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.timeout.TimeoutHelper
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
class AdvancedUnlockNotificationService : NotificationService() {
|
||||
|
||||
@@ -14,6 +18,9 @@ class AdvancedUnlockNotificationService : NotificationService() {
|
||||
|
||||
private var mActionTaskBinder = AdvancedUnlockBinder()
|
||||
|
||||
private var notificationTimeoutMilliSecs: Long = 0
|
||||
private var mTimerJob: Job? = null
|
||||
|
||||
inner class AdvancedUnlockBinder: Binder() {
|
||||
fun getCipherDatabase(databaseUri: Uri): CipherDatabaseEntity? {
|
||||
return mTempCipherDao.firstOrNull { it.databaseUri == databaseUri.toString()}
|
||||
@@ -51,8 +58,13 @@ class AdvancedUnlockNotificationService : NotificationService() {
|
||||
action = ACTION_REMOVE_KEYS
|
||||
}
|
||||
val pendingDeleteIntent = PendingIntent.getService(this, 0, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
val deviceCredential = PreferencesUtil.isDeviceCredentialUnlockEnable(this)
|
||||
val notificationBuilder = buildNewNotification().apply {
|
||||
setSmallIcon(R.drawable.bolt)
|
||||
setSmallIcon(if (deviceCredential) {
|
||||
R.drawable.bolt
|
||||
} else {
|
||||
R.drawable.fingerprint
|
||||
})
|
||||
intent?.let {
|
||||
setContentTitle(getString(R.string.advanced_unlock))
|
||||
}
|
||||
@@ -61,12 +73,35 @@ class AdvancedUnlockNotificationService : NotificationService() {
|
||||
// Unfortunately swipe is disabled in lollipop+
|
||||
setDeleteIntent(pendingDeleteIntent)
|
||||
}
|
||||
// Not necessarily a foreground service
|
||||
startForeground(notificationId, notificationBuilder.build())
|
||||
//notificationManager?.notify(notificationId, notificationBuilder.build())
|
||||
|
||||
if (intent?.action == ACTION_REMOVE_KEYS) {
|
||||
stopSelf()
|
||||
when (intent?.action) {
|
||||
ACTION_TIMEOUT -> {
|
||||
notificationTimeoutMilliSecs = PreferencesUtil.getAdvancedUnlockTimeout(this)
|
||||
// Not necessarily a foreground service
|
||||
if (mTimerJob == null && notificationTimeoutMilliSecs != TimeoutHelper.NEVER) {
|
||||
mTimerJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
val maxPos = 100
|
||||
val posDurationMills = notificationTimeoutMilliSecs / maxPos
|
||||
for (pos in maxPos downTo 0) {
|
||||
notificationBuilder.setProgress(maxPos, pos, false)
|
||||
startForeground(notificationId, notificationBuilder.build())
|
||||
delay(posDurationMills)
|
||||
if (pos <= 0) {
|
||||
stopSelf()
|
||||
}
|
||||
}
|
||||
notificationManager?.cancel(notificationId)
|
||||
mTimerJob = null
|
||||
cancel()
|
||||
}
|
||||
} else {
|
||||
startForeground(notificationId, notificationBuilder.build())
|
||||
}
|
||||
}
|
||||
ACTION_REMOVE_KEYS -> {
|
||||
stopSelf()
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
|
||||
return START_STICKY
|
||||
@@ -79,12 +114,20 @@ class AdvancedUnlockNotificationService : NotificationService() {
|
||||
|
||||
override fun onDestroy() {
|
||||
mTempCipherDao.clear()
|
||||
mTimerJob?.cancel()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val CHANNEL_ADVANCED_UNLOCK_ID = "com.kunzisoft.keepass.notification.channel.unlock"
|
||||
|
||||
const val ACTION_REMOVE_KEYS = "ACTION_REMOVE_KEYS"
|
||||
private const val ACTION_TIMEOUT = "ACTION_TIMEOUT"
|
||||
private const val ACTION_REMOVE_KEYS = "ACTION_REMOVE_KEYS"
|
||||
|
||||
fun startServiceForTimeout(context: Context) {
|
||||
context.startService(Intent(context, AdvancedUnlockNotificationService::class.java).apply {
|
||||
action = ACTION_TIMEOUT
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,7 +101,7 @@
|
||||
<string name="temp_advanced_unlock_enable_key" translatable="false">temp_advanced_unlock_enable_key</string>
|
||||
<bool name="temp_advanced_unlock_enable_default" translatable="false">false</bool>
|
||||
<string name="temp_advanced_unlock_timeout_key" translatable="false">temp_advanced_unlock_timeout_key</string>
|
||||
<string name="temp_advanced_unlock_timeout_default" translatable="false">30000</string>
|
||||
<string name="temp_advanced_unlock_timeout_default" translatable="false">36000000</string>
|
||||
<string name="biometric_delete_all_key_key" translatable="false">biometric_delete_all_key_key</string>
|
||||
|
||||
<!-- Form Filling Settings -->
|
||||
@@ -291,6 +291,20 @@
|
||||
<item translatable="false">1800000</item>
|
||||
<item translatable="false">-1</item>
|
||||
</string-array>
|
||||
<string-array name="large_timeout_values">
|
||||
<item translatable="false">300000</item>
|
||||
<item translatable="false">900000</item>
|
||||
<item translatable="false">1800000</item>
|
||||
<item translatable="false">3600000</item>
|
||||
<item translatable="false">7200000</item>
|
||||
<item translatable="false">18000000</item>
|
||||
<item translatable="false">36000000</item>
|
||||
<item translatable="false">86400000</item>
|
||||
<item translatable="false">172800000</item>
|
||||
<item translatable="false">604800000</item>
|
||||
<item translatable="false">2592000000</item>
|
||||
<item translatable="false">-1</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Text Size -->
|
||||
<dimen name="list_icon_size_default" translatable="false">32dp</dimen>
|
||||
|
||||
@@ -521,6 +521,20 @@
|
||||
<item>30 minutes</item>
|
||||
<item>Never</item>
|
||||
</string-array>
|
||||
<string-array name="large_timeout_options">
|
||||
<item>5 minutes</item>
|
||||
<item>15 minutes</item>
|
||||
<item>30 minutes</item>
|
||||
<item>1 hour</item>
|
||||
<item>2 hours</item>
|
||||
<item>5 hours</item>
|
||||
<item>10 hours</item>
|
||||
<item>24 hours</item>
|
||||
<item>48 hours</item>
|
||||
<item>1 week</item>
|
||||
<item>1 month</item>
|
||||
<item>Never</item>
|
||||
</string-array>
|
||||
<string-array name="list_size_options">
|
||||
<item>Small</item>
|
||||
<item>Medium</item>
|
||||
|
||||
@@ -52,8 +52,8 @@
|
||||
android:title="@string/temp_advanced_unlock_timeout_title"
|
||||
android:summary="@string/temp_advanced_unlock_timeout_summary"
|
||||
android:dependency="@string/temp_advanced_unlock_enable_key"
|
||||
android:entries="@array/timeout_options"
|
||||
android:entryValues="@array/timeout_values"
|
||||
android:entries="@array/large_timeout_options"
|
||||
android:entryValues="@array/large_timeout_values"
|
||||
android:dialogTitle="@string/advanced_unlock_timeout"
|
||||
android:defaultValue="@string/temp_advanced_unlock_timeout_default"/>
|
||||
<Preference
|
||||
|
||||
Reference in New Issue
Block a user