diff --git a/app/src/main/kotlin/at/bitfire/davdroid/settings/AccountSettings.kt b/app/src/main/kotlin/at/bitfire/davdroid/settings/AccountSettings.kt index f94002a384b936ccb3e2655edab2aecbf7d82ca0..9ad42b35a186bfcb842336d3422c78eb1eea121a 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/settings/AccountSettings.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/settings/AccountSettings.kt @@ -342,7 +342,7 @@ class AccountSettings( * @throws IllegalArgumentException when [seconds] is not [SYNC_INTERVAL_MANUALLY] but less than 15 min */ @WorkerThread - fun setSyncInterval(authority: String, argSeconds: Long): Boolean { + fun setSyncInterval(authority: String, argSeconds: Long, setAutomaticSync: Boolean = true): Boolean { var seconds = argSeconds if (seconds != SYNC_INTERVAL_MANUALLY && seconds < 60*15) { @@ -369,7 +369,9 @@ class AccountSettings( // Also enable/disable content change triggered syncs (SyncFramework automatic sync). // We could make this a separate user adjustable setting later on. - setSyncOnContentChange(authority, seconds != SYNC_INTERVAL_MANUALLY) + if (setAutomaticSync) { + setSyncOnContentChange(authority, seconds != SYNC_INTERVAL_MANUALLY) + } return true } @@ -626,6 +628,10 @@ class AccountSettings( return } + if (!ContentResolver.getSyncAutomatically(account, authority)) { + return + } + if (authority !in getPeriodicSyncEnableAuthorities()) { return } diff --git a/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/AccountDetailsFragment.kt b/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/AccountDetailsFragment.kt index c003b8409d6f91e5d22b65a8fe7e2ea8fcf385a2..27883cc305392813803c6914d59240001109d60d 100644 --- a/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/AccountDetailsFragment.kt +++ b/app/src/main/kotlin/at/bitfire/davdroid/ui/setup/AccountDetailsFragment.kt @@ -406,74 +406,225 @@ class AccountDetailsFragment : Fragment() { accountManager.setPassword(account, credentials?.password) } + // Account sync settings for eDrive + var mediaSyncEnabled = true + var appDataSyncEnabled = true + var meteredEdriveSyncEnabled = true + + // Account sync settings for other apps + var notesSyncEnabled = true + var emailSyncEnabled = true + var contactsSyncable = 1 + var calendarSyncable = 1 + var tasksSyncable = 1 + + var contactsGroupMethod = groupMethod + + // Sync interval + val defaultSyncInterval = Constants.DEFAULT_CALENDAR_SYNC_INTERVAL + var contactsSyncInterval = defaultSyncInterval + var calendarSyncInterval = defaultSyncInterval + var tasksSyncInterval = defaultSyncInterval + + var contactsSyncEnabled = true + var calendarSyncEnabled = true + var tasksSyncEnabled = true - ContentResolver.setSyncAutomatically(account, context.getString(R.string.notes_authority), true) - ContentResolver.setSyncAutomatically(account, context.getString(R.string.email_authority), true) - ContentResolver.setSyncAutomatically(account, context.getString(R.string.media_authority), true) - ContentResolver.setSyncAutomatically(account, context.getString(R.string.app_data_authority), true) - ContentResolver.setSyncAutomatically(account, context.getString(R.string.metered_edrive_authority), true) + if (accountToUpdate != null) { + val oldSettings = AccountSettings(context, accountToUpdate) + val addressBookAuthority = context.getString(R.string.address_books_authority) + val taskProvider = TaskUtils.currentProvider(context) + + mediaSyncEnabled = ContentResolver.getSyncAutomatically( + accountToUpdate, + context.getString(R.string.media_authority) + ) + appDataSyncEnabled = ContentResolver.getSyncAutomatically( + accountToUpdate, + context.getString(R.string.app_data_authority) + ) + meteredEdriveSyncEnabled = ContentResolver.getSyncAutomatically( + accountToUpdate, + context.getString(R.string.metered_edrive_authority) + ) + + notesSyncEnabled = ContentResolver.getSyncAutomatically( + accountToUpdate, + context.getString(R.string.notes_authority) + ) + emailSyncEnabled = ContentResolver.getSyncAutomatically( + accountToUpdate, + context.getString(R.string.email_authority) + ) + + // --- Contacts sync logic --- + contactsSyncable = + ContentResolver.getIsSyncable(accountToUpdate, addressBookAuthority) + val oldContactsSyncInterval = oldSettings.getSyncInterval(addressBookAuthority) + contactsSyncEnabled = + ContentResolver.getSyncAutomatically(accountToUpdate, addressBookAuthority) + + contactsSyncInterval = when { + contactsSyncEnabled -> oldContactsSyncInterval ?: defaultSyncInterval + oldContactsSyncInterval != null -> oldContactsSyncInterval + else -> AccountSettings.SYNC_INTERVAL_MANUALLY + } + contactsGroupMethod = oldSettings.getGroupMethod() + + // --- Calendar sync logic --- + calendarSyncable = + ContentResolver.getIsSyncable(accountToUpdate, CalendarContract.AUTHORITY) + val oldCalendarSyncInterval = + oldSettings.getSyncInterval(CalendarContract.AUTHORITY) + calendarSyncEnabled = ContentResolver.getSyncAutomatically( + accountToUpdate, + CalendarContract.AUTHORITY + ) + calendarSyncInterval = when { + calendarSyncEnabled -> oldCalendarSyncInterval ?: defaultSyncInterval + oldCalendarSyncInterval != null -> oldCalendarSyncInterval + else -> AccountSettings.SYNC_INTERVAL_MANUALLY + } + + // --- Tasks sync logic --- + if (taskProvider != null) { + tasksSyncable = + ContentResolver.getIsSyncable(accountToUpdate, taskProvider.authority) + tasksSyncEnabled = + ContentResolver.getSyncAutomatically(accountToUpdate, taskProvider.authority) + val oldTasksSyncInterval = + oldSettings.getSyncInterval(taskProvider.authority) + + tasksSyncInterval = when { + tasksSyncEnabled -> oldTasksSyncInterval ?: defaultSyncInterval + oldTasksSyncInterval != null -> oldTasksSyncInterval + else -> AccountSettings.SYNC_INTERVAL_MANUALLY + } + } + } + + ContentResolver.setSyncAutomatically( + account, + context.getString(R.string.notes_authority), + notesSyncEnabled + ) + ContentResolver.setSyncAutomatically( + account, + context.getString(R.string.email_authority), + emailSyncEnabled + ) + ContentResolver.setSyncAutomatically( + account, + context.getString(R.string.media_authority), + mediaSyncEnabled + ) + ContentResolver.setSyncAutomatically( + account, + context.getString(R.string.app_data_authority), + appDataSyncEnabled + ) + ContentResolver.setSyncAutomatically( + account, + context.getString(R.string.metered_edrive_authority), + meteredEdriveSyncEnabled + ) // add entries for account to service DB Logger.log.log(Level.INFO, "Writing account configuration to database", config) try { val accountSettings = AccountSettings(context, account) - val defaultSyncInterval = Constants.DEFAULT_CALENDAR_SYNC_INTERVAL // Configure CardDAV service - val addrBookAuthority = context.getString(R.string.address_books_authority) + val addressBookAuthority = context.getString(R.string.address_books_authority) if (config.cardDAV != null) { - // insert CardDAV service - val id = insertService( - credentials?.userName ?: "", - credentials?.authState?.jsonSerializeString(), - accountType, - addressBookAccountType, - Service.TYPE_CARDDAV, - config.cardDAV - ) - - // initial CardDAV account settings - accountSettings.setGroupMethod(groupMethod) + if (accountToUpdate != null) { + // Migration: update existing service + val service = db.serviceDao().getByAccountAndType(accountToUpdate.name, Service.TYPE_CARDDAV) + service?.let { + it.authState = credentials?.authState?.jsonSerializeString() + it.principal = config.cardDAV.principal + db.serviceDao().insertOrReplace(it) + RefreshCollectionsWorker.refreshCollections(context, it.id) + } + } else { + // New account: create new service + val id = insertService( + credentials?.userName ?: "", + credentials?.authState?.jsonSerializeString(), + accountType, + addressBookAccountType, + Service.TYPE_CARDDAV, + config.cardDAV + ) + accountSettings.setGroupMethod(contactsGroupMethod) + ContentResolver.setIsSyncable(account, addressBookAuthority, contactsSyncable) + RefreshCollectionsWorker.refreshCollections(context, id) + } - // start CardDAV service detection (refresh collections) - RefreshCollectionsWorker.refreshCollections(context, id) + // set sync settings + ContentResolver.setSyncAutomatically( + account, + addressBookAuthority, + contactsSyncEnabled + ) + accountSettings.setSyncInterval(addressBookAuthority, contactsSyncInterval, false) - // set default sync interval and enable sync regardless of permissions - ContentResolver.setIsSyncable(account, addrBookAuthority, 1) - accountSettings.setSyncInterval(addrBookAuthority, defaultSyncInterval) - } else - ContentResolver.setIsSyncable(account, addrBookAuthority, 0) + } else { + ContentResolver.setIsSyncable(account, addressBookAuthority, 0) + } // Configure CalDAV service if (config.calDAV != null) { - // insert CalDAV service - val id = insertService( - credentials?.userName ?: "", - credentials?.authState?.jsonSerializeString(), - accountType, - addressBookAccountType, - Service.TYPE_CALDAV, - config.calDAV - ) - - // start CalDAV service detection (refresh collections) - RefreshCollectionsWorker.refreshCollections(context, id) + if (accountToUpdate != null) { + // Migration: update existing service + val service = db.serviceDao().getByAccountAndType(accountToUpdate.name, Service.TYPE_CALDAV) + service?.let { + it.authState = credentials?.authState?.jsonSerializeString() + it.principal = config.calDAV.principal + db.serviceDao().insertOrReplace(it) + RefreshCollectionsWorker.refreshCollections(context, it.id) + } + } else { + // New account: create new service + val id = insertService( + credentials?.userName ?: "", + credentials?.authState?.jsonSerializeString(), + accountType, + addressBookAccountType, + Service.TYPE_CALDAV, + config.calDAV + ) + ContentResolver.setIsSyncable(account, CalendarContract.AUTHORITY, calendarSyncable) + RefreshCollectionsWorker.refreshCollections(context, id) + } - // set default sync interval and enable sync regardless of permissions - ContentResolver.setIsSyncable(account, CalendarContract.AUTHORITY, 1) - accountSettings.setSyncInterval(CalendarContract.AUTHORITY, defaultSyncInterval) + // set sync settings + ContentResolver.setSyncAutomatically( + account, + CalendarContract.AUTHORITY, + calendarSyncEnabled + ) + accountSettings.setSyncInterval(CalendarContract.AUTHORITY, calendarSyncInterval, false) // if task provider present, set task sync interval and enable sync val taskProvider = TaskUtils.currentProvider(context) if (taskProvider != null) { - ContentResolver.setIsSyncable(account, taskProvider.authority, 1) - accountSettings.setSyncInterval(taskProvider.authority, defaultSyncInterval) - // further changes will be handled by TasksWatcher on app start or when tasks app is (un)installed + if (accountToUpdate == null) + ContentResolver.setIsSyncable(account, taskProvider.authority, tasksSyncable) + + ContentResolver.setSyncAutomatically( + account, + taskProvider.authority, + tasksSyncEnabled + ) + accountSettings.setSyncInterval(taskProvider.authority, tasksSyncInterval, false) Logger.log.info("Tasks provider ${taskProvider.authority} found. Tasks sync enabled.") - } else + } else { Logger.log.info("No tasks provider found. Did not enable tasks sync.") - } else + } + } else { ContentResolver.setIsSyncable(account, CalendarContract.AUTHORITY, 0) + } } catch(e: InvalidAccountException) { Logger.log.log(Level.SEVERE, "Couldn't access account settings", e)