1
0
mirror of https://github.com/etesync/android synced 2025-05-29 20:28:48 +00:00

Move everything to use the new Logger

This commit is contained in:
Tom Hacohen 2019-03-14 19:21:41 +00:00
parent 216b51d138
commit 17b6e69c86
42 changed files with 266 additions and 315 deletions

View File

@ -20,6 +20,7 @@ import android.os.Bundle
import at.bitfire.vcard4android.ContactsStorageException import at.bitfire.vcard4android.ContactsStorageException
import at.bitfire.vcard4android.GroupMethod import at.bitfire.vcard4android.GroupMethod
import com.etesync.syncadapter.journalmanager.Crypto import com.etesync.syncadapter.journalmanager.Crypto
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.utils.Base64 import com.etesync.syncadapter.utils.Base64
import java.net.URI import java.net.URI
import java.net.URISyntaxException import java.net.URISyntaxException
@ -110,7 +111,7 @@ constructor(internal val context: Context, internal val account: Account) {
} catch (ignored: NumberFormatException) { } catch (ignored: NumberFormatException) {
} }
App.log.fine("Account " + account.name + " has version " + version + ", current version: " + CURRENT_VERSION) Logger.log.fine("Account " + account.name + " has version " + version + ", current version: " + CURRENT_VERSION)
if (version < CURRENT_VERSION) if (version < CURRENT_VERSION)
update(version) update(version)
@ -168,12 +169,12 @@ constructor(internal val context: Context, internal val account: Account) {
private fun update(fromVersion: Int) { private fun update(fromVersion: Int) {
val toVersion = CURRENT_VERSION val toVersion = CURRENT_VERSION
App.log.info("Updating account " + account.name + " from version " + fromVersion + " to " + toVersion) Logger.log.info("Updating account " + account.name + " from version " + fromVersion + " to " + toVersion)
try { try {
updateInner(fromVersion) updateInner(fromVersion)
accountManager.setUserData(account, KEY_SETTINGS_VERSION, toVersion.toString()) accountManager.setUserData(account, KEY_SETTINGS_VERSION, toVersion.toString())
} catch (e: Exception) { } catch (e: Exception) {
App.log.log(Level.SEVERE, "Couldn't update account settings", e) Logger.log.log(Level.SEVERE, "Couldn't update account settings", e)
} }
} }
@ -188,16 +189,16 @@ constructor(internal val context: Context, internal val account: Account) {
@SuppressLint("UnsafeProtectedBroadcastReceiver,MissingPermission") @SuppressLint("UnsafeProtectedBroadcastReceiver,MissingPermission")
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
App.log.info("EteSync was updated, checking for AccountSettings version") Logger.log.info("EteSync was updated, checking for AccountSettings version")
// peek into AccountSettings to initiate a possible migration // peek into AccountSettings to initiate a possible migration
val accountManager = AccountManager.get(context) val accountManager = AccountManager.get(context)
for (account in accountManager.getAccountsByType(App.accountType)) for (account in accountManager.getAccountsByType(App.accountType))
try { try {
App.log.info("Checking account " + account.name) Logger.log.info("Checking account " + account.name)
AccountSettings(context, account) AccountSettings(context, account)
} catch (e: InvalidAccountException) { } catch (e: InvalidAccountException) {
App.log.log(Level.SEVERE, "Couldn't check for updated account settings", e) Logger.log.log(Level.SEVERE, "Couldn't check for updated account settings", e)
} }
} }

View File

@ -15,6 +15,7 @@ import android.content.Intent
import android.os.Binder import android.os.Binder
import android.os.IBinder import android.os.IBinder
import at.bitfire.vcard4android.ContactsStorageException import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.ServiceEntity import com.etesync.syncadapter.model.ServiceEntity
import com.etesync.syncadapter.resource.LocalAddressBook import com.etesync.syncadapter.resource.LocalAddressBook
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@ -83,7 +84,7 @@ class AccountUpdateService : Service() {
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
internal fun cleanupAccounts() { internal fun cleanupAccounts() {
App.log.info("Cleaning up orphaned accounts") Logger.log.info("Cleaning up orphaned accounts")
val accountNames = LinkedList<String>() val accountNames = LinkedList<String>()
val am = AccountManager.get(this) val am = AccountManager.get(this)
@ -100,7 +101,7 @@ class AccountUpdateService : Service() {
if (!accountNames.contains(addressBook.mainAccount.name)) if (!accountNames.contains(addressBook.mainAccount.name))
addressBook.delete() addressBook.delete()
} catch (e: ContactsStorageException) { } catch (e: ContactsStorageException) {
App.log.log(Level.SEVERE, "Couldn't get address book main account", e) Logger.log.log(Level.SEVERE, "Couldn't get address book main account", e)
} }
} }

View File

