From cabea0c3ecdfa84c397bfaf99d5b57910e43004f Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Wed, 13 Feb 2019 14:42:51 +0000 Subject: [PATCH] Revert changes when changing read only journals. --- .../syncadapter/resource/LocalAddress.kt | 3 - .../syncadapter/resource/LocalEvent.kt | 6 ++ .../syncadapter/resource/LocalResource.kt | 2 + .../etesync/syncadapter/resource/LocalTask.kt | 6 ++ .../syncadapter/syncadapter/SyncManager.kt | 62 +++++++++++++++---- app/src/main/res/values/strings.xml | 3 + 6 files changed, 66 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/etesync/syncadapter/resource/LocalAddress.kt b/app/src/main/java/com/etesync/syncadapter/resource/LocalAddress.kt index 8fbdf95f..66fa3474 100644 --- a/app/src/main/java/com/etesync/syncadapter/resource/LocalAddress.kt +++ b/app/src/main/java/com/etesync/syncadapter/resource/LocalAddress.kt @@ -11,7 +11,4 @@ package com.etesync.syncadapter.resource import at.bitfire.vcard4android.Contact interface LocalAddress: LocalResource { - - fun resetDeleted() - } \ No newline at end of file diff --git a/app/src/main/java/com/etesync/syncadapter/resource/LocalEvent.kt b/app/src/main/java/com/etesync/syncadapter/resource/LocalEvent.kt index 01762a3f..6449061d 100644 --- a/app/src/main/java/com/etesync/syncadapter/resource/LocalEvent.kt +++ b/app/src/main/java/com/etesync/syncadapter/resource/LocalEvent.kt @@ -136,6 +136,12 @@ class LocalEvent : AndroidEvent, LocalResource { event.uid = uid } + override fun resetDeleted() { + val values = ContentValues(1) + values.put(CalendarContract.Events.DELETED, 0) + calendar.provider.update(eventSyncURI(), values, null, null) + } + override fun clearDirty(eTag: String) { val values = ContentValues(2) values.put(CalendarContract.Events.DIRTY, 0) diff --git a/app/src/main/java/com/etesync/syncadapter/resource/LocalResource.kt b/app/src/main/java/com/etesync/syncadapter/resource/LocalResource.kt index 89e5d286..e275fa49 100644 --- a/app/src/main/java/com/etesync/syncadapter/resource/LocalResource.kt +++ b/app/src/main/java/com/etesync/syncadapter/resource/LocalResource.kt @@ -22,4 +22,6 @@ interface LocalResource { fun prepareForUpload() fun clearDirty(eTag: String) + + fun resetDeleted() } diff --git a/app/src/main/java/com/etesync/syncadapter/resource/LocalTask.kt b/app/src/main/java/com/etesync/syncadapter/resource/LocalTask.kt index 24e67995..6f292ed3 100644 --- a/app/src/main/java/com/etesync/syncadapter/resource/LocalTask.kt +++ b/app/src/main/java/com/etesync/syncadapter/resource/LocalTask.kt @@ -104,6 +104,12 @@ class LocalTask : AndroidTask, LocalResource { task.uid = uid } + override fun resetDeleted() { + val values = ContentValues(1) + values.put(TaskContract.Tasks._DELETED, 0) + taskList.provider.client.update(taskSyncURI(), values, null, null) + } + override fun clearDirty(eTag: String) { val values = ContentValues(2) values.put(TaskContract.Tasks._DIRTY, 0) diff --git a/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncManager.kt b/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncManager.kt index a3e3f570..a9e4a69c 100644 --- a/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncManager.kt +++ b/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncManager.kt @@ -10,6 +10,7 @@ package com.etesync.syncadapter.syncadapter import android.accounts.Account import android.annotation.TargetApi import android.content.Context +import android.content.Intent import android.content.SyncResult import android.os.Bundle import at.bitfire.ical4android.CalendarStorageException @@ -24,6 +25,7 @@ import com.etesync.syncadapter.model.* import com.etesync.syncadapter.model.SyncEntry.Actions.ADD import com.etesync.syncadapter.resource.LocalCollection import com.etesync.syncadapter.resource.LocalResource +import com.etesync.syncadapter.ui.AccountsActivity import com.etesync.syncadapter.ui.DebugInfoActivity import com.etesync.syncadapter.ui.ViewCollectionActivity import io.requery.Persistable @@ -46,6 +48,8 @@ constructor(protected val context: Context, protected val account: Account, prot protected var journal: JournalEntryManager? = null private var _journalEntity: JournalEntity? = null + private var numDiscarded = 0 + private val crypto: Crypto.CryptoManager private val data: EntityDataStore @@ -168,6 +172,9 @@ constructor(protected val context: Context, protected val account: Account, prot App.log.info("Sync phase: " + context.getString(syncPhase)) postProcess() + if (numDiscarded > 0) { + notifyDiscardedChange() + } notifyUserOnSync() App.log.info("Finished sync with CTag=$remoteCTag") @@ -459,14 +466,22 @@ constructor(protected val context: Context, protected val account: Account, prot val localList = localCollection!!.findDeleted() val ret = ArrayList(localList.size) - for (local in localList) { - if (Thread.interrupted()) - return ret + if (journalEntity.isReadOnly) { + for (local in localList) { + App.log.info("Restoring locally deleted resource on a read only collection: ${local.uuid}") + local.resetDeleted() + numDiscarded++ + } + } else { + for (local in localList) { + if (Thread.interrupted()) + return ret - App.log.info(local.uuid + " has been deleted locally -> deleting from server") - ret.add(local) + App.log.info(local.uuid + " has been deleted locally -> deleting from server") + ret.add(local) - syncResult.stats.numDeletes++ + syncResult.stats.numDeletes++ + } } return ret @@ -474,15 +489,30 @@ constructor(protected val context: Context, protected val account: Account, prot @Throws(CalendarStorageException::class, ContactsStorageException::class) protected open fun prepareDirty() { - // assign file names and UIDs to new entries - App.log.info("Looking for local entries without a uuid") - for (local in localDirty) { - if (local.uuid != null) { - continue + if (journalEntity.isReadOnly) { + for (local in localDirty) { + App.log.info("Restoring locally modified resource on a read only collection: ${local.uuid}") + if (local.uuid == null) { + // If it was only local, delete. + local.delete() + } else { + local.clearDirty(local.uuid!!) + } + numDiscarded++ } - App.log.fine("Found local record without file name; generating file name/UID if necessary") - local.prepareForUpload() + localDirty = LinkedList() + } else { + // assign file names and UIDs to new entries + App.log.info("Looking for local entries without a uuid") + for (local in localDirty) { + if (local.uuid != null) { + continue + } + + App.log.fine("Found local record without file name; generating file name/UID if necessary") + local.prepareForUpload() + } } } @@ -493,6 +523,12 @@ constructor(protected val context: Context, protected val account: Account, prot protected open fun postProcess() { } + private fun notifyDiscardedChange() { + val notification = NotificationHelper(context, "discarded_${info.uid}", notificationId()) + val intent = Intent(context, AccountsActivity::class.java) + notification.notify(context.getString(R.string.sync_journal_readonly, info.displayName), context.getString(R.string.sync_journal_readonly_message, numDiscarded), null, intent, R.drawable.ic_error_light) + } + companion object { private val MAX_FETCH = 50 private val MAX_PUSH = 30 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ab1114fb..62a8788b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -341,6 +341,9 @@ Tasks \"%s\" modified (%s) %s modified. %s added.\n%s updated.\n%s deleted. + Journal \"%s\" is read only + The journal is read only so all of your changes (%d) have been reverted. + %s