Fix: Container and downloads stopping when the device is locked.#397
Closed
Juan-Antonio-Doe wants to merge 18 commits into
Closed
Fix: Container and downloads stopping when the device is locked.#397Juan-Antonio-Doe wants to merge 18 commits into
Juan-Antonio-Doe wants to merge 18 commits into
Conversation
Introduces a reference-counted foreground service to prevent the Android system from reclaiming the app process during active Wine sessions or long-running background tasks, such as component downloads and ImageFS extractions.
Key changes:
- **SessionKeepAliveService**: Created a new foreground service using `FOREGROUND_SERVICE_TYPE_SPECIAL_USE` and `DATA_SYNC`. It manages a notification and a `PARTIAL_WAKE_LOCK` to keep the CPU active when the screen is locked or the app is backgrounded.
- **Process Protection**: Added `setOomScoreAdj` in `ProcessHelper` to lower the kill priority of paused (SIGSTOP'd) Wine processes, preventing the kernel from reaping them during memory pressure.
- **Lifecycle Integration**:
- Updated `XServerDisplayActivity` to start/stop the service alongside the XServer session and toggle wake locks during pause/resume.
- Wrapped extraction and download logic in `SetupWizardActivity`, `ContentsFragment`, and `DriversFragment` with keep-alive tags to ensure multi-minute installs complete successfully in the background.
- **Manifest**: Added permissions for `FOREGROUND_SERVICE_SPECIAL_USE`, `WAKE_LOCK`, and defined the new service.
- **Input Handling**: Prevented generic motion and key event dispatching in `XServerDisplayActivity` when the session is paused.
What was missing for it to work seems to have been both the SPECIAL_USE and a CPU wakelock. There’s also a commented-out wifiLock in case someone want to stabilize suspension for online games or ones that need to download assets (and the user wants to turn off the screen or do something else in the meantime).
I’ve also verified that the container actually goes into suspension while the device is locked.
Using this *PowerShell* command to check the status of the processes:
adb shell ps -eA | Select-String -Pattern "wine", "box64", "wfm", "handler"
With the screen on and the container running, the command returns:
------------
u0_a297 19983 19102 10865704 38256 0 0 S wineserver
u0_a297 19996 19102 0 0 0 0 Z [wineboot.exe]
u0_a297 20002 19102 16256732 70704 0 0 S winedevice.exe
u0_a297 20011 19102 16535896 89960 0 0 S winedevice.exe
u0_a297 20039 19102 16230516 78720 0 0 S winhandler.exe
u0_a297 20045 19102 16342600 116620 0 0 S wfm.exe
------------
With the screen off after a few seconds, the command returns:
------------
root 7873 2 0 0 0 0 I [kworker/u16:0-qmi_msg_handler]
root 9916 2 0 0 0 0 I [kworker/u16:4-qmi_msg_handler]
u0_a297 19983 19102 10865704 38256 0 0 T wineserver
u0_a297 19996 19102 0 0 0 0 Z [wineboot.exe]
u0_a297 20002 19102 16256732 70704 0 0 T winedevice.exe
u0_a297 20011 19102 16535896 89960 0 0 T winedevice.exe
u0_a297 20039 19102 16230516 78720 0 0 T winhandler.exe
u0_a297 20045 19102 16342600 116620 0 0 T wfm.exe
------------
Which implies that the container should indeed reduce its consumption in sleep mode.
…ton in the DrawerMenu. - Restored the value of the isPaused boolean inside onResume and updated the drawer accordingly. - Simplified a duplicated logic in the drawer menu Kotlin class related to the pause/resume button.
…dling This change removes local notification management from `XServerDisplayActivity` and centralizes it within `SessionKeepAliveService`. It also updates the process resumption logic to better respect the activity's paused state. Key changes: - Disabled redundant notification creation and cancellation in `XServerDisplayActivity`. - Updated `SessionKeepAliveService` to use `XServerDisplayActivity` as the content intent target with `FLAG_ACTIVITY_REORDER_TO_FRONT`. - Enhanced service notification visibility on the lockscreen and updated its icon and priority. However, if the user has notifications set to "silent" it will still not work. - Modified `XServerDisplayActivity` to ensure Wine processes only resume when the activity is not paused. User need to resume it manually. - Properly set the `isPaused` flag in `onPause`. So, in summary: - Commented out the notification code in XServerDisplayActivity since its functionality has been replaced by the SessionKeepAliveService notification. - The container/game now remains paused when returning to the foreground. - Removed a commented-out line of code in XServerDrawerMenu.kt that I forgot to delete in the previous commit.
Update base string in generateNotificationId() in SessionKeepAliveService.java to match project name. I forgot to change it in the first commit. Switch javasteam version to the lastest release available. Required to prevent the build process from failing both locally and in GitHub CI.
…better notification feedback - The service notification is now shown only when: - The container is paused, regardless of whether it is in the foreground or background. - There is an active download. - The notification is not shown when: - The container is running. - The notification message has been adjusted to avoid confusion. - Previously commented-out code has been removed. - The service has been reinforced: - To ensure it stops when the container activity is destroyed. - If starting the service fails, a crash is prevented by attempting to start the foreground service again as a fallback.
XServerDisplayActivity: Removed unused imports related to notifications. SessionKeepAliveService: Removed a leftover log and commented out an import related to the wifiLock.
…tering inputs. Fixed a bug inherited from upstream (winlator_bionic or CMOD) where, when the container is paused, if the user continues to provide input, such as moving the cursor with two fingers at the same time, the app crashes with an exception: ANR in com.winnative.test (com.winnative.test/com.winlator.cmod.runtime.display.XServerDisplayActivity) Reason: Input dispatching timed out (ca8503b com.winnative.test/com.winlator.cmod.runtime.display.XServerDisplayActivity is not responding. Waited 5001ms for MotionEvent).
From Nick417: - Added "enable_background_session" preference. False by default. - Added "Background" to Other Settings. - Container default processes don't get paused when in background. New: - Added "pause_wine_on_background" preference. False by default. - Only shows up if Background setting is enabled. - Container default processes get paused when the previous boolean is true too. - Added new xml string for this new setting.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First, this PR is a continuation of the one already started by MaxsTechReview. In short, I’ve added what was missing to make it work and did my best to optimize its use in the background.
Details:
Introduces a background service to prevent the Android system from reclaiming the app process during paused Wine sessions or long-running background tasks, such as component downloads and ImageFS extractions.
Key changes:
FOREGROUND_SERVICE_TYPE_SPECIAL_USEandDATA_SYNC. It manages a notification and aPARTIAL_WAKE_LOCKto keep the CPU active when the screen is locked or the app is backgrounded.setOomScoreAdjinProcessHelperto lower the kill priority of paused (SIGSTOP'd) Wine processes, preventing the kernel from reaping them during memory pressure.XServerDisplayActivityto start/stop the service alongside the XServer session and toggle wake locks during pause/resume.SetupWizardActivity,ContentsFragment, andDriversFragmentwith keep-alive tags to ensure multi-minute installs complete successfully in the background.FOREGROUND_SERVICE_SPECIAL_USE,WAKE_LOCK, and defined the new service.XServerDisplayActivitywhen the session is paused.What was missing for it to work seems to have been both the SPECIAL_USE and a CPU wakelock. There’s also a commented-out wifiLock in case someone want to stabilize suspension for online games or ones that need to download assets (and the user wants to turn off the screen or do something else in the meantime).
I’ve also verified that the container actually goes into suspension while the device is locked.
Using this PowerShell command to check the status of the processes:
adb shell ps -eA | Select-String -Pattern "wine", "box64", "wfm", "handler"With the screen on and the container running, the command returns:
With the screen off after a few seconds, the command returns:
Which implies that the container should indeed reduce its consumption in sleep mode.
More details about the meaning of the letters here:
https://www.baeldung.com/linux/process-states
Things to test