Privacy-Period-Tracker/app/src/main/kotlin/dev/privacyllc/period/notifications/ClockChangeReceiver.kt

54 lines
2.2 KiB
Kotlin

package dev.privacyllc.period.notifications
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.EntryPointAccessors
import dagger.hilt.components.SingletonComponent
/**
* The clock or the time zone moved; re-aim the reminder.
*
* The delay to the next reminder is computed once, when it is scheduled, from
* the zone in force at that moment. Nothing recomputed it afterwards, so flying
* to another continent left the reminder arriving at the old wall-clock time
* indefinitely — and a manual clock change did the same.
*
* **Boot is deliberately not handled here.** WorkManager persists the periodic
* request and its own `RescheduleReceiver` restores it after a reboot; that
* receiver's manifest entry declares `BOOT_COMPLETED` and nothing else, which is
* exactly why the two broadcasts below need an entry of their own. A second boot
* receiver would duplicate work already done, and the coordinator's schedule at
* process start re-anchors any drift anyway.
*
* Unexported, like WorkManager's own: these are system broadcasts, and nothing
* else has any business sending them to this app.
*
* Reached through an entry point rather than `@AndroidEntryPoint`. The annotation
* generates a base class whose `onReceive` performs the injection and which the
* subclass must call through `super` — and `BroadcastReceiver.onReceive` is
* abstract, so that call resolves against the wrong class whenever the generated
* one is not yet on the compile path. An accessor has no such ordering.
*/
class ClockChangeReceiver : BroadcastReceiver() {
@EntryPoint
@InstallIn(SingletonComponent::class)
interface Dependencies {
fun reminderCoordinator(): ReminderCoordinator
}
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
Intent.ACTION_TIMEZONE_CHANGED, Intent.ACTION_TIME_CHANGED -> {
EntryPointAccessors
.fromApplication(context.applicationContext, Dependencies::class.java)
.reminderCoordinator()
.clockChanged()
}
}
}
}