diff --git a/app/src/main/java/com/todoroo/astrid/service/TaskDeleter.kt b/app/src/main/java/com/todoroo/astrid/service/TaskDeleter.kt index f25d45f93..6b90b4094 100644 --- a/app/src/main/java/com/todoroo/astrid/service/TaskDeleter.kt +++ b/app/src/main/java/com/todoroo/astrid/service/TaskDeleter.kt @@ -1,31 +1,49 @@ package com.todoroo.astrid.service +import android.content.Context +import androidx.room.withTransaction +import com.todoroo.astrid.alarms.AlarmService import com.todoroo.astrid.api.Filter import com.todoroo.astrid.api.FilterImpl +import com.todoroo.astrid.dao.Database import com.todoroo.astrid.data.Task +import com.todoroo.astrid.timers.TimerPlugin +import dagger.hilt.android.qualifiers.ApplicationContext +import org.tasks.BuildConfig import org.tasks.LocalBroadcastManager import org.tasks.caldav.VtodoCache import org.tasks.data.CaldavAccount import org.tasks.data.CaldavCalendar import org.tasks.data.DeletionDao +import org.tasks.data.LocationDao import org.tasks.data.TaskContainer import org.tasks.data.TaskDao +import org.tasks.data.UserActivityDao import org.tasks.db.QueryUtils import org.tasks.db.SuspendDbUtils.chunkedMap -import org.tasks.jobs.WorkManager +import org.tasks.files.FileHelper +import org.tasks.location.GeofenceApi +import org.tasks.notifications.NotificationManager import org.tasks.preferences.Preferences import org.tasks.sync.SyncAdapters import javax.inject.Inject class TaskDeleter @Inject constructor( - private val deletionDao: DeletionDao, - private val workManager: WorkManager, - private val taskDao: TaskDao, - private val localBroadcastManager: LocalBroadcastManager, - private val preferences: Preferences, - private val syncAdapters: SyncAdapters, - private val vtodoCache: VtodoCache, - ) { + @ApplicationContext private val context: Context, + private val database: Database, + private val deletionDao: DeletionDao, + private val taskDao: TaskDao, + private val localBroadcastManager: LocalBroadcastManager, + private val preferences: Preferences, + private val syncAdapters: SyncAdapters, + private val vtodoCache: VtodoCache, + private val notificationManager: NotificationManager, + private val geofenceApi: GeofenceApi, + private val timerPlugin: TimerPlugin, + private val alarmService: AlarmService, + private val userActivityDao: UserActivityDao, + private val locationDao: LocationDao, +) { suspend fun markDeleted(item: Task) = markDeleted(listOf(item.id)) @@ -36,8 +54,10 @@ class TaskDeleter @Inject constructor( .let { taskDao.fetch(it.toList()) } .filterNot { it.readOnly } .map { it.id } - deletionDao.markDeleted(ids) - workManager.cleanup(ids) + database.withTransaction { + deletionDao.markDeleted(ids) + cleanup(ids) + } syncAdapters.sync() localBroadcastManager.broadcastRefresh() return taskDao.fetch(ids) @@ -62,22 +82,48 @@ class TaskDeleter @Inject constructor( suspend fun delete(task: Long) = delete(listOf(task)) suspend fun delete(tasks: List) { - deletionDao.delete(tasks) - workManager.cleanup(tasks) + database.withTransaction { + deletionDao.delete(tasks) + cleanup(tasks) + } localBroadcastManager.broadcastRefresh() } suspend fun delete(list: CaldavCalendar) { vtodoCache.delete(list) - val tasks = deletionDao.delete(list) - delete(tasks) + database.withTransaction { + val tasks = deletionDao.delete(list) + delete(tasks) + } localBroadcastManager.broadcastRefreshList() } suspend fun delete(list: CaldavAccount) { vtodoCache.delete(list) - val tasks = deletionDao.delete(list) - delete(tasks) + database.withTransaction { + val tasks = deletionDao.delete(list) + delete(tasks) + } localBroadcastManager.broadcastRefreshList() } -} \ No newline at end of file + + private suspend fun cleanup(tasks: List) { + if (BuildConfig.DEBUG && !database.inTransaction()) { + throw IllegalStateException() + } + tasks.forEach { task -> + alarmService.cancelAlarms(task) + notificationManager.cancel(task) + locationDao.getGeofencesForTask(task).forEach { + locationDao.delete(it) + geofenceApi.update(it.place!!) + } + userActivityDao.getComments(task).forEach { + FileHelper.delete(context, it.pictureUri) + userActivityDao.delete(it) + } + } + timerPlugin.updateNotifications() + deletionDao.purgeDeleted() + } +} diff --git a/app/src/main/java/org/tasks/jobs/CleanupWork.kt b/app/src/main/java/org/tasks/jobs/CleanupWork.kt deleted file mode 100644 index 7eaa3b43f..000000000 --- a/app/src/main/java/org/tasks/jobs/CleanupWork.kt +++ /dev/null @@ -1,62 +0,0 @@ -package org.tasks.jobs - -import android.content.Context -import androidx.hilt.work.HiltWorker -import androidx.work.WorkerParameters -import com.todoroo.astrid.alarms.AlarmService -import com.todoroo.astrid.timers.TimerPlugin -import dagger.assisted.Assisted -import dagger.assisted.AssistedInject -import kotlinx.coroutines.runBlocking -import org.tasks.analytics.Firebase -import org.tasks.data.DeletionDao -import org.tasks.data.LocationDao -import org.tasks.data.UserActivityDao -import org.tasks.files.FileHelper -import org.tasks.injection.BaseWorker -import org.tasks.location.GeofenceApi -import org.tasks.notifications.NotificationManager -import timber.log.Timber - -@HiltWorker -class CleanupWork @AssistedInject constructor( - @Assisted context: Context, - @Assisted workerParams: WorkerParameters, - firebase: Firebase, - private val notificationManager: NotificationManager, - private val geofenceApi: GeofenceApi, - private val timerPlugin: TimerPlugin, - private val alarmService: AlarmService, - private val userActivityDao: UserActivityDao, - private val locationDao: LocationDao, - private val deletionDao: DeletionDao) : BaseWorker(context, workerParams, firebase) { - - override suspend fun run(): Result { - val tasks = inputData.getLongArray(EXTRA_TASK_IDS) - if (tasks == null) { - Timber.e("No task ids provided") - return Result.failure() - } - tasks.forEach { task -> - runBlocking { - alarmService.cancelAlarms(task) - } - notificationManager.cancel(task) - locationDao.getGeofencesForTask(task).forEach { - locationDao.delete(it) - geofenceApi.update(it.place!!) - } - userActivityDao.getComments(task).forEach { - FileHelper.delete(context, it.pictureUri) - userActivityDao.delete(it) - } - } - timerPlugin.updateNotifications() - deletionDao.purgeDeleted() - return Result.success() - } - - companion object { - const val EXTRA_TASK_IDS = "extra_task_ids" - } -} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/jobs/WorkManager.kt b/app/src/main/java/org/tasks/jobs/WorkManager.kt index ec49bfd1c..a4be58127 100644 --- a/app/src/main/java/org/tasks/jobs/WorkManager.kt +++ b/app/src/main/java/org/tasks/jobs/WorkManager.kt @@ -12,8 +12,6 @@ interface WorkManager { fun updateCalendar(task: Task) - fun cleanup(ids: Iterable) - fun migrateLocalTasks(caldavAccount: CaldavAccount) suspend fun sync(immediate: Boolean) @@ -42,7 +40,6 @@ interface WorkManager { companion object { val REMOTE_CONFIG_INTERVAL_HOURS = if (BuildConfig.DEBUG) 1 else 12.toLong() - const val MAX_CLEANUP_LENGTH = 500 const val TAG_BACKUP = "tag_backup" const val TAG_REFRESH = "tag_refresh" const val TAG_MIDNIGHT_REFRESH = "tag_midnight_refresh" diff --git a/app/src/main/java/org/tasks/jobs/WorkManagerImpl.kt b/app/src/main/java/org/tasks/jobs/WorkManagerImpl.kt index f17a3a67d..131b42013 100644 --- a/app/src/main/java/org/tasks/jobs/WorkManagerImpl.kt +++ b/app/src/main/java/org/tasks/jobs/WorkManagerImpl.kt @@ -29,7 +29,6 @@ import org.tasks.jobs.DriveUploader.Companion.EXTRA_URI import org.tasks.jobs.MigrateLocalWork.Companion.EXTRA_ACCOUNT import org.tasks.jobs.SyncWork.Companion.EXTRA_BACKGROUND import org.tasks.jobs.SyncWork.Companion.EXTRA_IMMEDIATE -import org.tasks.jobs.WorkManager.Companion.MAX_CLEANUP_LENGTH import org.tasks.jobs.WorkManager.Companion.REMOTE_CONFIG_INTERVAL_HOURS import org.tasks.jobs.WorkManager.Companion.TAG_BACKGROUND_SYNC import org.tasks.jobs.WorkManager.Companion.TAG_BACKUP @@ -82,15 +81,6 @@ class WorkManagerImpl( enqueue(workManager.beginUniqueWork(TAG_MIGRATE_LOCAL, APPEND_OR_REPLACE, builder.build())) } - override fun cleanup(ids: Iterable) { - ids.chunked(MAX_CLEANUP_LENGTH) { - enqueue( - OneTimeWorkRequest.Builder(CleanupWork::class.java) - .setInputData(CleanupWork.EXTRA_TASK_IDS to it.toLongArray()) - ) - } - } - override suspend fun startEnqueuedSync() { if (getSyncJob().any { it.state == WorkInfo.State.ENQUEUED }) { sync(true)