aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java')
-rw-r--r--app/src/main/java/org/pacien/tincapp/context/App.kt18
-rw-r--r--app/src/main/java/org/pacien/tincapp/context/AppLogger.kt45
-rw-r--r--app/src/main/java/org/pacien/tincapp/context/AppPaths.kt24
-rw-r--r--app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt25
4 files changed, 91 insertions, 21 deletions
diff --git a/app/src/main/java/org/pacien/tincapp/context/App.kt b/app/src/main/java/org/pacien/tincapp/context/App.kt
index d79ae3e..53049f3 100644
--- a/app/src/main/java/org/pacien/tincapp/context/App.kt
+++ b/app/src/main/java/org/pacien/tincapp/context/App.kt
@@ -9,15 +9,31 @@ import android.support.annotation.StringRes
9import android.support.v7.app.AlertDialog 9import android.support.v7.app.AlertDialog
10import android.view.WindowManager 10import android.view.WindowManager
11import org.pacien.tincapp.R 11import org.pacien.tincapp.R
12import org.slf4j.Logger
13import org.slf4j.LoggerFactory
12 14
13/** 15/**
14 * @author pacien 16 * @author pacien
15 */ 17 */
16class App : Application() { 18class App : Application(), Thread.UncaughtExceptionHandler {
19 private var logger: Logger? = null
20 private var systemCrashHandler: Thread.UncaughtExceptionHandler? = null
21
17 override fun onCreate() { 22 override fun onCreate() {
18 super.onCreate() 23 super.onCreate()
19 appContext = applicationContext 24 appContext = applicationContext
20 handler = Handler() 25 handler = Handler()
26
27 AppLogger.configure()
28 logger = LoggerFactory.getLogger(this.javaClass)
29
30 systemCrashHandler = Thread.getDefaultUncaughtExceptionHandler()
31 Thread.setDefaultUncaughtExceptionHandler(this)
32 }
33
34 override fun uncaughtException(thread: Thread, throwable: Throwable) {
35 logger?.error("Fatal application error.", throwable)
36 systemCrashHandler?.uncaughtException(thread, throwable)
21 } 37 }
22 38
23 companion object { 39 companion object {
diff --git a/app/src/main/java/org/pacien/tincapp/context/AppLogger.kt b/app/src/main/java/org/pacien/tincapp/context/AppLogger.kt
new file mode 100644
index 0000000..e240e70
--- /dev/null
+++ b/app/src/main/java/org/pacien/tincapp/context/AppLogger.kt
@@ -0,0 +1,45 @@
1package org.pacien.tincapp.context
2
3import ch.qos.logback.classic.Logger
4import ch.qos.logback.classic.LoggerContext
5import ch.qos.logback.classic.android.LogcatAppender
6import ch.qos.logback.classic.encoder.PatternLayoutEncoder
7import ch.qos.logback.classic.spi.ILoggingEvent
8import ch.qos.logback.core.Context
9import ch.qos.logback.core.FileAppender
10import org.slf4j.LoggerFactory
11
12/**
13 * @author pacien
14 */
15object AppLogger {
16 private const val LOGCAT_PATTERN = "[%thread] %msg%n%rEx"
17 private const val LOGFILE_PATTERN = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n%rEx"
18
19 fun configure() {
20 (LoggerFactory.getILoggerFactory() as LoggerContext)
21 .apply { reset() }
22 .let { loggerContext ->
23 (LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME) as Logger)
24 .apply {
25 addAppender(LogcatAppender()
26 .apply { context = loggerContext }
27 .apply { encoder = patternEncoder(loggerContext, LOGCAT_PATTERN) }
28 .apply { start() })
29 }
30 .apply {
31 addAppender(FileAppender<ILoggingEvent>()
32 .apply { context = loggerContext }
33 .apply { encoder = patternEncoder(loggerContext, LOGFILE_PATTERN) }
34 .apply { file = AppPaths.appLogFile().absolutePath }
35 .apply { start() })
36 }
37 }
38 }
39
40 private fun patternEncoder(ctx: Context, pat: String) =
41 PatternLayoutEncoder()
42 .apply { context = ctx }
43 .apply { pattern = pat }
44 .apply { start() }
45}
diff --git a/app/src/main/java/org/pacien/tincapp/context/AppPaths.kt b/app/src/main/java/org/pacien/tincapp/context/AppPaths.kt
index 9315060..4b36dfe 100644
--- a/app/src/main/java/org/pacien/tincapp/context/AppPaths.kt
+++ b/app/src/main/java/org/pacien/tincapp/context/AppPaths.kt
@@ -10,21 +10,22 @@ import java.io.FileNotFoundException
10 * @implNote Logs and PID files are stored in the cache directory for easy clean up. 10 * @implNote Logs and PID files are stored in the cache directory for easy clean up.
11 */ 11 */
12object AppPaths { 12object AppPaths {
13 private val TINCD_BIN = "libtincd.so" 13 private const val TINCD_BIN = "libtincd.so"
14 private val TINC_BIN = "libtinc.so" 14 private const val TINC_BIN = "libtinc.so"
15 15
16 private val LOGFILE_FORMAT = "tinc.%s.log" 16 private const val APPLOG_FILE = "tincapp.log"
17 private val PIDFILE_FORMAT = "tinc.%s.pid" 17 private const val LOGFILE_FORMAT = "tinc.%s.log"
18 private const val PIDFILE_FORMAT = "tinc.%s.pid"
18 19
19 private val NET_CONF_FILE = "network.conf" 20 private const val NET_CONF_FILE = "network.conf"
20 private val NET_TINC_CONF_FILE = "tinc.conf" 21 private const val NET_TINC_CONF_FILE = "tinc.conf"
21 private val NET_HOSTS_DIR = "hosts" 22 private const val NET_HOSTS_DIR = "hosts"
22 private val NET_INVITATION_FILE = "invitation-data" 23 private const val NET_INVITATION_FILE = "invitation-data"
23 private val NET_DEFAULT_ED25519_PRIVATE_KEY_FILE = "ed25519_key.priv" 24 private const val NET_DEFAULT_ED25519_PRIVATE_KEY_FILE = "ed25519_key.priv"
24 private val NET_DEFAULT_RSA_PRIVATE_KEY_FILE = "rsa_key.priv" 25 private const val NET_DEFAULT_RSA_PRIVATE_KEY_FILE = "rsa_key.priv"
25 26
26 fun storageAvailable() = 27 fun storageAvailable() =
27 Environment.getExternalStorageState().let { it == Environment.MEDIA_MOUNTED && it != Environment.MEDIA_MOUNTED_READ_ONLY } 28 Environment.getExternalStorageState().let { it == Environment.MEDIA_MOUNTED && it != Environment.MEDIA_MOUNTED_READ_ONLY }
28 29
29 fun cacheDir() = App.getContext().externalCacheDir 30 fun cacheDir() = App.getContext().externalCacheDir
30 fun confDir() = App.getContext().getExternalFilesDir(null) 31 fun confDir() = App.getContext().getExternalFilesDir(null)
@@ -37,6 +38,7 @@ object AppPaths {
37 fun invitationFile(netName: String) = File(confDir(netName), NET_INVITATION_FILE) 38 fun invitationFile(netName: String) = File(confDir(netName), NET_INVITATION_FILE)
38 fun logFile(netName: String) = File(cacheDir(), String.format(LOGFILE_FORMAT, netName)) 39 fun logFile(netName: String) = File(cacheDir(), String.format(LOGFILE_FORMAT, netName))
39 fun pidFile(netName: String) = File(App.getContext().cacheDir, String.format(PIDFILE_FORMAT, netName)) 40 fun pidFile(netName: String) = File(App.getContext().cacheDir, String.format(PIDFILE_FORMAT, netName))
41 fun appLogFile() = File(cacheDir(), APPLOG_FILE)
40 42
41 fun existing(f: File) = f.apply { if (!exists()) throw FileNotFoundException(f.absolutePath) } 43 fun existing(f: File) = f.apply { if (!exists()) throw FileNotFoundException(f.absolutePath) }
42 44
diff --git a/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt b/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt
index 0bf72a1..69811f4 100644
--- a/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt
+++ b/app/src/main/java/org/pacien/tincapp/service/TincVpnService.kt
@@ -5,7 +5,6 @@ import android.content.Intent
5import android.net.VpnService 5import android.net.VpnService
6import android.os.ParcelFileDescriptor 6import android.os.ParcelFileDescriptor
7import android.support.v4.content.LocalBroadcastManager 7import android.support.v4.content.LocalBroadcastManager
8import android.util.Log
9import java8.util.concurrent.CompletableFuture 8import java8.util.concurrent.CompletableFuture
10import org.apache.commons.configuration2.ex.ConversionException 9import org.apache.commons.configuration2.ex.ConversionException
11import org.bouncycastle.openssl.PEMException 10import org.bouncycastle.openssl.PEMException
@@ -22,19 +21,28 @@ import org.pacien.tincapp.extensions.Java.applyIgnoringException
22import org.pacien.tincapp.extensions.VpnServiceBuilder.applyCfg 21import org.pacien.tincapp.extensions.VpnServiceBuilder.applyCfg
23import org.pacien.tincapp.intent.Actions 22import org.pacien.tincapp.intent.Actions
24import org.pacien.tincapp.utils.TincKeyring 23import org.pacien.tincapp.utils.TincKeyring
24import org.slf4j.Logger
25import org.slf4j.LoggerFactory
25import java.io.FileNotFoundException 26import java.io.FileNotFoundException
26 27
27/** 28/**
28 * @author pacien 29 * @author pacien
29 */ 30 */
30class TincVpnService : VpnService() { 31class TincVpnService : VpnService() {
32 private var logger: Logger? = null
33
34 override fun onCreate() {
35 super.onCreate()
36 logger = LoggerFactory.getLogger(this.javaClass)
37 }
38
31 override fun onDestroy() { 39 override fun onDestroy() {
32 stopVpn() 40 stopVpn()
33 super.onDestroy() 41 super.onDestroy()
34 } 42 }
35 43
36 override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { 44 override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
37 Log.i(TAG, intent.action) 45 logger?.info("Intent received: {}", intent.action)
38 46
39 when { 47 when {
40 intent.action == Actions.ACTION_CONNECT && intent.scheme == Actions.TINC_SCHEME -> 48 intent.action == Actions.ACTION_CONNECT && intent.scheme == Actions.TINC_SCHEME ->
@@ -61,7 +69,7 @@ class TincVpnService : VpnService() {
61 if (!AppPaths.confDir(netName).exists()) 69 if (!AppPaths.confDir(netName).exists())
62 return reportError(resources.getString(R.string.message_no_configuration_for_network_format, netName), docTopic = "configuration") 70 return reportError(resources.getString(R.string.message_no_configuration_for_network_format, netName), docTopic = "configuration")
63 71
64 Log.i(TAG, "Starting tinc daemon for network \"$netName\".") 72 logger?.info("Starting tinc daemon for network \"$netName\".")
65 if (isConnected()) stopVpn() 73 if (isConnected()) stopVpn()
66 74
67 val interfaceCfg = try { 75 val interfaceCfg = try {
@@ -108,17 +116,17 @@ class TincVpnService : VpnService() {
108 if (exception != null) { 116 if (exception != null) {
109 reportError(resources.getString(R.string.message_daemon_exited, exception.cause!!.message!!), exception) 117 reportError(resources.getString(R.string.message_daemon_exited, exception.