mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
fix(upgrade): Add a persistent acknowledgement safety net for Play purchases
Play auto-refunds (and revokes) purchases not acknowledged within 3 days. The in-process ack machinery covers every case where the process lives long enough; what it cannot cover is a process death around the Play sheet (aggressive OEM task killers) followed by the user not reopening the app before the deadline. Add a gplay-only WorkManager safety net: - PurchaseAckWorker: self-completing sweep via a new bounded BillingManager.ensureAllAcknowledged() that refreshes and acknowledges in the same coroutine (the reactive ack collector is async, so a worker cannot prove its acks happened through it). Retries with exponential backoff until the purchase's refund deadline, then gives up visibly. - PurchaseAckScheduler: two unique work identities. A launch watch (REPLACE, armed and awaited before launchBillingFlow with a 30min delay so it cannot complete while the user is still in the sheet) and a discovered-purchase rescue (KEEP, 1min delay, armed directly from an ack pass that finds unacknowledged purchases, pre-attempt). Separate identities so a new purchase flow can never displace a pending rescue. Both triggers are fail-open: a broken WorkManager never blocks a purchase or an ack. WorkManager resolves via Provider at first arm so eager Application-time construction of the billing stack cannot trigger WorkManager's on-demand initialization prematurely. - Nothing cancels the work from the foreground path: an ack pass can see zero unacked purchases while the sheet is still open, so the worker completes itself after its own reconciliation instead. The ack pass now runs under a mutex (the worker sweep and the reactive collector would otherwise race the token bookkeeping) and reports per-outcome counts for the sweep result mapping. This is a port of d4rken-org/sdmaid-se#2685; the ported sources are byte-identical to the donor apart from the package rename. CAPod had no explicit WorkManager wiring at all (work-runtime only arrived transitively through Glance), so this also adds it: - addWorkerManager() pinning androidx.work 2.7.1, the version already resolved via Glance, plus androidx.hilt:hilt-work and its KSP compiler. work-runtime-ktx is required at 2.7.1: CoroutineWorker, Operation.await, OneTimeWorkRequestBuilder and workDataOf all still live in the ktx artifact at that version. androidx.hilt moves 1.0.0 -> 1.2.0 (by conflict resolution) because 1.0.0's hilt-compiler ships no KSP SymbolProcessorProvider, so @HiltWorker would generate nothing. - WorkManagerModule providing the singleton WorkManager. - App implements Configuration.Provider with the injected HiltWorkerFactory. WorkManager 2.7.1 still declares that interface as getWorkManagerConfiguration(), not the later property form. - The manifest removes androidx.work's startup initializer so the on-demand configuration is the one that takes effect. FOSS stays untouched behaviour-wise: all new billing types live in src/gplay, workers need no manifest entry, and the worker factory resolves the worker only in gplay variants.
This commit is contained in:
@@ -132,6 +132,19 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name="androidx.startup.InitializationProvider"
|
||||
android:authorities="${applicationId}.androidx-startup"
|
||||
android:exported="false"
|
||||
tools:node="merge">
|
||||
|
||||
<meta-data
|
||||
android:name="androidx.work.WorkManagerInitializer"
|
||||
android:value="androidx.startup"
|
||||
tools:node="remove" />
|
||||
|
||||
</provider>
|
||||
|
||||
<!-- Debug stuff-->
|
||||
<activity
|
||||
android:name=".common.debug.recording.ui.RecorderActivity"
|
||||
|
||||
Reference in New Issue
Block a user