Loading app/src/main/java/at/bitfire/davdroid/settings/AccountSettings.kt +82 −2 Original line number Diff line number Diff line Loading @@ -19,10 +19,15 @@ import android.os.Bundle import android.os.Parcel import android.os.RemoteException import android.provider.CalendarContract import android.provider.CalendarContract.ExtendedProperties import android.provider.ContactsContract import android.util.Base64 import androidx.annotation.WorkerThread import androidx.core.content.ContextCompat import at.bitfire.davdroid.* import at.bitfire.davdroid.InvalidAccountException import at.bitfire.davdroid.R import at.bitfire.davdroid.TasksWatcher import at.bitfire.davdroid.closeCompat import at.bitfire.davdroid.log.Logger import at.bitfire.davdroid.model.AppDatabase import at.bitfire.davdroid.model.Collection Loading @@ -32,13 +37,19 @@ import at.bitfire.davdroid.resource.LocalAddressBook import at.bitfire.davdroid.resource.LocalTask import at.bitfire.davdroid.resource.TaskUtils import at.bitfire.ical4android.AndroidCalendar import at.bitfire.ical4android.AndroidEvent import at.bitfire.ical4android.TaskProvider import at.bitfire.ical4android.TaskProvider.ProviderName.OpenTasks import at.bitfire.ical4android.UnknownProperty import at.bitfire.vcard4android.ContactsStorageException import at.bitfire.vcard4android.GroupMethod import net.fortuna.ical4j.model.Property import net.fortuna.ical4j.model.property.Url import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import org.apache.commons.lang3.StringUtils import org.dmfs.tasks.contract.TaskContract import java.io.ByteArrayInputStream import java.io.ObjectInputStream import java.util.logging.Level /** Loading @@ -54,7 +65,7 @@ class AccountSettings( companion object { const val CURRENT_VERSION = 11 const val CURRENT_VERSION = 12 const val KEY_SETTINGS_VERSION = "version" const val KEY_SYNC_INTERVAL_ADDRESSBOOKS = "sync_interval_addressbooks" Loading Loading @@ -419,6 +430,75 @@ class AccountSettings( } @Suppress("unused","FunctionName") /** * Store event URLs as URL (extended property) instead of unknown property. At the same time, * convert legacy unknown properties to the current format. */ private fun update_11_12() { if (ContextCompat.checkSelfPermission(context, android.Manifest.permission.WRITE_CALENDAR) == PackageManager.PERMISSION_GRANTED) context.contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)?.use { provider -> // Attention: CalendarProvider does NOT limit the results of the ExtendedProperties query // to the given account! So all extended properties will be processed number-of-accounts times. val extUri = AndroidCalendar.syncAdapterURI(ExtendedProperties.CONTENT_URI, account) provider.query(extUri, arrayOf( ExtendedProperties._ID, // idx 0 ExtendedProperties.NAME, // idx 1 ExtendedProperties.VALUE // idx 2 ), null, null, null)?.use { cursor -> while (cursor.moveToNext()) { val id = cursor.getLong(0) val rawValue = cursor.getString(2) val uri by lazy { AndroidCalendar.syncAdapterURI(ContentUris.withAppendedId(ExtendedProperties.CONTENT_URI, id), account) } when (cursor.getString(1)) { UnknownProperty.CONTENT_ITEM_TYPE -> { // unknown property; check whether it's a URL try { val property = UnknownProperty.fromJsonString(rawValue) if (property is Url) { // rewrite to MIMETYPE_URL val newValues = ContentValues(2) newValues.put(ExtendedProperties.NAME, AndroidEvent.MIMETYPE_URL) newValues.put(ExtendedProperties.VALUE, property.value) provider.update(uri, newValues, null, null) } } catch (e: Exception) { Logger.log.log(Level.WARNING, "Couldn't rewrite URL from unknown property to ${AndroidEvent.MIMETYPE_URL}", e) } } "unknown-property" -> { // unknown property (deprecated format); convert to current format try { val stream = ByteArrayInputStream(Base64.decode(rawValue, Base64.NO_WRAP)) ObjectInputStream(stream).use { (it.readObject() as? Property)?.let { property -> // rewrite to current format val newValues = ContentValues(2) newValues.put(ExtendedProperties.NAME, UnknownProperty.CONTENT_ITEM_TYPE) newValues.put(ExtendedProperties.VALUE, UnknownProperty.toJsonString(property)) provider.update(uri, newValues, null, null) } } } catch(e: Exception) { Logger.log.log(Level.WARNING, "Couldn't rewrite deprecated unknown property to current format", e) } } "unknown-property.v2" -> { // unknown property (deprecated MIME type); rewrite to current MIME type val newValues = ContentValues(1) newValues.put(ExtendedProperties.NAME, UnknownProperty.CONTENT_ITEM_TYPE) provider.update(uri, newValues, null, null) } } } } } } @Suppress("unused","FunctionName") /** * The tasks sync interval should be stored in account settings. It's used to set the sync interval Loading ical4android @ 235cde2e Compare 7d79f861 to 235cde2e Original line number Diff line number Diff line Subproject commit 7d79f861b0822173a9aaa6a2ab1ab6b9f5adac8d Subproject commit 235cde2ec49bbdfb588988c732b90b89561492d6 Loading
app/src/main/java/at/bitfire/davdroid/settings/AccountSettings.kt +82 −2 Original line number Diff line number Diff line Loading @@ -19,10 +19,15 @@ import android.os.Bundle import android.os.Parcel import android.os.RemoteException import android.provider.CalendarContract import android.provider.CalendarContract.ExtendedProperties import android.provider.ContactsContract import android.util.Base64 import androidx.annotation.WorkerThread import androidx.core.content.ContextCompat import at.bitfire.davdroid.* import at.bitfire.davdroid.InvalidAccountException import at.bitfire.davdroid.R import at.bitfire.davdroid.TasksWatcher import at.bitfire.davdroid.closeCompat import at.bitfire.davdroid.log.Logger import at.bitfire.davdroid.model.AppDatabase import at.bitfire.davdroid.model.Collection Loading @@ -32,13 +37,19 @@ import at.bitfire.davdroid.resource.LocalAddressBook import at.bitfire.davdroid.resource.LocalTask import at.bitfire.davdroid.resource.TaskUtils import at.bitfire.ical4android.AndroidCalendar import at.bitfire.ical4android.AndroidEvent import at.bitfire.ical4android.TaskProvider import at.bitfire.ical4android.TaskProvider.ProviderName.OpenTasks import at.bitfire.ical4android.UnknownProperty import at.bitfire.vcard4android.ContactsStorageException import at.bitfire.vcard4android.GroupMethod import net.fortuna.ical4j.model.Property import net.fortuna.ical4j.model.property.Url import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import org.apache.commons.lang3.StringUtils import org.dmfs.tasks.contract.TaskContract import java.io.ByteArrayInputStream import java.io.ObjectInputStream import java.util.logging.Level /** Loading @@ -54,7 +65,7 @@ class AccountSettings( companion object { const val CURRENT_VERSION = 11 const val CURRENT_VERSION = 12 const val KEY_SETTINGS_VERSION = "version" const val KEY_SYNC_INTERVAL_ADDRESSBOOKS = "sync_interval_addressbooks" Loading Loading @@ -419,6 +430,75 @@ class AccountSettings( } @Suppress("unused","FunctionName") /** * Store event URLs as URL (extended property) instead of unknown property. At the same time, * convert legacy unknown properties to the current format. */ private fun update_11_12() { if (ContextCompat.checkSelfPermission(context, android.Manifest.permission.WRITE_CALENDAR) == PackageManager.PERMISSION_GRANTED) context.contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)?.use { provider -> // Attention: CalendarProvider does NOT limit the results of the ExtendedProperties query // to the given account! So all extended properties will be processed number-of-accounts times. val extUri = AndroidCalendar.syncAdapterURI(ExtendedProperties.CONTENT_URI, account) provider.query(extUri, arrayOf( ExtendedProperties._ID, // idx 0 ExtendedProperties.NAME, // idx 1 ExtendedProperties.VALUE // idx 2 ), null, null, null)?.use { cursor -> while (cursor.moveToNext()) { val id = cursor.getLong(0) val rawValue = cursor.getString(2) val uri by lazy { AndroidCalendar.syncAdapterURI(ContentUris.withAppendedId(ExtendedProperties.CONTENT_URI, id), account) } when (cursor.getString(1)) { UnknownProperty.CONTENT_ITEM_TYPE -> { // unknown property; check whether it's a URL try { val property = UnknownProperty.fromJsonString(rawValue) if (property is Url) { // rewrite to MIMETYPE_URL val newValues = ContentValues(2) newValues.put(ExtendedProperties.NAME, AndroidEvent.MIMETYPE_URL) newValues.put(ExtendedProperties.VALUE, property.value) provider.update(uri, newValues, null, null) } } catch (e: Exception) { Logger.log.log(Level.WARNING, "Couldn't rewrite URL from unknown property to ${AndroidEvent.MIMETYPE_URL}", e) } } "unknown-property" -> { // unknown property (deprecated format); convert to current format try { val stream = ByteArrayInputStream(Base64.decode(rawValue, Base64.NO_WRAP)) ObjectInputStream(stream).use { (it.readObject() as? Property)?.let { property -> // rewrite to current format val newValues = ContentValues(2) newValues.put(ExtendedProperties.NAME, UnknownProperty.CONTENT_ITEM_TYPE) newValues.put(ExtendedProperties.VALUE, UnknownProperty.toJsonString(property)) provider.update(uri, newValues, null, null) } } } catch(e: Exception) { Logger.log.log(Level.WARNING, "Couldn't rewrite deprecated unknown property to current format", e) } } "unknown-property.v2" -> { // unknown property (deprecated MIME type); rewrite to current MIME type val newValues = ContentValues(1) newValues.put(ExtendedProperties.NAME, UnknownProperty.CONTENT_ITEM_TYPE) provider.update(uri, newValues, null, null) } } } } } } @Suppress("unused","FunctionName") /** * The tasks sync interval should be stored in account settings. It's used to set the sync interval Loading
ical4android @ 235cde2e Compare 7d79f861 to 235cde2e Original line number Diff line number Diff line Subproject commit 7d79f861b0822173a9aaa6a2ab1ab6b9f5adac8d Subproject commit 235cde2ec49bbdfb588988c732b90b89561492d6