davx5-ose icon indicating copy to clipboard operation
davx5-ose copied to clipboard

Pending sync not shown in some cases

Open rfc2822 opened this issue 11 months ago • 6 comments

When a sync has not been initiated by the sync framework yet, there's no pending worker, and we currently don't show that a sync is pending, which is confusing.

rfc2822 avatar Apr 28 '25 11:04 rfc2822

In AccountProgressUseCase (probably) just add a callback flow pendingInSyncFramework with ContentResolver.addStatusChangeListener() checking for pending and combine that flow in AccountProgressUseCase.invoke.

sunkup avatar Apr 28 '25 11:04 sunkup

Might be impossible, since:

  1. Android's ContentResolver.isSyncPending(account, authority) cannot, on its own, tell us if the pending sync is user-initiated or a periodic sync.
  2. periodic syncs always exist for calendar !?

sunkup avatar May 06 '25 13:05 sunkup

  • Android's ContentResolver.isSyncPending(account, authority) cannot, on its own, tell us if the pending sync is user-initiated or a periodic sync.

Periodic syncs should never be done over the sync framework.

But even if they would, I think they wouldn't be pending? Because that had worked too back then when we didn't have WorkManager yet.

rfc2822 avatar May 06 '25 13:05 rfc2822

hmm. it actually works just fine on my A13 emulator. But on my A15 emulator the calendar authority syncs stay pending forever ...

On Android 13 (works)

Here are logs from when the davx5 sync should be recognized as pending:

emu64x:/ $ dumpsys content | grep calendar
JobId=100004 [email protected]/bitfire.at.davdroid u0 [com.android.calendar] LOCAL ExpectedIn=-1s STANDBY-EXEMPTED(TOP) Reason=10084 Owner={u0a194 at.bitfire.davdroid [10] [ACTIVE]} [upload=true ]
com.android.calendar     1         true     Total  4    0     0    0     3     4     11   0     0    15s   USER SUCCESS           
com.android.calendar  1         false    Total  0    0     0    0     0     0     0    0     0    0s                 
  com.android.calendar                                                   : 4/66%      3s/50%     
  #1  : 2025-05-07 11:44:04     USER    0.4s            [email protected]/bitfire.at.davdroid u0                             com.android.calendar ws.xsoh.etar
  #2  : 2025-05-07 11:43:58     USER    1.1s         6  [email protected]/bitfire.at.davdroid u0                             com.android.calendar ws.xsoh.etar
  #3  : 2025-05-07 11:42:21    OTHER    0.5s     01:36  [email protected]/bitfire.at.davdroid u0                             com.android.calendar ServiceChanged
  #4  : 2025-05-07 11:42:04    OTHER    1.4s        16  [email protected]/bitfire.at.davdroid u0                             com.android.calendar com.android.providers.calendar
  #1  : 2025-05-07 11:44:04     USER   [email protected]/bitfire.at.davdroid u0                             com.android.calendar Bundle[{ignore_settings=true, force=true, ignore_backoff=true}]
  #2  : 2025-05-07 11:43:58     USER   [email protected]/bitfire.at.davdroid u0                             com.android.calendar Bundle[{ignore_settings=true, force=true, ignore_backoff=true}]
  [email protected]/bitfire.at.davdroid u0 [com.android.calendar]
  Calendar subscriptions/at.bitfire.icsdroid u0 [com.android.calendar]
  ServiceInfo: SyncAdapterType {name=com.google.android.calendar.tasks, type=com.google, userVisible=true, supportsUploading=false, isAlwaysSyncable=false, allowParallelSyncs=true, settingsActivity=null, packageName=com.google.android.calendar}, ComponentInfo{com.google.android.calendar/com.google.android.apps.calendar.vagabond.tasks.impl.sync.PlatformSync$SyncService}, uid 10141
  ServiceInfo: SyncAdapterType {name=com.android.calendar, type=bitfire.at.davdroid, userVisible=false, supportsUploading=true, isAlwaysSyncable=true, allowParallelSyncs=true, settingsActivity=null, packageName=at.bitfire.davdroid}, ComponentInfo{at.bitfire.davdroid/at.bitfire.davdroid.sync.CalendarsSyncAdapterService}, uid 10194
  ServiceInfo: SyncAdapterType {name=com.android.calendar, type=at.bitfire.icsdroid, userVisible=true, supportsUploading=false, isAlwaysSyncable=true, allowParallelSyncs=true, settingsActivity=null, packageName=at.bitfire.icsdroid}, ComponentInfo{at.bitfire.icsdroid/at.bitfire.icsdroid.SyncAdapterService}, uid 10174
  ServiceInfo: SyncAdapterType {name=com.google.android.calendar, type=com.google, userVisible=true, supportsUploading=false, isAlwaysSyncable=false, allowParallelSyncs=true, settingsActivity=null, packageName=com.google.android.calendar}, ComponentInfo{com.google.android.calendar/com.google.calendar.v2a.shared.sync.impl.android.PlatformSyncShell$SyncAdapterService}, uid 10141
  ServiceInfo: SyncAdapterType {name=com.android.calendar, type=com.google, userVisible=true, supportsUploading=true, isAlwaysSyncable=false, allowParallelSyncs=false, settingsActivity=null, packageName=com.google.android.calendar}, ComponentInfo{com.google.android.calendar/com.google.android.syncadapters.calendar.CalendarSyncAdapterService}, uid 10141
  ServiceInfo: SyncAdapterType {name=com.android.calendar, type=com.google.android.gm.exchange, userVisible=true, supportsUploading=true, isAlwaysSyncable=false, allowParallelSyncs=true, settingsActivity=null, packageName=com.google.android.gm}, ComponentInfo{com.google.android.gm/com.android.exchange.service.CalendarSyncAdapterService}, uid 10145
  com.android.calendar: pid=554 uid=1000 user=0 target=58a043e
  com.android.calendar/instances/when: pid=554 uid=1000 user=0 target=c91dfaf
  com.android.calendar/events: pid=554 uid=1000 user=0 target=c91dfaf
  com.android.calendar/calendars: pid=554 uid=1000 user=0 target=c91dfaf

