Fix some cases when refresh rate switching didn't work/timed out (#901)

## Description
An attempt to fix #769

1. Always fetch the `DisplayManager` when switching refresh rates
2. Use the Activity context instead of Application context

### Related issues
Fixes #769

### Testing
I still haven't reproduced #769 myself, but this change works fine on my
shield + LG C2

## Screenshots
N/A

## AI or LLM usage
None
This commit is contained in:
Ray 2026-02-16 09:04:28 -05:00 committed by GitHub
parent 0276c5f49b
commit dc3c6dc739
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 19 deletions

View file

@ -409,7 +409,7 @@ class MainActivity : AppCompatActivity() {
} }
fun changeDisplayMode(modeId: Int) { fun changeDisplayMode(modeId: Int) {
lifecycleScope.launch(Dispatchers.Main + ExceptionHandler()) { lifecycleScope.launch(Dispatchers.Main + ExceptionHandler(autoToast = true)) {
val attrs = window.attributes val attrs = window.attributes
if (attrs.preferredDisplayModeId != modeId) { if (attrs.preferredDisplayModeId != modeId) {
Timber.d("Switch preferredDisplayModeId to %s", modeId) Timber.d("Switch preferredDisplayModeId to %s", modeId)

View file

@ -28,21 +28,6 @@ class RefreshRateService
constructor( constructor(
@param:ApplicationContext private val context: Context, @param:ApplicationContext private val context: Context,
) { ) {
private val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
private val display get() = displayManager.getDisplay(Display.DEFAULT_DISPLAY)
val supportedDisplayModes get() = display.supportedModes.orEmpty()
private val displayModes: List<DisplayMode> by lazy {
display.supportedModes
.orEmpty()
.map { DisplayMode(it) }
.sortedWith(
compareByDescending<DisplayMode>({ it.physicalWidth * it.physicalHeight })
.thenBy { it.refreshRateRounded },
)
}
/** /**
* Find the best display mode for the given stream and signal to change to it * Find the best display mode for the given stream and signal to change to it
*/ */
@ -55,6 +40,18 @@ class RefreshRateService
Timber.v("Not switching either refresh rate nor resolution") Timber.v("Not switching either refresh rate nor resolution")
return@withContext return@withContext
} }
val displayManager =
MainActivity.instance.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val display = displayManager.getDisplay(Display.DEFAULT_DISPLAY)
val displayModes =
display.supportedModes
.orEmpty()
.map { DisplayMode(it) }
.sortedWith(
compareByDescending<DisplayMode>({ it.physicalWidth * it.physicalHeight })
.thenBy { it.refreshRateRounded },
)
val currentDisplayMode = display.mode val currentDisplayMode = display.mode
require(stream.type == MediaStreamType.VIDEO) { "Stream is not video" } require(stream.type == MediaStreamType.VIDEO) { "Stream is not video" }
val width = stream.width val width = stream.width

View file

@ -1,8 +1,10 @@
package com.github.damontecres.wholphin.ui.detail package com.github.damontecres.wholphin.ui.detail
import android.content.Context import android.content.Context
import android.hardware.display.DisplayManager
import android.os.Build import android.os.Build
import android.util.Log import android.util.Log
import android.view.Display
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.focusable import androidx.compose.foundation.focusable
import androidx.compose.foundation.gestures.scrollBy import androidx.compose.foundation.gestures.scrollBy
@ -32,11 +34,11 @@ import androidx.lifecycle.viewModelScope
import androidx.tv.material3.MaterialTheme import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text import androidx.tv.material3.Text
import com.github.damontecres.wholphin.BuildConfig import com.github.damontecres.wholphin.BuildConfig
import com.github.damontecres.wholphin.MainActivity
import com.github.damontecres.wholphin.data.ItemPlaybackDao import com.github.damontecres.wholphin.data.ItemPlaybackDao
import com.github.damontecres.wholphin.data.ServerRepository import com.github.damontecres.wholphin.data.ServerRepository
import com.github.damontecres.wholphin.data.model.ItemPlayback import com.github.damontecres.wholphin.data.model.ItemPlayback
import com.github.damontecres.wholphin.preferences.UserPreferences import com.github.damontecres.wholphin.preferences.UserPreferences
import com.github.damontecres.wholphin.services.RefreshRateService
import com.github.damontecres.wholphin.ui.launchIO import com.github.damontecres.wholphin.ui.launchIO
import com.github.damontecres.wholphin.ui.showToast import com.github.damontecres.wholphin.ui.showToast
import com.github.damontecres.wholphin.util.ExceptionHandler import com.github.damontecres.wholphin.util.ExceptionHandler
@ -60,13 +62,19 @@ class DebugViewModel
constructor( constructor(
val serverRepository: ServerRepository, val serverRepository: ServerRepository,
val itemPlaybackDao: ItemPlaybackDao, val itemPlaybackDao: ItemPlaybackDao,
val refreshRateService: RefreshRateService,
val clientInfo: ClientInfo, val clientInfo: ClientInfo,
val deviceInfo: DeviceInfo, val deviceInfo: DeviceInfo,
) : ViewModel() { ) : ViewModel() {
val itemPlaybacks = MutableLiveData<List<ItemPlayback>>(listOf()) val itemPlaybacks = MutableLiveData<List<ItemPlayback>>(listOf())
val logcat = MutableLiveData<List<LogcatLine>>(listOf()) val logcat = MutableLiveData<List<LogcatLine>>(listOf())
val supportedModes by lazy {
val displayManager =
MainActivity.instance.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val display = displayManager.getDisplay(Display.DEFAULT_DISPLAY)
display.supportedModes.orEmpty()
}
init { init {
viewModelScope.launchIO { viewModelScope.launchIO {
serverRepository.currentUser.value?.rowId?.let { serverRepository.currentUser.value?.rowId?.let {
@ -260,7 +268,7 @@ fun DebugPage(
"Model: ${Build.MODEL}", "Model: ${Build.MODEL}",
"API Level: ${Build.VERSION.SDK_INT}", "API Level: ${Build.VERSION.SDK_INT}",
"Display Modes:", "Display Modes:",
*viewModel.refreshRateService.supportedDisplayModes, *viewModel.supportedModes,
).forEach { ).forEach {
Text( Text(
text = it.toString(), text = it.toString(),