Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f1911c22 authored by Jonathan Klee's avatar Jonathan Klee
Browse files

fix(sync): preserve autosync timestamps on Android 14

Limit the pending-sync workaround to upload/content-triggered requests only.
This prevents initial automatic syncs from being marked canceled.
parent 5e1c8c35
Loading
Loading
Loading
Loading
Loading
+36 −6
Original line number Diff line number Diff line
@@ -119,11 +119,24 @@ class SyncAdapterImpl @Inject constructor(
        val workerName = syncWorkerManager.enqueueOneTime(account, dataType = SyncDataType.Companion.fromAuthority(authority), fromUpload = upload)

        // Android 14+ does not handle pending sync state correctly.
        // As a defensive workaround, we can cancel specifically this still pending sync only
        // See: https://github.com/bitfireAT/davx5-ose/issues/1458
        if (Build.VERSION.SDK_INT >= 34) {
            logger.fine("Android 14+ bug: Canceling forever pending sync adapter framework sync request for " +
                    "account=$accountOrAddressBookAccount authority=$authority extras=$extras")
        // As a defensive workaround, only cancel content-triggered upload syncs.
        // Do not cancel manual/Settings-triggered syncs (marked via explicit manual/ignore extras),
        // otherwise Android records them as "canceled" and no last successful sync date is shown.
        val manualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false)
        val ignoreSettings = extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
        val shouldCancelPendingWorkaroundSync =
            shouldCancelPendingWorkaroundSync(
                sdkInt = Build.VERSION.SDK_INT,
                upload = upload,
                manualSync = manualSync,
                ignoreSettings = ignoreSettings
            )

        if (shouldCancelPendingWorkaroundSync) {
            logger.fine(
                "Android 14+ bug workaround: canceling potential forever-pending sync request for " +
                    "account=$accountOrAddressBookAccount authority=$authority extras=$extras"
            )
            syncFrameworkIntegration.get().cancelSync(accountOrAddressBookAccount, authority, extras)
        }

@@ -187,4 +200,21 @@ class SyncAdapterImpl @Inject constructor(
        abstract fun provide(impl: SyncAdapterImpl): SyncAdapter
    }

    companion object {
        internal fun shouldCancelPendingWorkaroundSync(
            sdkInt: Int,
            upload: Boolean,
            manualSync: Boolean,
            ignoreSettings: Boolean
        ): Boolean {
            if (sdkInt < 34 || !upload) {
                return false
            }

            val isManualOrSettingsTriggered = manualSync || ignoreSettings

            return !isManualOrSettingsTriggered
        }
    }

}