diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 6ee7f0784209fa1c5dc596d5cedac7460916583a..760e0a74bb7e40328cde3a5cb31772bb3261bfce 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -156,6 +156,9 @@ dependencies { implementation(libs.coil) implementation(libs.coil.compose) + implementation(libs.acra.mail) + implementation(libs.acra.limiter) + implementation(libs.commonutils) diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/App.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/App.kt index 2040e85c285696c6cde36e9d78f737ec113afa6e..1eb22a529fdbad99e6a8565de183fe6ec53df7ec 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/App.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/App.kt @@ -40,12 +40,14 @@ class App : Application(), RepositoryProvider, CoroutineScope by MainScope() + C override fun attachBaseContext(base: Context?) { super.attachBaseContext(base) + CrashHandling.init() } override fun onCreate() { super.onCreate() info { "App instance available" } runBlocking { loadInitialSettings() } + launch { CrashHandling.syncInformation() } launch { tryAutoLoginDevice() } launch { fetchNewerReleases() } } diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/CrashHandling.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/CrashHandling.kt new file mode 100644 index 0000000000000000000000000000000000000000..e11f52376c540e9893df87b217970053495b18b4 --- /dev/null +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/CrashHandling.kt @@ -0,0 +1,73 @@ +package net.novagamestudios.kaffeekasse + +import android.app.Application +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import cafe.adriel.voyager.navigator.Navigator +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.launch +import kotlinx.coroutines.supervisorScope +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import net.novagamestudios.kaffeekasse.repositories.RepositoryProvider +import net.novagamestudios.kaffeekasse.repositories.Settings +import org.acra.ACRA +import org.acra.config.limiter +import org.acra.config.mailSender +import org.acra.data.StringFormat +import org.acra.ktx.initAcra + + +object CrashHandling { + private const val ReportEmail = "broeckmann@embedded.rwth-aachen.de" + + context (Application) + fun init() = initAcra { + buildConfigClass = BuildConfig::class.java + reportFormat = StringFormat.JSON + mailSender { + val appName = getString(R.string.app_name) + mailTo = ReportEmail + + reportAsFile = true + reportFileName = "${appName.uppercase()}-CRASH-REPORT.json" + + subject = "$appName Crash Report" + body = """ + Whoops! It seems like $appName crashed. + Please help us to improve the app by sending this crash report. + """.trimIndent() + } + limiter { + enabled = true + } + } + + private val jsonFormat = Json { + allowStructuredMapKeys = true + ignoreUnknownKeys = true + explicitNulls = false + serializersModule = Settings.serializersModule + } + + context (RepositoryProvider) + suspend fun syncInformation() = supervisorScope { + launch { + settingsRepository.values.collectLatest { + ACRA.errorReporter.putCustomData("CurrentSettings", jsonFormat.encodeToString(it)) + } + } + launch { + portalRepository.session.collectLatest { + ACRA.errorReporter.putCustomData("CurrentPortalSession", "$it") + } + } + } + + @Composable + fun updateNavigation(navigator: Navigator) { + LaunchedEffect(navigator.lastItem) { + ACRA.errorReporter.putCustomData("CurrentNavigationScreen", "${navigator.lastItem::class.qualifiedName}") + } + } +} diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/AppModules.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/AppModules.kt index ca4763e308cf065cd4adae9d010217b03cab333f..6c4752c81c9264c8c9bf1a45de79e6ffac424972 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/AppModules.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/AppModules.kt @@ -39,9 +39,9 @@ import net.novagamestudios.kaffeekasse.ui.navigation.AppModulesScreen import net.novagamestudios.kaffeekasse.ui.navigation.HiwiTrackerNavigation import net.novagamestudios.kaffeekasse.ui.navigation.KaffeekasseNavigation import net.novagamestudios.kaffeekasse.ui.navigation.ModuleTab +import net.novagamestudios.kaffeekasse.ui.util.navigation.nearestScreen import net.novagamestudios.kaffeekasse.ui.util.screenmodel.ScreenModelFactory import net.novagamestudios.kaffeekasse.ui.util.screenmodel.collectAsStateHere -import net.novagamestudios.kaffeekasse.ui.util.navigation.nearestScreen class AppModulesScreenModel private constructor( diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/Updates.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/Updates.kt index 0f0f542e2de999310653ef1926b8c23c74314fea..b3a1c89761e46bf3ad9b5f378378759a8faa3579 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/Updates.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/Updates.kt @@ -58,7 +58,6 @@ import net.novagamestudios.common_utils.toastLong import net.novagamestudios.kaffeekasse.App import net.novagamestudios.kaffeekasse.App.Companion.settings import net.novagamestudios.kaffeekasse.BuildConfig -import net.novagamestudios.kaffeekasse.getValue import net.novagamestudios.kaffeekasse.model.app.AppRelease import net.novagamestudios.kaffeekasse.model.app.AppVersion import net.novagamestudios.kaffeekasse.model.date_time.format diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScaffold.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScaffold.kt index ac586aef77d337043b18fe43a39950e32b5ab266..915805c2a38e2d5b7a3892eeee85679c2768f592 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScaffold.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScaffold.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.unit.dp import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.navigator.Navigator +import net.novagamestudios.kaffeekasse.CrashHandling import net.novagamestudios.kaffeekasse.ui.theme.LocalAnimationSwitch import net.novagamestudios.kaffeekasse.ui.theme.ifAnimationsEnabled import net.novagamestudios.kaffeekasse.ui.util.navigation.BackNavigationHandler @@ -44,6 +45,7 @@ fun AppScaffoldNavigator( key = key ) { navigator -> debugNavigation() + CrashHandling.updateNavigation(navigator) val backNavigationHandler = backNavigationHandlerProvider(navigator) AppScaffold( topBar = { diff --git a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScreens.kt b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScreens.kt index fcfa2b943a49dd502a5143e20945346d177e3582..ebbea3a7c606464d029ba886e4170f7588239d13 100644 --- a/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScreens.kt +++ b/app/src/main/java/net/novagamestudios/kaffeekasse/ui/navigation/AppScreens.kt @@ -13,11 +13,11 @@ import cafe.adriel.voyager.navigator.tab.Tab import cafe.adriel.voyager.navigator.tab.TabNavigator import cafe.adriel.voyager.navigator.tab.TabOptions import net.novagamestudios.common_utils.compose.components.BoxCenter -import net.novagamestudios.kaffeekasse.getValue import net.novagamestudios.kaffeekasse.model.session.Device import net.novagamestudios.kaffeekasse.model.session.Session import net.novagamestudios.kaffeekasse.model.session.deviceOrNull import net.novagamestudios.kaffeekasse.ui.AppModulesScreenModel +import net.novagamestudios.kaffeekasse.ui.getValue import net.novagamestudios.kaffeekasse.ui.hiwi_tracker.HiwiTrackerModuleScreenModel import net.novagamestudios.kaffeekasse.ui.hiwi_tracker.HiwiTrackerTopBarActions import net.novagamestudios.kaffeekasse.ui.hiwi_tracker.HiwiTrackerTopBarTitle diff --git a/settings.gradle.kts b/settings.gradle.kts index 3591222ca145c7a19703a35d8a1ec902e6f598a4..2adf01d1c75fd5f40602d5963c5a4472212f3fc8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,6 +24,7 @@ dependencyResolutionManagement { version("vico", "2.0.0-alpha.8") version("voyager", "1.0.0") version("coil", "2.6.0") + version("acra", "5.11.3") plugin("gradle-versions", "com.github.ben-manes.versions").version("0.51.0") @@ -79,6 +80,15 @@ dependencyResolutionManagement { library("coil", "io.coil-kt", "coil").versionRef("coil") library("coil-compose", "io.coil-kt", "coil-compose").versionRef("coil") + library("acra-http", "ch.acra", "acra-http").versionRef("acra") + library("acra-mail", "ch.acra", "acra-mail").versionRef("acra") + library("acra-core", "ch.acra", "acra-core").versionRef("acra") + library("acra-dialog", "ch.acra", "acra-dialog").versionRef("acra") + library("acra-notification", "ch.acra", "acra-notification").versionRef("acra") + library("acra-toast", "ch.acra", "acra-toast").versionRef("acra") + library("acra-limiter", "ch.acra", "acra-limiter").versionRef("acra") + library("acra-advancedscheduler", "ch.acra", "acra-advanced-scheduler").versionRef("acra") + library("commonutils", "com.gitlab.JojoIV", "common_utils").version("2d5e5c9a17") } }