diff --git a/core/data/src/androidMain/kotlin/zed/rainxch/core/data/services/BootReceiver.kt b/core/data/src/androidMain/kotlin/zed/rainxch/core/data/services/BootReceiver.kt index c8f5d5de..e5e36537 100644 --- a/core/data/src/androidMain/kotlin/zed/rainxch/core/data/services/BootReceiver.kt +++ b/core/data/src/androidMain/kotlin/zed/rainxch/core/data/services/BootReceiver.kt @@ -34,6 +34,13 @@ class BootReceiver : BroadcastReceiver() { Logger.i { "BootReceiver: Device booted, update check disabled — skipping" } UpdateScheduler.cancel(context) } + } catch (t: Throwable) { + // Don't let scheduling failures crash the framework's + // broadcast pipeline — propagation triggers a second + // `sendFinished` from the platform after our own + // `pendingResult.finish()` and surfaces as + // `IllegalStateException: Broadcast already finished`. + Logger.e(t) { "BootReceiver: scheduling failed; dropped" } } finally { pendingResult.finish() } diff --git a/core/data/src/androidMain/kotlin/zed/rainxch/core/data/services/UpdateScheduler.kt b/core/data/src/androidMain/kotlin/zed/rainxch/core/data/services/UpdateScheduler.kt index 9978f6ae..a80f4c8f 100644 --- a/core/data/src/androidMain/kotlin/zed/rainxch/core/data/services/UpdateScheduler.kt +++ b/core/data/src/androidMain/kotlin/zed/rainxch/core/data/services/UpdateScheduler.kt @@ -46,15 +46,15 @@ object UpdateScheduler { request = request, ) + // Note: an expedited request CANNOT carry an initial delay — + // WorkManager throws `IllegalArgumentException: Expedited jobs + // cannot be delayed` at build time. Drop the cold-start backoff + // and let the OS scheduler dispatch as soon as the network + // constraint is satisfied; on aggressive-OEM ROMs the expedited + // tier is what actually gets the work to run. val immediateRequest = OneTimeWorkRequestBuilder() .setConstraints(constraints) - .setInitialDelay(1, TimeUnit.MINUTES) - // Aggressive-OEM ROMs (Oppo / OnePlus / Realme / Xiaomi) - // throttle generic background work hard. Expedited tier - // gets more headroom; fall back to non-expedited when - // the system has no expedited budget left so the work - // still runs eventually rather than failing outright. .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST) .build()