fix(calendars): don't reconcile visibility off an unreadable calendar list

The data source turns a null cursor — a provider that is momentarily
unavailable — into an empty list, which the reconciler read as "this device has
no calendars". Both of the decisions it then takes are one-way: every pending id
counts as settled, so the whole set is dropped without VISIBLE = 0 ever being
written and the calendars the user switched off come back on with their events
and reminders; and with nothing to find hidden, the one-time notice is stored as
"nothing to explain" for good.

The repository already refuses to cache an empty read for exactly this reason.
Do the same here and leave both decisions to the next run.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-26 18:49:29 +02:00
parent 2685730c44
commit 2c7d976d6f

View File

@@ -67,6 +67,14 @@ class CalendarVisibilityReconciler @Inject constructor(
// drain and nothing left to decide, so don't pay for the query. // drain and nothing left to decide, so don't pay for the query.
if (pending.isEmpty() && noticeSettled) return@withContext if (pending.isEmpty() && noticeSettled) return@withContext
val calendars = dataSource.calendars() val calendars = dataSource.calendars()
// An empty read means "couldn't read", not "no calendars": the data
// source turns a null cursor — a provider momentarily unavailable —
// into an empty list. Both decisions below are one-way, so taking
// that reading as the truth would drop the whole pending set without
// ever writing VISIBLE = 0 (switching the user's calendars back on,
// events and reminders with them) and settle the notice as "nothing
// to explain". Leave both to the next run.
if (calendars.isEmpty()) return@withContext
settleNoticeOnce(hasSystemHiddenCalendars(calendars, pending)) settleNoticeOnce(hasSystemHiddenCalendars(calendars, pending))
if (pending.isEmpty() || !hasPermission(Manifest.permission.WRITE_CALENDAR)) { if (pending.isEmpty() || !hasPermission(Manifest.permission.WRITE_CALENDAR)) {
return@withContext return@withContext