Resume sessions on visibility transitions

This commit is contained in:
xXJsonDeruloXx committed 2026-10-13 17:38:34 -04:00
1 parent 4fd326bd01
commit 155cbbb894
3 files changed
+79 -5

No files matched your search

@@ -91,6 +91,7 @@ class SessionService : Service() {
private var activityVisible = true
private var activityDisplayId = Display.DEFAULT_DISPLAY
private var screenOn = true
private var previouslyHidden: Boolean? = null
private var manualPauseRequested = false
/** An explicit Steam sleep request is independent of the background policy. */
private var steamSleepToken: String? = null
@@ -115,7 +116,6 @@ class SessionService : Service() {
Intent.ACTION_SCREEN_ON -> screenOn = true
else -> return
}
if (screenOn) resumeSteamSleepOnReturn()
suspendAttemptFailed = false
updateSuspendPolicy()
}
@@ -182,7 +182,6 @@ class SessionService : Service() {
if (!SessionState.pipActive) pipTask = false
activityVisible = true
suspendDownloadNow = false
resumeSteamSleepOnReturn()
suspendAttemptFailed = false
updateSuspendPolicy()
return START_NOT_STICKY
@@ -196,9 +195,6 @@ class SessionService : Service() {
}
ACTION_ACTIVITY_DISPLAY_CHANGED -> {
activityDisplayId = intent.getIntExtra(EXTRA_ACTIVITY_DISPLAY_ID, activityDisplayId)
if (activityVisible && (SessionState.suspended || steamSleepToken != null || nativeSleepToken != null)) {
resumeSteamSleepOnReturn()
}
suspendAttemptFailed = false
updateSuspendPolicy()
return START_NOT_STICKY
@@ -240,6 +236,7 @@ class SessionService : Service() {
activityVisible = true
activityDisplayId = SessionState.activityDisplayId
screenOn = (getSystemService(Context.POWER_SERVICE) as? PowerManager)?.isInteractive ?: true
previouslyHidden = null
manualPauseRequested = false
suspendDownloadNow = false
steamDownloadMonitor.reset()
@@ -1357,6 +1354,11 @@ class SessionService : Service() {
activityOnDefaultDisplay = activityDisplayId == Display.DEFAULT_DISPLAY,
activityDisplayOn = activityDisplayOn,
)
val wasHidden = previouslyHidden
previouslyHidden = hidden
if (SessionVisibilityPolicy.shouldResumeOnVisibleTransition(wasHidden, hidden, suspendPolicy)) {
resumeSteamSleepOnReturn()
}
if (suspendPolicy == SessionPrefs.SUSPEND_MANUAL && hidden) {
manualPauseRequested = true
}
@@ -11,4 +11,11 @@ internal object SessionVisibilityPolicy {
activityOnDefaultDisplay: Boolean,
activityDisplayOn: Boolean,
): Boolean = !activityStarted || if (activityOnDefaultDisplay) !screenOn else !activityDisplayOn
fun shouldResumeOnVisibleTransition(
previouslyHidden: Boolean?,
currentlyHidden: Boolean,
suspendPolicy: String,
): Boolean = previouslyHidden == true && !currentlyHidden &&
suspendPolicy in setOf(SessionPrefs.SUSPEND_AUTO, SessionPrefs.SUSPEND_NATIVE)
}
@@ -30,4 +30,69 @@ class SessionVisibilityPolicyTest {
// SessionActivity reports onStart/onStop; a focus-only onPause does not mark it hidden.
assertFalse(SessionVisibilityPolicy.isHidden(true, true, true, true))
}
@Test fun defaultDisplayScreenOnResumesAfterScreenOff() {
val wasHidden = SessionVisibilityPolicy.isHidden(true, false, true, true)
val isHidden = SessionVisibilityPolicy.isHidden(true, true, true, true)
assertTrue(SessionVisibilityPolicy.shouldResumeOnVisibleTransition(
previouslyHidden = wasHidden,
currentlyHidden = isHidden,
suspendPolicy = SessionPrefs.SUSPEND_AUTO,
))
}
@Test fun externalDisplayOnResumesAfterOffOrDisconnect() {
val wasHidden = SessionVisibilityPolicy.isHidden(true, false, false, false)
val isHidden = SessionVisibilityPolicy.isHidden(true, false, false, true)
assertTrue(SessionVisibilityPolicy.shouldResumeOnVisibleTransition(
previouslyHidden = wasHidden,
currentlyHidden = isHidden,
suspendPolicy = SessionPrefs.SUSPEND_NATIVE,
))
}
@Test fun startedActivityResumesAfterBeingStopped() {
val wasHidden = SessionVisibilityPolicy.isHidden(false, false, false, true)
val isHidden = SessionVisibilityPolicy.isHidden(true, false, false, true)
assertTrue(SessionVisibilityPolicy.shouldResumeOnVisibleTransition(
previouslyHidden = wasHidden,
currentlyHidden = isHidden,
suspendPolicy = SessionPrefs.SUSPEND_AUTO,
))
}
@Test fun onToOnDisplayPropertyChangeDoesNotResume() {
val wasHidden = SessionVisibilityPolicy.isHidden(true, true, false, true)
val isHidden = SessionVisibilityPolicy.isHidden(true, true, false, true)
assertFalse(SessionVisibilityPolicy.shouldResumeOnVisibleTransition(
previouslyHidden = wasHidden,
currentlyHidden = isHidden,
suspendPolicy = SessionPrefs.SUSPEND_AUTO,
))
assertFalse(SessionVisibilityPolicy.shouldResumeOnVisibleTransition(
previouslyHidden = null,
currentlyHidden = isHidden,
suspendPolicy = SessionPrefs.SUSPEND_AUTO,
))
}
@Test fun handsetScreenOnDoesNotResumeVisibleExternalDisplay() {
val wasHidden = SessionVisibilityPolicy.isHidden(true, false, false, true)
val isHidden = SessionVisibilityPolicy.isHidden(true, true, false, true)
assertFalse(SessionVisibilityPolicy.shouldResumeOnVisibleTransition(
previouslyHidden = wasHidden,
currentlyHidden = isHidden,
suspendPolicy = SessionPrefs.SUSPEND_AUTO,
))
}
@Test fun manualPolicyDoesNotResumeOnVisibleTransition() {
val wasHidden = SessionVisibilityPolicy.isHidden(true, false, true, true)
val isHidden = SessionVisibilityPolicy.isHidden(true, true, true, true)
assertFalse(SessionVisibilityPolicy.shouldResumeOnVisibleTransition(
previouslyHidden = wasHidden,
currentlyHidden = isHidden,
suspendPolicy = SessionPrefs.SUSPEND_MANUAL,
))
}
}