67 lines
2.4 KiB
Kotlin
67 lines
2.4 KiB
Kotlin
package co.electriccoin.zcash.work
|
|
|
|
import android.content.Context
|
|
import androidx.annotation.Keep
|
|
import androidx.work.Constraints
|
|
import androidx.work.CoroutineWorker
|
|
import androidx.work.NetworkType
|
|
import androidx.work.PeriodicWorkRequest
|
|
import androidx.work.PeriodicWorkRequestBuilder
|
|
import androidx.work.WorkerParameters
|
|
import cash.z.ecc.android.sdk.Synchronizer
|
|
import cash.z.ecc.android.sdk.WalletCoordinator
|
|
import co.electriccoin.zcash.global.getInstance
|
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
import kotlinx.coroutines.flow.collect
|
|
import kotlinx.coroutines.flow.combine
|
|
import kotlinx.coroutines.flow.emptyFlow
|
|
import kotlinx.coroutines.flow.flatMapLatest
|
|
import kotlinx.coroutines.flow.takeWhile
|
|
import kotlin.time.Duration.Companion.hours
|
|
import kotlin.time.toJavaDuration
|
|
|
|
@Keep
|
|
class SyncWorker(context: Context, workerParameters: WorkerParameters) : CoroutineWorker(context, workerParameters) {
|
|
@OptIn(ExperimentalCoroutinesApi::class)
|
|
override suspend fun doWork(): Result {
|
|
// Enhancements to this implementation would be:
|
|
// - Quit early if the synchronizer is null after a timeout period
|
|
// - Return better status information
|
|
|
|
WalletCoordinator.getInstance(applicationContext).synchronizer
|
|
.flatMapLatest {
|
|
it?.status?.combine(it.progress) { status, progress ->
|
|
StatusAndProgress(status, progress)
|
|
} ?: emptyFlow()
|
|
}
|
|
.takeWhile {
|
|
it.status != Synchronizer.Status.DISCONNECTED && it.progress < ONE_HUNDRED_PERCENT
|
|
}
|
|
.collect()
|
|
|
|
return Result.success()
|
|
}
|
|
|
|
companion object {
|
|
private const val ONE_HUNDRED_PERCENT = 100
|
|
|
|
/*
|
|
* There may be better periods; we have not optimized for this yet.
|
|
*/
|
|
private val DEFAULT_SYNC_PERIOD = 24.hours
|
|
|
|
fun newWorkRequest(): PeriodicWorkRequest {
|
|
val constraints = Constraints.Builder()
|
|
.setRequiresStorageNotLow(true)
|
|
.setRequiredNetworkType(NetworkType.CONNECTED)
|
|
.build()
|
|
|
|
return PeriodicWorkRequestBuilder<SyncWorker>(DEFAULT_SYNC_PERIOD.toJavaDuration())
|
|
.setConstraints(constraints)
|
|
.build()
|
|
}
|
|
}
|
|
}
|
|
|
|
private data class StatusAndProgress(val status: Synchronizer.Status, val progress: Int)
|