Move everything to use the new Logger

pull/71/head
Tom Hacohen 5 years ago
parent 216b51d138
commit 17b6e69c86

@ -20,6 +20,7 @@ import android.os.Bundle
import at.bitfire.vcard4android.ContactsStorageException
import at.bitfire.vcard4android.GroupMethod
import com.etesync.syncadapter.journalmanager.Crypto
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.utils.Base64
import java.net.URI
import java.net.URISyntaxException
@ -110,7 +111,7 @@ constructor(internal val context: Context, internal val account: Account) {
} 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)
update(version)
@ -168,12 +169,12 @@ constructor(internal val context: Context, internal val account: Account) {
private fun update(fromVersion: Int) {
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 {
updateInner(fromVersion)
accountManager.setUserData(account, KEY_SETTINGS_VERSION, toVersion.toString())
} 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")
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
val accountManager = AccountManager.get(context)
for (account in accountManager.getAccountsByType(App.accountType))
try {
App.log.info("Checking account " + account.name)
Logger.log.info("Checking account " + account.name)
AccountSettings(context, account)
} 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)
}
}

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

@ -13,6 +13,7 @@ import android.accounts.OnAccountsUpdateListener
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.etesync.syncadapter.log.Logger
import java.util.*
class AccountsChangedReceiver : BroadcastReceiver() {
@ -24,7 +25,7 @@ class AccountsChangedReceiver : BroadcastReceiver() {
try {
context.startService(serviceIntent)
} 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)

@ -18,20 +18,15 @@ import android.database.sqlite.SQLiteDatabase
import android.graphics.Bitmap
import android.graphics.drawable.BitmapDrawable
import android.os.Build
import android.os.Process
import android.os.StrictMode
import android.provider.CalendarContract
import android.provider.ContactsContract
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import android.util.Log
import at.bitfire.cert4android.CustomCertManager
import at.bitfire.ical4android.AndroidCalendar
import at.bitfire.ical4android.CalendarStorageException
import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.log.LogcatHandler
import com.etesync.syncadapter.log.PlainTextFormatter
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.*
import com.etesync.syncadapter.resource.LocalAddressBook
import com.etesync.syncadapter.resource.LocalCalendar
@ -44,14 +39,8 @@ import io.requery.meta.EntityModel
import io.requery.sql.EntityDataStore
import okhttp3.internal.tls.OkHostnameVerifier
import org.acra.ACRA
import org.apache.commons.lang3.time.DateFormatUtils
import org.jetbrains.anko.doAsync
import java.io.File
import java.io.IOException
import java.util.*
import java.util.logging.FileHandler
import java.util.logging.Level
import java.util.logging.Logger
import javax.net.ssl.HostnameVerifier
@ -145,72 +134,14 @@ class App : Application() {
}
fun reinitLogger() {
val dbHelper = ServiceDB.OpenHelper(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()
Logger.initialize(this)
}
class ReinitSettingsReceiver : BroadcastReceiver() {
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
app.reinitLogger()
@ -259,7 +190,7 @@ class App : Application() {
}
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) {
val data = this.data
@ -324,7 +255,7 @@ class App : Application() {
@SuppressLint("UnsafeProtectedBroadcastReceiver,MissingPermission")
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 prefs = app.getSharedPreferences("app", Context.MODE_PRIVATE)
@ -396,10 +327,8 @@ class App : Application() {
var hostnameVerifier: HostnameVerifier? = null
private set
val log = Logger.getLogger("etesync")
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

@ -24,7 +24,8 @@ import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit
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 {
private val client = OkHttpClient()
@ -36,7 +37,7 @@ object HttpClient {
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)
// use account settings for authentication
@ -46,21 +47,21 @@ object HttpClient {
}
@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)
}
@JvmOverloads
fun create(context: Context?, logger: Logger = App.log): OkHttpClient {
fun create(context: Context?, logger: LoggerType = Logger.log): OkHttpClient {
return defaultBuilder(context, logger).build()
}
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()
// use MemorizingTrustManager to manage self-signed certificates
@ -90,12 +91,12 @@ object HttpClient {
val proxy = Proxy(Proxy.Type.HTTP, address)
builder.proxy(proxy)
App.log.log(Level.INFO, "Using proxy", proxy)
Logger.log.log(Level.INFO, "Using proxy", proxy)
}
} 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) {
App.log.log(Level.SEVERE, "Can't set proxy, ignoring", e)
Logger.log.log(Level.SEVERE, "Can't set proxy, ignoring", e)
} finally {
dbHelper.close()
}

@ -15,6 +15,7 @@ import androidx.core.app.NotificationManagerCompat
import at.bitfire.ical4android.CalendarStorageException
import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.ui.AccountSettingsActivity
import com.etesync.syncadapter.ui.DebugInfoActivity
import com.etesync.syncadapter.ui.WebViewActivity
@ -36,28 +37,28 @@ class NotificationHelper(internal val context: Context, internal val notificatio
fun setThrowable(e: Throwable) {
throwable = e
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
} 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
} 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
} 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
} 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
} 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
} 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
} else {
App.log.log(Level.SEVERE, "Unknown sync error", e)
Logger.log.log(Level.SEVERE, "Unknown sync error", e)
messageString = R.string.sync_error
}

