Skip to content

Fix: Container and downloads stopping when the device is locked.#397

Closed
Juan-Antonio-Doe wants to merge 18 commits into
WinNative-Emu:mainfrom
Juan-Antonio-Doe:background-persistance-fix
Closed

Fix: Container and downloads stopping when the device is locked.#397
Juan-Antonio-Doe wants to merge 18 commits into
WinNative-Emu:mainfrom
Juan-Antonio-Doe:background-persistance-fix

Conversation

@Juan-Antonio-Doe
Copy link
Copy Markdown
Contributor

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:

  • 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.

More details about the meaning of the letters here:
https://www.baeldung.com/linux/process-states


Things to test

  • If the container or the game used to close after the device was locked, that should no longer happen.
    • I need to verify that this works across different Android versions; in my case, Android 16.
  • Downloads, especially layer downloads, should complete and install even while the phone is suspended.
  • Test both cases while the app is running in the background and other apps are being used.

Juan-Antonio-Doe and others added 7 commits May 10, 2026 20:07
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.
@Juan-Antonio-Doe Juan-Antonio-Doe marked this pull request as draft May 12, 2026 20:33
Juan-Antonio-Doe and others added 2 commits May 13, 2026 08:40
…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.
Comment thread app/src/main/runtime/system/SessionKeepAliveService.java Outdated
maxjivi05 and others added 3 commits May 13, 2026 22:08
XServerDisplayActivity: Removed unused imports related to notifications.
SessionKeepAliveService: Removed a leftover log and commented out an import related to the wifiLock.
@Juan-Antonio-Doe Juan-Antonio-Doe marked this pull request as ready for review May 14, 2026 06:37
@Juan-Antonio-Doe Juan-Antonio-Doe marked this pull request as draft May 14, 2026 11:23
maxjivi05 and others added 2 commits May 14, 2026 09:30
…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).
@Juan-Antonio-Doe Juan-Antonio-Doe marked this pull request as ready for review May 14, 2026 21:31
@Juan-Antonio-Doe Juan-Antonio-Doe marked this pull request as draft May 17, 2026 15:23
@Juan-Antonio-Doe Juan-Antonio-Doe marked this pull request as ready for review May 17, 2026 15:26
@Juan-Antonio-Doe Juan-Antonio-Doe marked this pull request as draft May 19, 2026 10:56
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants