mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Better notification timer implementation
This commit is contained in:
@@ -10,7 +10,6 @@ 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() {
|
||||
|
||||
@@ -18,9 +17,6 @@ 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()}
|
||||
@@ -80,23 +76,11 @@ class AdvancedUnlockNotificationService : NotificationService() {
|
||||
|
||||
when (intent?.action) {
|
||||
ACTION_TIMEOUT -> {
|
||||
notificationTimeoutMilliSecs = PreferencesUtil.getAdvancedUnlockTimeout(this)
|
||||
val 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()
|
||||
defineTimerJob(notificationBuilder, notificationTimeoutMilliSecs) {
|
||||
stopSelf()
|
||||
}
|
||||
} else {
|
||||
startForeground(notificationId, notificationBuilder.build())
|
||||
@@ -118,7 +102,6 @@ class AdvancedUnlockNotificationService : NotificationService() {
|
||||
|
||||
override fun onDestroy() {
|
||||
mTempCipherDao.clear()
|
||||
mTimerJob?.cancel()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
|
||||
@@ -37,8 +37,7 @@ class ClipboardEntryNotificationService : LockNotificationService() {
|
||||
override val notificationId = 485
|
||||
private var mEntryInfo: EntryInfo? = null
|
||||
private var clipboardHelper: ClipboardHelper? = null
|
||||
private var notificationTimeoutMilliSecs: Long = 0
|
||||
private var cleanCopyNotificationTimerTask: Thread? = null
|
||||
private var mNotificationTimeoutMilliSecs: Long = 0
|
||||
|
||||
override fun retrieveChannelId(): String {
|
||||
return CHANNEL_CLIPBOARD_ID
|
||||
@@ -70,7 +69,7 @@ class ClipboardEntryNotificationService : LockNotificationService() {
|
||||
mEntryInfo = intent?.getParcelableExtra(EXTRA_ENTRY_INFO)
|
||||
|
||||
//Get settings
|
||||
notificationTimeoutMilliSecs = PreferencesUtil.getClipboardTimeout(this)
|
||||
mNotificationTimeoutMilliSecs = PreferencesUtil.getClipboardTimeout(this)
|
||||
|
||||
when {
|
||||
intent == null -> Log.w(TAG, "null intent")
|
||||
@@ -78,7 +77,7 @@ class ClipboardEntryNotificationService : LockNotificationService() {
|
||||
newNotification(mEntryInfo?.title, constructListOfField(intent))
|
||||
}
|
||||
ACTION_CLEAN_CLIPBOARD == intent.action -> {
|
||||
stopTask(cleanCopyNotificationTimerTask)
|
||||
mTimerJob?.cancel()
|
||||
cleanClipboard()
|
||||
stopNotificationAndSendLockIfNeeded()
|
||||
}
|
||||
@@ -121,7 +120,7 @@ class ClipboardEntryNotificationService : LockNotificationService() {
|
||||
}
|
||||
|
||||
private fun newNotification(title: String?, fieldsToAdd: ArrayList<ClipboardEntryNotificationField>) {
|
||||
stopTask(cleanCopyNotificationTimerTask)
|
||||
mTimerJob?.cancel()
|
||||
|
||||
val builder = buildNewNotification()
|
||||
.setSmallIcon(R.drawable.notification_ic_clipboard_key_24dp)
|
||||
@@ -147,7 +146,7 @@ class ClipboardEntryNotificationService : LockNotificationService() {
|
||||
}
|
||||
|
||||
private fun copyField(fieldToCopy: ClipboardEntryNotificationField, nextFields: ArrayList<ClipboardEntryNotificationField>) {
|
||||
stopTask(cleanCopyNotificationTimerTask)
|
||||
mTimerJob?.cancel()
|
||||
|
||||
try {
|
||||
var generatedValue = fieldToCopy.getGeneratedValue(mEntryInfo)
|
||||
@@ -170,40 +169,23 @@ class ClipboardEntryNotificationService : LockNotificationService() {
|
||||
this, 0, cleanIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||
builder.setDeleteIntent(cleanPendingIntent)
|
||||
|
||||
val myNotificationId = notificationId
|
||||
|
||||
if (notificationTimeoutMilliSecs != NEVER) {
|
||||
cleanCopyNotificationTimerTask = Thread {
|
||||
val maxPos = 100
|
||||
val posDurationMills = notificationTimeoutMilliSecs / maxPos
|
||||
for (pos in maxPos downTo 0) {
|
||||
val newGeneratedValue = fieldToCopy.getGeneratedValue(mEntryInfo)
|
||||
// New auto generated value
|
||||
if (generatedValue != newGeneratedValue) {
|
||||
generatedValue = newGeneratedValue
|
||||
clipboardHelper?.copyToClipboard(fieldToCopy.label, generatedValue)
|
||||
}
|
||||
builder.setProgress(maxPos, pos, false)
|
||||
notificationManager?.notify(myNotificationId, builder.build())
|
||||
try {
|
||||
Thread.sleep(posDurationMills)
|
||||
} catch (e: InterruptedException) {
|
||||
break
|
||||
}
|
||||
if (pos <= 0) {
|
||||
stopNotificationAndSendLockIfNeeded()
|
||||
}
|
||||
if (mNotificationTimeoutMilliSecs != NEVER) {
|
||||
defineTimerJob(builder, mNotificationTimeoutMilliSecs, {
|
||||
val newGeneratedValue = fieldToCopy.getGeneratedValue(mEntryInfo)
|
||||
// New auto generated value
|
||||
if (generatedValue != newGeneratedValue) {
|
||||
generatedValue = newGeneratedValue
|
||||
clipboardHelper?.copyToClipboard(fieldToCopy.label, generatedValue)
|
||||
}
|
||||
stopTask(cleanCopyNotificationTimerTask)
|
||||
notificationManager?.cancel(myNotificationId)
|
||||
}) {
|
||||
stopNotificationAndSendLockIfNeeded()
|
||||
// Clean password only if no next field
|
||||
if (nextFields.size <= 0)
|
||||
cleanClipboard()
|
||||
}
|
||||
cleanCopyNotificationTimerTask?.start()
|
||||
} else {
|
||||
// No timer
|
||||
notificationManager?.notify(myNotificationId, builder.build())
|
||||
notificationManager?.notify(notificationId, builder.build())
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
@@ -228,10 +210,6 @@ class ClipboardEntryNotificationService : LockNotificationService() {
|
||||
|
||||
override fun onDestroy() {
|
||||
cleanClipboard()
|
||||
|
||||
stopTask(cleanCopyNotificationTimerTask)
|
||||
cleanCopyNotificationTimerTask = null
|
||||
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
|
||||
@@ -35,8 +35,7 @@ import com.kunzisoft.keepass.utils.LOCK_ACTION
|
||||
class KeyboardEntryNotificationService : LockNotificationService() {
|
||||
|
||||
override val notificationId = 486
|
||||
private var cleanNotificationTimerTask: Thread? = null
|
||||
private var notificationTimeoutMilliSecs: Long = 0
|
||||
private var mNotificationTimeoutMilliSecs: Long = 0
|
||||
|
||||
private var pendingDeleteIntent: PendingIntent? = null
|
||||
|
||||
@@ -61,7 +60,7 @@ class KeyboardEntryNotificationService : LockNotificationService() {
|
||||
super.onStartCommand(intent, flags, startId)
|
||||
|
||||
//Get settings
|
||||
notificationTimeoutMilliSecs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
mNotificationTimeoutMilliSecs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
.getString(getString(R.string.keyboard_entry_timeout_key),
|
||||
getString(R.string.timeout_default))?.toLong() ?: TimeoutHelper.DEFAULT_TIMEOUT
|
||||
|
||||
@@ -107,27 +106,12 @@ class KeyboardEntryNotificationService : LockNotificationService() {
|
||||
notificationManager?.cancel(notificationId)
|
||||
notificationManager?.notify(notificationId, builder.build())
|
||||
|
||||
stopTask(cleanNotificationTimerTask)
|
||||
// Timeout only if notification clear is available
|
||||
if (PreferencesUtil.isClearKeyboardNotificationEnable(this)) {
|
||||
if (notificationTimeoutMilliSecs != TimeoutHelper.NEVER) {
|
||||
cleanNotificationTimerTask = Thread {
|
||||
val maxPos = 100
|
||||
val posDurationMills = notificationTimeoutMilliSecs / maxPos
|
||||
for (pos in maxPos downTo 0) {
|
||||
builder.setProgress(maxPos, pos, false)
|
||||
notificationManager?.notify(notificationId, builder.build())
|
||||
try {
|
||||
Thread.sleep(posDurationMills)
|
||||
} catch (e: InterruptedException) {
|
||||
break
|
||||
}
|
||||
if (pos <= 0) {
|
||||
stopNotificationAndSendLockIfNeeded()
|
||||
}
|
||||
}
|
||||
if (mNotificationTimeoutMilliSecs != TimeoutHelper.NEVER) {
|
||||
defineTimerJob(builder, mNotificationTimeoutMilliSecs) {
|
||||
stopNotificationAndSendLockIfNeeded()
|
||||
}
|
||||
cleanNotificationTimerTask?.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -142,8 +126,6 @@ class KeyboardEntryNotificationService : LockNotificationService() {
|
||||
// Remove the entry from the keyboard
|
||||
MagikIME.removeEntry(this)
|
||||
|
||||
stopTask(cleanNotificationTimerTask)
|
||||
cleanNotificationTimerTask = null
|
||||
pendingDeleteIntent?.cancel()
|
||||
|
||||
super.onDestroy()
|
||||
|
||||
@@ -50,11 +50,6 @@ abstract class LockNotificationService : NotificationService() {
|
||||
return super.onStartCommand(intent, flags, startId)
|
||||
}
|
||||
|
||||
protected fun stopTask(task: Thread?) {
|
||||
if (task != null && task.isAlive)
|
||||
task.interrupt()
|
||||
}
|
||||
|
||||
override fun onTaskRemoved(rootIntent: Intent?) {
|
||||
notificationManager?.cancel(notificationId)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.stylish.Stylish
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
|
||||
abstract class NotificationService : Service() {
|
||||
@@ -18,6 +19,8 @@ abstract class NotificationService : Service() {
|
||||
protected var notificationManager: NotificationManagerCompat? = null
|
||||
private var colorNotificationAccent: Int = 0
|
||||
|
||||
protected var mTimerJob: Job? = null
|
||||
|
||||
protected abstract val notificationId: Int
|
||||
|
||||
override fun onBind(intent: Intent): IBinder? {
|
||||
@@ -71,7 +74,33 @@ abstract class NotificationService : Service() {
|
||||
}
|
||||
}
|
||||
|
||||
protected fun defineTimerJob(builder: NotificationCompat.Builder,
|
||||
timeoutMilliseconds: Long,
|
||||
actionAfterASecond: (() -> Unit)? = null,
|
||||
actionEnd: () -> Unit) {
|
||||
mTimerJob?.cancel()
|
||||
mTimerJob = CoroutineScope(Dispatchers.Main).launch {
|
||||
val timeoutInSeconds = timeoutMilliseconds / 1000L
|
||||
for (currentTime in timeoutInSeconds downTo 0) {
|
||||
actionAfterASecond?.invoke()
|
||||
builder.setProgress(100,
|
||||
(currentTime * 100 / timeoutInSeconds).toInt(),
|
||||
false)
|
||||
startForeground(notificationId, builder.build())
|
||||
delay(1000)
|
||||
if (currentTime <= 0) {
|
||||
actionEnd()
|
||||
}
|
||||
}
|
||||
notificationManager?.cancel(notificationId)
|
||||
mTimerJob = null
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
mTimerJob?.cancel()
|
||||
mTimerJob = null
|
||||
notificationManager?.cancel(notificationId)
|
||||
|
||||
super.onDestroy()
|
||||
|
||||
Reference in New Issue
Block a user