-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathAppWidgetRefreshWorker.kt
More file actions
92 lines (80 loc) · 3.42 KB
/
AppWidgetRefreshWorker.kt
File metadata and controls
92 lines (80 loc) · 3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package to.bitkit.appwidget
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Context
import androidx.glance.appwidget.GlanceAppWidgetReceiver
import androidx.glance.appwidget.updateAll
import androidx.hilt.work.HiltWorker
import androidx.work.Constraints
import androidx.work.CoroutineWorker
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.NetworkType
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import to.bitkit.appwidget.model.AppWidgetType
import to.bitkit.appwidget.ui.price.PriceGlanceReceiver
import to.bitkit.appwidget.ui.price.PriceGlanceWidget
import to.bitkit.utils.Logger
import kotlin.time.Duration.Companion.minutes
import kotlin.time.toJavaDuration
@HiltWorker
class AppWidgetRefreshWorker @AssistedInject constructor(
@Assisted private val appContext: Context,
@Assisted workerParams: WorkerParameters,
private val dataRepository: AppWidgetDataRepository,
private val preferencesStore: AppWidgetPreferencesStore,
) : CoroutineWorker(appContext, workerParams) {
companion object {
private const val TAG = "AppWidgetRefreshWorker"
private const val WORK_NAME = "appwidget_refresh"
fun enqueue(context: Context) {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val request = PeriodicWorkRequestBuilder<AppWidgetRefreshWorker>(15.minutes.toJavaDuration())
.setConstraints(constraints)
.build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
WORK_NAME,
ExistingPeriodicWorkPolicy.KEEP,
request,
)
}
fun cancelIfNoWidgets(context: Context) {
val manager = AppWidgetManager.getInstance(context)
val hasAny = AppWidgetType.entries.any { type ->
manager.getAppWidgetIds(ComponentName(context, receiverClassFor(type))).isNotEmpty()
}
if (!hasAny) {
WorkManager.getInstance(context).cancelUniqueWork(WORK_NAME)
}
}
private fun receiverClassFor(type: AppWidgetType): Class<out GlanceAppWidgetReceiver> = when (type) {
AppWidgetType.PRICE -> PriceGlanceReceiver::class.java
}
}
override suspend fun doWork(): Result {
val activeTypes = preferencesStore.getActiveWidgetTypes()
if (activeTypes.isEmpty()) return Result.success()
Logger.debug("Refreshing data for widget types: '$activeTypes'", context = TAG)
for (type in activeTypes) {
when (type) {
AppWidgetType.PRICE -> {
val periods = preferencesStore.getActivePricePeriods()
periods.forEach { period ->
dataRepository.fetchPriceData(period)
.onSuccess { preferencesStore.cachePriceData(period, it) }
.onFailure {
Logger.warn("Failed to refresh price for '$period'", it, context = TAG)
}
}
PriceGlanceWidget().updateAll(appContext)
}
}
}
return Result.success()
}
}