Better notification timer implementation

This commit is contained in:
J-Jamet
2021-04-10 20:30:48 +02:00
parent 014b0cce14
commit b8890aca7f
5 changed files with 52 additions and 85 deletions

View File

@@ -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()
}

View File

@@ -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()
}

View File

@@ -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()

View File

@@ -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)

View File

@@ -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()