@ -16,6 +16,7 @@ import android.content.Context
import android.content.Intent
import android.provider.CalendarContract
import at.bitfire.ical4android.TaskProvider
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.resource.LocalTaskList
class PackageChangedReceiver : BroadcastReceiver() {
@ -30,7 +31,7 @@ class PackageChangedReceiver : BroadcastReceiver() {
internal fun updateTaskSync(context: 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)) {
val settings = AccountSettings(context, account)

@ -9,6 +9,7 @@
package com.etesync.syncadapter
import android.os.Build
import com.etesync.syncadapter.log.Logger
import java.io.IOException
import java.net.InetAddress
import java.net.Socket
@ -105,7 +106,7 @@ class SSLSocketFactoryCompat(trustManager: X509TrustManager) : SSLSocketFactory(
// - all modern ciphers are activated by default
protocols = null
cipherSuites = null
App.log.fine("Using device default TLS protocols/ciphers")
Logger.log.fine("Using device default TLS protocols/ciphers")
} else {
(SSLSocketFactory.getDefault().createSocket() as? SSLSocket)?.use { socket ->
try {
@ -115,7 +116,7 @@ class SSLSocketFactoryCompat(trustManager: X509TrustManager) : SSLSocketFactory(
val whichProtocols = LinkedList<String>()
for (protocol in socket.supportedProtocols.filterNot { it.contains("SSL", true) })
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()
/* set up reasonable cipher suites */
@ -140,7 +141,7 @@ class SSLSocketFactoryCompat(trustManager: X509TrustManager) : SSLSocketFactory(
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
)
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
* 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, ...
val whichCiphers = LinkedList<String>()
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 ...
whichCiphers.addAll(knownCiphers)
// ... and keep only those which are actually available
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()
} catch (e: IOException) {
App.log.severe("Couldn't determine default TLS settings")
Logger.log.severe("Couldn't determine default TLS settings")
}
}
}

@ -1,7 +1,7 @@
package com.etesync.syncadapter.journalmanager
import com.etesync.syncadapter.App
import com.etesync.syncadapter.GsonHelper
import com.etesync.syncadapter.log.Logger
import okhttp3.*
import java.io.ByteArrayOutputStream
import java.io.IOException
@ -19,7 +19,7 @@ abstract class BaseManager {
try {
response = client!!.newCall(request).execute()
} 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)
}

@ -1,7 +1,7 @@
package com.etesync.syncadapter.journalmanager
import com.etesync.syncadapter.App
import com.etesync.syncadapter.journalmanager.util.ByteUtil
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.utils.Base64
import org.apache.commons.lang3.ArrayUtils
import org.spongycastle.crypto.AsymmetricBlockCipher
@ -69,7 +69,7 @@ object Crypto {
e.printStackTrace()
} catch (e: InvalidCipherTextException) {
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
@ -85,7 +85,7 @@ object Crypto {
e.printStackTrace()
} catch (e: InvalidCipherTextException) {
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
@ -182,7 +182,7 @@ object Crypto {
len += cipher.doFinal(buf, len)
} catch (e: InvalidCipherTextException) {
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
}
@ -205,7 +205,7 @@ object Crypto {
try {
cipher.doFinal(buf, len)
} 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()
return null
}

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

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

@ -58,7 +58,7 @@ object Logger : SharedPreferences.OnSharedPreferenceChangeListener {
val settings = Settings(dbHelper.readableDatabase)
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")

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

@ -20,6 +20,7 @@ import android.provider.ContactsContract.Groups
import android.provider.ContactsContract.RawContacts
import at.bitfire.vcard4android.*
import com.etesync.syncadapter.App
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity
import java.io.FileNotFoundException
@ -156,13 +157,13 @@ class LocalAddressBook(
arrayOf(account.name, account.type))
}
} 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)
account = future.result
}
App.log.info("Address book write permission? = ${!journalEntity.isReadOnly}")
Logger.log.info("Address book write permission? = ${!journalEntity.isReadOnly}")
readOnly = journalEntity.isReadOnly
// make sure it will still be synchronized when contacts are updated
@ -244,10 +245,10 @@ class LocalAddressBook(
val currentHash = contact.dataHashCode()
if (lastHash == currentHash) {
// 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()
} 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++
}
}
@ -338,7 +339,7 @@ class LocalAddressBook(
// find groups without members
/** 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 ->
App.log.log(Level.FINE, "Deleting group", group)
Logger.log.log(Level.FINE, "Deleting group", group)
group.delete()
}
}
@ -355,7 +356,7 @@ class LocalAddressBook(
try {
val fixed = provider?.update(syncAdapterURI(RawContacts.CONTENT_URI),
values, where, null)
App.log.info("Fixed entries: " + fixed.toString())
Logger.log.info("Fixed entries: " + fixed.toString())
} catch (e: RemoteException) {
throw ContactsStorageException("Couldn't query contacts", e)
}

@ -18,7 +18,7 @@ import android.os.RemoteException
import android.provider.CalendarContract
import android.provider.CalendarContract.*
import at.bitfire.ical4android.*
import com.etesync.syncadapter.App
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.JournalEntity
import org.apache.commons.lang3.StringUtils
import java.util.*
@ -77,7 +77,7 @@ class LocalCalendar private constructor(
values.put(Calendars.CALENDAR_TIME_ZONE, DateUtils.findAndroidTimezoneID(tzId.value))
}
} 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)
@ -125,14 +125,14 @@ class LocalCalendar private constructor(
fun processDirtyExceptions() {
// process deleted exceptions
App.log.info("Processing deleted exceptions")
Logger.log.info("Processing deleted exceptions")
try {
val cursor = provider.query(
syncAdapterURI(Events.CONTENT_URI),
arrayOf(Events._ID, Events.ORIGINAL_ID, LocalEvent.COLUMN_SEQUENCE),
Events.DELETED + "!=0 AND " + Events.ORIGINAL_ID + " IS NOT NULL", null, null)
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)
// can't be null (by definition)
val originalID = cursor.getLong(1) // can't be null (by query)
@ -163,14 +163,14 @@ class LocalCalendar private constructor(
}
// process dirty exceptions
App.log.info("Processing dirty exceptions")
Logger.log.info("Processing dirty exceptions")
try {
val cursor = provider.query(
syncAdapterURI(Events.CONTENT_URI),
arrayOf(Events._ID, Events.ORIGINAL_ID, LocalEvent.COLUMN_SEQUENCE),
Events.DIRTY + "!=0 AND " + Events.ORIGINAL_ID + " IS NOT NULL", null, null)
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)
// can't be null (by definition)
val originalID = cursor.getLong(1) // can't be null (by query)
@ -227,7 +227,7 @@ class LocalCalendar private constructor(
try {
val fixed = provider.update(syncAdapterURI(Events.CONTENT_URI),
values, where, whereArgs)
App.log.info("Fixed entries: " + fixed.toString())
Logger.log.info("Fixed entries: " + fixed.toString())
} catch (e: RemoteException) {
throw CalendarStorageException("Couldn't fix etags", e)
}

@ -24,8 +24,8 @@ import at.bitfire.vcard4android.CachedGroupMembership
import at.bitfire.vcard4android.Contact
import at.bitfire.vcard4android.ContactsStorageException
import at.bitfire.vcard4android.GroupMethod.GROUP_VCARDS
import com.etesync.syncadapter.App
import com.etesync.syncadapter.Constants
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.UnknownProperties
import ezvcard.Ezvcard
import ezvcard.VCardVersion
@ -62,7 +62,7 @@ class LocalContact : AndroidContact, LocalAddress {
val contact: 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()
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
val hashCode = dataHashCode()
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)
@ -173,7 +173,7 @@ class LocalContact : AndroidContact, LocalAddress {
// groupMemberships is filled by getContact()
val dataHash = contact!!.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
}
@ -183,7 +183,7 @@ class LocalContact : AndroidContact, LocalAddress {
val values = ContentValues(1)
val hashCode = dataHashCode()
App.log.fine("Storing contact hash = $hashCode")
Logger.log.fine("Storing contact hash = $hashCode")
values.put(COLUMN_HASHCODE, hashCode)
if (batch == null)

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

@ -21,7 +21,7 @@ import android.provider.ContactsContract.RawContacts.Data
import android.text.TextUtils
import at.bitfire.vcard4android.*
import at.bitfire.vcard4android.GroupMethod.GROUP_VCARDS
import com.etesync.syncadapter.App
import com.etesync.syncadapter.log.Logger
import ezvcard.VCardVersion
import java.io.ByteArrayOutputStream
import java.util.*
@ -86,7 +86,7 @@ class LocalGroup : AndroidGroup, LocalAddress {
val contact: 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()
contact.write(VCardVersion.V4_0, GROUP_VCARDS, os)

@ -15,7 +15,7 @@ import at.bitfire.ical4android.AndroidTask
import at.bitfire.ical4android.AndroidTaskFactory
import at.bitfire.ical4android.AndroidTaskList
import at.bitfire.ical4android.Task
import com.etesync.syncadapter.App
import com.etesync.syncadapter.log.Logger
import org.dmfs.tasks.contract.TaskContract
import java.io.ByteArrayOutputStream
import java.util.*
@ -33,7 +33,7 @@ class LocalTask : AndroidTask, LocalResource<Task> {
override val content: String
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()
task?.write(os)

@ -19,6 +19,7 @@ import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.*
import com.etesync.syncadapter.Constants.KEY_ACCOUNT
import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity
import com.etesync.syncadapter.model.JournalModel
@ -46,7 +47,7 @@ class AddressBooksSyncAdapterService : SyncAdapterService() {
try {
val contactsProvider = context.contentResolver.acquireContentProviderClient(ContactsContract.AUTHORITY)
if (contactsProvider == null) {
App.log.severe("Couldn't access contacts provider")
Logger.log.severe("Couldn't access contacts provider")
syncResult.databaseError = true
return
}
@ -63,7 +64,7 @@ class AddressBooksSyncAdapterService : SyncAdapterService() {
val accountManager = AccountManager.get(context)
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)
syncExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true)
syncExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true)
@ -76,7 +77,7 @@ class AddressBooksSyncAdapterService : SyncAdapterService() {
// Ignore
} catch (e: Exception) {
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
}
@ -102,7 +103,7 @@ class AddressBooksSyncAdapterService : SyncAdapterService() {
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 journalEntity = remote[url]
if (journalEntity == null) {
App.log.fine("Deleting obsolete local address book $url")
Logger.log.fine("Deleting obsolete local address book $url")
addressBook.delete()
} else {
// 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)
// we already have a local collection for this remote collection, don't take into consideration anymore
remote.remove(url)
@ -139,7 +140,7 @@ class AddressBooksSyncAdapterService : SyncAdapterService() {
// create new local address books
for (url in remote.keys) {
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)
}
}

@ -17,9 +17,13 @@ import at.bitfire.ical4android.CalendarStorageException
import at.bitfire.ical4android.Event
import at.bitfire.ical4android.InvalidCalendarException
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.JournalEntryManager
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.SyncEntry
import com.etesync.syncadapter.resource.LocalCalendar
@ -80,10 +84,10 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
val events = Event.fromReader(inputReader)
if (events.size == 0) {
App.log.warning("Received VCard without data, ignoring")
Logger.log.warning("Received VCard without data, ignoring")
return
} 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]
@ -93,10 +97,10 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
processEvent(event, local)
} else {
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()
} 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
// delete local event, if it exists
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.update(newData)
syncResult.stats.numUpdates++
} 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.add()
syncResult.stats.numInserts++

@ -17,6 +17,7 @@ import at.bitfire.ical4android.CalendarStorageException
import com.etesync.syncadapter.*
import com.etesync.syncadapter.Constants.KEY_ACCOUNT
import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity
import com.etesync.syncadapter.model.JournalModel
@ -53,7 +54,7 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
val principal = HttpUrl.get(settings.uri!!)!!
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)
syncManager.performSync()
}
@ -64,7 +65,7 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
// Ignore
} catch (e: Exception) {
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
}
@ -90,7 +91,7 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
notificationManager.notify(title, context.getString(syncPhase))
}
App.log.info("Calendar sync complete")
Logger.log.info("Calendar sync complete")
}
@Throws(CalendarStorageException::class)
@ -113,11 +114,11 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
val url = calendar.name
val journalEntity = remote[url]
if (journalEntity == null) {
App.log.fine("Deleting obsolete local calendar $url")
Logger.log.fine("Deleting obsolete local calendar $url")
calendar.delete()
} else {
// 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)
// we already have a local calendar for this remote collection, don't take into consideration anymore
remote.remove(url)
@ -127,7 +128,7 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
// create new local calendars
for (url in remote.keys) {
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)
}
}

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

@ -16,9 +16,13 @@ import at.bitfire.ical4android.CalendarStorageException
import at.bitfire.vcard4android.BatchOperation
import at.bitfire.vcard4android.Contact
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.JournalEntryManager
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.SyncEntry
import com.etesync.syncadapter.resource.LocalAddress
@ -66,7 +70,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
val reallyDirty = localAddressBook.verifyDirty()
val deleted = localAddressBook.findDeleted().size
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
}
}
@ -96,11 +100,11 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
val batch = BatchOperation(addressBook.provider!!)
for (contact in addressBook.findDirtyContacts()) {
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 currentGroups = contact.getGroupMemberships()
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(
ContentProviderOperation.newUpdate(addressBook.syncAdapterURI(ContentUris.withAppendedId(ContactsContract.Groups.CONTENT_URI, groupID)))
.withValue(ContactsContract.Groups.DIRTY, 1)
@ -118,7 +122,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
override fun postProcess() {
super.postProcess()
/* 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())
}
@ -136,10 +140,10 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
val contacts = Contact.fromReader(inputReader, downloader)
if (contacts.size == 0) {
App.log.warning("Received VCard without data, ignoring")
Logger.log.warning("Received VCard without data, ignoring")
return
} 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 local = localCollection!!.findByUid(contact.uid!!)
@ -148,10 +152,10 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
processContact(contact, local)
} else {
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()
} 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
// update local contact, if it exists
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) {
// update group
@ -192,13 +196,13 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
if (local == null) {
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)
group.add()
local = group
} 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)
contact.add()
@ -222,13 +226,13 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
val httpUrl = HttpUrl.parse(url)
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
}
val host = httpUrl.host()
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
}
@ -253,7 +257,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
return body.bytes()
}
} 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

@ -23,6 +23,7 @@ import com.etesync.syncadapter.*
import com.etesync.syncadapter.journalmanager.Crypto
import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.journalmanager.JournalManager
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity
import com.etesync.syncadapter.model.JournalModel
@ -45,14 +46,14 @@ abstract class SyncAdapterService : Service() {
abstract class SyncAdapter(context: Context) : AbstractThreadedSyncAdapter(context, false) {
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)
Thread.currentThread().contextClassLoader = context.classLoader
}
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
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 network = cm.activeNetworkInfo
if (network == null) {
App.log.info("No network available, stopping")
Logger.log.info("No network available, stopping")
return false
}
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
}
@ -89,7 +90,7 @@ abstract class SyncAdapterService : Service() {
val wifi = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
val info = wifi.connectionInfo
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
}
}
@ -106,7 +107,7 @@ abstract class SyncAdapterService : Service() {
@Throws(Exceptions.HttpException::class, Exceptions.IntegrityException::class, InvalidAccountException::class, Exceptions.GenericCryptoException::class)
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 httpClient = HttpClient.create(context, settings)
@ -162,7 +163,7 @@ abstract class SyncAdapterService : Service() {
for (pair in journals) {
val journal = pair.first
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
val journalEntity = JournalEntity.fetchOrCreate(data, collection)
@ -176,7 +177,7 @@ abstract class SyncAdapterService : Service() {
}
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
data.update(journalEntity)

@ -21,6 +21,7 @@ import com.etesync.syncadapter.Constants.KEY_ACCOUNT
import com.etesync.syncadapter.journalmanager.Crypto
import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.journalmanager.JournalEntryManager
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.*
import com.etesync.syncadapter.model.SyncEntry.Actions.ADD
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.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) {
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() {
var syncPhase = R.string.sync_phase_prepare
try {
App.log.info("Sync phase: " + context.getString(syncPhase))
Logger.log.info("Sync phase: " + context.getString(syncPhase))
if (!prepare()) {
App.log.info("No reason to synchronize, aborting")
Logger.log.info("No reason to synchronize, aborting")
return
}
if (Thread.interrupted())
throw InterruptedException()
syncPhase = R.string.sync_phase_query_capabilities
App.log.info("Sync phase: " + context.getString(syncPhase))
Logger.log.info("Sync phase: " + context.getString(syncPhase))
queryCapabilities()
if (Thread.interrupted())
throw InterruptedException()
syncPhase = R.string.sync_phase_prepare_local
App.log.info("Sync phase: " + context.getString(syncPhase))
Logger.log.info("Sync phase: " + context.getString(syncPhase))
prepareLocal()
do {
if (Thread.interrupted())
throw InterruptedException()
syncPhase = R.string.sync_phase_fetch_entries
App.log.info("Sync phase: " + context.getString(syncPhase))
Logger.log.info("Sync phase: " + context.getString(syncPhase))
fetchEntries()
if (Thread.interrupted())
throw InterruptedException()
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()
} while (remoteEntries!!.size == MAX_FETCH)
@ -148,13 +149,13 @@ constructor(protected val context: Context, protected val account: Account, prot
if (Thread.interrupted())
throw InterruptedException()
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()
if (Thread.interrupted())
throw InterruptedException()
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.
applyLocalEntries();
*/
@ -162,7 +163,7 @@ constructor(protected val context: Context, protected val account: Account, prot
if (Thread.interrupted())
throw InterruptedException()
syncPhase = R.string.sync_phase_push_entries
App.log.info("Sync phase: " + context.getString(syncPhase))
Logger.log.info("Sync phase: " + context.getString(syncPhase))
pushEntries()
} while (localEntries!!.size == MAX_PUSH)
@ -170,7 +171,7 @@ constructor(protected val context: Context, protected val account: Account, prot
if (Thread.interrupted())
throw InterruptedException()
syncPhase = R.string.sync_phase_post_processing
App.log.info("Sync phase: " + context.getString(syncPhase))
Logger.log.info("Sync phase: " + context.getString(syncPhase))
postProcess()
if (numDiscarded > 0) {
@ -178,9 +179,9 @@ constructor(protected val context: Context, protected val account: Account, prot
}
notifyUserOnSync()
App.log.info("Finished sync with CTag=$remoteCTag")
Logger.log.info("Finished sync with CTag=$remoteCTag")
} 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++
} catch (e: Exceptions.ServiceUnavailableException) {
syncResult.stats.numIoExceptions++
@ -298,13 +299,13 @@ constructor(protected val context: Context, protected val account: Account, prot
throw InterruptedException()
}
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)
if (cEntry.isAction(SyncEntry.Actions.DELETE)) {
continue
}
App.log.info("Processing resource for journal entry")
Logger.log.info("Processing resource for journal entry")
processSyncEntry(cEntry)
}
}
@ -333,7 +334,7 @@ constructor(protected val context: Context, protected val account: Account, prot
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)
@ -347,10 +348,10 @@ constructor(protected val context: Context, protected val account: Account, prot
throw InterruptedException()
}
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)
App.log.info("Processing resource for journal entry")
Logger.log.info("Processing resource for journal entry")
processSyncEntry(cEntry)
persistSyncEntry(entry.uid, cEntry)
@ -394,7 +395,7 @@ constructor(protected val context: Context, protected val account: Account, prot
if (pushed-- <= 0) {
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!!)
}
if (left > 0) {
@ -402,7 +403,7 @@ constructor(protected val context: Context, protected val account: Account, prot
}
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) {
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()
numDiscarded++
}
@ -480,9 +481,9 @@ constructor(protected val context: Context, protected val account: Account, prot
return ret
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 {
App.log.fine("Entry deleted before ever syncing - genarting a UUID")
Logger.log.fine("Entry deleted before ever syncing - genarting a UUID")
local.prepareForUpload()
}
@ -499,7 +500,7 @@ constructor(protected val context: Context, protected val account: Account, prot
protected open fun prepareDirty() {
if (journalEntity.isReadOnly) {
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 it was only local, delete.
local.delete()
@ -512,13 +513,13 @@ constructor(protected val context: Context, protected val account: Account, prot
localDirty = LinkedList()
} else {
// 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) {
if (local.uuid != null) {
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()
}
}

@ -16,11 +16,11 @@ import android.content.SyncResult
import android.database.sqlite.SQLiteException
import android.os.Build
import android.os.Bundle
import android.provider.CalendarContract
import at.bitfire.ical4android.AndroidTaskList
import at.bitfire.ical4android.TaskProvider
import com.etesync.syncadapter.*
import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity
import com.etesync.syncadapter.model.JournalModel
@ -72,7 +72,7 @@ class TasksSyncAdapterService: SyncAdapterService() {
val principal = HttpUrl.get(accountSettings.uri!!)!!
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);
tasksSyncManager.performSync()
}
@ -83,7 +83,7 @@ class TasksSyncAdapterService: SyncAdapterService() {
// Ignore
} catch (e: Exception) {
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
}
@ -109,7 +109,7 @@ class TasksSyncAdapterService: SyncAdapterService() {
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) {
@ -131,11 +131,11 @@ class TasksSyncAdapterService: SyncAdapterService() {
val url = taskList.url
val journalEntity = remote[url]
if (journalEntity == null) {
App.log.fine("Deleting obsolete local task list $url")
Logger.log.fine("Deleting obsolete local task list $url")
taskList.delete()
} else {
// 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)
// we already have a local tasks for this remote collection, don't take into consideration anymore
remote.remove(url)
@ -145,7 +145,7 @@ class TasksSyncAdapterService: SyncAdapterService() {
// create new local taskss
for (url in remote.keys) {
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)
}
}

@ -14,10 +14,10 @@ import android.content.SyncResult
import android.os.Bundle
import at.bitfire.ical4android.Task
import com.etesync.syncadapter.AccountSettings
import com.etesync.syncadapter.App
import com.etesync.syncadapter.Constants
import com.etesync.syncadapter.R
import com.etesync.syncadapter.journalmanager.JournalEntryManager
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.SyncEntry
import com.etesync.syncadapter.resource.LocalTask
@ -73,10 +73,10 @@ class TasksSyncManager(
val tasks = Task.fromReader(inputReader)
if (tasks.size == 0) {
App.log.warning("Received VCard without data, ignoring")
Logger.log.warning("Received VCard without data, ignoring")
return
} 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]
@ -86,10 +86,10 @@ class TasksSyncManager(
processTask(event, local)
} else {
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()
} 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
// delete local Task, if it exists
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.update(newData)
syncResult.stats.numUpdates++
} 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.add()
syncResult.stats.numInserts++

@ -11,15 +11,6 @@ package com.etesync.syncadapter.ui
import android.annotation.SuppressLint
import android.content.Context
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.Spanned
import android.text.util.Linkify
@ -27,12 +18,21 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
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.BuildConfig
import com.etesync.syncadapter.Constants
import com.etesync.syncadapter.R
import com.etesync.syncadapter.log.Logger
import com.google.android.material.tabs.TabLayout
import ezvcard.Ezvcard
import org.apache.commons.lang3.time.DateFormatUtils
import java.io.IOException
import java.util.logging.Level
@ -140,7 +140,7 @@ class AboutActivity : BaseActivity() {
}
override fun loadInBackground(): Spanned? {
App.log.fine("Loading license file $fileName")
Logger.log.fine("Loading license file $fileName")
try {
val inputStream = context.resources.assets.open(fileName)
val raw = inputStream.readBytes()
@ -148,7 +148,7 @@ class AboutActivity : BaseActivity() {
content = Html.fromHtml(String(raw))
return content
} 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
}

@ -19,17 +19,17 @@ import android.os.Bundle
import android.os.IBinder
import android.provider.CalendarContract
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.view.*
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.vcard4android.ContactsStorageException
import com.etesync.syncadapter.*
import com.etesync.syncadapter.journalmanager.Crypto
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity
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.ShowcaseBuilder
import com.etesync.syncadapter.utils.packageInstalled
import com.google.android.material.snackbar.Snackbar
import tourguide.tourguide.ToolTip
import java.util.logging.Level
@ -418,7 +419,7 @@ class AccountActivity : BaseActivity(), Toolbar.OnMenuItemClickListener, PopupMe
if (future.result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT))
finish()
} catch(e: Exception) {
App.log.log(Level.SEVERE, "Couldn't remove account", e)
Logger.log.log(Level.SEVERE, "Couldn't remove account", e)
}
}, null)
else
@ -427,7 +428,7 @@ class AccountActivity : BaseActivity(), Toolbar.OnMenuItemClickListener, PopupMe
if (future.result)
finish()
} catch (e: Exception) {
App.log.log(Level.SEVERE, "Couldn't remove account", e)
Logger.log.log(Level.SEVERE, "Couldn't remove account", e)
}
}, null)
}

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

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

@ -23,15 +23,16 @@ import android.os.Bundle
import android.os.PowerManager
import android.provider.CalendarContract
import android.provider.ContactsContract
import androidx.core.content.ContextCompat
import android.text.TextUtils
import android.view.Menu
import android.view.MenuItem
import android.widget.TextView
import androidx.core.content.ContextCompat
import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.*
import com.etesync.syncadapter.Constants.KEY_ACCOUNT
import com.etesync.syncadapter.journalmanager.Exceptions.HttpException
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.EntryEntity
import com.etesync.syncadapter.model.JournalEntity
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.text.WordUtils
import java.io.File
import java.util.*
import java.util.logging.Level
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")
.append("Installed from: ").append(installedFrom).append("\n")
} 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")
@ -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"
)
} 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")

@ -8,7 +8,7 @@ import android.provider.CalendarContract
import android.provider.CalendarContract.Calendars
import android.provider.CalendarContract.Events
import android.provider.ContactsContract
import com.etesync.syncadapter.App
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.resource.LocalCalendar
import java.util.*
@ -51,7 +51,7 @@ class CalendarAccount protected constructor(val account: Account) {
CAL_COLS, null, null,
ContactsContract.RawContacts.ACCOUNT_NAME + " ASC, " + ContactsContract.RawContacts.ACCOUNT_TYPE)
} 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)
except.printStackTrace()
}

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

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

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

