Revert changes when changing read only journals.

pull/71/head
Tom Hacohen 5 years ago
parent 7216a177c5
commit cabea0c3ec

@ -11,7 +11,4 @@ package com.etesync.syncadapter.resource
import at.bitfire.vcard4android.Contact
interface LocalAddress: LocalResource<Contact> {
fun resetDeleted()
}

@ -136,6 +136,12 @@ class LocalEvent : AndroidEvent, LocalResource<Event> {
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)

@ -22,4 +22,6 @@ interface LocalResource<in TData: Any> {
fun prepareForUpload()
fun clearDirty(eTag: String)
fun resetDeleted()
}

@ -104,6 +104,12 @@ class LocalTask : AndroidTask, LocalResource<Task> {
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)

@ -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<Persistable>
@ -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<T>(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

@ -341,6 +341,9 @@
<string name="sync_successfully_tasks" formatted="false">Tasks \"%s\" modified (%s)</string>
<string name="sync_successfully_modified" formatted="false">%s modified.</string>
<string name="sync_successfully_modified_full" formatted="false">%s added.\n%s updated.\n%s deleted.</string>
<string name="sync_journal_readonly">Journal \"%s\" is read only</string>
<string name="sync_journal_readonly_message">The journal is read only so all of your changes (%d) have been reverted.</string>
<!-- Calendar invites -->
<string name="sync_calendar_attendees_notification_title" formatted="false">%s</string>

Loading…
Cancel
Save