fix(push): handle Service.onTimeout for the 24/7 dataSync FGS (push silently dies after ~6h on Android 14+) #302

Closed
opened 2026-07-04 06:50:12 +00:00 by JMR-dev · 0 comments
JMR-dev commented 2026-07-04 06:50:12 +00:00 (Migrated from github.com)

Phase-3 review (HIGH). IdleService (:206) runs continuously as FOREGROUND_SERVICE_TYPE_DATA_SYNC, and push is ON by default (AppSettings.pushIdle=true). With targetSdk 37, Android 14+'s dataSync FGS runtime cap (~6h per rolling 24h) calls Service.onTimeout(...) then force-stops + throws if the service doesn't stop itself. IdleService overrides onStartCommand/onDestroy/onBind but NOT onTimeout (absent from all of app/src/main). Effect: any Android 14+/15/16 user with default settings + ≥1 account loses push after ~6 cumulative hours and the app hits a system FGS-timeout exception; on API 35+ the budget is cumulative per-24h and restarting doesn't reset it, so MainActivity.ensurePushStarted can't recover it — push stays dead until the next window. Fix: override onTimeout(startId[,fgsType]) to cleanly stop foreground state and fall back to the scheduled 15-min periodic sync (mirror the low-battery PushMode.POLLING fallback + surface in the persistent notification).

Phase-3 review (HIGH). `IdleService` (:206) runs continuously as `FOREGROUND_SERVICE_TYPE_DATA_SYNC`, and push is ON by default (`AppSettings.pushIdle=true`). With targetSdk 37, Android 14+'s dataSync FGS runtime cap (~6h per rolling 24h) calls `Service.onTimeout(...)` then force-stops + throws if the service doesn't stop itself. `IdleService` overrides onStartCommand/onDestroy/onBind but **NOT onTimeout** (absent from all of app/src/main). Effect: any Android 14+/15/16 user with default settings + ≥1 account loses push after ~6 cumulative hours and the app hits a system FGS-timeout exception; on API 35+ the budget is cumulative per-24h and restarting doesn't reset it, so `MainActivity.ensurePushStarted` can't recover it — push stays dead until the next window. **Fix:** override `onTimeout(startId[,fgsType])` to cleanly stop foreground state and fall back to the scheduled 15-min periodic sync (mirror the low-battery `PushMode.POLLING` fallback + surface in the persistent notification).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: JMR-dev/LibreMail#302