@ -13,6 +13,7 @@ import android.accounts.OnAccountsUpdateListener
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import com.etesync.syncadapter.log.Logger
import java.util.* import java.util.*
class AccountsChangedReceiver : BroadcastReceiver() { class AccountsChangedReceiver : BroadcastReceiver() {
@ -24,7 +25,7 @@ class AccountsChangedReceiver : BroadcastReceiver() {
try { try {
context.startService(serviceIntent) context.startService(serviceIntent)
} catch (e: IllegalStateException) { } catch (e: IllegalStateException) {
App.log.warning("Got an illegal state exception! Ignoring...") Logger.log.warning("Got an illegal state exception! Ignoring...")
} }
for (listener in listeners) for (listener in listeners)

View File

@ -18,20 +18,15 @@ import android.database.sqlite.SQLiteDatabase
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.BitmapDrawable
import android.os.Build import android.os.Build
import android.os.Process
import android.os.StrictMode import android.os.StrictMode
import android.provider.CalendarContract import android.provider.CalendarContract
import android.provider.ContactsContract import android.provider.ContactsContract
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import android.util.Log
import at.bitfire.cert4android.CustomCertManager import at.bitfire.cert4android.CustomCertManager
import at.bitfire.ical4android.AndroidCalendar import at.bitfire.ical4android.AndroidCalendar
import at.bitfire.ical4android.CalendarStorageException import at.bitfire.ical4android.CalendarStorageException
import at.bitfire.vcard4android.ContactsStorageException import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.log.LogcatHandler import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.log.PlainTextFormatter
import com.etesync.syncadapter.model.* import com.etesync.syncadapter.model.*
import com.etesync.syncadapter.resource.LocalAddressBook import com.etesync.syncadapter.resource.LocalAddressBook
import com.etesync.syncadapter.resource.LocalCalendar import com.etesync.syncadapter.resource.LocalCalendar
@ -44,14 +39,8 @@ import io.requery.meta.EntityModel
import io.requery.sql.EntityDataStore import io.requery.sql.EntityDataStore
import okhttp3.internal.tls.OkHostnameVerifier import okhttp3.internal.tls.OkHostnameVerifier
import org.acra.ACRA import org.acra.ACRA
import org.apache.commons.lang3.time.DateFormatUtils
import org.jetbrains.anko.doAsync import org.jetbrains.anko.doAsync
import java.io.File
import java.io.IOException
import java.util.* import java.util.*
import java.util.logging.FileHandler
import java.util.logging.Level
import java.util.logging.Logger
import javax.net.ssl.HostnameVerifier import javax.net.ssl.HostnameVerifier
@ -145,72 +134,14 @@ class App : Application() {
} }
fun reinitLogger() { fun reinitLogger() {
val dbHelper = ServiceDB.OpenHelper(this) Logger.initialize(this)
val settings = Settings(dbHelper.readableDatabase)
val logToFile = settings.getBoolean(LOG_TO_EXTERNAL_STORAGE, false)
val logVerbose = logToFile || Log.isLoggable(log.name, Log.DEBUG)
App.log.info("Verbose logging: $logVerbose")
// set logging level according to preferences
val rootLogger = Logger.getLogger("")
rootLogger.level = if (logVerbose) Level.ALL else Level.INFO
// remove all handlers and add our own logcat handler
rootLogger.useParentHandlers = false
for (handler in rootLogger.handlers)
rootLogger.removeHandler(handler)
rootLogger.addHandler(LogcatHandler)
val nm = NotificationManagerCompat.from(this)
// log to external file according to preferences
if (logToFile) {
val builder = NotificationCompat.Builder(this)
builder.setSmallIcon(R.drawable.ic_sd_storage_light)
.setLargeIcon(getLauncherBitmap(this))
.setContentTitle(getString(R.string.logging_davdroid_file_logging))
.setLocalOnly(true)
val dir = getExternalFilesDir(null)
if (dir != null)
try {
val fileName = File(dir, "etesync-" + Process.myPid() + "-" +
DateFormatUtils.format(System.currentTimeMillis(), "yyyyMMdd-HHmmss") + ".txt").toString()
log.info("Logging to $fileName")
val fileHandler = FileHandler(fileName)
fileHandler.formatter = PlainTextFormatter.DEFAULT
log.addHandler(fileHandler)
builder.setContentText(dir.path)
.setSubText(getString(R.string.logging_to_external_storage_warning))
.setCategory(NotificationCompat.CATEGORY_STATUS)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setStyle(NotificationCompat.BigTextStyle()
.bigText(getString(R.string.logging_to_external_storage, dir.path)))
.setOngoing(true)
} catch (e: IOException) {
log.log(Level.SEVERE, "Couldn't create external log file", e)
builder.setContentText(getString(R.string.logging_couldnt_create_file, e.localizedMessage))
.setCategory(NotificationCompat.CATEGORY_ERROR)
}
else
builder.setContentText(getString(R.string.logging_no_external_storage))
nm.notify(Constants.NOTIFICATION_EXTERNAL_FILE_LOGGING, builder.build())
} else
nm.cancel(Constants.NOTIFICATION_EXTERNAL_FILE_LOGGING)
dbHelper.close()
} }
class ReinitSettingsReceiver : BroadcastReceiver() { class ReinitSettingsReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
log.info("Received broadcast: re-initializing settings (logger/cert manager)") Logger.log.info("Received broadcast: re-initializing settings (logger/cert manager)")
val app = context.applicationContext as App val app = context.applicationContext as App
app.reinitLogger() app.reinitLogger()
@ -259,7 +190,7 @@ class App : Application() {
} }
private fun update(fromVersion: Int) { private fun update(fromVersion: Int) {
App.log.info("Updating from version " + fromVersion + " to " + BuildConfig.VERSION_CODE) Logger.log.info("Updating from version " + fromVersion + " to " + BuildConfig.VERSION_CODE)
if (fromVersion < 6) { if (fromVersion < 6) {
val data = this.data val data = this.data
@ -324,7 +255,7 @@ class App : Application() {
@SuppressLint("UnsafeProtectedBroadcastReceiver,MissingPermission") @SuppressLint("UnsafeProtectedBroadcastReceiver,MissingPermission")
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
App.log.info("EteSync was updated, checking for app version") Logger.log.info("EteSync was updated, checking for app version")
val app = context.applicationContext as App val app = context.applicationContext as App
val prefs = app.getSharedPreferences("app", Context.MODE_PRIVATE) val prefs = app.getSharedPreferences("app", Context.MODE_PRIVATE)
@ -396,10 +327,8 @@ class App : Application() {
var hostnameVerifier: HostnameVerifier? = null var hostnameVerifier: HostnameVerifier? = null
private set private set
val log = Logger.getLogger("etesync")
init { init {
at.bitfire.cert4android.Constants.log = Logger.getLogger("etesync.cert4android") at.bitfire.cert4android.Constants.log = java.util.logging.Logger.getLogger("etesync.cert4android")
} }
lateinit var accountType: String lateinit var accountType: String

View File

@ -24,7 +24,8 @@ import java.text.SimpleDateFormat
import java.util.* import java.util.*
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.logging.Level import java.util.logging.Level
import java.util.logging.Logger import java.util.logging.Logger as LoggerType
import com.etesync.syncadapter.log.Logger
object HttpClient { object HttpClient {
private val client = OkHttpClient() private val client = OkHttpClient()
@ -36,7 +37,7 @@ object HttpClient {
userAgent = "${App.appName}/${BuildConfig.VERSION_NAME} (okhttp3) Android/${Build.VERSION.RELEASE}" userAgent = "${App.appName}/${BuildConfig.VERSION_NAME} (okhttp3) Android/${Build.VERSION.RELEASE}"
} }
fun create(context: Context?, logger: Logger, host: String?, token: String): OkHttpClient { fun create(context: Context?, logger: LoggerType, host: String?, token: String): OkHttpClient {
var builder = defaultBuilder(context, logger) var builder = defaultBuilder(context, logger)
// use account settings for authentication // use account settings for authentication
@ -46,21 +47,21 @@ object HttpClient {
} }
@JvmOverloads @JvmOverloads
fun create(context: Context?, settings: AccountSettings, logger: Logger = App.log): OkHttpClient { fun create(context: Context?, settings: AccountSettings, logger: LoggerType = Logger.log): OkHttpClient {
return create(context, logger, settings.uri!!.host, settings.authToken) return create(context, logger, settings.uri!!.host, settings.authToken)
} }
@JvmOverloads @JvmOverloads
fun create(context: Context?, logger: Logger = App.log): OkHttpClient { fun create(context: Context?, logger: LoggerType = Logger.log): OkHttpClient {
return defaultBuilder(context, logger).build() return defaultBuilder(context, logger).build()
} }
fun create(context: Context?, uri: URI, authToken: String): OkHttpClient { fun create(context: Context?, uri: URI, authToken: String): OkHttpClient {
return create(context, App.log, uri.host, authToken) return create(context, Logger.log, uri.host, authToken)
} }
private fun defaultBuilder(context: Context?, logger: Logger): OkHttpClient.Builder { private fun defaultBuilder(context: Context?, logger: LoggerType): OkHttpClient.Builder {
val builder = client.newBuilder() val builder = client.newBuilder()
// use MemorizingTrustManager to manage self-signed certificates // use MemorizingTrustManager to manage self-signed certificates
@ -90,12 +91,12 @@ object HttpClient {
val proxy = Proxy(Proxy.Type.HTTP, address) val proxy = Proxy(Proxy.Type.HTTP, address)
builder.proxy(proxy) builder.proxy(proxy)
App.log.log(Level.INFO, "Using proxy", proxy) Logger.log.log(Level.INFO, "Using proxy", proxy)
} }
} catch (e: IllegalArgumentException) { } catch (e: IllegalArgumentException) {
App.log.log(Level.SEVERE, "Can't set proxy, ignoring", e) Logger.log.log(Level.SEVERE, "Can't set proxy, ignoring", e)
} catch (e: NullPointerException) { } catch (e: NullPointerException) {
App.log.log(Level.SEVERE, "Can't set proxy, ignoring", e) Logger.log.log(Level.SEVERE, "Can't set proxy, ignoring", e)
} finally { } finally {
dbHelper.close() dbHelper.close()
} }

View File

@ -15,6 +15,7 @@ import androidx.core.app.NotificationManagerCompat
import at.bitfire.ical4android.CalendarStorageException import at.bitfire.ical4android.CalendarStorageException
import at.bitfire.vcard4android.ContactsStorageException import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.journalmanager.Exceptions import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.ui.AccountSettingsActivity import com.etesync.syncadapter.ui.AccountSettingsActivity
import com.etesync.syncadapter.ui.DebugInfoActivity import com.etesync.syncadapter.ui.DebugInfoActivity
import com.etesync.syncadapter.ui.WebViewActivity import com.etesync.syncadapter.ui.WebViewActivity
@ -36,28 +37,28 @@ class NotificationHelper(internal val context: Context, internal val notificatio
fun setThrowable(e: Throwable) { fun setThrowable(e: Throwable) {
throwable = e throwable = e
if (e is Exceptions.UnauthorizedException) { if (e is Exceptions.UnauthorizedException) {
App.log.log(Level.SEVERE, "Not authorized anymore", e) Logger.log.log(Level.SEVERE, "Not authorized anymore", e)
messageString = R.string.sync_error_unauthorized messageString = R.string.sync_error_unauthorized
} else if (e is Exceptions.UserInactiveException) { } else if (e is Exceptions.UserInactiveException) {
App.log.log(Level.SEVERE, "User inactive") Logger.log.log(Level.SEVERE, "User inactive")
messageString = R.string.sync_error_user_inactive messageString = R.string.sync_error_user_inactive
} else if (e is Exceptions.ServiceUnavailableException) { } else if (e is Exceptions.ServiceUnavailableException) {
App.log.log(Level.SEVERE, "Service unavailable") Logger.log.log(Level.SEVERE, "Service unavailable")
messageString = R.string.sync_error_unavailable messageString = R.string.sync_error_unavailable
} else if (e is Exceptions.ReadOnlyException) { } else if (e is Exceptions.ReadOnlyException) {
App.log.log(Level.SEVERE, "Journal is read only", e) Logger.log.log(Level.SEVERE, "Journal is read only", e)
messageString = R.string.sync_error_journal_readonly messageString = R.string.sync_error_journal_readonly
} else if (e is Exceptions.HttpException) { } else if (e is Exceptions.HttpException) {
App.log.log(Level.SEVERE, "HTTP Exception during sync", e) Logger.log.log(Level.SEVERE, "HTTP Exception during sync", e)
messageString = R.string.sync_error_http_dav messageString = R.string.sync_error_http_dav
} else if (e is CalendarStorageException || e is ContactsStorageException || e is SQLiteException) { } else if (e is CalendarStorageException || e is ContactsStorageException || e is SQLiteException) {
App.log.log(Level.SEVERE, "Couldn't access local storage", e) Logger.log.log(Level.SEVERE, "Couldn't access local storage", e)
messageString = R.string.sync_error_local_storage messageString = R.string.sync_error_local_storage
} else if (e is Exceptions.IntegrityException) { } else if (e is Exceptions.IntegrityException) {
App.log.log(Level.SEVERE, "Integrity error", e) Logger.log.log(Level.SEVERE, "Integrity error", e)
messageString = R.string.sync_error_integrity messageString = R.string.sync_error_integrity
} else { } else {
App.log.log(Level.SEVERE, "Unknown sync error", e) Logger.log.log(Level.SEVERE, "Unknown sync error", e)
messageString = R.string.sync_error messageString = R.string.sync_error
} }

View File

@ -16,6 +16,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.provider.CalendarContract import android.provider.CalendarContract
import at.bitfire.ical4android.TaskProvider import at.bitfire.ical4android.TaskProvider
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.resource.LocalTaskList import com.etesync.syncadapter.resource.LocalTaskList
class PackageChangedReceiver : BroadcastReceiver() { class PackageChangedReceiver : BroadcastReceiver() {
@ -30,7 +31,7 @@ class PackageChangedReceiver : BroadcastReceiver() {
internal fun updateTaskSync(context: Context) { internal fun updateTaskSync(context: Context) {
val tasksInstalled = LocalTaskList.tasksProviderAvailable(context) val tasksInstalled = LocalTaskList.tasksProviderAvailable(context)
App.log.info("Package (un)installed; OpenTasks provider now available = $tasksInstalled") Logger.log.info("Package (un)installed; OpenTasks provider now available = $tasksInstalled")
for (account in AccountManager.get(context).getAccountsByType(App.accountType)) { for (account in AccountManager.get(context).getAccountsByType(App.accountType)) {
val settings = AccountSettings(context, account) val settings = AccountSettings(context, account)

View File

@ -9,6 +9,7 @@
package com.etesync.syncadapter package com.etesync.syncadapter
import android.os.Build import android.os.Build
import com.etesync.syncadapter.log.Logger
import java.io.IOException import java.io.IOException
import java.net.InetAddress import java.net.InetAddress
import java.net.Socket import java.net.Socket
@ -105,7 +106,7 @@ class SSLSocketFactoryCompat(trustManager: X509TrustManager) : SSLSocketFactory(
// - all modern ciphers are activated by default // - all modern ciphers are activated by default
protocols = null protocols = null
cipherSuites = null cipherSuites = null
App.log.fine("Using device default TLS protocols/ciphers") Logger.log.fine("Using device default TLS protocols/ciphers")
} else { } else {
(SSLSocketFactory.getDefault().createSocket() as? SSLSocket)?.use { socket -> (SSLSocketFactory.getDefault().createSocket() as? SSLSocket)?.use { socket ->
try { try {
@ -115,7 +116,7 @@ class SSLSocketFactoryCompat(trustManager: X509TrustManager) : SSLSocketFactory(
val whichProtocols = LinkedList<String>() val whichProtocols = LinkedList<String>()
for (protocol in socket.supportedProtocols.filterNot { it.contains("SSL", true) }) for (protocol in socket.supportedProtocols.filterNot { it.contains("SSL", true) })
whichProtocols += protocol whichProtocols += protocol
App.log.info("Enabling (only) these TLS protocols: ${whichProtocols.joinToString(", ")}") Logger.log.info("Enabling (only) these TLS protocols: ${whichProtocols.joinToString(", ")}")
protocols = whichProtocols.toTypedArray() protocols = whichProtocols.toTypedArray()
/* set up reasonable cipher suites */ /* set up reasonable cipher suites */
@ -140,7 +141,7 @@ class SSLSocketFactoryCompat(trustManager: X509TrustManager) : SSLSocketFactory(
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA" "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
) )
val availableCiphers = socket.supportedCipherSuites val availableCiphers = socket.supportedCipherSuites
App.log.info("Available cipher suites: ${availableCiphers.joinToString(", ")}") Logger.log.info("Available cipher suites: ${availableCiphers.joinToString(", ")}")
/* For maximum security, preferredCiphers should *replace* enabled ciphers (thus /* For maximum security, preferredCiphers should *replace* enabled ciphers (thus
* disabling ciphers which are enabled by default, but have become unsecure), but for * disabling ciphers which are enabled by default, but have become unsecure), but for
@ -150,16 +151,16 @@ class SSLSocketFactoryCompat(trustManager: X509TrustManager) : SSLSocketFactory(
// for the final set of enabled ciphers, take the ciphers enabled by default, ... // for the final set of enabled ciphers, take the ciphers enabled by default, ...
val whichCiphers = LinkedList<String>() val whichCiphers = LinkedList<String>()
whichCiphers.addAll(socket.enabledCipherSuites) whichCiphers.addAll(socket.enabledCipherSuites)
App.log.fine("Cipher suites enabled by default: ${whichCiphers.joinToString(", ")}") Logger.log.fine("Cipher suites enabled by default: ${whichCiphers.joinToString(", ")}")
// ... add explicitly allowed ciphers ... // ... add explicitly allowed ciphers ...
whichCiphers.addAll(knownCiphers) whichCiphers.addAll(knownCiphers)
// ... and keep only those which are actually available // ... and keep only those which are actually available
whichCiphers.retainAll(availableCiphers) whichCiphers.retainAll(availableCiphers)
App.log.info("Enabling (only) these TLS ciphers: " + whichCiphers.joinToString(", ")) Logger.log.info("Enabling (only) these TLS ciphers: " + whichCiphers.joinToString(", "))
cipherSuites = whichCiphers.toTypedArray() cipherSuites = whichCiphers.toTypedArray()
} catch (e: IOException) { } catch (e: IOException) {
App.log.severe("Couldn't determine default TLS settings") Logger.log.severe("Couldn't determine default TLS settings")
} }
} }
} }

View File

@ -1,7 +1,7 @@
package com.etesync.syncadapter.journalmanager package com.etesync.syncadapter.journalmanager
import com.etesync.syncadapter.App
import com.etesync.syncadapter.GsonHelper import com.etesync.syncadapter.GsonHelper
import com.etesync.syncadapter.log.Logger
import okhttp3.* import okhttp3.*
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.IOException import java.io.IOException
@ -19,7 +19,7 @@ abstract class BaseManager {
try { try {
response = client!!.newCall(request).execute() response = client!!.newCall(request).execute()
} catch (e: IOException) { } catch (e: IOException) {
App.log.log(Level.SEVERE, "Failed while connecting to server", e) Logger.log.log(Level.SEVERE, "Failed while connecting to server", e)
throw Exceptions.ServiceUnavailableException("[" + e.javaClass.name + "] " + e.localizedMessage) throw Exceptions.ServiceUnavailableException("[" + e.javaClass.name + "] " + e.localizedMessage)
} }

View File

@ -1,7 +1,7 @@
package com.etesync.syncadapter.journalmanager package com.etesync.syncadapter.journalmanager
import com.etesync.syncadapter.App
import com.etesync.syncadapter.journalmanager.util.ByteUtil import com.etesync.syncadapter.journalmanager.util.ByteUtil
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.utils.Base64 import com.etesync.syncadapter.utils.Base64
import org.apache.commons.lang3.ArrayUtils import org.apache.commons.lang3.ArrayUtils
import org.spongycastle.crypto.AsymmetricBlockCipher import org.spongycastle.crypto.AsymmetricBlockCipher
@ -69,7 +69,7 @@ object Crypto {
e.printStackTrace() e.printStackTrace()
} catch (e: InvalidCipherTextException) { } catch (e: InvalidCipherTextException) {
e.printStackTrace() e.printStackTrace()
App.log.severe("Invalid ciphertext: " + Base64.encodeToString(content, Base64.NO_WRAP)) Logger.log.severe("Invalid ciphertext: " + Base64.encodeToString(content, Base64.NO_WRAP))
} }
return null return null
@ -85,7 +85,7 @@ object Crypto {
e.printStackTrace() e.printStackTrace()
} catch (e: InvalidCipherTextException) { } catch (e: InvalidCipherTextException) {
e.printStackTrace() e.printStackTrace()
App.log.severe("Invalid ciphertext: " + Base64.encodeToString(cipherText, Base64.NO_WRAP)) Logger.log.severe("Invalid ciphertext: " + Base64.encodeToString(cipherText, Base64.NO_WRAP))
} }
return null return null
@ -182,7 +182,7 @@ object Crypto {
len += cipher.doFinal(buf, len) len += cipher.doFinal(buf, len)
} catch (e: InvalidCipherTextException) { } catch (e: InvalidCipherTextException) {
e.printStackTrace() e.printStackTrace()
App.log.severe("Invalid ciphertext: " + Base64.encodeToString(_data, Base64.NO_WRAP)) Logger.log.severe("Invalid ciphertext: " + Base64.encodeToString(_data, Base64.NO_WRAP))
return null return null
} }
@ -205,7 +205,7 @@ object Crypto {
try { try {
cipher.doFinal(buf, len) cipher.doFinal(buf, len)
} catch (e: InvalidCipherTextException) { } catch (e: InvalidCipherTextException) {
App.log.severe("Invalid ciphertext: " + Base64.encodeToString(data, Base64.NO_WRAP)) Logger.log.severe("Invalid ciphertext: " + Base64.encodeToString(data, Base64.NO_WRAP))
e.printStackTrace() e.printStackTrace()
return null return null
} }

View File

@ -1,7 +1,7 @@
package com.etesync.syncadapter.journalmanager package com.etesync.syncadapter.journalmanager
import com.etesync.syncadapter.App
import com.etesync.syncadapter.GsonHelper import com.etesync.syncadapter.GsonHelper
import com.etesync.syncadapter.log.Logger
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -17,7 +17,7 @@ class JournalEntryManager(httpClient: OkHttpClient, remote: HttpUrl, val uid: St
.addPathSegment("entries") .addPathSegment("entries")
.addPathSegment("") .addPathSegment("")
.build() .build()
App.log.info("Created for: " + this.remote!!.toString()) Logger.log.info("Created for: " + this.remote!!.toString())
this.client = httpClient this.client = httpClient
} }

View File

@ -1,10 +1,10 @@
package com.etesync.syncadapter.journalmanager package com.etesync.syncadapter.journalmanager
import com.etesync.syncadapter.App
import com.etesync.syncadapter.GsonHelper import com.etesync.syncadapter.GsonHelper
import com.etesync.syncadapter.journalmanager.Crypto.CryptoManager.Companion.HMAC_SIZE import com.etesync.syncadapter.journalmanager.Crypto.CryptoManager.Companion.HMAC_SIZE
import com.etesync.syncadapter.journalmanager.Crypto.sha256 import com.etesync.syncadapter.journalmanager.Crypto.sha256
import com.etesync.syncadapter.journalmanager.Crypto.toHex import com.etesync.syncadapter.journalmanager.Crypto.toHex
import com.etesync.syncadapter.log.Logger
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -19,7 +19,7 @@ class JournalManager(httpClient: OkHttpClient, remote: HttpUrl) : BaseManager()
.addPathSegments("api/v1/journals") .addPathSegments("api/v1/journals")
.addPathSegment("") .addPathSegment("")
.build() .build()
App.log.info("Created for: " + this.remote!!.toString()) Logger.log.info("Created for: " + this.remote!!.toString())
this.client = httpClient this.client = httpClient
} }

View File

@ -58,7 +58,7 @@ object Logger : SharedPreferences.OnSharedPreferenceChangeListener {
val settings = Settings(dbHelper.readableDatabase) val settings = Settings(dbHelper.readableDatabase)
val logToFile = settings.getBoolean(App.LOG_TO_EXTERNAL_STORAGE, false) val logToFile = settings.getBoolean(App.LOG_TO_EXTERNAL_STORAGE, false)
val logVerbose = logToFile || Log.isLoggable(App.log.name, Log.DEBUG) val logVerbose = logToFile || Log.isLoggable(Logger.log.name, Log.DEBUG)
log.info("Verbose logging: $logVerbose; to file: $logToFile") log.info("Verbose logging: $logVerbose; to file: $logToFile")

View File

@ -14,9 +14,8 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build; import android.os.Build;
import androidx.annotation.RequiresApi;
import com.etesync.syncadapter.App; import androidx.annotation.RequiresApi;
public class ServiceDB { public class ServiceDB {
@ -75,8 +74,6 @@ public class ServiceDB {
@Override @Override
public void onCreate(SQLiteDatabase db) { public void onCreate(SQLiteDatabase db) {
App.Companion.getLog().info("Creating database " + db.getPath());
db.execSQL("CREATE TABLE " + Settings._TABLE + "(" + db.execSQL("CREATE TABLE " + Settings._TABLE + "(" +
Settings.NAME + " TEXT NOT NULL," + Settings.NAME + " TEXT NOT NULL," +
Settings.VALUE + " TEXT NOT NULL" + Settings.VALUE + " TEXT NOT NULL" +

View File

@ -20,6 +20,7 @@ import android.provider.ContactsContract.Groups
import android.provider.ContactsContract.RawContacts import android.provider.ContactsContract.RawContacts
import at.bitfire.vcard4android.* import at.bitfire.vcard4android.*
import com.etesync.syncadapter.App import com.etesync.syncadapter.App
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity import com.etesync.syncadapter.model.JournalEntity
import java.io.FileNotFoundException import java.io.FileNotFoundException
@ -156,13 +157,13 @@ class LocalAddressBook(
arrayOf(account.name, account.type)) arrayOf(account.name, account.type))
} }
} catch (e: RemoteException) { } catch (e: RemoteException) {
App.log.log(Level.WARNING, "Couldn't re-assign contacts to new account name", e) Logger.log.log(Level.WARNING, "Couldn't re-assign contacts to new account name", e)
} }
}, null) }, null)
account = future.result account = future.result
} }
App.log.info("Address book write permission? = ${!journalEntity.isReadOnly}") Logger.log.info("Address book write permission? = ${!journalEntity.isReadOnly}")
readOnly = journalEntity.isReadOnly readOnly = journalEntity.isReadOnly
// make sure it will still be synchronized when contacts are updated // make sure it will still be synchronized when contacts are updated
@ -244,10 +245,10 @@ class LocalAddressBook(
val currentHash = contact.dataHashCode() val currentHash = contact.dataHashCode()
if (lastHash == currentHash) { if (lastHash == currentHash) {
// hash is code still the same, contact is not "really dirty" (only metadata been have changed) // hash is code still the same, contact is not "really dirty" (only metadata been have changed)
App.log.log(Level.FINE, "Contact data hash has not changed, resetting dirty flag", contact) Logger.log.log(Level.FINE, "Contact data hash has not changed, resetting dirty flag", contact)
contact.resetDirty() contact.resetDirty()
} else { } else {
App.log.log(Level.FINE, "Contact data has changed from hash $lastHash to $currentHash", contact) Logger.log.log(Level.FINE, "Contact data has changed from hash $lastHash to $currentHash", contact)
reallyDirty++ reallyDirty++
} }
} }
@ -338,7 +339,7 @@ class LocalAddressBook(
// find groups without members // find groups without members
/** should be done using {@link Groups.SUMMARY_COUNT}, but it's not implemented in Android yet */ /** should be done using {@link Groups.SUMMARY_COUNT}, but it's not implemented in Android yet */
queryGroups(null, null).filter { it.getMembers().isEmpty() }.forEach { group -> queryGroups(null, null).filter { it.getMembers().isEmpty() }.forEach { group ->
App.log.log(Level.FINE, "Deleting group", group) Logger.log.log(Level.FINE, "Deleting group", group)
group.delete() group.delete()
} }
} }
@ -355,7 +356,7 @@ class LocalAddressBook(
try { try {
val fixed = provider?.update(syncAdapterURI(RawContacts.CONTENT_URI), val fixed = provider?.update(syncAdapterURI(RawContacts.CONTENT_URI),
values, where, null) values, where, null)
App.log.info("Fixed entries: " + fixed.toString()) Logger.log.info("Fixed entries: " + fixed.toString())
} catch (e: RemoteException) { } catch (e: RemoteException) {
throw ContactsStorageException("Couldn't query contacts", e) throw ContactsStorageException("Couldn't query contacts", e)
} }

View File

@ -18,7 +18,7 @@ import android.os.RemoteException
import android.provider.CalendarContract import android.provider.CalendarContract
import android.provider.CalendarContract.* import android.provider.CalendarContract.*
import at.bitfire.ical4android.* import at.bitfire.ical4android.*
import com.etesync.syncadapter.App import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.JournalEntity import com.etesync.syncadapter.model.JournalEntity
import org.apache.commons.lang3.StringUtils import org.apache.commons.lang3.StringUtils
import java.util.* import java.util.*
@ -77,7 +77,7 @@ class LocalCalendar private constructor(
values.put(Calendars.CALENDAR_TIME_ZONE, DateUtils.findAndroidTimezoneID(tzId.value)) values.put(Calendars.CALENDAR_TIME_ZONE, DateUtils.findAndroidTimezoneID(tzId.value))
} }
} catch(e: IllegalArgumentException) { } catch(e: IllegalArgumentException) {
App.log.log(Level.WARNING, "Couldn't parse calendar default time zone", e) Logger.log.log(Level.WARNING, "Couldn't parse calendar default time zone", e)
} }
} }
values.put(Calendars.ALLOWED_REMINDERS, Reminders.METHOD_ALERT) values.put(Calendars.ALLOWED_REMINDERS, Reminders.METHOD_ALERT)
@ -125,14 +125,14 @@ class LocalCalendar private constructor(
fun processDirtyExceptions() { fun processDirtyExceptions() {
// process deleted exceptions // process deleted exceptions
App.log.info("Processing deleted exceptions") Logger.log.info("Processing deleted exceptions")
try { try {
val cursor = provider.query( val cursor = provider.query(
syncAdapterURI(Events.CONTENT_URI), syncAdapterURI(Events.CONTENT_URI),
arrayOf(Events._ID, Events.ORIGINAL_ID, LocalEvent.COLUMN_SEQUENCE), arrayOf(Events._ID, Events.ORIGINAL_ID, LocalEvent.COLUMN_SEQUENCE),
Events.DELETED + "!=0 AND " + Events.ORIGINAL_ID + " IS NOT NULL", null, null) Events.DELETED + "!=0 AND " + Events.ORIGINAL_ID + " IS NOT NULL", null, null)
while (cursor != null && cursor.moveToNext()) { while (cursor != null && cursor.moveToNext()) {
App.log.fine("Found deleted exception, removing; then re-schuling original event") Logger.log.fine("Found deleted exception, removing; then re-schuling original event")
val id = cursor.getLong(0) val id = cursor.getLong(0)
// can't be null (by definition) // can't be null (by definition)
val originalID = cursor.getLong(1) // can't be null (by query) val originalID = cursor.getLong(1) // can't be null (by query)
@ -163,14 +163,14 @@ class LocalCalendar private constructor(
} }
// process dirty exceptions // process dirty exceptions
App.log.info("Processing dirty exceptions") Logger.log.info("Processing dirty exceptions")
try { try {
val cursor = provider.query( val cursor = provider.query(
syncAdapterURI(Events.CONTENT_URI), syncAdapterURI(Events.CONTENT_URI),
arrayOf(Events._ID, Events.ORIGINAL_ID, LocalEvent.COLUMN_SEQUENCE), arrayOf(Events._ID, Events.ORIGINAL_ID, LocalEvent.COLUMN_SEQUENCE),
Events.DIRTY + "!=0 AND " + Events.ORIGINAL_ID + " IS NOT NULL", null, null) Events.DIRTY + "!=0 AND " + Events.ORIGINAL_ID + " IS NOT NULL", null, null)
while (cursor != null && cursor.moveToNext()) { while (cursor != null && cursor.moveToNext()) {
App.log.fine("Found dirty exception, increasing SEQUENCE to re-schedule") Logger.log.fine("Found dirty exception, increasing SEQUENCE to re-schedule")
val id = cursor.getLong(0) val id = cursor.getLong(0)
// can't be null (by definition) // can't be null (by definition)
val originalID = cursor.getLong(1) // can't be null (by query) val originalID = cursor.getLong(1) // can't be null (by query)
@ -227,7 +227,7 @@ class LocalCalendar private constructor(
try { try {
val fixed = provider.update(syncAdapterURI(Events.CONTENT_URI), val fixed = provider.update(syncAdapterURI(Events.CONTENT_URI),
values, where, whereArgs) values, where, whereArgs)
App.log.info("Fixed entries: " + fixed.toString()) Logger.log.info("Fixed entries: " + fixed.toString())
} catch (e: RemoteException) { } catch (e: RemoteException) {
throw CalendarStorageException("Couldn't fix etags", e) throw CalendarStorageException("Couldn't fix etags", e)
} }

View File

@ -24,8 +24,8 @@ import at.bitfire.vcard4android.CachedGroupMembership
import at.bitfire.vcard4android.Contact import at.bitfire.vcard4android.Contact
import at.bitfire.vcard4android.ContactsStorageException import at.bitfire.vcard4android.ContactsStorageException
import at.bitfire.vcard4android.GroupMethod.GROUP_VCARDS import at.bitfire.vcard4android.GroupMethod.GROUP_VCARDS
import com.etesync.syncadapter.App
import com.etesync.syncadapter.Constants import com.etesync.syncadapter.Constants
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.UnknownProperties import com.etesync.syncadapter.model.UnknownProperties
import ezvcard.Ezvcard import ezvcard.Ezvcard
import ezvcard.VCardVersion import ezvcard.VCardVersion
@ -62,7 +62,7 @@ class LocalContact : AndroidContact, LocalAddress {
val contact: Contact val contact: Contact
contact = this.contact!! contact = this.contact!!
App.log.log(Level.FINE, "Preparing upload of VCard $uuid", contact) Logger.log.log(Level.FINE, "Preparing upload of VCard $uuid", contact)
val os = ByteArrayOutputStream() val os = ByteArrayOutputStream()
contact.write(VCardVersion.V4_0, GROUP_VCARDS, os) contact.write(VCardVersion.V4_0, GROUP_VCARDS, os)
@ -97,7 +97,7 @@ class LocalContact : AndroidContact, LocalAddress {
// workaround for Android 7 which sets DIRTY flag when only meta-data is changed // workaround for Android 7 which sets DIRTY flag when only meta-data is changed
val hashCode = dataHashCode() val hashCode = dataHashCode()
values.put(COLUMN_HASHCODE, hashCode) values.put(COLUMN_HASHCODE, hashCode)
App.log.finer("Clearing dirty flag with eTag = $eTag, contact hash = $hashCode") Logger.log.finer("Clearing dirty flag with eTag = $eTag, contact hash = $hashCode")
} }
addressBook.provider?.update(rawContactSyncURI(), values, null, null) addressBook.provider?.update(rawContactSyncURI(), values, null, null)
@ -173,7 +173,7 @@ class LocalContact : AndroidContact, LocalAddress {
// groupMemberships is filled by getContact() // groupMemberships is filled by getContact()
val dataHash = contact!!.hashCode() val dataHash = contact!!.hashCode()
val groupHash = groupMemberships.hashCode() val groupHash = groupMemberships.hashCode()
App.log.finest("Calculated data hash = $dataHash, group memberships hash = $groupHash") Logger.log.finest("Calculated data hash = $dataHash, group memberships hash = $groupHash")
return dataHash xor groupHash return dataHash xor groupHash
} }
@ -183,7 +183,7 @@ class LocalContact : AndroidContact, LocalAddress {
val values = ContentValues(1) val values = ContentValues(1)
val hashCode = dataHashCode() val hashCode = dataHashCode()
App.log.fine("Storing contact hash = $hashCode") Logger.log.fine("Storing contact hash = $hashCode")
values.put(COLUMN_HASHCODE, hashCode) values.put(COLUMN_HASHCODE, hashCode)
if (batch == null) if (batch == null)

View File

@ -16,8 +16,8 @@ import android.provider.CalendarContract.Events
import android.text.TextUtils import android.text.TextUtils
import at.bitfire.ical4android.* import at.bitfire.ical4android.*
import at.bitfire.ical4android.Constants.ical4jVersion import at.bitfire.ical4android.Constants.ical4jVersion
import com.etesync.syncadapter.App
import com.etesync.syncadapter.Constants import com.etesync.syncadapter.Constants
import com.etesync.syncadapter.log.Logger
import net.fortuna.ical4j.model.property.ProdId import net.fortuna.ical4j.model.property.ProdId
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.util.* import java.util.*
@ -43,7 +43,7 @@ class LocalEvent : AndroidEvent, LocalResource<Event> {
override val content: String override val content: String
get() { get() {
App.log.log(Level.FINE, "Preparing upload of event " + fileName!!, event) Logger.log.log(Level.FINE, "Preparing upload of event " + fileName!!, event)
val os = ByteArrayOutputStream() val os = ByteArrayOutputStream()
event?.write(os) event?.write(os)

View File

@ -21,7 +21,7 @@ import android.provider.ContactsContract.RawContacts.Data
import android.text.TextUtils import android.text.TextUtils
import at.bitfire.vcard4android.* import at.bitfire.vcard4android.*
import at.bitfire.vcard4android.GroupMethod.GROUP_VCARDS import at.bitfire.vcard4android.GroupMethod.GROUP_VCARDS
import com.etesync.syncadapter.App import com.etesync.syncadapter.log.Logger
import ezvcard.VCardVersion import ezvcard.VCardVersion
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.util.* import java.util.*
@ -86,7 +86,7 @@ class LocalGroup : AndroidGroup, LocalAddress {
val contact: Contact val contact: Contact
contact = this.contact!! contact = this.contact!!
App.log.log(Level.FINE, "Preparing upload of VCard $uuid", contact) Logger.log.log(Level.FINE, "Preparing upload of VCard $uuid", contact)
val os = ByteArrayOutputStream() val os = ByteArrayOutputStream()
contact.write(VCardVersion.V4_0, GROUP_VCARDS, os) contact.write(VCardVersion.V4_0, GROUP_VCARDS, os)

View File

@ -15,7 +15,7 @@ import at.bitfire.ical4android.AndroidTask
import at.bitfire.ical4android.AndroidTaskFactory import at.bitfire.ical4android.AndroidTaskFactory
import at.bitfire.ical4android.AndroidTaskList import at.bitfire.ical4android.AndroidTaskList
import at.bitfire.ical4android.Task import at.bitfire.ical4android.Task
import com.etesync.syncadapter.App import com.etesync.syncadapter.log.Logger
import org.dmfs.tasks.contract.TaskContract import org.dmfs.tasks.contract.TaskContract
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.util.* import java.util.*
@ -33,7 +33,7 @@ class LocalTask : AndroidTask, LocalResource<Task> {
override val content: String override val content: String
get() { get() {
App.log.log(Level.FINE, "Preparing upload of task ${fileName} ${task}") Logger.log.log(Level.FINE, "Preparing upload of task ${fileName} ${task}")
val os = ByteArrayOutputStream() val os = ByteArrayOutputStream()
task?.write(os) task?.write(os)

View File

@ -19,6 +19,7 @@ import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.* import com.etesync.syncadapter.*
import com.etesync.syncadapter.Constants.KEY_ACCOUNT import com.etesync.syncadapter.Constants.KEY_ACCOUNT
import com.etesync.syncadapter.journalmanager.Exceptions import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity import com.etesync.syncadapter.model.JournalEntity
import com.etesync.syncadapter.model.JournalModel import com.etesync.syncadapter.model.JournalModel
@ -46,7 +47,7 @@ class AddressBooksSyncAdapterService : SyncAdapterService() {
try { try {
val contactsProvider = context.contentResolver.acquireContentProviderClient(ContactsContract.AUTHORITY) val contactsProvider = context.contentResolver.acquireContentProviderClient(ContactsContract.AUTHORITY)
if (contactsProvider == null) { if (contactsProvider == null) {
App.log.severe("Couldn't access contacts provider") Logger.log.severe("Couldn't access contacts provider")
syncResult.databaseError = true syncResult.databaseError = true
return return
} }
@ -63,7 +64,7 @@ class AddressBooksSyncAdapterService : SyncAdapterService() {
val accountManager = AccountManager.get(context) val accountManager = AccountManager.get(context)
for (addressBookAccount in accountManager.getAccountsByType(App.addressBookAccountType)) { for (addressBookAccount in accountManager.getAccountsByType(App.addressBookAccountType)) {
App.log.log(Level.INFO, "Running sync for address book", addressBookAccount) Logger.log.log(Level.INFO, "Running sync for address book", addressBookAccount)
val syncExtras = Bundle(extras) val syncExtras = Bundle(extras)
syncExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true) syncExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true)
syncExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true) syncExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true)
@ -76,7 +77,7 @@ class AddressBooksSyncAdapterService : SyncAdapterService() {
// Ignore // Ignore
} catch (e: Exception) { } catch (e: Exception) {
if (e is ContactsStorageException || e is SQLiteException) { if (e is ContactsStorageException || e is SQLiteException) {
App.log.log(Level.SEVERE, "Couldn't prepare local address books", e) Logger.log.log(Level.SEVERE, "Couldn't prepare local address books", e)
syncResult.databaseError = true syncResult.databaseError = true
} }
@ -102,7 +103,7 @@ class AddressBooksSyncAdapterService : SyncAdapterService() {
notificationManager.notify(title, context.getString(syncPhase)) notificationManager.notify(title, context.getString(syncPhase))
} }
App.log.info("Address book sync complete") Logger.log.info("Address book sync complete")
} }
@ -125,11 +126,11 @@ class AddressBooksSyncAdapterService : SyncAdapterService() {
val url = addressBook.url val url = addressBook.url
val journalEntity = remote[url] val journalEntity = remote[url]
if (journalEntity == null) { if (journalEntity == null) {
App.log.fine("Deleting obsolete local address book $url") Logger.log.fine("Deleting obsolete local address book $url")
addressBook.delete() addressBook.delete()
} else { } else {
// remote CollectionInfo found for this local collection, update data // remote CollectionInfo found for this local collection, update data
App.log.fine("Updating local address book $url with $journalEntity") Logger.log.fine("Updating local address book $url with $journalEntity")
addressBook.update(journalEntity) addressBook.update(journalEntity)
// we already have a local collection for this remote collection, don't take into consideration anymore // we already have a local collection for this remote collection, don't take into consideration anymore
remote.remove(url) remote.remove(url)
@ -139,7 +140,7 @@ class AddressBooksSyncAdapterService : SyncAdapterService() {
// create new local address books // create new local address books
for (url in remote.keys) { for (url in remote.keys) {
val journalEntity = remote[url]!! val journalEntity = remote[url]!!
App.log.info("Adding local address book $journalEntity") Logger.log.info("Adding local address book $journalEntity")
LocalAddressBook.create(context, provider, account, journalEntity) LocalAddressBook.create(context, provider, account, journalEntity)
} }
} }

View File

@ -17,9 +17,13 @@ import at.bitfire.ical4android.CalendarStorageException
import at.bitfire.ical4android.Event import at.bitfire.ical4android.Event
import at.bitfire.ical4android.InvalidCalendarException import at.bitfire.ical4android.InvalidCalendarException
import at.bitfire.vcard4android.ContactsStorageException import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.* import com.etesync.syncadapter.AccountSettings
import com.etesync.syncadapter.Constants
import com.etesync.syncadapter.NotificationHelper
import com.etesync.syncadapter.R
import com.etesync.syncadapter.journalmanager.Exceptions import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.journalmanager.JournalEntryManager import com.etesync.syncadapter.journalmanager.JournalEntryManager
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.SyncEntry import com.etesync.syncadapter.model.SyncEntry
import com.etesync.syncadapter.resource.LocalCalendar import com.etesync.syncadapter.resource.LocalCalendar
@ -80,10 +84,10 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
val events = Event.fromReader(inputReader) val events = Event.fromReader(inputReader)
if (events.size == 0) { if (events.size == 0) {
App.log.warning("Received VCard without data, ignoring") Logger.log.warning("Received VCard without data, ignoring")
return return
} else if (events.size > 1) { } else if (events.size > 1) {
App.log.warning("Received multiple VCALs, using first one") Logger.log.warning("Received multiple VCALs, using first one")
} }
val event = events[0] val event = events[0]
@ -93,10 +97,10 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
processEvent(event, local) processEvent(event, local)
} else { } else {
if (local != null) { if (local != null) {
App.log.info("Removing local record #" + local.id + " which has been deleted on the server") Logger.log.info("Removing local record #" + local.id + " which has been deleted on the server")
local.delete() local.delete()
} else { } else {
App.log.warning("Tried deleting a non-existent record: " + event.uid) Logger.log.warning("Tried deleting a non-existent record: " + event.uid)
} }
} }
} }
@ -140,12 +144,12 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
var localEvent = _localEvent var localEvent = _localEvent
// delete local event, if it exists // delete local event, if it exists
if (localEvent != null) { if (localEvent != null) {
App.log.info("Updating " + newData.uid + " in local calendar") Logger.log.info("Updating " + newData.uid + " in local calendar")
localEvent.eTag = newData.uid localEvent.eTag = newData.uid
localEvent.update(newData) localEvent.update(newData)
syncResult.stats.numUpdates++ syncResult.stats.numUpdates++
} else { } else {
App.log.info("Adding " + newData.uid + " to local calendar") Logger.log.info("Adding " + newData.uid + " to local calendar")
localEvent = LocalEvent(localCalendar(), newData, newData.uid, newData.uid) localEvent = LocalEvent(localCalendar(), newData, newData.uid, newData.uid)
localEvent.add() localEvent.add()
syncResult.stats.numInserts++ syncResult.stats.numInserts++

View File

@ -17,6 +17,7 @@ import at.bitfire.ical4android.CalendarStorageException
import com.etesync.syncadapter.* import com.etesync.syncadapter.*
import com.etesync.syncadapter.Constants.KEY_ACCOUNT import com.etesync.syncadapter.Constants.KEY_ACCOUNT
import com.etesync.syncadapter.journalmanager.Exceptions import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity import com.etesync.syncadapter.model.JournalEntity
import com.etesync.syncadapter.model.JournalModel import com.etesync.syncadapter.model.JournalModel
@ -53,7 +54,7 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
val principal = HttpUrl.get(settings.uri!!)!! val principal = HttpUrl.get(settings.uri!!)!!
for (calendar in AndroidCalendar.find(account, provider, LocalCalendar.Factory, CalendarContract.Calendars.SYNC_EVENTS + "!=0", null)) { for (calendar in AndroidCalendar.find(account, provider, LocalCalendar.Factory, CalendarContract.Calendars.SYNC_EVENTS + "!=0", null)) {
App.log.info("Synchronizing calendar #" + calendar.id + ", URL: " + calendar.name) Logger.log.info("Synchronizing calendar #" + calendar.id + ", URL: " + calendar.name)
val syncManager = CalendarSyncManager(context, account, settings, extras, authority, syncResult, calendar, principal) val syncManager = CalendarSyncManager(context, account, settings, extras, authority, syncResult, calendar, principal)
syncManager.performSync() syncManager.performSync()
} }
@ -64,7 +65,7 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
// Ignore // Ignore
} catch (e: Exception) { } catch (e: Exception) {
if (e is CalendarStorageException || e is SQLiteException) { if (e is CalendarStorageException || e is SQLiteException) {
App.log.log(Level.SEVERE, "Couldn't prepare local calendars", e) Logger.log.log(Level.SEVERE, "Couldn't prepare local calendars", e)
syncResult.databaseError = true syncResult.databaseError = true
} }
@ -90,7 +91,7 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
notificationManager.notify(title, context.getString(syncPhase)) notificationManager.notify(title, context.getString(syncPhase))
} }
App.log.info("Calendar sync complete") Logger.log.info("Calendar sync complete")
} }
@Throws(CalendarStorageException::class) @Throws(CalendarStorageException::class)
@ -113,11 +114,11 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
val url = calendar.name val url = calendar.name
val journalEntity = remote[url] val journalEntity = remote[url]
if (journalEntity == null) { if (journalEntity == null) {
App.log.fine("Deleting obsolete local calendar $url") Logger.log.fine("Deleting obsolete local calendar $url")
calendar.delete() calendar.delete()
} else { } else {
// remote CollectionInfo found for this local collection, update data // remote CollectionInfo found for this local collection, update data
App.log.fine("Updating local calendar $url with $journalEntity") Logger.log.fine("Updating local calendar $url with $journalEntity")
calendar.update(journalEntity, updateColors) calendar.update(journalEntity, updateColors)
// we already have a local calendar for this remote collection, don't take into consideration anymore // we already have a local calendar for this remote collection, don't take into consideration anymore
remote.remove(url) remote.remove(url)
@ -127,7 +128,7 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
// create new local calendars // create new local calendars
for (url in remote.keys) { for (url in remote.keys) {
val journalEntity = remote[url]!! val journalEntity = remote[url]!!
App.log.info("Adding local calendar list $journalEntity") Logger.log.info("Adding local calendar list $journalEntity")
LocalCalendar.create(account, provider, journalEntity) LocalCalendar.create(account, provider, journalEntity)
} }
} }

View File

@ -14,6 +14,7 @@ import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.* import com.etesync.syncadapter.*
import com.etesync.syncadapter.Constants.KEY_ACCOUNT import com.etesync.syncadapter.Constants.KEY_ACCOUNT
import com.etesync.syncadapter.journalmanager.Exceptions import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.resource.LocalAddressBook import com.etesync.syncadapter.resource.LocalAddressBook
import com.etesync.syncadapter.ui.DebugInfoActivity import com.etesync.syncadapter.ui.DebugInfoActivity
import okhttp3.HttpUrl import okhttp3.HttpUrl
@ -39,20 +40,20 @@ class ContactsSyncAdapterService : SyncAdapterService() {
try { try {
settings = AccountSettings(context, addressBook.mainAccount) settings = AccountSettings(context, addressBook.mainAccount)
} catch (e: InvalidAccountException) { } catch (e: InvalidAccountException) {
App.log.info("Skipping sync due to invalid account.") Logger.log.info("Skipping sync due to invalid account.")
App.log.info(e.localizedMessage) Logger.log.info(e.localizedMessage)
return return
} catch (e: ContactsStorageException) { } catch (e: ContactsStorageException) {
App.log.info("Skipping sync due to invalid account.") Logger.log.info("Skipping sync due to invalid account.")
App.log.info(e.localizedMessage) Logger.log.info(e.localizedMessage)
return return
} }
if (!extras.containsKey(ContentResolver.SYNC_EXTRAS_MANUAL) && !checkSyncConditions(settings)) if (!extras.containsKey(ContentResolver.SYNC_EXTRAS_MANUAL) && !checkSyncConditions(settings))
return return
App.log.info("Synchronizing address book: " + addressBook.url) Logger.log.info("Synchronizing address book: " + addressBook.url)
App.log.info("Taking settings from: " + addressBook.mainAccount) Logger.log.info("Taking settings from: " + addressBook.mainAccount)
val principal = HttpUrl.get(settings.uri!!)!! val principal = HttpUrl.get(settings.uri!!)!!
val syncManager = ContactsSyncManager(context, account, settings, extras, authority, provider, syncResult, addressBook, principal) val syncManager = ContactsSyncManager(context, account, settings, extras, authority, provider, syncResult, addressBook, principal)
@ -79,7 +80,7 @@ class ContactsSyncAdapterService : SyncAdapterService() {
notificationManager.notify(title, context.getString(syncPhase)) notificationManager.notify(title, context.getString(syncPhase))
} }
App.log.info("Contacts sync complete") Logger.log.info("Contacts sync complete")
} }
} }

View File

@ -16,9 +16,13 @@ import at.bitfire.ical4android.CalendarStorageException
import at.bitfire.vcard4android.BatchOperation import at.bitfire.vcard4android.BatchOperation
import at.bitfire.vcard4android.Contact import at.bitfire.vcard4android.Contact
import at.bitfire.vcard4android.ContactsStorageException import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.* import com.etesync.syncadapter.AccountSettings
import com.etesync.syncadapter.Constants
import com.etesync.syncadapter.HttpClient
import com.etesync.syncadapter.R
import com.etesync.syncadapter.journalmanager.Exceptions import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.journalmanager.JournalEntryManager import com.etesync.syncadapter.journalmanager.JournalEntryManager
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.SyncEntry import com.etesync.syncadapter.model.SyncEntry
import com.etesync.syncadapter.resource.LocalAddress import com.etesync.syncadapter.resource.LocalAddress
@ -66,7 +70,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
val reallyDirty = localAddressBook.verifyDirty() val reallyDirty = localAddressBook.verifyDirty()
val deleted = localAddressBook.findDeleted().size val deleted = localAddressBook.findDeleted().size
if (extras.containsKey(ContentResolver.SYNC_EXTRAS_UPLOAD) && reallyDirty == 0 && deleted == 0) { if (extras.containsKey(ContentResolver.SYNC_EXTRAS_UPLOAD) && reallyDirty == 0 && deleted == 0) {
App.log.info("This sync was called to up-sync dirty/deleted contacts, but no contacts have been changed") Logger.log.info("This sync was called to up-sync dirty/deleted contacts, but no contacts have been changed")
return false return false
} }
} }
@ -96,11 +100,11 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
val batch = BatchOperation(addressBook.provider!!) val batch = BatchOperation(addressBook.provider!!)
for (contact in addressBook.findDirtyContacts()) { for (contact in addressBook.findDirtyContacts()) {
try { try {
App.log.fine("Looking for changed group memberships of contact " + contact.fileName) Logger.log.fine("Looking for changed group memberships of contact " + contact.fileName)
val cachedGroups = contact.getCachedGroupMemberships() val cachedGroups = contact.getCachedGroupMemberships()
val currentGroups = contact.getGroupMemberships() val currentGroups = contact.getGroupMemberships()
for (groupID in SetUtils.disjunction(cachedGroups, currentGroups)) { for (groupID in SetUtils.disjunction(cachedGroups, currentGroups)) {
App.log.fine("Marking group as dirty: " + groupID!!) Logger.log.fine("Marking group as dirty: " + groupID!!)
batch.enqueue(BatchOperation.Operation( batch.enqueue(BatchOperation.Operation(
ContentProviderOperation.newUpdate(addressBook.syncAdapterURI(ContentUris.withAppendedId(ContactsContract.Groups.CONTENT_URI, groupID))) ContentProviderOperation.newUpdate(addressBook.syncAdapterURI(ContentUris.withAppendedId(ContactsContract.Groups.CONTENT_URI, groupID)))
.withValue(ContactsContract.Groups.DIRTY, 1) .withValue(ContactsContract.Groups.DIRTY, 1)
@ -118,7 +122,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
override fun postProcess() { override fun postProcess() {
super.postProcess() super.postProcess()
/* VCard4 group handling: there are group contacts and individual contacts */ /* VCard4 group handling: there are group contacts and individual contacts */
App.log.info("Assigning memberships of downloaded contact groups") Logger.log.info("Assigning memberships of downloaded contact groups")
LocalGroup.applyPendingMemberships(localAddressBook()) LocalGroup.applyPendingMemberships(localAddressBook())
} }
@ -136,10 +140,10 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
val contacts = Contact.fromReader(inputReader, downloader) val contacts = Contact.fromReader(inputReader, downloader)
if (contacts.size == 0) { if (contacts.size == 0) {
App.log.warning("Received VCard without data, ignoring") Logger.log.warning("Received VCard without data, ignoring")
return return
} else if (contacts.size > 1) } else if (contacts.size > 1)
App.log.warning("Received multiple VCards, using first one") Logger.log.warning("Received multiple VCards, using first one")
val contact = contacts[0] val contact = contacts[0]
val local = localCollection!!.findByUid(contact.uid!!) val local = localCollection!!.findByUid(contact.uid!!)
@ -148,10 +152,10 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
processContact(contact, local) processContact(contact, local)
} else { } else {
if (local != null) { if (local != null) {
App.log.info("Removing local record which has been deleted on the server") Logger.log.info("Removing local record which has been deleted on the server")
local.delete() local.delete()
} else { } else {
App.log.warning("Tried deleting a non-existent record: " + contact.uid) Logger.log.warning("Tried deleting a non-existent record: " + contact.uid)
} }
} }
} }
@ -162,7 +166,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
val uuid = newData.uid val uuid = newData.uid
// update local contact, if it exists // update local contact, if it exists
if (local != null) { if (local != null) {
App.log.log(Level.INFO, "Updating $uuid in local address book") Logger.log.log(Level.INFO, "Updating $uuid in local address book")
if (local is LocalGroup && newData.group) { if (local is LocalGroup && newData.group) {
// update group // update group
@ -192,13 +196,13 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
if (local == null) { if (local == null) {
if (newData.group) { if (newData.group) {
App.log.log(Level.INFO, "Creating local group", newData.uid) Logger.log.log(Level.INFO, "Creating local group", newData.uid)
val group = LocalGroup(localAddressBook(), newData, uuid, uuid) val group = LocalGroup(localAddressBook(), newData, uuid, uuid)
group.add() group.add()
local = group local = group
} else { } else {
App.log.log(Level.INFO, "Creating local contact", newData.uid) Logger.log.log(Level.INFO, "Creating local contact", newData.uid)
val contact = LocalContact(localAddressBook(), newData, uuid, uuid) val contact = LocalContact(localAddressBook(), newData, uuid, uuid)
contact.add() contact.add()
@ -222,13 +226,13 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
val httpUrl = HttpUrl.parse(url) val httpUrl = HttpUrl.parse(url)
if (httpUrl == null) { if (httpUrl == null) {
App.log.log(Level.SEVERE, "Invalid external resource URL", url) Logger.log.log(Level.SEVERE, "Invalid external resource URL", url)
return null return null
} }
val host = httpUrl.host() val host = httpUrl.host()
if (host == null) { if (host == null) {
App.log.log(Level.SEVERE, "External resource URL doesn't specify a host name", url) Logger.log.log(Level.SEVERE, "External resource URL doesn't specify a host name", url)
return null return null
} }
@ -253,7 +257,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
return body.bytes() return body.bytes()
} }
} catch (e: IOException) { } catch (e: IOException) {
App.log.log(Level.SEVERE, "Couldn't download external resource", e) Logger.log.log(Level.SEVERE, "Couldn't download external resource", e)
} }
return null return null

View File

@ -23,6 +23,7 @@ import com.etesync.syncadapter.*
import com.etesync.syncadapter.journalmanager.Crypto import com.etesync.syncadapter.journalmanager.Crypto
import com.etesync.syncadapter.journalmanager.Exceptions import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.journalmanager.JournalManager import com.etesync.syncadapter.journalmanager.JournalManager
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity import com.etesync.syncadapter.model.JournalEntity
import com.etesync.syncadapter.model.JournalModel import com.etesync.syncadapter.model.JournalModel
@ -45,14 +46,14 @@ abstract class SyncAdapterService : Service() {
abstract class SyncAdapter(context: Context) : AbstractThreadedSyncAdapter(context, false) { abstract class SyncAdapter(context: Context) : AbstractThreadedSyncAdapter(context, false) {
override fun onPerformSync(account: Account, extras: Bundle, authority: String, provider: ContentProviderClient, syncResult: SyncResult) { override fun onPerformSync(account: Account, extras: Bundle, authority: String, provider: ContentProviderClient, syncResult: SyncResult) {
App.log.log(Level.INFO, "$authority sync of $account has been initiated.", extras.keySet().toTypedArray()) Logger.log.log(Level.INFO, "$authority sync of $account has been initiated.", extras.keySet().toTypedArray())
// required for dav4android (ServiceLoader) // required for dav4android (ServiceLoader)
Thread.currentThread().contextClassLoader = context.classLoader Thread.currentThread().contextClassLoader = context.classLoader
} }
override fun onSecurityException(account: Account, extras: Bundle, authority: String, syncResult: SyncResult) { override fun onSecurityException(account: Account, extras: Bundle, authority: String, syncResult: SyncResult) {
App.log.log(Level.WARNING, "Security exception when opening content provider for $authority") Logger.log.log(Level.WARNING, "Security exception when opening content provider for $authority")
syncResult.databaseError = true syncResult.databaseError = true
val intent = Intent(context, PermissionsActivity::class.java) val intent = Intent(context, PermissionsActivity::class.java)
@ -75,11 +76,11 @@ abstract class SyncAdapterService : Service() {
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val network = cm.activeNetworkInfo val network = cm.activeNetworkInfo
if (network == null) { if (network == null) {
App.log.info("No network available, stopping") Logger.log.info("No network available, stopping")
return false return false
} }
if (network.type != ConnectivityManager.TYPE_WIFI || !network.isConnected) { if (network.type != ConnectivityManager.TYPE_WIFI || !network.isConnected) {
App.log.info("Not on connected WiFi, stopping") Logger.log.info("Not on connected WiFi, stopping")
return false return false
} }
@ -89,7 +90,7 @@ abstract class SyncAdapterService : Service() {
val wifi = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager val wifi = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
val info = wifi.connectionInfo val info = wifi.connectionInfo
if (info == null || onlySSID != info.ssid) { if (info == null || onlySSID != info.ssid) {
App.log.info("Connected to wrong WiFi network (" + info!!.ssid + ", required: " + onlySSID + "), ignoring") Logger.log.info("Connected to wrong WiFi network (" + info!!.ssid + ", required: " + onlySSID + "), ignoring")
return false return false
} }
} }
@ -106,7 +107,7 @@ abstract class SyncAdapterService : Service() {
@Throws(Exceptions.HttpException::class, Exceptions.IntegrityException::class, InvalidAccountException::class, Exceptions.GenericCryptoException::class) @Throws(Exceptions.HttpException::class, Exceptions.IntegrityException::class, InvalidAccountException::class, Exceptions.GenericCryptoException::class)
internal fun run() { internal fun run() {
App.log.info("Refreshing " + serviceType + " collections of service #" + serviceType.toString()) Logger.log.info("Refreshing " + serviceType + " collections of service #" + serviceType.toString())
val settings = AccountSettings(context, account) val settings = AccountSettings(context, account)
val httpClient = HttpClient.create(context, settings) val httpClient = HttpClient.create(context, settings)
@ -162,7 +163,7 @@ abstract class SyncAdapterService : Service() {
for (pair in journals) { for (pair in journals) {
val journal = pair.first val journal = pair.first
val collection = pair.second val collection = pair.second
App.log.log(Level.FINE, "Saving collection", journal!!.uid) Logger.log.log(Level.FINE, "Saving collection", journal!!.uid)
collection!!.serviceID = service.id collection!!.serviceID = service.id
val journalEntity = JournalEntity.fetchOrCreate(data, collection) val journalEntity = JournalEntity.fetchOrCreate(data, collection)
@ -176,7 +177,7 @@ abstract class SyncAdapterService : Service() {
} }
for (journalEntity in existing.values) { for (journalEntity in existing.values) {
App.log.log(Level.FINE, "Deleting collection", journalEntity.uid) Logger.log.log(Level.FINE, "Deleting collection", journalEntity.uid)
journalEntity.isDeleted = true journalEntity.isDeleted = true
data.update(journalEntity) data.update(journalEntity)

View File

@ -21,6 +21,7 @@ import com.etesync.syncadapter.Constants.KEY_ACCOUNT
import com.etesync.syncadapter.journalmanager.Crypto import com.etesync.syncadapter.journalmanager.Crypto
import com.etesync.syncadapter.journalmanager.Exceptions import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.journalmanager.JournalEntryManager import com.etesync.syncadapter.journalmanager.JournalEntryManager
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.* import com.etesync.syncadapter.model.*
import com.etesync.syncadapter.model.SyncEntry.Actions.ADD import com.etesync.syncadapter.model.SyncEntry.Actions.ADD
import com.etesync.syncadapter.resource.LocalCollection import com.etesync.syncadapter.resource.LocalCollection
@ -96,7 +97,7 @@ constructor(protected val context: Context, protected val account: Account, prot
notificationManager = NotificationHelper(context, journalUid, notificationId()) notificationManager = NotificationHelper(context, journalUid, notificationId())
notificationManager.cancel() notificationManager.cancel()
App.log.info(String.format(Locale.getDefault(), "Syncing collection %s (version: %d)", journalUid, info.version)) Logger.log.info(String.format(Locale.getDefault(), "Syncing collection %s (version: %d)", journalUid, info.version))
if (journalEntity.encryptedKey != null) { if (journalEntity.encryptedKey != null) {
crypto = Crypto.CryptoManager(info.version, settings.keyPair!!, journalEntity.encryptedKey) crypto = Crypto.CryptoManager(info.version, settings.keyPair!!, journalEntity.encryptedKey)
@ -111,35 +112,35 @@ constructor(protected val context: Context, protected val account: Account, prot
fun performSync() { fun performSync() {
var syncPhase = R.string.sync_phase_prepare var syncPhase = R.string.sync_phase_prepare
try { try {
App.log.info("Sync phase: " + context.getString(syncPhase)) Logger.log.info("Sync phase: " + context.getString(syncPhase))
if (!prepare()) { if (!prepare()) {
App.log.info("No reason to synchronize, aborting") Logger.log.info("No reason to synchronize, aborting")
return return
} }
if (Thread.interrupted()) if (Thread.interrupted())
throw InterruptedException() throw InterruptedException()
syncPhase = R.string.sync_phase_query_capabilities syncPhase = R.string.sync_phase_query_capabilities
App.log.info("Sync phase: " + context.getString(syncPhase)) Logger.log.info("Sync phase: " + context.getString(syncPhase))
queryCapabilities() queryCapabilities()
if (Thread.interrupted()) if (Thread.interrupted())
throw InterruptedException() throw InterruptedException()
syncPhase = R.string.sync_phase_prepare_local syncPhase = R.string.sync_phase_prepare_local
App.log.info("Sync phase: " + context.getString(syncPhase)) Logger.log.info("Sync phase: " + context.getString(syncPhase))
prepareLocal() prepareLocal()
do { do {
if (Thread.interrupted()) if (Thread.interrupted())
throw InterruptedException() throw InterruptedException()
syncPhase = R.string.sync_phase_fetch_entries syncPhase = R.string.sync_phase_fetch_entries
App.log.info("Sync phase: " + context.getString(syncPhase)) Logger.log.info("Sync phase: " + context.getString(syncPhase))
fetchEntries() fetchEntries()
if (Thread.interrupted()) if (Thread.interrupted())
throw InterruptedException() throw InterruptedException()
syncPhase = R.string.sync_phase_apply_remote_entries syncPhase = R.string.sync_phase_apply_remote_entries
App.log.info("Sync phase: " + context.getString(syncPhase)) Logger.log.info("Sync phase: " + context.getString(syncPhase))
applyRemoteEntries() applyRemoteEntries()
} while (remoteEntries!!.size == MAX_FETCH) } while (remoteEntries!!.size == MAX_FETCH)
@ -148,13 +149,13 @@ constructor(protected val context: Context, protected val account: Account, prot
if (Thread.interrupted()) if (Thread.interrupted())
throw InterruptedException() throw InterruptedException()
syncPhase = R.string.sync_phase_create_local_entries syncPhase = R.string.sync_phase_create_local_entries
App.log.info("Sync phase: " + context.getString(syncPhase)) Logger.log.info("Sync phase: " + context.getString(syncPhase))
createLocalEntries() createLocalEntries()
if (Thread.interrupted()) if (Thread.interrupted())
throw InterruptedException() throw InterruptedException()
syncPhase = R.string.sync_phase_apply_local_entries syncPhase = R.string.sync_phase_apply_local_entries
App.log.info("Sync phase: " + context.getString(syncPhase)) Logger.log.info("Sync phase: " + context.getString(syncPhase))
/* FIXME: Skipping this now, because we already override with remote. /* FIXME: Skipping this now, because we already override with remote.
applyLocalEntries(); applyLocalEntries();
*/ */
@ -162,7 +163,7 @@ constructor(protected val context: Context, protected val account: Account, prot
if (Thread.interrupted()) if (Thread.interrupted())
throw InterruptedException() throw InterruptedException()
syncPhase = R.string.sync_phase_push_entries syncPhase = R.string.sync_phase_push_entries
App.log.info("Sync phase: " + context.getString(syncPhase)) Logger.log.info("Sync phase: " + context.getString(syncPhase))
pushEntries() pushEntries()
} while (localEntries!!.size == MAX_PUSH) } while (localEntries!!.size == MAX_PUSH)
@ -170,7 +171,7 @@ constructor(protected val context: Context, protected val account: Account, prot
if (Thread.interrupted()) if (Thread.interrupted())
throw InterruptedException() throw InterruptedException()
syncPhase = R.string.sync_phase_post_processing syncPhase = R.string.sync_phase_post_processing
App.log.info("Sync phase: " + context.getString(syncPhase)) Logger.log.info("Sync phase: " + context.getString(syncPhase))
postProcess() postProcess()
if (numDiscarded > 0) { if (numDiscarded > 0) {
@ -178,9 +179,9 @@ constructor(protected val context: Context, protected val account: Account, prot
} }
notifyUserOnSync() notifyUserOnSync()
App.log.info("Finished sync with CTag=$remoteCTag") Logger.log.info("Finished sync with CTag=$remoteCTag")
} catch (e: IOException) { } catch (e: IOException) {
App.log.log(Level.WARNING, "I/O exception during sync, trying again later", e) Logger.log.log(Level.WARNING, "I/O exception during sync, trying again later", e)
syncResult.stats.numIoExceptions++ syncResult.stats.numIoExceptions++
} catch (e: Exceptions.ServiceUnavailableException) { } catch (e: Exceptions.ServiceUnavailableException) {
syncResult.stats.numIoExceptions++ syncResult.stats.numIoExceptions++
@ -298,13 +299,13 @@ constructor(protected val context: Context, protected val account: Account, prot
throw InterruptedException() throw InterruptedException()
} }
i++ i++
App.log.info("Processing (" + i.toString() + "/" + strTotal + ") " + entry.toString()) Logger.log.info("Processing (" + i.toString() + "/" + strTotal + ") " + entry.toString())
val cEntry = SyncEntry.fromJournalEntry(crypto, entry) val cEntry = SyncEntry.fromJournalEntry(crypto, entry)
if (cEntry.isAction(SyncEntry.Actions.DELETE)) { if (cEntry.isAction(SyncEntry.Actions.DELETE)) {
continue continue
} }
App.log.info("Processing resource for journal entry") Logger.log.info("Processing resource for journal entry")
processSyncEntry(cEntry) processSyncEntry(cEntry)
} }
} }
@ -333,7 +334,7 @@ constructor(protected val context: Context, protected val account: Account, prot
remoteEntries = journal!!.list(crypto, remoteCTag, MAX_FETCH) remoteEntries = journal!!.list(crypto, remoteCTag, MAX_FETCH)
} }
App.log.info("Fetched " + remoteEntries!!.size.toString() + " entries") Logger.log.info("Fetched " + remoteEntries!!.size.toString() + " entries")
} }
@Throws(IOException::class, ContactsStorageException::class, CalendarStorageException::class, InvalidCalendarException::class, InterruptedException::class) @Throws(IOException::class, ContactsStorageException::class, CalendarStorageException::class, InvalidCalendarException::class, InterruptedException::class)
@ -347,10 +348,10 @@ constructor(protected val context: Context, protected val account: Account, prot
throw InterruptedException() throw InterruptedException()
} }
i++ i++
App.log.info("Processing (" + i.toString() + "/" + strTotal + ") " + entry.toString()) Logger.log.info("Processing (" + i.toString() + "/" + strTotal + ") " + entry.toString())
val cEntry = SyncEntry.fromJournalEntry(crypto, entry) val cEntry = SyncEntry.fromJournalEntry(crypto, entry)
App.log.info("Processing resource for journal entry") Logger.log.info("Processing resource for journal entry")
processSyncEntry(cEntry) processSyncEntry(cEntry)
persistSyncEntry(entry.uid, cEntry) persistSyncEntry(entry.uid, cEntry)
@ -394,7 +395,7 @@ constructor(protected val context: Context, protected val account: Account, prot
if (pushed-- <= 0) { if (pushed-- <= 0) {
break break
} }
App.log.info("Added/changed resource with UUID: " + local.uuid) Logger.log.info("Added/changed resource with UUID: " + local.uuid)
local.clearDirty(local.uuid!!) local.clearDirty(local.uuid!!)
} }
if (left > 0) { if (left > 0) {
@ -402,7 +403,7 @@ constructor(protected val context: Context, protected val account: Account, prot
} }
if (pushed > 0) { if (pushed > 0) {
App.log.severe("Unprocessed localentries left, this should never happen!") Logger.log.severe("Unprocessed localentries left, this should never happen!")
} }
} }
} }
@ -470,7 +471,7 @@ constructor(protected val context: Context, protected val account: Account, prot
if (journalEntity.isReadOnly) { if (journalEntity.isReadOnly) {
for (local in localList) { for (local in localList) {
App.log.info("Restoring locally deleted resource on a read only collection: ${local.uuid}") Logger.log.info("Restoring locally deleted resource on a read only collection: ${local.uuid}")
local.resetDeleted() local.resetDeleted()
numDiscarded++ numDiscarded++
} }
@ -480,9 +481,9 @@ constructor(protected val context: Context, protected val account: Account, prot
return ret return ret
if (local.uuid != null) { if (local.uuid != null) {
App.log.info(local.uuid + " has been deleted locally -> deleting from server") Logger.log.info(local.uuid + " has been deleted locally -> deleting from server")
} else { } else {
App.log.fine("Entry deleted before ever syncing - genarting a UUID") Logger.log.fine("Entry deleted before ever syncing - genarting a UUID")
local.prepareForUpload() local.prepareForUpload()
} }
@ -499,7 +500,7 @@ constructor(protected val context: Context, protected val account: Account, prot
protected open fun prepareDirty() { protected open fun prepareDirty() {
if (journalEntity.isReadOnly) { if (journalEntity.isReadOnly) {
for (local in localDirty) { for (local in localDirty) {
App.log.info("Restoring locally modified resource on a read only collection: ${local.uuid}") Logger.log.info("Restoring locally modified resource on a read only collection: ${local.uuid}")
if (local.uuid == null) { if (local.uuid == null) {
// If it was only local, delete. // If it was only local, delete.
local.delete() local.delete()
@ -512,13 +513,13 @@ constructor(protected val context: Context, protected val account: Account, prot
localDirty = LinkedList() localDirty = LinkedList()
} else { } else {
// assign file names and UIDs to new entries // assign file names and UIDs to new entries
App.log.info("Looking for local entries without a uuid") Logger.log.info("Looking for local entries without a uuid")
for (local in localDirty) { for (local in localDirty) {
if (local.uuid != null) { if (local.uuid != null) {
continue continue
} }
App.log.fine("Found local record without file name; generating file name/UID if necessary") Logger.log.fine("Found local record without file name; generating file name/UID if necessary")
local.prepareForUpload() local.prepareForUpload()
} }
} }

View File

@ -16,11 +16,11 @@ import android.content.SyncResult
import android.database.sqlite.SQLiteException import android.database.sqlite.SQLiteException
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.provider.CalendarContract
import at.bitfire.ical4android.AndroidTaskList import at.bitfire.ical4android.AndroidTaskList
import at.bitfire.ical4android.TaskProvider import at.bitfire.ical4android.TaskProvider
import com.etesync.syncadapter.* import com.etesync.syncadapter.*
import com.etesync.syncadapter.journalmanager.Exceptions import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity import com.etesync.syncadapter.model.JournalEntity
import com.etesync.syncadapter.model.JournalModel import com.etesync.syncadapter.model.JournalModel
@ -72,7 +72,7 @@ class TasksSyncAdapterService: SyncAdapterService() {
val principal = HttpUrl.get(accountSettings.uri!!)!! val principal = HttpUrl.get(accountSettings.uri!!)!!
for (taskList in AndroidTaskList.find(account, taskProvider, LocalTaskList.Factory, "${TaskContract.TaskLists.SYNC_ENABLED}!=0", null)) { for (taskList in AndroidTaskList.find(account, taskProvider, LocalTaskList.Factory, "${TaskContract.TaskLists.SYNC_ENABLED}!=0", null)) {
App.log.info("Synchronizing task list #${taskList.id} [${taskList.syncId}]") Logger.log.info("Synchronizing task list #${taskList.id} [${taskList.syncId}]")
val tasksSyncManager = TasksSyncManager(context, account, accountSettings, extras, authority, syncResult, taskList, principal); val tasksSyncManager = TasksSyncManager(context, account, accountSettings, extras, authority, syncResult, taskList, principal);
tasksSyncManager.performSync() tasksSyncManager.performSync()
} }
@ -83,7 +83,7 @@ class TasksSyncAdapterService: SyncAdapterService() {
// Ignore // Ignore
} catch (e: Exception) { } catch (e: Exception) {
if (e is SQLiteException) { if (e is SQLiteException) {
App.log.log(Level.SEVERE, "Couldn't prepare local task list", e) Logger.log.log(Level.SEVERE, "Couldn't prepare local task list", e)
syncResult.databaseError = true syncResult.databaseError = true
} }
@ -109,7 +109,7 @@ class TasksSyncAdapterService: SyncAdapterService() {
notificationManager.notify(title, context.getString(syncPhase)) notificationManager.notify(title, context.getString(syncPhase))
} }
App.log.info("Task sync complete") Logger.log.info("Task sync complete")
} }
private fun updateLocalTaskLists(provider: TaskProvider, account: Account, settings: AccountSettings) { private fun updateLocalTaskLists(provider: TaskProvider, account: Account, settings: AccountSettings) {
@ -131,11 +131,11 @@ class TasksSyncAdapterService: SyncAdapterService() {
val url = taskList.url val url = taskList.url
val journalEntity = remote[url] val journalEntity = remote[url]
if (journalEntity == null) { if (journalEntity == null) {
App.log.fine("Deleting obsolete local task list $url") Logger.log.fine("Deleting obsolete local task list $url")
taskList.delete() taskList.delete()
} else { } else {
// remote CollectionInfo found for this local collection, update data // remote CollectionInfo found for this local collection, update data
App.log.fine("Updating local task list $url with $journalEntity") Logger.log.fine("Updating local task list $url with $journalEntity")
taskList.update(journalEntity, updateColors) taskList.update(journalEntity, updateColors)
// we already have a local tasks for this remote collection, don't take into consideration anymore // we already have a local tasks for this remote collection, don't take into consideration anymore
remote.remove(url) remote.remove(url)
@ -145,7 +145,7 @@ class TasksSyncAdapterService: SyncAdapterService() {
// create new local taskss // create new local taskss
for (url in remote.keys) { for (url in remote.keys) {
val journalEntity = remote[url]!! val journalEntity = remote[url]!!
App.log.info("Adding local task list $journalEntity") Logger.log.info("Adding local task list $journalEntity")
LocalTaskList.create(account, provider, journalEntity) LocalTaskList.create(account, provider, journalEntity)
} }
} }

View File

@ -14,10 +14,10 @@ import android.content.SyncResult
import android.os.Bundle import android.os.Bundle
import at.bitfire.ical4android.Task import at.bitfire.ical4android.Task
import com.etesync.syncadapter.AccountSettings import com.etesync.syncadapter.AccountSettings
import com.etesync.syncadapter.App
import com.etesync.syncadapter.Constants import com.etesync.syncadapter.Constants
import com.etesync.syncadapter.R import com.etesync.syncadapter.R
import com.etesync.syncadapter.journalmanager.JournalEntryManager import com.etesync.syncadapter.journalmanager.JournalEntryManager
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.SyncEntry import com.etesync.syncadapter.model.SyncEntry
import com.etesync.syncadapter.resource.LocalTask import com.etesync.syncadapter.resource.LocalTask
@ -73,10 +73,10 @@ class TasksSyncManager(
val tasks = Task.fromReader(inputReader) val tasks = Task.fromReader(inputReader)
if (tasks.size == 0) { if (tasks.size == 0) {
App.log.warning("Received VCard without data, ignoring") Logger.log.warning("Received VCard without data, ignoring")
return return
} else if (tasks.size > 1) { } else if (tasks.size > 1) {
App.log.warning("Received multiple VCALs, using first one") Logger.log.warning("Received multiple VCALs, using first one")
} }
val event = tasks[0] val event = tasks[0]
@ -86,10 +86,10 @@ class TasksSyncManager(
processTask(event, local) processTask(event, local)
} else { } else {
if (local != null) { if (local != null) {
App.log.info("Removing local record #" + local.id + " which has been deleted on the server") Logger.log.info("Removing local record #" + local.id + " which has been deleted on the server")
local.delete() local.delete()
} else { } else {
App.log.warning("Tried deleting a non-existent record: " + event.uid) Logger.log.warning("Tried deleting a non-existent record: " + event.uid)
} }
} }
} }
@ -98,12 +98,12 @@ class TasksSyncManager(
var localTask = _localTask var localTask = _localTask
// delete local Task, if it exists // delete local Task, if it exists
if (localTask != null) { if (localTask != null) {
App.log.info("Updating " + newData.uid + " in local calendar") Logger.log.info("Updating " + newData.uid + " in local calendar")
localTask.eTag = newData.uid localTask.eTag = newData.uid
localTask.update(newData) localTask.update(newData)
syncResult.stats.numUpdates++ syncResult.stats.numUpdates++
} else { } else {
App.log.info("Adding " + newData.uid + " to local calendar") Logger.log.info("Adding " + newData.uid + " to local calendar")
localTask = LocalTask(localTaskList(), newData, newData.uid, newData.uid) localTask = LocalTask(localTaskList(), newData, newData.uid, newData.uid)
localTask.add() localTask.add()
syncResult.stats.numInserts++ syncResult.stats.numInserts++

View File

@ -11,15 +11,6 @@ package com.etesync.syncadapter.ui
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import com.google.android.material.tabs.TabLayout
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import androidx.loader.app.LoaderManager
import androidx.loader.content.AsyncTaskLoader
import androidx.loader.content.Loader
import androidx.viewpager.widget.ViewPager
import androidx.appcompat.widget.Toolbar
import android.text.Html import android.text.Html
import android.text.Spanned import android.text.Spanned
import android.text.util.Linkify import android.text.util.Linkify
@ -27,12 +18,21 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import androidx.loader.app.LoaderManager
import androidx.loader.content.AsyncTaskLoader
import androidx.loader.content.Loader
import androidx.viewpager.widget.ViewPager
import com.etesync.syncadapter.App import com.etesync.syncadapter.App
import com.etesync.syncadapter.BuildConfig import com.etesync.syncadapter.BuildConfig
import com.etesync.syncadapter.Constants import com.etesync.syncadapter.Constants
import com.etesync.syncadapter.R import com.etesync.syncadapter.R
import com.etesync.syncadapter.log.Logger
import com.google.android.material.tabs.TabLayout
import ezvcard.Ezvcard import ezvcard.Ezvcard
import org.apache.commons.lang3.time.DateFormatUtils
import java.io.IOException import java.io.IOException
import java.util.logging.Level import java.util.logging.Level
@ -140,7 +140,7 @@ class AboutActivity : BaseActivity() {
} }
override fun loadInBackground(): Spanned? { override fun loadInBackground(): Spanned? {
App.log.fine("Loading license file $fileName") Logger.log.fine("Loading license file $fileName")
try { try {
val inputStream = context.resources.assets.open(fileName) val inputStream = context.resources.assets.open(fileName)
val raw = inputStream.readBytes() val raw = inputStream.readBytes()
@ -148,7 +148,7 @@ class AboutActivity : BaseActivity() {
content = Html.fromHtml(String(raw)) content = Html.fromHtml(String(raw))
return content return content
} catch (e: IOException) { } catch (e: IOException) {
App.log.log(Level.SEVERE, "Couldn't read license file", e) Logger.log.log(Level.SEVERE, "Couldn't read license file", e)
return null return null
} }

View File

@ -19,17 +19,17 @@ import android.os.Bundle
import android.os.IBinder import android.os.IBinder
import android.provider.CalendarContract import android.provider.CalendarContract
import android.provider.ContactsContract import android.provider.ContactsContract
import com.google.android.material.snackbar.Snackbar
import androidx.core.content.ContextCompat
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.Toolbar
import android.text.TextUtils import android.text.TextUtils
import android.view.* import android.view.*
import android.widget.* import android.widget.*
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
import at.bitfire.ical4android.TaskProvider import at.bitfire.ical4android.TaskProvider
import at.bitfire.vcard4android.ContactsStorageException import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.* import com.etesync.syncadapter.*
import com.etesync.syncadapter.journalmanager.Crypto import com.etesync.syncadapter.journalmanager.Crypto
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity import com.etesync.syncadapter.model.JournalEntity
import com.etesync.syncadapter.model.ServiceEntity import com.etesync.syncadapter.model.ServiceEntity
@ -40,6 +40,7 @@ import com.etesync.syncadapter.ui.setup.SetupUserInfoFragment
import com.etesync.syncadapter.utils.HintManager import com.etesync.syncadapter.utils.HintManager
import com.etesync.syncadapter.utils.ShowcaseBuilder import com.etesync.syncadapter.utils.ShowcaseBuilder
import com.etesync.syncadapter.utils.packageInstalled import com.etesync.syncadapter.utils.packageInstalled
import com.google.android.material.snackbar.Snackbar
import tourguide.tourguide.ToolTip import tourguide.tourguide.ToolTip
import java.util.logging.Level import java.util.logging.Level
@ -418,7 +419,7 @@ class AccountActivity : BaseActivity(), Toolbar.OnMenuItemClickListener, PopupMe
if (future.result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) if (future.result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT))
finish() finish()
} catch(e: Exception) { } catch(e: Exception) {
App.log.log(Level.SEVERE, "Couldn't remove account", e) Logger.log.log(Level.SEVERE, "Couldn't remove account", e)
} }
}, null) }, null)
else else
@ -427,7 +428,7 @@ class AccountActivity : BaseActivity(), Toolbar.OnMenuItemClickListener, PopupMe
if (future.result) if (future.result)
finish() finish()
} catch (e: Exception) { } catch (e: Exception) {
App.log.log(Level.SEVERE, "Couldn't remove account", e) Logger.log.log(Level.SEVERE, "Couldn't remove account", e)
} }
}, null) }, null)
} }

View File

@ -15,17 +15,18 @@ import android.content.Intent
import android.content.SyncStatusObserver import android.content.SyncStatusObserver
import android.os.Bundle import android.os.Bundle
import android.provider.CalendarContract import android.provider.CalendarContract
import androidx.loader.app.LoaderManager import android.text.TextUtils
import android.view.MenuItem
import androidx.core.app.NavUtils import androidx.core.app.NavUtils
import androidx.loader.app.LoaderManager
import androidx.loader.content.AsyncTaskLoader import androidx.loader.content.AsyncTaskLoader
import androidx.loader.content.Loader import androidx.loader.content.Loader
import androidx.preference.* import androidx.preference.*
import android.text.TextUtils
import android.view.MenuItem
import at.bitfire.ical4android.TaskProvider import at.bitfire.ical4android.TaskProvider
import com.etesync.syncadapter.* import com.etesync.syncadapter.*
import com.etesync.syncadapter.Constants.KEY_ACCOUNT import com.etesync.syncadapter.Constants.KEY_ACCOUNT
import com.etesync.syncadapter.R import com.etesync.syncadapter.R
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.ui.setup.LoginCredentials import com.etesync.syncadapter.ui.setup.LoginCredentials
import com.etesync.syncadapter.ui.setup.LoginCredentialsChangeFragment import com.etesync.syncadapter.ui.setup.LoginCredentialsChangeFragment
@ -185,7 +186,7 @@ class AccountSettingsActivity : BaseActivity() {
} }
override fun onStatusChanged(which: Int) { override fun onStatusChanged(which: Int) {
App.log.fine("Reloading account settings") Logger.log.fine("Reloading account settings")
forceLoad() forceLoad()
} }

View File

@ -13,17 +13,17 @@ import android.app.ProgressDialog
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import com.google.android.material.textfield.TextInputLayout
import androidx.appcompat.app.AlertDialog
import android.view.View import android.view.View
import androidx.appcompat.app.AlertDialog
import com.etesync.syncadapter.AccountSettings import com.etesync.syncadapter.AccountSettings
import com.etesync.syncadapter.App
import com.etesync.syncadapter.HttpClient import com.etesync.syncadapter.HttpClient
import com.etesync.syncadapter.R import com.etesync.syncadapter.R
import com.etesync.syncadapter.journalmanager.Crypto import com.etesync.syncadapter.journalmanager.Crypto
import com.etesync.syncadapter.journalmanager.JournalManager import com.etesync.syncadapter.journalmanager.JournalManager
import com.etesync.syncadapter.journalmanager.UserInfoManager import com.etesync.syncadapter.journalmanager.UserInfoManager
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.syncadapter.requestSync import com.etesync.syncadapter.syncadapter.requestSync
import com.google.android.material.textfield.TextInputLayout
import okhttp3.HttpUrl import okhttp3.HttpUrl
import org.jetbrains.anko.doAsync import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread import org.jetbrains.anko.uiThread
@ -64,9 +64,9 @@ open class ChangeEncryptionPasswordActivity : BaseActivity() {
val httpClient = HttpClient.create(this, settings) val httpClient = HttpClient.create(this, settings)
doAsync { doAsync {
App.log.info("Started deriving old key") Logger.log.info("Started deriving old key")
val old_key = Crypto.deriveKey(account.name, old_password) val old_key = Crypto.deriveKey(account.name, old_password)
App.log.info("Finished deriving old key") Logger.log.info("Finished deriving old key")
var cryptoManager: Crypto.CryptoManager var cryptoManager: Crypto.CryptoManager
val principal = HttpUrl.get(settings.uri!!)!! val principal = HttpUrl.get(settings.uri!!)!!
@ -74,19 +74,19 @@ open class ChangeEncryptionPasswordActivity : BaseActivity() {
try { try {
val userInfoManager = UserInfoManager(httpClient, principal) val userInfoManager = UserInfoManager(httpClient, principal)
val userInfo = userInfoManager.fetch(account.name)!! val userInfo = userInfoManager.fetch(account.name)!!
App.log.info("Fetched userInfo for " + account.name) Logger.log.info("Fetched userInfo for " + account.name)
cryptoManager = Crypto.CryptoManager(userInfo.version!!.toInt(), old_key, "userInfo") cryptoManager = Crypto.CryptoManager(userInfo.version!!.toInt(), old_key, "userInfo")
userInfo.verify(cryptoManager) userInfo.verify(cryptoManager)
App.log.info("Started deriving new key") Logger.log.info("Started deriving new key")
val new_key = Crypto.deriveKey(account.name, new_password) val new_key = Crypto.deriveKey(account.name, new_password)
App.log.info("Finished deriving new key") Logger.log.info("Finished deriving new key")
val userInfoContent = userInfo.getContent(cryptoManager)!! val userInfoContent = userInfo.getContent(cryptoManager)!!
cryptoManager = Crypto.CryptoManager(userInfo.version.toInt(), new_key, "userInfo") cryptoManager = Crypto.CryptoManager(userInfo.version.toInt(), new_key, "userInfo")
userInfo.setContent(cryptoManager, userInfoContent) userInfo.setContent(cryptoManager, userInfoContent)
App.log.info("Fetching journal list") Logger.log.info("Fetching journal list")
val membersToAdd = LinkedList<Pair<JournalManager.Journal, ByteArray?>>() val membersToAdd = LinkedList<Pair<JournalManager.Journal, ByteArray?>>()
val journalManager = JournalManager(httpClient, principal) val journalManager = JournalManager(httpClient, principal)
val journals = journalManager.list() val journals = journalManager.list()
@ -102,13 +102,13 @@ open class ChangeEncryptionPasswordActivity : BaseActivity() {
cryptoManager = Crypto.CryptoManager(journal.version, old_key, journal.uid!!) cryptoManager = Crypto.CryptoManager(journal.version, old_key, journal.uid!!)
} }
App.log.info("Converting journal ${journal.uid}") Logger.log.info("Converting journal ${journal.uid}")
journal.verify(cryptoManager) journal.verify(cryptoManager)
membersToAdd.add(Pair(journal, cryptoManager.getEncryptedKey(settings.keyPair!!, userInfo.pubkey!!))) membersToAdd.add(Pair(journal, cryptoManager.getEncryptedKey(settings.keyPair!!, userInfo.pubkey!!)))
} }
App.log.info("Finished converting account. Uploading changes") Logger.log.info("Finished converting account. Uploading changes")
userInfoManager.update(userInfo) userInfoManager.update(userInfo)
for ((journal, encryptedKey) in membersToAdd) { for ((journal, encryptedKey) in membersToAdd) {
@ -116,13 +116,13 @@ open class ChangeEncryptionPasswordActivity : BaseActivity() {
continue continue
} }
App.log.info("Uploading journal ${journal.uid}") Logger.log.info("Uploading journal ${journal.uid}")
val member = JournalManager.Member(account.name, encryptedKey!!) val member = JournalManager.Member(account.name, encryptedKey!!)
journalManager.addMember(journal, member) journalManager.addMember(journal, member)
} }
settings.password(new_key) settings.password(new_key)
App.log.info("Finished uploading changes. Encryption password changed successfully.") Logger.log.info("Finished uploading changes. Encryption password changed successfully.")
uiThread { uiThread {
progress.dismiss() progress.dismiss()

View File

@ -23,15 +23,16 @@ import android.os.Bundle
import android.os.PowerManager import android.os.PowerManager
import android.provider.CalendarContract import android.provider.CalendarContract
import android.provider.ContactsContract import android.provider.ContactsContract
import androidx.core.content.ContextCompat
import android.text.TextUtils import android.text.TextUtils
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.widget.TextView import android.widget.TextView
import androidx.core.content.ContextCompat
import at.bitfire.vcard4android.ContactsStorageException import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.* import com.etesync.syncadapter.*
import com.etesync.syncadapter.Constants.KEY_ACCOUNT import com.etesync.syncadapter.Constants.KEY_ACCOUNT
import com.etesync.syncadapter.journalmanager.Exceptions.HttpException import com.etesync.syncadapter.journalmanager.Exceptions.HttpException
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.EntryEntity import com.etesync.syncadapter.model.EntryEntity
import com.etesync.syncadapter.model.JournalEntity import com.etesync.syncadapter.model.JournalEntity
import com.etesync.syncadapter.model.ServiceDB import com.etesync.syncadapter.model.ServiceDB
@ -41,7 +42,6 @@ import org.acra.ACRA
import org.apache.commons.lang3.exception.ExceptionUtils import org.apache.commons.lang3.exception.ExceptionUtils
import org.apache.commons.lang3.text.WordUtils import org.apache.commons.lang3.text.WordUtils
import java.io.File import java.io.File
import java.util.*
import java.util.logging.Level import java.util.logging.Level
class DebugInfoActivity : BaseActivity(), LoaderManager.LoaderCallbacks<String> { class DebugInfoActivity : BaseActivity(), LoaderManager.LoaderCallbacks<String> {
@ -144,7 +144,7 @@ class DebugInfoActivity : BaseActivity(), LoaderManager.LoaderCallbacks<String>
report.append("\nSOFTWARE INFORMATION\n" + "EteSync version: ").append(BuildConfig.VERSION_NAME).append(" (").append(BuildConfig.VERSION_CODE).append(") ").append("\n") report.append("\nSOFTWARE INFORMATION\n" + "EteSync version: ").append(BuildConfig.VERSION_NAME).append(" (").append(BuildConfig.VERSION_CODE).append(") ").append("\n")
.append("Installed from: ").append(installedFrom).append("\n") .append("Installed from: ").append(installedFrom).append("\n")
} catch (ex: Exception) { } catch (ex: Exception) {
App.log.log(Level.SEVERE, "Couldn't get software information", ex) Logger.log.log(Level.SEVERE, "Couldn't get software information", ex)
} }
report.append("CONFIGURATION\n") report.append("CONFIGURATION\n")
@ -216,7 +216,7 @@ class DebugInfoActivity : BaseActivity(), LoaderManager.LoaderCallbacks<String>
"SYSTEM INFORMATION\n" + "Android version: ").append(Build.VERSION.RELEASE).append(" (").append(Build.DISPLAY).append(")\n" + "Device: ").append(WordUtils.capitalize(Build.MANUFACTURER)).append(" ").append(Build.MODEL).append(" (").append(Build.DEVICE).append(")\n\n" "SYSTEM INFORMATION\n" + "Android version: ").append(Build.VERSION.RELEASE).append(" (").append(Build.DISPLAY).append(")\n" + "Device: ").append(WordUtils.capitalize(Build.MANUFACTURER)).append(" ").append(Build.MODEL).append(" (").append(Build.DEVICE).append(")\n\n"
) )
} catch (ex: Exception) { } catch (ex: Exception) {
App.log.log(Level.SEVERE, "Couldn't get system details", ex) Logger.log.log(Level.SEVERE, "Couldn't get system details", ex)
} }
report.append("--- END DEBUG INFO ---\n") report.append("--- END DEBUG INFO ---\n")

View File

@ -8,7 +8,7 @@ import android.provider.CalendarContract
import android.provider.CalendarContract.Calendars import android.provider.CalendarContract.Calendars
import android.provider.CalendarContract.Events import android.provider.CalendarContract.Events
import android.provider.ContactsContract import android.provider.ContactsContract
import com.etesync.syncadapter.App import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.resource.LocalCalendar import com.etesync.syncadapter.resource.LocalCalendar
import java.util.* import java.util.*
@ -51,7 +51,7 @@ class CalendarAccount protected constructor(val account: Account) {
CAL_COLS, null, null, CAL_COLS, null, null,
ContactsContract.RawContacts.ACCOUNT_NAME + " ASC, " + ContactsContract.RawContacts.ACCOUNT_TYPE) ContactsContract.RawContacts.ACCOUNT_NAME + " ASC, " + ContactsContract.RawContacts.ACCOUNT_TYPE)
} catch (except: Exception) { } catch (except: Exception) {
App.log.warning("Calendar provider is missing columns, continuing anyway") Logger.log.warning("Calendar provider is missing columns, continuing anyway")
cur = resolver.query(Calendars.CONTENT_URI, null, null, null, null) cur = resolver.query(Calendars.CONTENT_URI, null, null, null, null)
except.printStackTrace() except.printStackTrace()
} }

View File

@ -20,10 +20,10 @@ import at.bitfire.ical4android.InvalidCalendarException
import at.bitfire.vcard4android.BatchOperation import at.bitfire.vcard4android.BatchOperation
import at.bitfire.vcard4android.Contact import at.bitfire.vcard4android.Contact
import at.bitfire.vcard4android.ContactsStorageException import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.App
import com.etesync.syncadapter.Constants.KEY_ACCOUNT import com.etesync.syncadapter.Constants.KEY_ACCOUNT
import com.etesync.syncadapter.Constants.KEY_COLLECTION_INFO import com.etesync.syncadapter.Constants.KEY_COLLECTION_INFO
import com.etesync.syncadapter.R import com.etesync.syncadapter.R
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.resource.* import com.etesync.syncadapter.resource.*
import com.etesync.syncadapter.syncadapter.ContactsSyncManager import com.etesync.syncadapter.syncadapter.ContactsSyncManager
@ -144,13 +144,13 @@ class ImportFragment : DialogFragment() {
if (data != null) { if (data != null) {
// Get the URI of the selected file // Get the URI of the selected file
val uri = data.data!! val uri = data.data!!
App.log.info("Importing uri = ${uri}") Logger.log.info("Importing uri = ${uri}")
try { try {
inputStream = activity!!.contentResolver.openInputStream(uri) inputStream = activity!!.contentResolver.openInputStream(uri)
Thread(ImportEntriesLoader()).start() Thread(ImportEntriesLoader()).start()
} catch (e: Exception) { } catch (e: Exception) {
App.log.severe("File select error: ${e.message}") Logger.log.severe("File select error: ${e.message}")
val importResult = ImportResult() val importResult = ImportResult()
importResult.e = e importResult.e = e
@ -218,7 +218,7 @@ class ImportFragment : DialogFragment() {
importReader.close() importReader.close()
if (events.size == 0) { if (events.size == 0) {
App.log.warning("Empty/invalid file.") Logger.log.warning("Empty/invalid file.")
result.e = Exception("Empty/invalid file.") result.e = Exception("Empty/invalid file.")
return result return result
} }
@ -235,11 +235,11 @@ class ImportFragment : DialogFragment() {
throw FileNotFoundException("Failed to load local resource.") throw FileNotFoundException("Failed to load local resource.")
} }
} catch (e: CalendarStorageException) { } catch (e: CalendarStorageException) {
App.log.info("Fail" + e.localizedMessage) Logger.log.info("Fail" + e.localizedMessage)
result.e = e result.e = e
return result return result
} catch (e: FileNotFoundException) { } catch (e: FileNotFoundException) {
App.log.info("Fail" + e.localizedMessage) Logger.log.info("Fail" + e.localizedMessage)
result.e = e result.e = e
return result return result
} }
@ -261,7 +261,7 @@ class ImportFragment : DialogFragment() {
val contacts = Contact.fromReader(importReader, downloader) val contacts = Contact.fromReader(importReader, downloader)
if (contacts.size == 0) { if (contacts.size == 0) {
App.log.warning("Empty/invalid file.") Logger.log.warning("Empty/invalid file.")
result.e = Exception("Empty/invalid file.") result.e = Exception("Empty/invalid file.")
return result return result
} }

View File

@ -13,13 +13,13 @@ import android.app.ProgressDialog
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.loader.app.LoaderManager import androidx.loader.app.LoaderManager
import androidx.loader.content.AsyncTaskLoader import androidx.loader.content.AsyncTaskLoader
import androidx.loader.content.Loader import androidx.loader.content.Loader
import androidx.appcompat.app.AlertDialog
import com.etesync.syncadapter.App
import com.etesync.syncadapter.R import com.etesync.syncadapter.R
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.ui.DebugInfoActivity import com.etesync.syncadapter.ui.DebugInfoActivity
import com.etesync.syncadapter.ui.setup.BaseConfigurationFinder.Configuration import com.etesync.syncadapter.ui.setup.BaseConfigurationFinder.Configuration
@ -59,7 +59,7 @@ class DetectConfigurationFragment : DialogFragment(), LoaderManager.LoaderCallba
.addToBackStack(null) .addToBackStack(null)
.commitAllowingStateLoss() .commitAllowingStateLoss()
} else } else
App.log.severe("Configuration detection failed") Logger.log.severe("Configuration detection failed")
dismissAllowingStateLoss() dismissAllowingStateLoss()
} }

View File

@ -10,10 +10,8 @@ package com.etesync.syncadapter.ui.setup
import android.os.Parcel import android.os.Parcel
import android.os.Parcelable import android.os.Parcelable
import com.etesync.syncadapter.App
import com.etesync.syncadapter.Constants import com.etesync.syncadapter.Constants
import com.etesync.syncadapter.log.Logger
import java.net.URI import java.net.URI
import java.net.URISyntaxException import java.net.URISyntaxException
@ -27,7 +25,7 @@ class LoginCredentials(_uri: URI?, val userName: String, val password: String) :
try { try {
uri = URI(Constants.serviceUrl.toString()) uri = URI(Constants.serviceUrl.toString())
} catch (e: URISyntaxException) { } catch (e: URISyntaxException) {
App.log.severe("Should never happen, it's a constant") Logger.log.severe("Should never happen, it's a constant")
} }
} }

View File

@ -14,15 +14,15 @@ import android.app.ProgressDialog
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.loader.app.LoaderManager import androidx.loader.app.LoaderManager
import androidx.loader.content.AsyncTaskLoader import androidx.loader.content.AsyncTaskLoader
import androidx.loader.content.Loader import androidx.loader.content.Loader
import androidx.appcompat.app.AlertDialog
import com.etesync.syncadapter.AccountSettings import com.etesync.syncadapter.AccountSettings
import com.etesync.syncadapter.App
import com.etesync.syncadapter.InvalidAccountException import com.etesync.syncadapter.InvalidAccountException
import com.etesync.syncadapter.R import com.etesync.syncadapter.R
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.ui.DebugInfoActivity import com.etesync.syncadapter.ui.DebugInfoActivity
import com.etesync.syncadapter.ui.setup.BaseConfigurationFinder.Configuration import com.etesync.syncadapter.ui.setup.BaseConfigurationFinder.Configuration
import java.util.logging.Level import java.util.logging.Level
@ -64,7 +64,7 @@ class LoginCredentialsChangeFragment : DialogFragment(), LoaderManager.LoaderCal
try { try {
settings = AccountSettings(activity!!, account) settings = AccountSettings(activity!!, account)
} catch (e: InvalidAccountException) { } catch (e: InvalidAccountException) {
App.log.log(Level.INFO, "Account is invalid or doesn't exist (anymore)", e) Logger.log.log(Level.INFO, "Account is invalid or doesn't exist (anymore)", e)
activity!!.finish() activity!!.finish()
return return
} }
@ -72,7 +72,7 @@ class LoginCredentialsChangeFragment : DialogFragment(), LoaderManager.LoaderCal
settings.authToken = data.authtoken!! settings.authToken = data.authtoken!!
} }
} else } else
App.log.severe("Configuration detection failed") Logger.log.severe("Configuration detection failed")
dismissAllowingStateLoss() dismissAllowingStateLoss()
} }

View File

@ -18,13 +18,14 @@ import android.content.Context
import android.os.AsyncTask import android.os.AsyncTask
import android.os.Bundle import android.os.Bundle
import android.provider.CalendarContract import android.provider.CalendarContract
import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import at.bitfire.ical4android.TaskProvider import at.bitfire.ical4android.TaskProvider
import com.etesync.syncadapter.* import com.etesync.syncadapter.*
import com.etesync.syncadapter.journalmanager.Crypto import com.etesync.syncadapter.journalmanager.Crypto
import com.etesync.syncadapter.journalmanager.Exceptions import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.journalmanager.UserInfoManager import com.etesync.syncadapter.journalmanager.UserInfoManager
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity import com.etesync.syncadapter.model.JournalEntity
import com.etesync.syncadapter.model.ServiceEntity import com.etesync.syncadapter.model.ServiceEntity
@ -56,7 +57,7 @@ class SetupEncryptionFragment : DialogFragment() {
override fun onPostExecute(result: Configuration) { override fun onPostExecute(result: Configuration) {
if (config.error != null && config.error is Exceptions.IntegrityException) { if (config.error != null && config.error is Exceptions.IntegrityException) {
App.log.severe("Wrong encryption password.") Logger.log.severe("Wrong encryption password.")
AlertDialog.Builder(activity!!) AlertDialog.Builder(activity!!)
.setTitle(R.string.wrong_encryption_password) .setTitle(R.string.wrong_encryption_password)
.setIcon(R.drawable.ic_error_dark) .setIcon(R.drawable.ic_error_dark)
@ -71,7 +72,7 @@ class SetupEncryptionFragment : DialogFragment() {
activity!!.finish() activity!!.finish()
} }
} catch (e: InvalidAccountException) { } catch (e: InvalidAccountException) {
App.log.severe("Account creation failed!") Logger.log.severe("Account creation failed!")
AlertDialog.Builder(activity!!) AlertDialog.Builder(activity!!)
.setTitle(R.string.account_creation_failed) .setTitle(R.string.account_creation_failed)
.setIcon(R.drawable.ic_error_dark) .setIcon(R.drawable.ic_error_dark)
@ -87,9 +88,9 @@ class SetupEncryptionFragment : DialogFragment() {
} }
override fun doInBackground(vararg aVoids: Void): Configuration { override fun doInBackground(vararg aVoids: Void): Configuration {
App.log.info("Started deriving key") Logger.log.info("Started deriving key")
config.password = Crypto.deriveKey(config.userName, config.rawPassword!!) config.password = Crypto.deriveKey(config.userName, config.rawPassword!!)
App.log.info("Finished deriving key") Logger.log.info("Finished deriving key")
config.error = null config.error = null
try { try {
@ -99,7 +100,7 @@ class SetupEncryptionFragment : DialogFragment() {
val userInfoManager = UserInfoManager(httpClient, HttpUrl.get(config.url)!!) val userInfoManager = UserInfoManager(httpClient, HttpUrl.get(config.url)!!)
val userInfo = userInfoManager.fetch(config.userName) val userInfo = userInfoManager.fetch(config.userName)
if (userInfo != null) { if (userInfo != null) {
App.log.info("Fetched userInfo for " + config.userName) Logger.log.info("Fetched userInfo for " + config.userName)
cryptoManager = Crypto.CryptoManager(userInfo.version!!.toInt(), config.password!!, "userInfo") cryptoManager = Crypto.CryptoManager(userInfo.version!!.toInt(), config.password!!, "userInfo")
userInfo.verify(cryptoManager) userInfo.verify(cryptoManager)
config.keyPair = Crypto.AsymmetricKeyPair(userInfo.getContent(cryptoManager)!!, userInfo.pubkey!!) config.keyPair = Crypto.AsymmetricKeyPair(userInfo.getContent(cryptoManager)!!, userInfo.pubkey!!)
@ -119,7 +120,7 @@ class SetupEncryptionFragment : DialogFragment() {
val account = Account(accountName, App.accountType) val account = Account(accountName, App.accountType)
// create Android account // create Android account
App.log.log(Level.INFO, "Creating Android account with initial config", arrayOf(account, config.userName, config.url)) Logger.log.log(Level.INFO, "Creating Android account with initial config", arrayOf(account, config.userName, config.url))
val accountManager = AccountManager.get(context) val accountManager = AccountManager.get(context)
if (!accountManager.addAccountExplicitly(account, config.password, null)) if (!accountManager.addAccountExplicitly(account, config.password, null))
@ -128,7 +129,7 @@ class SetupEncryptionFragment : DialogFragment() {
AccountSettings.setUserData(accountManager, account, config.url, config.userName) AccountSettings.setUserData(accountManager, account, config.url, config.userName)
// add entries for account to service DB // add entries for account to service DB
App.log.log(Level.INFO, "Writing account configuration to database", config) Logger.log.log(Level.INFO, "Writing account configuration to database", config)
try { try {
val settings = AccountSettings(context!!, account) val settings = AccountSettings(context!!, account)
@ -165,7 +166,7 @@ class SetupEncryptionFragment : DialogFragment() {
} }
} catch (e: InvalidAccountException) { } catch (e: InvalidAccountException) {
App.log.log(Level.SEVERE, "Couldn't access account settings", e) Logger.log.log(Level.SEVERE, "Couldn't access account settings", e)
AndroidCompat.removeAccount(accountManager, account) AndroidCompat.removeAccount(accountManager, account)
throw e throw e
} }

View File

@ -6,13 +6,17 @@ import android.app.ProgressDialog
import android.content.Context import android.content.Context
import android.os.AsyncTask import android.os.AsyncTask
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import com.etesync.syncadapter.* import androidx.fragment.app.DialogFragment
import com.etesync.syncadapter.AccountSettings
import com.etesync.syncadapter.Constants.KEY_ACCOUNT import com.etesync.syncadapter.Constants.KEY_ACCOUNT
import com.etesync.syncadapter.HttpClient
import com.etesync.syncadapter.InvalidAccountException
import com.etesync.syncadapter.R
import com.etesync.syncadapter.journalmanager.Constants import com.etesync.syncadapter.journalmanager.Constants
import com.etesync.syncadapter.journalmanager.Crypto import com.etesync.syncadapter.journalmanager.Crypto
import com.etesync.syncadapter.journalmanager.UserInfoManager import com.etesync.syncadapter.journalmanager.UserInfoManager
import com.etesync.syncadapter.log.Logger
import okhttp3.HttpUrl import okhttp3.HttpUrl
class SetupUserInfoFragment : DialogFragment() { class SetupUserInfoFragment : DialogFragment() {
@ -53,12 +57,12 @@ class SetupUserInfoFragment : DialogFragment() {
var userInfo: UserInfoManager.UserInfo? = userInfoManager.fetch(account.name) var userInfo: UserInfoManager.UserInfo? = userInfoManager.fetch(account.name)
if (userInfo == null) { if (userInfo == null) {
App.log.info("Creating userInfo for " + account.name) Logger.log.info("Creating userInfo for " + account.name)
cryptoManager = Crypto.CryptoManager(Constants.CURRENT_VERSION, settings.password(), "userInfo") cryptoManager = Crypto.CryptoManager(Constants.CURRENT_VERSION, settings.password(), "userInfo")
userInfo = UserInfoManager.UserInfo.generate(cryptoManager, account.name) userInfo = UserInfoManager.UserInfo.generate(cryptoManager, account.name)
userInfoManager.create(userInfo) userInfoManager.create(userInfo)
} else { } else {
App.log.info("Fetched userInfo for " + account.name) Logger.log.info("Fetched userInfo for " + account.name)
cryptoManager = Crypto.CryptoManager(userInfo.version!!.toInt(), settings.password(), "userInfo") cryptoManager = Crypto.CryptoManager(userInfo.version!!.toInt(), settings.password(), "userInfo")
userInfo.verify(cryptoManager) userInfo.verify(cryptoManager)
} }

View File

@ -3,11 +3,10 @@ package com.etesync.syncadapter.utils
import android.accounts.Account import android.accounts.Account
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri import android.net.Uri
import at.bitfire.ical4android.Event import at.bitfire.ical4android.Event
import com.etesync.syncadapter.App
import com.etesync.syncadapter.R import com.etesync.syncadapter.R
import com.etesync.syncadapter.log.Logger
import net.fortuna.ical4j.model.property.Attendee import net.fortuna.ical4j.model.property.Attendee
import org.acra.attachment.AcraContentProvider import org.acra.attachment.AcraContentProvider
import org.acra.util.IOUtils import org.acra.util.IOUtils
@ -38,7 +37,7 @@ class EventEmailInvitation constructor(val context: Context, val account: Accoun
formatAttendees(event.attendees))) formatAttendees(event.attendees)))
val uri = createAttachmentFromString(context, icsContent) val uri = createAttachmentFromString(context, icsContent)
if (uri == null) { if (uri == null) {
App.log.severe("Unable to create attachment from calendar event") Logger.log.severe("Unable to create attachment from calendar event")
return null return null
} }
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)