Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
21f27f6
Refactor: Refactored several classes such as SessionKeepAliveService,…
Juan-Antonio-Doe Jun 27, 2026
8d6cdc6
Merge branch 'refs/heads/main' into background-persistance-fix-2
Juan-Antonio-Doe Jun 28, 2026
7c25fb0
Merge with main (resolved conflicts in XServerDisplayActivity.java)
Juan-Antonio-Doe Jun 28, 2026
05c4e85
Enhance logging system.
Juan-Antonio-Doe Jul 1, 2026
ffd1d3f
Add translations for the new debug options.
Juan-Antonio-Doe Jul 1, 2026
cb50dfe
Add more logs to several classes.
Juan-Antonio-Doe Jul 1, 2026
d5b422d
Enhance background protection, improve crash logging and fixed some b…
Juan-Antonio-Doe Jul 4, 2026
be70310
Background setting enabled by default.
Juan-Antonio-Doe Jul 5, 2026
5739c6b
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 5, 2026
0e713f4
Fixed some errors after merge with main in Debug and Other Settings m…
Juan-Antonio-Doe Jul 6, 2026
6a42008
Resolved conflicts after merge with main (Steam Friends & Controller …
Juan-Antonio-Doe Jul 10, 2026
4c4b816
Fix wrong flavors that were used in local tests.
Juan-Antonio-Doe Jul 10, 2026
6c27d7c
Cleaning.
Juan-Antonio-Doe Jul 10, 2026
c50ed84
Fix: Uncommented the notificationHelper variable in SteamService (req…
Juan-Antonio-Doe Jul 10, 2026
867ea39
Disabled the Exit button in the notification to close the container/g…
Juan-Antonio-Doe Jul 10, 2026
19ec97a
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 10, 2026
fe42ce1
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 10, 2026
b4b471d
LogManager: Included system tag list and hardcoded tag list in UI Log…
Juan-Antonio-Doe Jul 11, 2026
ade1df9
Merge remote-tracking branch 'origin/background-persistance-fix-2' in…
Juan-Antonio-Doe Jul 11, 2026
40aab66
feat: Android system tags are now highlighted in yellow when selected…
Juan-Antonio-Doe Jul 11, 2026
af0f1b4
Epic and GOG services updated to work with the master foreground serv…
Juan-Antonio-Doe Jul 11, 2026
c626749
Updated store services notification.
Juan-Antonio-Doe Jul 11, 2026
5ef2d68
Optimized crash trace report in LogManager.
Juan-Antonio-Doe Jul 11, 2026
d8b0f9d
Enable WakeLock by default on Android 16+ if it hasn’t been explicitl…
Juan-Antonio-Doe Jul 11, 2026
6017a74
Hide lastExitReason toggle in debug settings and collapsed Heart beat…
Juan-Antonio-Doe Jul 11, 2026
a4eea2b
LogManager: Optimized exitReasons and Crash logs avoiding duplicated …
Juan-Antonio-Doe Jul 12, 2026
aabff7a
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 12, 2026
4d050d8
Updated some log lines in XServerDisplayActivity
Juan-Antonio-Doe Jul 12, 2026
c577995
Commented out a log line in XConnectorEpoll to avoid unnecessary noise.
Juan-Antonio-Doe Jul 12, 2026
8c005de
Fixed some lines and logs that shouldn't appear in some conditions.
Juan-Antonio-Doe Jul 12, 2026
7042518
Fixed issues introduced in the commit that enables background protect…
Juan-Antonio-Doe Jul 12, 2026
4509240
Replaced hardcoded foreground notification content strings with trans…
Juan-Antonio-Doe Jul 12, 2026
24956e4
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 12, 2026
33a8ea1
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 13, 2026
14aa9e4
Renamed log file generated with filtered tags.
Juan-Antonio-Doe Jul 13, 2026
92a14ff
UI: Improved the window appearance of the Custom tag filter.
Juan-Antonio-Doe Jul 13, 2026
4052026
Fix: Avoid deleting the ExitReasons and Crash keys when deleting an u…
Juan-Antonio-Doe Jul 13, 2026
829ef5a
Added post-mortem logic to LogManager and refactored duplicate checki…
Juan-Antonio-Doe Jul 13, 2026
ff72477
Differentiate system tags in yellow from the other tags when they are…
Juan-Antonio-Doe Jul 13, 2026
51e6f23
Fixed Event Watch log not returning logs in some cases.
Juan-Antonio-Doe Jul 14, 2026
4ccb21e
Fix: The crash log generated with DefaultUncaughtExceptionHandler was…
Juan-Antonio-Doe Jul 14, 2026
7c01191
Updated translations with the new strings.
Juan-Antonio-Doe Jul 14, 2026
32e80f5
Some more bugs fixed #1.
Juan-Antonio-Doe Jul 14, 2026
e928593
Some bug fixes and improvements (2).
Juan-Antonio-Doe Jul 15, 2026
4c92334
Some bug fixes and improvements (3).
Juan-Antonio-Doe Jul 15, 2026
85b5b45
Some bug fixes and improvements (4).
Juan-Antonio-Doe Jul 16, 2026
e77fa52
Some bug fixes and improvements (5).
Juan-Antonio-Doe Jul 16, 2026
bfc1982
Some bug fixes and improvements (6).
Juan-Antonio-Doe Jul 16, 2026
b688eec
Split general Application Log toggle behaviour into the default and g…
Juan-Antonio-Doe Jul 17, 2026
9dbf78c
Some options in the Debug section (UI) have been grouped into expanda…
Juan-Antonio-Doe Jul 17, 2026
511eedd
Updated translations.
Juan-Antonio-Doe Jul 17, 2026
59cf66c
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 18, 2026
22df89a
Fixed erros after merge with main.
Juan-Antonio-Doe Jul 18, 2026
767914b
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 18, 2026
ecde94a
More fixes for Event Watch logger.
Juan-Antonio-Doe Jul 18, 2026
bfe862c
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 18, 2026
8f756cd
Removed commented-out code related to Steam Friends Chat.
Juan-Antonio-Doe Jul 18, 2026
1f08965
Added a suggestion to improve the current Event Watch.
Juan-Antonio-Doe Jul 18, 2026
ce8060d
Merge branch 'background-persistance-fix-2' of https://github.com/Jua…
Juan-Antonio-Doe Jul 18, 2026
0dd82d2
A new ToDo comment has been added that would affect the entire app.
Juan-Antonio-Doe Jul 18, 2026
915ae38
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 19, 2026
bdf34e0
Fixed controller navigation and improved DebugScreen appearance.
Juan-Antonio-Doe Jul 19, 2026
8a83275
Merge branch 'background-persistance-fix-2' of https://github.com/Jua…
Juan-Antonio-Doe Jul 19, 2026
a0715d9
Converted collapsible groups (Debug Screen) into controlled component…
Juan-Antonio-Doe Jul 19, 2026
1f6e9fa
A few more fixes and edits to comments.
Juan-Antonio-Doe Jul 20, 2026
5d94343
Another cleaning.
Juan-Antonio-Doe Jul 21, 2026
72ebfb8
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 21, 2026
9865486
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 23, 2026
7203feb
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 24, 2026
c467713
Enable background protection by default on Android 13+
Juan-Antonio-Doe Jul 24, 2026
b9df1ee
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 24, 2026
77d8f40
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 25, 2026
9ea48b2
Nick patch: Hide all application log options behind a toggle.
Juan-Antonio-Doe Jul 25, 2026
f0944b1
Almost all log files are now generated and saved in the app’s interna…
Juan-Antonio-Doe Jul 26, 2026
485a31f
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 27, 2026
f3fe8b1
Some bug fixes and improvements (7).
Juan-Antonio-Doe Jul 27, 2026
4a4d34d
Merge branch 'background-persistance-fix-2' of https://github.com/Jua…
Juan-Antonio-Doe Jul 27, 2026
a1c002a
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 27, 2026
f48990f
Some bug fixes and improvements (8).
Juan-Antonio-Doe Jul 27, 2026
173a3f2
SteamLoginActivity: Fix persistent foreground service when Steam Logi…
Juan-Antonio-Doe Jul 27, 2026
8317eba
LogManager: Fixed a regression in the anti-duplication PostMortem log…
Juan-Antonio-Doe Jul 28, 2026
665d7a4
SteamLoginActivity: Handling the correct exit from the login screen t…
Juan-Antonio-Doe Jul 28, 2026
fa03ef4
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 28, 2026
85943b6
Merge branch 'main' into background-persistance-fix-2
Juan-Antonio-Doe Jul 29, 2026
b71df8e
Fix indentation in SessionKeepAliveService.java
Juan-Antonio-Doe Jul 30, 2026
5909135
Merge branch 'background-persistance-fix-2' of https://github.com/Jua…
Juan-Antonio-Doe Jul 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ plugins {
alias(libs.plugins.spotless)
}

apply from: rootProject.file('gradle/collectLogTags.gradle')

/*
abstract class InstallVulkanValidationLayerTask extends DefaultTask {
@Input
Expand Down Expand Up @@ -59,6 +61,10 @@ task checkSubmodules {

preBuild.dependsOn(checkSubmodules)

tasks.named('preBuild') {
dependsOn 'collectLogTags'
}

/*
def installVulkanValidationLayer = tasks.register("installVulkanValidationLayer", InstallVulkanValidationLayerTask) {
layerVersion.set("1.4.341.0")
Expand Down Expand Up @@ -205,11 +211,13 @@ android {
sourceSets {
main {
java.srcDirs = [
// 'src/main/java', // Needed for Android Studio
'src/main/app',
'src/main/feature',
'src/main/sharedmemory',
'src/main/runtime',
'src/main/shared'
'src/main/shared',
'build/generated/source/logtags' // Generated by collectLogTags.gradle
]
}
}
Expand All @@ -229,7 +237,7 @@ android {
}

dependencies {
// debugImplementation "com.squareup.leakcanary:leakcanary-android:2.14"
// debugImplementation "com.squareup.leakcanary:leakcanary-android:2.14"

implementation libs.okhttp
implementation libs.okhttpDnsOverHttps
Expand Down Expand Up @@ -277,6 +285,7 @@ dependencies {
implementation files('libs/MidiSynth/MidiSynth.jar')
implementation libs.recyclerview
implementation libs.coreKtx
implementation(libs.lifecycleProcess) // New = compilation errors / gradle plugin update requirement.


implementation 'com.android.ndk.thirdparty:openssl:1.1.1q-beta-1'
Expand Down
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_LOGS" tools:ignore="ProtectedPermissions"/>
<uses-permission
android:name="android.permission.WRITE_SECURE_SETTINGS"
tools:ignore="ProtectedPermissions" />
Expand Down
12 changes: 12 additions & 0 deletions app/src/main/app/PluviaApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import com.winlator.cmod.feature.stores.steam.events.EventDispatcher
import com.winlator.cmod.feature.stores.steam.service.SteamService
import com.winlator.cmod.feature.stores.steam.utils.PrefManager
import com.winlator.cmod.runtime.display.XServerDisplayActivity
import com.winlator.cmod.runtime.system.LogManager
import com.winlator.cmod.shared.android.RefreshRateUtils
import dagger.hilt.android.HiltAndroidApp
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber
import java.io.File

@HiltAndroidApp
Expand All @@ -40,6 +42,16 @@ class PluviaApp : Application() {
.init(this)
scheduleColdStartWarmups()

// Initialize Timber in debug builds for app wide logging.
// If 'BuildConfig' give error, ignore it.
// The file needed will be autogenerated when building the apk.
if (com.winlator.cmod.BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree());
}

// Initialize the LogManager context in case a fallback is needed.
LogManager.init(this.applicationContext)

Thread.setDefaultUncaughtExceptionHandler { thread, throwable ->
Log.e("PluviaApp", "CRASH in thread ${thread.name}", throwable)
}
Expand Down
1 change: 1 addition & 0 deletions app/src/main/app/shell/UnifiedActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,7 @@ class UnifiedActivity :
override fun onCreate(savedInstanceState: Bundle?) {
instance = this
super.onCreate(savedInstanceState)

if (!SetupWizardActivity.isSetupComplete(this) || !ImageFs.find(this).isUpToDate) {
startActivity(
Intent(this, SetupWizardActivity::class.java)
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/cpp/winlator/xconnector_epoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#include <sys/time.h>

#define printf(...) \
__android_log_print(ANDROID_LOG_DEBUG, "System.out", __VA_ARGS__);
Expand Down Expand Up @@ -74,6 +75,10 @@ Java_com_winlator_cmod_runtime_display_connector_XConnectorEpoll_doEpollIndefini
if (events[i].data.fd == serverFd) {
int clientFd = accept(serverFd, NULL, NULL);
if (clientFd >= 0) {
// Set a write timeout to avoid hanging the XServer if a client is stopped (SIGSTOP)
struct timeval tv = {.tv_sec = 2, .tv_usec = 0};
setsockopt(clientFd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));

if (addClientToEpoll) {
struct epoll_event event;
event.data.fd = clientFd;
Expand Down
106 changes: 105 additions & 1 deletion app/src/main/feature/settings/debug/DebugFragment.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Settings > Debug fragment — hosts DebugScreen via ComposeView.
package com.winlator.cmod.feature.settings
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
Expand All @@ -8,11 +9,11 @@ import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.ComposeView
Expand All @@ -25,6 +26,8 @@ import androidx.fragment.app.Fragment
import androidx.preference.PreferenceManager
import com.winlator.cmod.R
import com.winlator.cmod.app.config.SettingsConfig
import com.winlator.cmod.runtime.system.GeneratedLogTags
import com.winlator.cmod.runtime.system.LogManager
import com.winlator.cmod.app.shell.UnifiedActivity
import com.winlator.cmod.shared.io.AssetPaths
import com.winlator.cmod.shared.io.FileUtils
Expand Down Expand Up @@ -70,6 +73,31 @@ class DebugFragment : Fragment() {
state = debugState,
wineChannelOptions = wineChannelOptions,
wineClassOptions = SettingsConfig.WINE_DEBUG_CLASSES,
onLoggingEnabledChanged = { checked ->
preferences.edit {
putBoolean("enable_application_logging", checked)
if (!checked) {
putBoolean("enable_app_debug", false)
putBoolean("enable_input_logs", false)
putBoolean("enable_download_logs", false)
putBoolean("enable_exit_reason_log", false)
putBoolean("enable_crash_log", false)
putBoolean("enable_filtered_logs", false)
putBoolean("enable_event_watch_log", false)
}
}
if (!checked) {
com.winlator.cmod.feature.stores.steam.utils.PrefManager.enableSteamLogs = false
com.winlator.cmod.runtime.system.ApplicationLogGate
.setEnabled(false)
}

refresh()
},
onLogcatGroupExpandedChanged = { expanded ->
preferences.edit { putBoolean("debug_group_logcat_expanded", expanded) }
refresh()
},
onAppDebugChanged = { checked ->
preferences.edit { putBoolean("enable_app_debug", checked) }
com.winlator.cmod.runtime.system.ApplicationLogGate
Expand All @@ -85,6 +113,55 @@ class DebugFragment : Fragment() {
}
refresh()
},
onFilteredLogsChanged = { checked ->
preferences.edit { putBoolean("enable_filtered_logs", checked) }
if (!checked) {
com.winlator.cmod.runtime.system.LogManager
.clearManualTextFilter()
if (!debugState.eventWatchLog) {
com.winlator.cmod.runtime.system.LogManager.clearManualTextFilter()
}
}
refresh()
},
onExitReasonLogChanged = { checked ->
preferences.edit { putBoolean("enable_exit_reason_log", checked) }
if (checked) {
// Capture previous exit reasons, so the user doesn't need
// to restart the app to check previous reasons.
com.winlator.cmod.runtime.system.LogManager
.logLastExitReasons(ctx)
}
refresh()
},
onCrashLogChanged = { checked ->
preferences.edit { putBoolean("enable_crash_log", checked) }
if (checked) {
// Capture previous crashes, so the user doesn't need
// to restart to check previous reasons.
com.winlator.cmod.runtime.system.LogManager
.logLastExitReasons(ctx)
}
refresh()
},
onEventWatchLogChanged = { checked ->
preferences.edit { putBoolean("enable_event_watch_log", checked) }
refresh()
},
onTagFilterModeChanged = { mode -> LogManager.setTagFilterMode(requireContext(), mode); refresh() },
onSelectedTagsChanged = { tags -> LogManager.setSelectedTags(requireContext(), tags.toSet()); refresh() },
onAddCustomTag = { tag -> LogManager.addCustomTag(requireContext(), tag); refresh() },
onRemoveCustomTag = { tag -> LogManager.removeCustomTag(requireContext(), tag); refresh() },
onManualTextFilterChanged = { text -> LogManager.setManualTextFilter(text) }, // no persistence, no refreshState needed
allLogTagOptions = remember(debugState.customTags) { LogManager.getAllKnownTags() },
onExitGroupExpandedChanged = { expanded ->
preferences.edit { putBoolean("debug_group_exit_expanded", expanded) }
refresh()
},
onFilterGroupExpandedChanged = { expanded ->
preferences.edit { putBoolean("debug_group_filter_expanded", expanded) }
refresh()
},
onWineDebugChanged = { checked ->
preferences.edit { putBoolean("enable_wine_debug", checked) }
com.winlator.cmod.runtime.system.LogManager
Expand Down Expand Up @@ -127,18 +204,21 @@ class DebugFragment : Fragment() {
) {
timber.log.Timber.plant(timber.log.Timber.DebugTree())
}
if (checked) ensureAppLoggingOn()
com.winlator.cmod.runtime.system.LogManager
.updateLoggingState(ctx)
refresh()
},
onInputLogsChanged = { checked ->
preferences.edit { putBoolean("enable_input_logs", checked) }
if (checked) ensureAppLoggingOn()
com.winlator.cmod.runtime.system.LogManager
.updateLoggingState(ctx)
refresh()
},
onDownloadLogsChanged = { checked ->
preferences.edit { putBoolean("enable_download_logs", checked) }
if (checked) ensureAppLoggingOn()
com.winlator.cmod.runtime.system.LogManager
.updateLoggingState(ctx)
refresh()
Expand Down Expand Up @@ -205,7 +285,20 @@ class DebugFragment : Fragment() {
?.filter { it.isNotBlank() } ?: emptyList()
debugState =
DebugState(
loggingEnabled = preferences.getBoolean("enable_application_logging", false),
appDebug = preferences.getBoolean("enable_app_debug", false),
filteredLogs = preferences.getBoolean("enable_filtered_logs", false),
exitReasonLog = preferences.getBoolean("enable_exit_reason_log", false),
crashLog = preferences.getBoolean("enable_crash_log", false),
eventWatchLog = preferences.getBoolean("enable_event_watch_log", false),
tagFilterMode = LogManager.getTagFilterMode(),
selectedTags = LogManager.getSelectedTags().toList(),
customTags = LogManager.getCachedCustomTags(),

logcatGroupExpanded = preferences.getBoolean("debug_group_logcat_expanded", false),
exitGroupExpanded = preferences.getBoolean("debug_group_exit_expanded", false),
filterGroupExpanded = preferences.getBoolean("debug_group_filter_expanded", false),

wineDebug = preferences.getBoolean("enable_wine_debug", false),
wineChannels = channels,
wineClasses = classes,
Expand Down Expand Up @@ -455,6 +548,17 @@ class DebugFragment : Fragment() {
refresh()
}

// Steam/input/download logs are only flags on log statements that land in the application
// log capture, so they produce nothing unless application logging is running.
private fun ensureAppLoggingOn() {
if (preferences.getBoolean("enable_app_debug", false)) return
preferences.edit { putBoolean("enable_app_debug", true) }
com.winlator.cmod.runtime.system.ApplicationLogGate
.setEnabled(true)
com.winlator.cmod.runtime.system.LogManager
.startAppLogging(requireContext(), reset = false)
}

companion object {
private const val KEY_DOWNLOADED_LOGS = "downloaded_log_keys"

Expand Down
Loading