Here for when davx5 sync should not be recognized as pending:

emu64x:/ $ dumpsys content | grep calendar                                                               
com.android.calendar     1         true     Total  5    0     0    0     3     4     12   0     0    16s   LOCAL SUCCESS          
com.android.calendar  1         false    Total  0    0     0    0     0     0     0    0     0    0s                 
  com.android.calendar                                                   : 5/71%      4s/59%     
  #1  : 2025-05-07 11:45:13    LOCAL    1.5s            [email protected]/bitfire.at.davdroid u0                             com.android.calendar com.android.providers.calendar
  #2  : 2025-05-07 11:44:04     USER    0.4s     01:09  [email protected]/bitfire.at.davdroid u0                             com.android.calendar ws.xsoh.etar
  #3  : 2025-05-07 11:43:58     USER    1.1s         6  [email protected]/bitfire.at.davdroid u0                             com.android.calendar ws.xsoh.etar
  #4  : 2025-05-07 11:42:21    OTHER    0.5s     01:36  [email protected]/bitfire.at.davdroid u0                             com.android.calendar ServiceChanged
  #5  : 2025-05-07 11:42:04    OTHER    1.4s        16  [email protected]/bitfire.at.davdroid u0                             com.android.calendar com.android.providers.calendar
  #1  : 2025-05-07 11:45:13    LOCAL   [email protected]/bitfire.at.davdroid u0                             com.android.calendar Bundle[{upload=true}]
  #2  : 2025-05-07 11:44:04     USER   [email protected]/bitfire.at.davdroid u0                             com.android.calendar Bundle[{ignore_settings=true, force=true, ignore_backoff=true}]
  #3  : 2025-05-07 11:43:58     USER   [email protected]/bitfire.at.davdroid u0                             com.android.calendar Bundle[{ignore_settings=true, force=true, ignore_backoff=true}]
  [email protected]/bitfire.at.davdroid u0 [com.android.calendar]
  Calendar subscriptions/at.bitfire.icsdroid u0 [com.android.calendar]
  ServiceInfo: SyncAdapterType {name=com.google.android.calendar.tasks, type=com.google, userVisible=true, supportsUploading=false, isAlwaysSyncable=false, allowParallelSyncs=true, settingsActivity=null, packageName=com.google.android.calendar}, ComponentInfo{com.google.android.calendar/com.google.android.apps.calendar.vagabond.tasks.impl.sync.PlatformSync$SyncService}, uid 10141
  ServiceInfo: SyncAdapterType {name=com.android.calendar, type=bitfire.at.davdroid, userVisible=false, supportsUploading=true, isAlwaysSyncable=true, allowParallelSyncs=true, settingsActivity=null, packageName=at.bitfire.davdroid}, ComponentInfo{at.bitfire.davdroid/at.bitfire.davdroid.sync.CalendarsSyncAdapterService}, uid 10194
  ServiceInfo: SyncAdapterType {name=com.android.calendar, type=at.bitfire.icsdroid, userVisible=true, supportsUploading=false, 

Android 15 (wrongly shows as pending)

Now here is for the Android 15 emulator where davx5 sync is always seen as pending. Regardless of whether it is truly pending.

Logs for when it should truly be pending:

JobId=9 [email protected]/com.google u0 [com.android.calendar] LOCAL ExpectedIn=20s STANDBY-EXEMPTED(TOP) Reason=10094 Owner={u0a149 com.google.android.calendar [10] [ACTIVE]} [upload=true ]
JobId=32 [email protected]/com.google u0 [com.android.calendar] PERIODIC Reason=Periodic (period=1d00h00m00s flex=57m36s) Owner={u0a149 com.google.android.calendar [10] [ACTIVE]} [sync_extra_get_settings=true sync_extra_get_recent_notifications=true sync_extra_get_default_notifications=true sync_periodic=true ]
JobId=33 [email protected]/com.google u0 [com.google.android.calendar] PERIODIC Reason=Periodic (period=1d00h00m00s flex=57m36s) Owner={u0a149 com.google.android.calendar [10] [ACTIVE]} [periodic_sync=true run_sync=true ]
JobId=44 [email protected]/com.google u0 [com.google.android.calendar.tasks] PERIODIC Reason=Periodic (period=1d00h00m00s flex=57m36s) Owner={u0a149 com.google.android.calendar [10] [ACTIVE]} [sync_reason=PERIODIC ]
com.android.calendar                     1         true     Total  63   0     0    3     161   29    256  0     5    1m40s  LOCAL SUCCESS          
com.google.android.calendar              1         true     Total  0    0     0    0     0     5     5    0     0    4s     OTHER SUCCESS          
com.google.android.calendar.tasks        1         true     Total  0    0     0    0     0     2     2    0     0    1s     OTHER SUCCESS          
com.android.calendar     1         false    Total  0    0     0    0     1     2     3    0     0    4s    USER SUCCESS           
  com.android.calendar                        : 6/46%      3s/45%     
  #1  : 2025-05-07 11:55:05    LOCAL    0.0s            [email protected]/com.google u0      com.android.calendar                    com.android.providers.calendar
  #2  : 2025-05-07 11:52:17     USER    0.3s     02:47  [email protected]/com.google u0      com.android.calendar                    com.google.android.calendar
  #3  : 2025-05-07 11:52:17     USER    0.5s         0  [email protected]/com.google u0      com.android.calendar                    com.google.android.calendar
  #4  : 2025-05-07 11:52:17     USER    0.2s         0  [email protected]/com.google u0      com.android.calendar                    com.google.android.calendar
  #5  : 2025-05-07 11:52:15     USER    0.4s            [email protected]/bitfire.at.davdroid u0  com.android.calendar                    ws.xsoh.etar
  #6  : 2025-05-07 11:52:15     USER    2.0s         1  [email protected]/com.google u0      com.android.calendar                    ws.xsoh.etar
  #1  : 2025-05-07 11:55:05    LOCAL   [email protected]/com.google u0      com.android.calendar                    Bundle[{upload=true}]
  #2  : 2025-05-07 11:52:17     USER   [email protected]/com.google u0      com.android.calendar                    Bundle[{ignore_settings=true, force=true, ignore_backoff=true, feed_internal=en.usa#[email protected]}]
  #3  : 2025-05-07 11:52:17     USER   [email protected]/com.google u0      com.android.calendar                    Bundle[{ignore_settings=true, force=true, ignore_backoff=true, feed_internal=de.austrian#[email protected]}]
  #4  : 2025-05-07 11:52:17     USER   [email protected]/com.google u0      com.android.calendar                    Bundle[{ignore_settings=true, force=true, ignore_backoff=true, [email protected]}]
  #5  : 2025-05-07 11:52:15     USER   [email protected]/bitfire.at.davdroid u0  com.android.calendar                    Bundle[{ignore_settings=true, force=true, ignore_backoff=true}]
  #6  : 2025-05-07 11:52:15     USER   [email protected]/com.google u0      com.android.calendar                    Bundle[{ignore_settings=true, force=true, ignore_backoff=true}]
  [email protected]/com.google u0 [com.android.calendar]
      2025-05-07 11:52:18 success Source=USER Elapsed=0s Reason=10149 Exemption=fg Extras=[ignore_settings=true force=true ignore_backoff=true feed_internal=en.usa#[email protected] ]
      2025-05-07 11:52:17 success Source=USER Elapsed=0s Reason=10149 Exemption=fg Extras=[ignore_settings=true force=true ignore_backoff=true feed_internal=de.austrian#[email protected] ]
  [email protected]/com.google u0 [com.google.android.calendar]
  [email protected]/com.google u0 [com.google.android.calendar.tasks]
  [email protected]/bitfire.at.davdroid u0 [com.android.calendar]
  ServiceInfo: SyncAdapterType {name=com.google.android.calendar.tasks, type=com.google, userVisible=true, supportsUploading=false, isAlwaysSyncable=false, allowParallelSyncs=true, settingsActivity=null, packageName=com.google.android.calendar}, ComponentInfo{com.google.android.calendar/com.google.android.apps.calendar.vagabond.tasks.impl.sync.PlatformSync$SyncService}, uid 10149
  ServiceInfo: SyncAdapterType {name=com.android.calendar, type=bitfire.at.davdroid, userVisible=false, supportsUploading=true, isAlwaysSyncable=true, allowParallelSyncs=true, settingsActivity=null, packageName=at.bitfire.davdroid}, ComponentInfo{at.bitfire.davdroid/at.bitfire.davdroid.sync.CalendarsSyncAdapterService}, uid 10222
  ServiceInfo: SyncAdapterType {name=com.google.android.calendar, type=com.google, userVisible=true, supportsUploading=false, isAlwaysSyncable=false, allowParallelSyncs=true, settingsActivity=null, packageName=com.google.android.calendar}, ComponentInfo{com.google.android.calendar/com.google.calendar.v2a.shared.sync.impl.android.PlatformSyncShell$SyncAdapterService}, uid 10149
  ServiceInfo: SyncAdapterType {name=com.android.calendar, type=com.google, userVisible=true, supportsUploading=true, isAlwaysSyncable=false, allowParallelSyncs=false, settingsActivity=null, packageName=com.google.android.calendar}, ComponentInfo{com.google.android.calendar/com.google.android.syncadapters.calendar.CalendarSyncAdapterService}, uid 10149
  com.android.calendar: pid=581 uid=1000 user=0 target=e198d8d
  com.android.calendar/instances/when: pid=581 uid=1000 user=0 target=e677066
  com.android.calendar/events: pid=581 uid=1000 user=0 target=e677066
  com.android.calendar/calendars: pid=581 uid=1000 user=0 target=e677066
  com.google.android.gms.phenotype/com.google.android.gms.auth_account_client#com.google.android.calendar: pid=4443 uid=10149 user=0 target=e01d2a5

Logs for when it should not be seen as pending (but still seen as pending):

emu64xa:/ $ dumpsys content | grep calendar                                                              
JobId=32 [email protected]/com.google u0 [com.android.calendar] PERIODIC Reason=Periodic (period=1d00h00m00s flex=57m36s) Owner={u0a149 com.google.android.calendar [10] [ACTIVE]} [sync_extra_get_settings=true sync_extra_get_recent_notifications=true sync_extra_get_default_notifications=true sync_periodic=true ]
JobId=33 [email protected]/com.google u0 [com.google.android.calendar] PERIODIC Reason=Periodic (period=1d00h00m00s flex=57m36s) Owner={u0a149 com.google.android.calendar [10] [ACTIVE]} [periodic_sync=true run_sync=true ]
JobId=44 [email protected]/com.google u0 [com.google.android.calendar.tasks] PERIODIC Reason=Periodic (period=1d00h00m00s flex=57m36s) Owner={u0a149 com.google.android.calendar [10] [ACTIVE]} [sync_reason=PERIODIC ]
com.android.calendar                     1         true     Total  64   0     0    3     161   33    261  0     7    1m46s  OTHER SUCCESS          
com.google.android.calendar              1         true     Total  0    0     0    0     0     5     5    0     0    4s     OTHER SUCCESS          
com.google.android.calendar.tasks        1         true     Total  0    0     0    0     0     2     2    0     0    1s     OTHER SUCCESS          
com.android.calendar     1         true     Total  0    0     0    0     0     1     1    0     0    1s    OTHER SUCCESS          
  com.android.calendar                        : 5/29%      6s/39%     
  #1  : 2025-05-07 11:58:30    OTHER    1.2s            [email protected]/bitfire.at.davdroid u0  com.android.calendar                    AutoSync
  #6  : 2025-05-07 11:57:31    OTHER    0.1s            [email protected]/com.google u0      com.android.calendar                    com.google.android.calendar
  #7  : 2025-05-07 11:57:30    OTHER    1.3s         1  [email protected]/com.google u0      com.android.calendar                    ServiceChanged
  #9  : 2025-05-07 11:57:28    OTHER    0.7s         1  [email protected]/com.google u0      com.android.calendar                    ServiceChanged
  #11 : 2025-05-07 11:57:24    OTHER    3.1s         3  [email protected]/com.google u0      com.android.calendar                    ServiceChanged
  #6  : 2025-05-07 11:57:31    OTHER   [email protected]/com.google u0      com.android.calendar                    Bundle[{[email protected]}]
  [email protected]/com.google u0 [com.android.calendar]
      2025-05-07 11:52:18 success Source=USER Elapsed=0s Reason=10149 Exemption=fg Extras=[ignore_settings=true force=true ignore_backoff=true feed_internal=en.usa#[email protected] ]
      2025-05-07 11:52:17 success Source=USER Elapsed=0s Reason=10149 Exemption=fg Extras=[ignore_settings=true force=true ignore_backoff=true feed_internal=de.austrian#[email protected] ]
  [email protected]/com.google u0 [com.google.android.calendar]
  [email protected]/com.google u0 [com.google.android.calendar.tasks]
  [email protected]/bitfire.at.davdroid u0 [com.android.calendar]
  ServiceInfo: SyncAdapterType {name=com.google.android.calendar.tasks, type=com.google, userVisible=true, supportsUploading=false, isAlwaysSyncable=false, allowParallelSyncs=true, settingsActivity=null, packageName=com.google.android.calendar}, ComponentInfo{com.google.android.calendar/com.google.android.apps.calendar.vagabond.tasks.impl.sync.PlatformSync$SyncService}, uid 10149
  ServiceInfo: SyncAdapterType {name=com.android.calendar, type=bitfire.at.davdroid, userVisible=false, supportsUploading=true, isAlwaysSyncable=true, allowParallelSyncs=true, settingsActivity=null, packageName=at.bitfire.davdroid}, ComponentInfo{at.bitfire.davdroid/at.bitfire.davdroid.sync.CalendarsSyncAdapterService}, uid 10209
  ServiceInfo: SyncAdapterType {name=com.google.android.calendar, type=com.google, userVisible=true, supportsUploading=false, isAlwaysSyncable=false, allowParallelSyncs=true, settingsActivity=null, packageName=com.google.android.calendar}, ComponentInfo{com.google.android.calendar/com.google.calendar.v2a.shared.sync.impl.android.PlatformSyncShell$SyncAdapterService}, uid 10149
  ServiceInfo: SyncAdapterType {name=com.android.calendar, type=com.google, userVisible=true, supportsUploading=true, isAlwaysSyncable=false, allowParallelSyncs=false, settingsActivity=null, packageName=com.google.android.calendar}, ComponentInfo{com.google.android.calendar/com.google.android.syncadapters.calendar.CalendarSyncAdapterService}, uid 10149
  com.android.calendar: pid=587 uid=1000 user=0 target=6a76881
  com.android.calendar/instances/when: pid=587 uid=1000 user=0 target=c4d6d4f
  com.android.calendar/events: pid=587 uid=1000 user=0 target=c4d6d4f
  com.android.calendar/calendars: pid=587 uid=1000 user=0 target=c4d6d4f
  com.google.android.gms.phenotype/com.google.android.gms.auth_account_client#com.google.android.calendar: pid=3573 uid=10149 user=0 target=520ffc6

I think it might be due to the AutoSync entry

  #1  : 2025-05-07 11:58:30    OTHER    1.2s            [email protected]/bitfire.at.davdroid u0  com.android.calendar                    AutoSync

I am not sure how and why, but I'd like to address that in a different PR and will simply use my A13 emulator for now.


~After installing jtxBoard and creating a task in synchronized collection, I observe the same behaviour (forever pending state) on the A13 emulator. It stays even after uninstalling jtxBoard or rebooting the emulator.~

sunkup avatar May 07 '25 10:05 sunkup

Just interested in the wording: Are "periodic syncs" the same as "pending syncs"? Or can a periodic sync also be a pending sync?

devvv4ever avatar May 12 '25 19:05 devvv4ever

No, they are not the same. A periodic sync runs in intervals and will be "pending" the moment it has been requested/enqueued to run and will then transition to "active" when it actually runs. So "pending" refers to the state a periodic (or manual) sync operation can be in.

sunkup avatar May 13 '25 06:05 sunkup

Fixed in #1445 for Android <14. For Android >= 14, see #1458.

rfc2822 avatar Jun 26 '25 13:06 rfc2822