LocalTaskList: Stop subclassing DmfsTaskList (#1882)

* LocalTaskList: Stop subclassing DmfsTaskList

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

# Conflicts:
#	gradle/libs.versions.toml

* Dont touch agp

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

* Update synctools

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

---------

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>
This commit is contained in:
Sunik Kupfer
2025-12-11 16:22:02 +01:00
committed by GitHub
parent a938b511cd
commit 0e455d8371
6 changed files with 31 additions and 49 deletions

View File

@@ -4,13 +4,9 @@
package at.bitfire.davdroid.resource package at.bitfire.davdroid.resource
import android.accounts.Account
import android.content.ContentProviderClient
import androidx.core.content.contentValuesOf import androidx.core.content.contentValuesOf
import at.bitfire.ical4android.DmfsTask import at.bitfire.ical4android.DmfsTask
import at.bitfire.ical4android.DmfsTaskList import at.bitfire.ical4android.DmfsTaskList
import at.bitfire.ical4android.DmfsTaskListFactory
import at.bitfire.ical4android.TaskProvider
import org.dmfs.tasks.contract.TaskContract.TaskListColumns import org.dmfs.tasks.contract.TaskContract.TaskListColumns
import org.dmfs.tasks.contract.TaskContract.Tasks import org.dmfs.tasks.contract.TaskContract.Tasks
import java.util.logging.Level import java.util.logging.Level
@@ -21,40 +17,37 @@ import java.util.logging.Logger
* *
* [TaskLists._SYNC_ID] corresponds to the database collection ID ([at.bitfire.davdroid.db.Collection.id]). * [TaskLists._SYNC_ID] corresponds to the database collection ID ([at.bitfire.davdroid.db.Collection.id]).
*/ */
class LocalTaskList private constructor( class LocalTaskList (
account: Account, val dmfsTaskList: DmfsTaskList
provider: ContentProviderClient, ): LocalCollection<LocalTask> {
providerName: TaskProvider.ProviderName,
id: Long
): DmfsTaskList(account, provider, providerName, id), LocalCollection<LocalTask> {
private val logger = Logger.getGlobal() private val logger = Logger.getGlobal()
override val readOnly override val readOnly
get() = accessLevel?.let { get() = dmfsTaskList.accessLevel?.let {
it != TaskListColumns.ACCESS_LEVEL_UNDEFINED && it <= TaskListColumns.ACCESS_LEVEL_READ it != TaskListColumns.ACCESS_LEVEL_UNDEFINED && it <= TaskListColumns.ACCESS_LEVEL_READ
} ?: false } ?: false
override val dbCollectionId: Long? override val dbCollectionId: Long?
get() = syncId?.toLongOrNull() get() = dmfsTaskList.syncId?.toLongOrNull()
override val tag: String override val tag: String
get() = "tasks-${account.name}-$id" get() = "tasks-${dmfsTaskList.account.name}-${dmfsTaskList.id}"
override val title: String override val title: String
get() = name ?: id.toString() get() = dmfsTaskList.name ?: dmfsTaskList.id.toString()
override var lastSyncState: SyncState? override var lastSyncState: SyncState?
get() = readSyncState()?.let { SyncState.fromString(it) } get() = dmfsTaskList.readSyncState()?.let { SyncState.fromString(it) }
set(state) { set(state) {
writeSyncState(state.toString()) dmfsTaskList.writeSyncState(state.toString())
} }
override fun findDeleted() = queryTasks(Tasks._DELETED, null) override fun findDeleted() = dmfsTaskList.queryTasks(Tasks._DELETED, null)
.map { LocalTask(it) } .map { LocalTask(it) }
override fun findDirty(): List<LocalTask> { override fun findDirty(): List<LocalTask> {
val dmfsTasks = queryTasks(Tasks._DIRTY, null) val dmfsTasks = dmfsTaskList.queryTasks(Tasks._DIRTY, null)
for (localTask in dmfsTasks) { for (localTask in dmfsTasks) {
try { try {
val task = requireNotNull(localTask.task) val task = requireNotNull(localTask.task)
@@ -71,7 +64,7 @@ class LocalTaskList private constructor(
} }
override fun findByName(name: String) = override fun findByName(name: String) =
queryTasks("${Tasks._SYNC_ID}=?", arrayOf(name)) dmfsTaskList.queryTasks("${Tasks._SYNC_ID}=?", arrayOf(name))
.firstOrNull()?.let { .firstOrNull()?.let {
LocalTask(it) LocalTask(it)
} }
@@ -79,32 +72,20 @@ class LocalTaskList private constructor(
override fun markNotDirty(flags: Int): Int { override fun markNotDirty(flags: Int): Int {
val values = contentValuesOf(DmfsTask.COLUMN_FLAGS to flags) val values = contentValuesOf(DmfsTask.COLUMN_FLAGS to flags)
return provider.update(tasksSyncUri(), values, return dmfsTaskList.provider.update(dmfsTaskList.tasksSyncUri(), values,
"${Tasks.LIST_ID}=? AND ${Tasks._DIRTY}=0", "${Tasks.LIST_ID}=? AND ${Tasks._DIRTY}=0",
arrayOf(id.toString())) arrayOf(dmfsTaskList.id.toString()))
} }
override fun removeNotDirtyMarked(flags: Int) = override fun removeNotDirtyMarked(flags: Int) =
provider.delete(tasksSyncUri(), dmfsTaskList.provider.delete(dmfsTaskList.tasksSyncUri(),
"${Tasks.LIST_ID}=? AND NOT ${Tasks._DIRTY} AND ${DmfsTask.COLUMN_FLAGS}=?", "${Tasks.LIST_ID}=? AND NOT ${Tasks._DIRTY} AND ${DmfsTask.COLUMN_FLAGS}=?",
arrayOf(id.toString(), flags.toString())) arrayOf(dmfsTaskList.id.toString(), flags.toString()))
override fun forgetETags() { override fun forgetETags() {
val values = contentValuesOf(DmfsTask.COLUMN_ETAG to null) val values = contentValuesOf(DmfsTask.COLUMN_ETAG to null)
provider.update(tasksSyncUri(), values, "${Tasks.LIST_ID}=?", dmfsTaskList.provider.update(dmfsTaskList.tasksSyncUri(), values, "${Tasks.LIST_ID}=?",
arrayOf(id.toString())) arrayOf(dmfsTaskList.id.toString()))
}
object Factory: DmfsTaskListFactory<LocalTaskList> {
override fun newInstance(
account: Account,
provider: ContentProviderClient,
providerName: TaskProvider.ProviderName,
id: Long
) = LocalTaskList(account, provider, providerName, id)
} }
} }

View File

@@ -63,7 +63,7 @@ class LocalTaskListStore @AssistedInject constructor(
logger.log(Level.INFO, "Adding local task list", fromCollection) logger.log(Level.INFO, "Adding local task list", fromCollection)
val uri = create(account, client, providerName, fromCollection) val uri = create(account, client, providerName, fromCollection)
return DmfsTaskList.findByID(account, client, providerName, LocalTaskList.Factory, ContentUris.parseId(uri)) return LocalTaskList(DmfsTaskList.findByID(account, client, providerName, ContentUris.parseId(uri)))
} }
private fun create(account: Account, provider: ContentProviderClient, providerName: TaskProvider.ProviderName, fromCollection: Collection): Uri { private fun create(account: Account, provider: ContentProviderClient, providerName: TaskProvider.ProviderName, fromCollection: Collection): Uri {
@@ -81,7 +81,7 @@ class LocalTaskListStore @AssistedInject constructor(
put(TaskLists.SYNC_ENABLED, 1) put(TaskLists.SYNC_ENABLED, 1)
put(TaskLists.VISIBLE, 1) put(TaskLists.VISIBLE, 1)
} }
return DmfsTaskList.Companion.create(account, provider, providerName, values) return DmfsTaskList.create(account, provider, providerName, values)
} }
private fun valuesFromCollectionInfo(info: Collection, withColor: Boolean): ContentValues { private fun valuesFromCollectionInfo(info: Collection, withColor: Boolean): ContentValues {
@@ -102,12 +102,13 @@ class LocalTaskListStore @AssistedInject constructor(
} }
override fun getAll(account: Account, client: ContentProviderClient) = override fun getAll(account: Account, client: ContentProviderClient) =
DmfsTaskList.find(account, LocalTaskList.Factory, client, providerName, null, null) DmfsTaskList.find(account, client, providerName, null, null)
.map { LocalTaskList(it) }
override fun update(client: ContentProviderClient, localCollection: LocalTaskList, fromCollection: Collection) { override fun update(client: ContentProviderClient, localCollection: LocalTaskList, fromCollection: Collection) {
logger.log(Level.FINE, "Updating local task list ${fromCollection.url}", fromCollection) logger.log(Level.FINE, "Updating local task list ${fromCollection.url}", fromCollection)
val accountSettings = accountSettingsFactory.create(localCollection.account) val accountSettings = accountSettingsFactory.create(localCollection.dmfsTaskList.account)
localCollection.update(valuesFromCollectionInfo(fromCollection, withColor = accountSettings.getManageCalendarColors())) localCollection.dmfsTaskList.update(valuesFromCollectionInfo(fromCollection, withColor = accountSettings.getManageCalendarColors()))
} }
override fun updateAccount(oldAccount: Account, newAccount: Account, @WillNotClose client: ContentProviderClient?) { override fun updateAccount(oldAccount: Account, newAccount: Account, @WillNotClose client: ContentProviderClient?) {
@@ -119,7 +120,7 @@ class LocalTaskListStore @AssistedInject constructor(
} }
override fun delete(localCollection: LocalTaskList) { override fun delete(localCollection: LocalTaskList) {
localCollection.delete() localCollection.dmfsTaskList.delete()
} }
} }

View File

@@ -98,9 +98,9 @@ class AccountSettingsMigration20 @Inject constructor(
for (taskList in taskListStore.getAll(account, provider)) { for (taskList in taskListStore.getAll(account, provider)) {
when (taskList) { when (taskList) {
is LocalTaskList -> { // tasks.org, OpenTasks is LocalTaskList -> { // tasks.org, OpenTasks
val url = taskList.syncId ?: continue val url = taskList.dmfsTaskList.syncId ?: continue
collectionRepository.getByServiceAndUrl(calDavServiceId, url)?.let { collection -> collectionRepository.getByServiceAndUrl(calDavServiceId, url)?.let { collection ->
taskList.update(contentValuesOf( taskList.dmfsTaskList.update(contentValuesOf(
TaskLists._SYNC_ID to collection.id.toString() TaskLists._SYNC_ID to collection.id.toString()
)) ))
} }

View File

@@ -68,7 +68,7 @@ class TaskSyncer @AssistedInject constructor(
collectionRepository.getSyncTaskLists(serviceId) collectionRepository.getSyncTaskLists(serviceId)
override fun syncCollection(provider: ContentProviderClient, localCollection: LocalTaskList, remoteCollection: Collection) { override fun syncCollection(provider: ContentProviderClient, localCollection: LocalTaskList, remoteCollection: Collection) {
logger.info("Synchronizing task list ${localCollection.id} with database collection ID: ${localCollection.dbCollectionId}") logger.info("Synchronizing task list ${localCollection.dmfsTaskList.id} with database collection ID: ${localCollection.dbCollectionId}")
val syncManager = tasksSyncManagerFactory.tasksSyncManager( val syncManager = tasksSyncManagerFactory.tasksSyncManager(
account, account,

View File

@@ -164,7 +164,7 @@ class TasksSyncManager @AssistedInject constructor(
} }
override fun postProcess() { override fun postProcess() {
val touched = localCollection.touchRelations() val touched = localCollection.dmfsTaskList.touchRelations()
logger.info("Touched $touched relations") logger.info("Touched $touched relations")
} }
@@ -192,7 +192,7 @@ class TasksSyncManager @AssistedInject constructor(
local.update(newData) local.update(newData)
} else { } else {
logger.log(Level.INFO, "Adding $fileName to local task list", newData) logger.log(Level.INFO, "Adding $fileName to local task list", newData)
val newLocal = LocalTask(DmfsTask(localCollection, newData, fileName, eTag, LocalResource.FLAG_REMOTELY_PRESENT)) val newLocal = LocalTask(DmfsTask(localCollection.dmfsTaskList, newData, fileName, eTag, LocalResource.FLAG_REMOTELY_PRESENT))
SyncException.wrapWithLocalResource(newLocal) { SyncException.wrapWithLocalResource(newLocal) {
newLocal.add() newLocal.add()
} }

View File

@@ -20,7 +20,7 @@ androidx-test-junit = "1.3.0"
androidx-work = "2.11.0" androidx-work = "2.11.0"
bitfire-cert4android = "42d883e958" bitfire-cert4android = "42d883e958"
bitfire-dav4jvm = "57321c95ad" bitfire-dav4jvm = "57321c95ad"
bitfire-synctools = "de78892b5c" bitfire-synctools = "42e82f4769"
compose-accompanist = "0.37.3" compose-accompanist = "0.37.3"
compose-bom = "2025.12.00" compose-bom = "2025.12.00"
conscrypt = "2.5.3" conscrypt = "2.5.3"