Merge pull request #5340 from k9mail/imap_folder_pusher
Add ImapFolderPusher to listen for changes to an IMAP folder
This commit is contained in:
commit
154dbe1229
3 changed files with 119 additions and 0 deletions
|
@ -0,0 +1,85 @@
|
|||
package com.fsck.k9.backend.imap
|
||||
|
||||
import com.fsck.k9.mail.power.PowerManager
|
||||
import com.fsck.k9.mail.store.imap.IdleRefreshManager
|
||||
import com.fsck.k9.mail.store.imap.IdleResult
|
||||
import com.fsck.k9.mail.store.imap.ImapFolderIdler
|
||||
import com.fsck.k9.mail.store.imap.ImapStore
|
||||
import kotlin.concurrent.thread
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Listens for changes to an IMAP folder in a dedicated thread.
|
||||
*/
|
||||
class ImapFolderPusher(
|
||||
private val imapStore: ImapStore,
|
||||
private val powerManager: PowerManager,
|
||||
private val idleRefreshManager: IdleRefreshManager,
|
||||
private val callback: ImapPusherCallback,
|
||||
private val accountName: String,
|
||||
private val folderServerId: String,
|
||||
private val idleRefreshTimeoutMs: Long
|
||||
) {
|
||||
@Volatile
|
||||
private var folderIdler: ImapFolderIdler? = null
|
||||
|
||||
@Volatile
|
||||
private var stopPushing = false
|
||||
|
||||
fun start() {
|
||||
Timber.v("Starting ImapFolderPusher for %s / %s", accountName, folderServerId)
|
||||
|
||||
thread(name = "ImapFolderPusher-$accountName-$folderServerId") {
|
||||
Timber.v("Starting ImapFolderPusher thread for %s / %s", accountName, folderServerId)
|
||||
|
||||
runPushLoop()
|
||||
|
||||
Timber.v("Exiting ImapFolderPusher thread for %s / %s", accountName, folderServerId)
|
||||
}
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
Timber.v("Stopping ImapFolderPusher for %s / %s", accountName, folderServerId)
|
||||
|
||||
stopPushing = true
|
||||
folderIdler?.stop()
|
||||
}
|
||||
|
||||
private fun runPushLoop() {
|
||||
val wakeLock = powerManager.newWakeLock("ImapFolderPusher-$accountName-$folderServerId")
|
||||
wakeLock.acquire()
|
||||
|
||||
performInitialSync()
|
||||
|
||||
val folderIdler = ImapFolderIdler.create(
|
||||
idleRefreshManager,
|
||||
wakeLock,
|
||||
imapStore,
|
||||
folderServerId,
|
||||
idleRefreshTimeoutMs
|
||||
).also {
|
||||
folderIdler = it
|
||||
}
|
||||
|
||||
try {
|
||||
while (!stopPushing) {
|
||||
val idleResult = folderIdler.idle()
|
||||
|
||||
if (idleResult == IdleResult.SYNC) {
|
||||
callback.onPushEvent(folderServerId)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.v(e, "Exception in ImapFolderPusher")
|
||||
|
||||
this.folderIdler = null
|
||||
callback.onPushError(folderServerId, e)
|
||||
}
|
||||
|
||||
wakeLock.release()
|
||||
}
|
||||
|
||||
private fun performInitialSync() {
|
||||
callback.onPushEvent(folderServerId)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package com.fsck.k9.backend.imap
|
||||
|
||||
interface ImapPusherCallback {
|
||||
fun onPushEvent(folderServerId: String)
|
||||
fun onPushError(folderServerId: String, exception: Exception)
|
||||
}
|
|
@ -1,9 +1,37 @@
|
|||
package com.fsck.k9.mail.store.imap
|
||||
|
||||
import com.fsck.k9.mail.power.WakeLock
|
||||
|
||||
interface ImapFolderIdler {
|
||||
fun idle(): IdleResult
|
||||
|
||||
fun stop()
|
||||
|
||||
companion object {
|
||||
private val connectionProvider = object : ImapConnectionProvider {
|
||||
override fun getConnection(folder: ImapFolder): ImapConnection? {
|
||||
require(folder is RealImapFolder)
|
||||
return folder.connection
|
||||
}
|
||||
}
|
||||
|
||||
fun create(
|
||||
idleRefreshManager: IdleRefreshManager,
|
||||
wakeLock: WakeLock,
|
||||
imapStore: ImapStore,
|
||||
folderServerId: String,
|
||||
idleRefreshTimeoutMs: Long
|
||||
): ImapFolderIdler {
|
||||
return RealImapFolderIdler(
|
||||
idleRefreshManager,
|
||||
wakeLock,
|
||||
imapStore,
|
||||
connectionProvider,
|
||||
folderServerId,
|
||||
idleRefreshTimeoutMs
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class IdleResult {
|
||||
|
|
Loading…
Reference in a new issue