@ -14,15 +14,15 @@ import android.app.ProgressDialog
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import androidx.loader.app.LoaderManager
import androidx.loader.content.AsyncTaskLoader
import androidx.loader.content.Loader
import androidx.appcompat.app.AlertDialog
import com.etesync.syncadapter.AccountSettings
import com.etesync.syncadapter.App
import com.etesync.syncadapter.InvalidAccountException
import com.etesync.syncadapter.R
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.ui.DebugInfoActivity
import com.etesync.syncadapter.ui.setup.BaseConfigurationFinder.Configuration
import java.util.logging.Level
@ -64,7 +64,7 @@ class LoginCredentialsChangeFragment : DialogFragment(), LoaderManager.LoaderCal
try {
settings = AccountSettings(activity!!, account)
} 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()
return
}
@ -72,7 +72,7 @@ class LoginCredentialsChangeFragment : DialogFragment(), LoaderManager.LoaderCal
settings.authToken = data.authtoken!!
}
} else
App.log.severe("Configuration detection failed")
Logger.log.severe("Configuration detection failed")
dismissAllowingStateLoss()
}

@ -18,13 +18,14 @@ import android.content.Context
import android.os.AsyncTask
import android.os.Bundle
import android.provider.CalendarContract
import androidx.fragment.app.DialogFragment
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import at.bitfire.ical4android.TaskProvider
import com.etesync.syncadapter.*
import com.etesync.syncadapter.journalmanager.Crypto
import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.journalmanager.UserInfoManager
import com.etesync.syncadapter.log.Logger
import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.JournalEntity
import com.etesync.syncadapter.model.ServiceEntity
@ -56,7 +57,7 @@ class SetupEncryptionFragment : DialogFragment() {
override fun onPostExecute(result: Configuration) {
if (config.error != null && config.error is Exceptions.IntegrityException) {
App.log.severe("Wrong encryption password.")
Logger.log.severe("Wrong encryption password.")
AlertDialog.Builder(activity!!)
.setTitle(R.string.wrong_encryption_password)
.setIcon(R.drawable.ic_error_dark)
@ -71,7 +72,7 @@ class SetupEncryptionFragment : DialogFragment() {
activity!!.finish()
}
} catch (e: InvalidAccountException) {
App.log.severe("Account creation failed!")
Logger.log.severe("Account creation failed!")
AlertDialog.Builder(activity!!)
.setTitle(R.string.account_creation_failed)
.setIcon(R.drawable.ic_error_dark)
@ -87,9 +88,9 @@ class SetupEncryptionFragment : DialogFragment() {
}
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!!)
App.log.info("Finished deriving key")
Logger.log.info("Finished deriving key")
config.error = null
try {
@ -99,7 +100,7 @@ class SetupEncryptionFragment : DialogFragment() {
val userInfoManager = UserInfoManager(httpClient, HttpUrl.get(config.url)!!)
val userInfo = userInfoManager.fetch(config.userName)
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")
userInfo.verify(cryptoManager)
config.keyPair = Crypto.AsymmetricKeyPair(userInfo.getContent(cryptoManager)!!, userInfo.pubkey!!)
@ -119,7 +120,7 @@ class SetupEncryptionFragment : DialogFragment() {
val account = Account(accountName, App.accountType)
// 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)
if (!accountManager.addAccountExplicitly(account, config.password, null))
@ -128,7 +129,7 @@ class SetupEncryptionFragment : DialogFragment() {
AccountSettings.setUserData(accountManager, account, config.url, config.userName)
// 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 {
val settings = AccountSettings(context!!, account)
@ -165,7 +166,7 @@ class SetupEncryptionFragment : DialogFragment() {
}
} 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)
throw e
}

@ -6,13 +6,17 @@ import android.app.ProgressDialog
import android.content.Context
import android.os.AsyncTask
import android.os.Bundle
import androidx.fragment.app.DialogFragment
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.HttpClient
import com.etesync.syncadapter.InvalidAccountException
import com.etesync.syncadapter.R
import com.etesync.syncadapter.journalmanager.Constants
import com.etesync.syncadapter.journalmanager.Crypto
import com.etesync.syncadapter.journalmanager.UserInfoManager
import com.etesync.syncadapter.log.Logger
import okhttp3.HttpUrl
class SetupUserInfoFragment : DialogFragment() {
@ -53,12 +57,12 @@ class SetupUserInfoFragment : DialogFragment() {
var userInfo: UserInfoManager.UserInfo? = userInfoManager.fetch(account.name)
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")
userInfo = UserInfoManager.UserInfo.generate(cryptoManager, account.name)
userInfoManager.create(userInfo)
} 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")
userInfo.verify(cryptoManager)
}

@ -3,11 +3,10 @@ package com.etesync.syncadapter.utils
import android.accounts.Account
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import at.bitfire.ical4android.Event
import com.etesync.syncadapter.App
import com.etesync.syncadapter.R
import com.etesync.syncadapter.log.Logger
import net.fortuna.ical4j.model.property.Attendee
import org.acra.attachment.AcraContentProvider
import org.acra.util.IOUtils
@ -38,7 +37,7 @@ class EventEmailInvitation constructor(val context: Context, val account: Accoun
formatAttendees(event.attendees)))
val uri = createAttachmentFromString(context, icsContent)
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
}
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)

Loading…
Cancel
Save