diff --git a/app/src/main/java/com/droiddeck/launcher/session/SessionService.kt b/app/src/main/java/com/droiddeck/launcher/session/SessionService.kt index 6cc20e1f..4b810cd5 100644 --- a/app/src/main/java/com/droiddeck/launcher/session/SessionService.kt +++ b/app/src/main/java/com/droiddeck/launcher/session/SessionService.kt @@ -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 } diff --git a/app/src/main/java/com/droiddeck/launcher/session/SessionVisibilityPolicy.kt b/app/src/main/java/com/droiddeck/launcher/session/SessionVisibilityPolicy.kt index 4383b694..a7b066d5 100644 --- a/app/src/main/java/com/droiddeck/launcher/session/SessionVisibilityPolicy.kt +++ b/app/src/main/java/com/droiddeck/launcher/session/SessionVisibilityPolicy.kt @@ -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) } diff --git a/app/src/test/java/com/droiddeck/launcher/session/SessionVisibilityPolicyTest.kt b/app/src/test/java/com/droiddeck/launcher/session/SessionVisibilityPolicyTest.kt index 14e9eff7..3b0a45b0 100644 --- a/app/src/test/java/com/droiddeck/launcher/session/SessionVisibilityPolicyTest.kt +++ b/app/src/test/java/com/droiddeck/launcher/session/SessionVisibilityPolicyTest.kt @@ -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, + )) + } }