F-Droid background syncing
See original GitHub issueCentralising the fdroid specific background notification issues - #3263 #3159 #2827 #2669 #2143 #1419 #2519
Context
The fdroid variant of element does not use Google play services which means we cannot receive push notifications (FCM). Instead we must manually poll the server for new events at a scheduled rate whilst the app is in the background to achieve a similar messaging experience.
Element currently provides 2 mechanisms for polling in the background
- Optimised for battery
- Self rescheduling
WorkManager
workers - The recommended way to do background work, respects battery optimisations like Doze, inexactly triggering at set times or during the Doze maintenance window.
- Self rescheduling
- Optimised for real time
- Self rescheduling short lived
ForegroundService
triggered byAlarmManager.setAndAllowWhileIdle
AlarmManager
usage allows some system battery optimisations to be skipped like executing during Doze however they’re limited to once per 9 minutes.
- Self rescheduling short lived
but…
Both mechanisms suffer from OEMs being able to ignore our background scheduled tasks and the system applying restrictions to how often we can schedule.
#3844 approaches the problem by using a long running ForegroundService
along with an explicit timer to manually trigger and reapply the background scheduling. We have reports that this resolves the notification issue.
#2921 is similar in approach by using PeriodicWorkManager
workers as a way to ensure the polling workers are being scheduled, there’s a 15 minute minimum interval. This approach still suffers from the system being able to ignore the scheduling.
Through my local testing simply the existence of a foreground service allows the Element process to avoid being killed early (especially in combination with disabling battery optimisations)
*Pocofone F1 MIUI android 10 & Nexus 6P android 8.1.0 *Unplugged on WIFI *Battery optimised background sync set to 60 seconds *Noop foreground service *Writing a timestamp to disk each time the sync worker is triggered
NEXUS 6P WITHOUT SERVICE | POCO WITHOUT SERVICE | POCO WITH SERVICE |
---|---|---|
08:31 | 21:40 | 10:50 |
08:32 | 21:42 | 10:52 |
08:34 | was running overnight, no other syncs | 10:56 |
08:35 | 10:57 | |
08:42 | 11:01 | |
08:52 | 11:11 | |
09:10 | 11:28 | |
09:26 | 11:50 | |
09:43 | 12:08 | |
10:07 | 13:05 | |
10:08 | 14:17 | |
every minute until 12:20 | 14:54 | |
12:50 | 15:56 | |
13:51 | 15:59 | |
15:46 | 18:14 | |
19:45 | 18:43 | |
21:33 plugged in to collect results | 19:27 | |
21:31 plugged in to collect results |
We can see the WorkManager
quickly starts to ignore our 60 second rescheduling requests on the Pocofone, but it takes a few hours for the Nexus 6P to start scaling back.
The foreground service also protects against #2143 (closing the app through recents, only some OEMs ignore WorkManager/AlarmManager jobs when doing this)
Proposed solution
- A long running
ForegroundService
with a persistent notification, including when the app is in the foreground. This will stop the system from ignoring our scheduled work when the app is in the background/has been stopped.
An example notification…
PERSISTENT NOTIFICATION |
---|
- This has the downside that the system may label us as consuming battery despite our service doing nothing.
1.
may not be enough for some OEMs, this is where we provide another background sync option in which we manually reschedule events instead of relying on the system, this will use more battery than the other mechanisms. I would argue for only doing this once we confirm 1. doesn’t fix the issue.
CURRENT OPTIONS |
---|
Issue Analytics
- State:
- Created 2 years ago
- Reactions:9
- Comments:11 (8 by maintainers)
Top GitHub Comments
I am running Element-FDroid on /e/OS 0.18-o in an “always online” mode (= “optimized for real time”, 0 seconds delay, 179 seconds timeout; notifications working perfectly). I can report that version 1.3.7 is using 25 to 30% less energy when idling. Thanks!
Element is now down to using ~8 times as much battery as Conversations.
Is part of 1.3.7