diff --git a/app/src/main/java/app/gamenative/ui/component/QuickMenu.kt b/app/src/main/java/app/gamenative/ui/component/QuickMenu.kt index 6b634ec6f0..a9b6116684 100644 --- a/app/src/main/java/app/gamenative/ui/component/QuickMenu.kt +++ b/app/src/main/java/app/gamenative/ui/component/QuickMenu.kt @@ -4,8 +4,6 @@ import android.view.KeyEvent import androidx.activity.compose.BackHandler import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.MutableTransitionState -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring import androidx.compose.animation.core.tween import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn @@ -1054,6 +1052,77 @@ private fun PerformanceHudQuickMenuTab( }, accentColor = accentColor, ) + + QuickMenuToggleRow( + title = stringResource(R.string.performance_hud_battery_level_warning), + enabled = performanceHudConfig.batteryLevelWarningEnabled, + onToggle = { + onPerformanceHudConfigChanged( + performanceHudConfig.copy(batteryLevelWarningEnabled = !performanceHudConfig.batteryLevelWarningEnabled), + ) + }, + accentColor = accentColor, + ) + if (performanceHudConfig.batteryLevelWarningEnabled) + { + QuickMenuAdjustmentRow( + title = stringResource(R.string.performance_hud_battery_level_limit), + valueText = stringResource( + R.string.performance_hud_percentage_value, + (performanceHudConfig.batteryLevelWarningLimit * 100f).roundToInt(), + ), + progress = normalizedProgress(performanceHudConfig.batteryLevelWarningLimit, 0f, 1f), + onDecrease = { + onPerformanceHudConfigChanged( + performanceHudConfig.copy( + batteryLevelWarningLimit = (performanceHudConfig.batteryLevelWarningLimit - 0.05f).coerceIn(0f, 1f), + ), + ) + }, + onIncrease = { + onPerformanceHudConfigChanged( + performanceHudConfig.copy( + batteryLevelWarningLimit = (performanceHudConfig.batteryLevelWarningLimit + 0.05f).coerceIn(0f, 1f), + ), + ) + }, + accentColor = accentColor, + ) + } + + QuickMenuToggleRow( + title = stringResource(R.string.performance_hud_battery_temp_warning), + enabled = performanceHudConfig.batteryTemperatureWarningEnabled, + onToggle = { + onPerformanceHudConfigChanged( + performanceHudConfig.copy(batteryTemperatureWarningEnabled = !performanceHudConfig.batteryTemperatureWarningEnabled), + ) + }, + accentColor = accentColor, + ) + if (performanceHudConfig.batteryTemperatureWarningEnabled) + { + QuickMenuAdjustmentRow( + title = stringResource(R.string.performance_hud_battery_temp_limit), + valueText = "${(performanceHudConfig.batteryTemperatureWarningLimit * 100f).roundToInt()} °C", + progress = normalizedProgress(performanceHudConfig.batteryTemperatureWarningLimit, 0f, 1f), + onDecrease = { + onPerformanceHudConfigChanged( + performanceHudConfig.copy( + batteryTemperatureWarningLimit = (performanceHudConfig.batteryTemperatureWarningLimit - 0.05f).coerceIn(0f, 1f), + ), + ) + }, + onIncrease = { + onPerformanceHudConfigChanged( + performanceHudConfig.copy( + batteryTemperatureWarningLimit = (performanceHudConfig.batteryTemperatureWarningLimit + 0.05f).coerceIn(0f, 1f), + ), + ) + }, + accentColor = accentColor, + ) + } QuickMenuToggleRow( title = stringResource(R.string.performance_hud_power_draw), enabled = performanceHudConfig.showPowerDraw, diff --git a/app/src/main/java/app/gamenative/ui/data/PerformanceHudConfig.kt b/app/src/main/java/app/gamenative/ui/data/PerformanceHudConfig.kt index 86f1c3a920..7ef497a5b2 100644 --- a/app/src/main/java/app/gamenative/ui/data/PerformanceHudConfig.kt +++ b/app/src/main/java/app/gamenative/ui/data/PerformanceHudConfig.kt @@ -25,9 +25,13 @@ data class PerformanceHudConfig( val showGpuUsage: Boolean = true, val showRamUsage: Boolean = true, val showBatteryLevel: Boolean = true, + val batteryLevelWarningLimit: Float = 0.1f, + val batteryLevelWarningEnabled: Boolean = false, val showPowerDraw: Boolean = true, val showBatteryRuntime: Boolean = false, val showBatteryTemperature: Boolean = false, + val batteryTemperatureWarningLimit: Float = 0.40F, + val batteryTemperatureWarningEnabled: Boolean = false, val showClockTime: Boolean = false, val showCpuTemperature: Boolean = true, val showGpuTemperature: Boolean = true, diff --git a/app/src/main/java/app/gamenative/ui/widget/PerformanceHudModels.kt b/app/src/main/java/app/gamenative/ui/widget/PerformanceHudModels.kt index 4e864327bf..cc8d3ac5ce 100644 --- a/app/src/main/java/app/gamenative/ui/widget/PerformanceHudModels.kt +++ b/app/src/main/java/app/gamenative/ui/widget/PerformanceHudModels.kt @@ -35,9 +35,11 @@ internal data class HudSnapshot( val gpu: String?, val ram: String, val battery: String?, + val batteryPercent: Int?, val power: String?, val runtime: String?, val batteryTemp: String?, + val batteryTempValue: Int?, val clock: String, val cpuTemp: String?, val gpuTemp: String?, diff --git a/app/src/main/java/app/gamenative/ui/widget/PerformanceHudView.kt b/app/src/main/java/app/gamenative/ui/widget/PerformanceHudView.kt index d9ea1a1773..7ca8cb7640 100644 --- a/app/src/main/java/app/gamenative/ui/widget/PerformanceHudView.kt +++ b/app/src/main/java/app/gamenative/ui/widget/PerformanceHudView.kt @@ -9,8 +9,10 @@ import android.graphics.Color import android.graphics.Paint import android.graphics.Path import android.graphics.Typeface +import android.graphics.drawable.ColorDrawable import android.graphics.drawable.GradientDrawable import android.os.BatteryManager +import android.os.Build import android.text.TextUtils import android.text.format.DateFormat import android.util.TypedValue @@ -40,6 +42,13 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import android.hardware.BatteryState +import android.view.InputDevice +import androidx.annotation.RequiresApi +import kotlin.math.roundToInt +import android.media.AudioManager +import android.media.ToneGenerator + /** * Lightweight floating HUD shown above the in-game surface. @@ -109,6 +118,21 @@ class PerformanceHudView( private val gpuTempMetric = createMetricViews(MetricId.GPU_TEMP, 0xFFBDBDBD.toInt()) private val batteryTempMetric = createMetricViews(MetricId.BATTERY_TEMP, 0xFFBDBDBD.toInt()) + private var currentBackgroundColor = (backgroundDrawable as? GradientDrawable) + ?.color?.defaultColor ?: Color.BLACK + + private val backupBackgroundColor = currentBackgroundColor + private val batteryLevelBackgroundColor = Color.argb( + 102, + 128, + 0, + 0) + + private val batteryTempBackgroundColor = Color.argb( + 102, + 128, + 0, + 128) private val allMetrics = listOf( fpsMetric, cpuMetric, @@ -137,6 +161,16 @@ class PerformanceHudView( private var thermalZonesCache: List>? = null private var gpuUsageDiscoveryLogged = false private var gpuUsagePathsCache: List? = null + + private var toneGenerator: ToneGenerator? = null + + private fun getToneGenerator(): ToneGenerator = + toneGenerator ?: ToneGenerator(AudioManager.STREAM_ALARM, 100).also { toneGenerator = it } + + private fun releaseToneGenerator() { + toneGenerator?.release() + toneGenerator = null + } init { background = backgroundDrawable @@ -195,6 +229,7 @@ class PerformanceHudView( override fun onDetachedFromWindow() { stopUpdates() + releaseToneGenerator() super.onDetachedFromWindow() } @@ -216,6 +251,33 @@ class PerformanceHudView( collectSnapshot(currentFps) } renderSnapshot(snapshot) + + val levelWarning = snapshot.batteryPercent != null && config.batteryLevelWarningEnabled && + snapshot.batteryPercent < (config.batteryLevelWarningLimit * 100) + + val tempWarning = snapshot.batteryTempValue != null && config.batteryTemperatureWarningEnabled && + snapshot.batteryTempValue > (config.batteryTemperatureWarningLimit * 100) + + if (levelWarning) { + getToneGenerator().startTone(ToneGenerator.TONE_PROP_ACK, 150) + } + if (tempWarning) { + getToneGenerator().startTone(ToneGenerator.TONE_CDMA_PIP, 150) + } + + val warningColor = when { + tempWarning -> batteryTempBackgroundColor + levelWarning -> batteryLevelBackgroundColor + else -> null + } + + currentBackgroundColor = if (warningColor != null) { + if (currentBackgroundColor == backupBackgroundColor) warningColor else backupBackgroundColor + } else { + backupBackgroundColor + } + backgroundDrawable.setColor(currentBackgroundColor) + delay(UPDATE_INTERVAL_MS) } } @@ -321,11 +383,13 @@ class PerformanceHudView( gpu = gpuPercent?.let { "GPU $it%" }, ram = "RAM ${readUsedRamText()}", battery = batterySnapshot.percent?.let { "BAT $it%" }, + batteryPercent = batterySnapshot.percent, power = batterySnapshot.powerWatts?.let { watts -> String.format(Locale.US, "PWR %.1fW", watts) }, runtime = batterySnapshot.runtimeText, batteryTemp = batterySnapshot.temperatureC?.let { "BAT TEMP ${it}°C" }, + batteryTempValue = batterySnapshot.temperatureC ?: 0, clock = readClockText(), cpuTemp = readCpuTempC()?.let { "CPU TEMP ${it}°C" }, gpuTemp = readGpuTempC()?.let { "GPU TEMP ${it}°C" }, diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 6a9149e05b..902578fc86 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -279,6 +279,10 @@ Klokkeslæt CPU-temperatur GPU-temperatur + Batteriniveau-advarsel + Batteriniveau-grænse + Batteritemperatur-advarsel + Batteritemperatur-grænse Touchpad-hjælp Skjul on-screen-kontroller med controller Skjul automatisk on-screen-kontroller når en fysisk controller er tilsluttet diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 9bdbc48e14..947f8cfacc 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -343,6 +343,10 @@ Uhrzeit CPU-Temperatur GPU-Temperatur + Batteriestand Warnung + Batteriestand Limit + Akkutemperatur-Warnung + Batterie Temp Limit Touchpad-Hilfe On-Screen-Controller bei Gamepad ausblenden On-Screen-Steuerung automatisch ausblenden, wenn ein physischer Controller verbunden ist diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 088fd5047a..f4672366fa 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -361,6 +361,10 @@ Hora Temperatura de CPU Temperatura de GPU + Aviso de nivel de batería + Límite nivel batería + Aviso temp. batería + Límite temp. batería Ayuda del touchpad Ocultar controles táctiles al usar mando Oculta automáticamente los controles en pantalla cuando se conecta un mando físico. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 5fd128d2a6..44d55b632d 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -350,6 +350,10 @@ Heure Température CPU Température GPU + Alerte niveau batterie + Limite niveau batterie + Alerte temp. batterie + Limite temp. batterie Aide du pavé tactile Masquer les contrôles à l\'écran avec manette Masquer automatiquement les contrôles à l\'écran lorsqu\'un contrôleur physique est connecté diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 91548c544d..e161e11043 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -350,6 +350,10 @@ Ora Temperatura CPU Temperatura GPU + Avviso livello batteria + Limite livello batteria + Avviso temp. batteria + Limite temp. batteria Aiuto Touchpad Nascondi controlli a schermo con controller Nascondi automaticamente i controlli a schermo quando è connesso un controller fisico diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index e026b6a855..eb07a8d5a3 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -338,6 +338,10 @@ 時計の時間 CPU温度 GPU温度 + バッテリー残量警告 + バッテリー残量制限 + バッテリー温度警告 + バッテリー温度制限 タッチパッドのヘルプ コントローラーを使用して画面上のコントロールを非表示にする 物理コントローラーが接続されている場合、画面上のコントロールを自動的に非表示にします diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index dd77ad66b7..17e5d185f7 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -356,6 +356,10 @@ 시계 CPU 온도 GPU 온도 + 배터리 잔량 경고 + 배터리 잔량 제한 + 배터리 온도 경고 + 배터리 온도 제한 터치패드 도움말 컨트롤러 연결 시 화면 컨트롤 숨기기 물리 컨트롤러가 연결되면 화면 컨트롤을 자동으로 숨깁니다 diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index b4724da797..592dffdc9f 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -358,6 +358,10 @@ Czas Temperatura CPU Temperatura GPU + Ostrz. poziomu baterii + Limit poziomu baterii + Ostrz. temp. baterii + Limit temp. baterii Pomoc touchpada Ukryj kontroler ekranowy przy podłączonym kontrolerze Automatycznie ukrywa kontroler ekranowy, gdy podłączony jest kontroler fizyczny diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index d2e3448ef3..c9bf9a24ea 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -279,6 +279,10 @@ Hora Temperatura da CPU Temperatura da GPU + Aviso do nível da bateria + Limite do nível da bateria + Aviso de temperatura da bateria + Limite de temperatura da bateria Ajuda Touchpad Ocultar controles on-screen com controle Ocultar automaticamente controles on-screen quando um controle físico estiver conectado diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 0e02bc5009..931adbc12d 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -348,6 +348,10 @@ Ora Temperatura CPU Temperatura GPU + Avert. nivel baterie + Limită nivel baterie + Avert. temp. baterie + Limită temp. baterie Ajutor touchpad Ascunde controalele pe ecran când există controller Ascunde automat controalele pe ecran când un controller fizic este conectat diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 5acdf6d8a7..046b2e5a33 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -948,6 +948,10 @@ https://gamenative.app Время Температура CPU Температура GPU + Предупр. об уровне батареи + Лимит уровня батареи + Предупр. о темп. батареи + Лимит темп. батареи Быстрые предустановки 1 – 0 A – Z diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 37ab892d42..48f0fcba20 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -345,6 +345,10 @@ Час Температура CPU Температура GPU + Попер. рівень батареї + Ліміт рівня батареї + Попер. темп. батареї + Ліміт темп. батареї Довідка сенсорної панелі Приховувати екранні елементи з контролером Автоматично приховувати екранні елементи керування, коли під\'єднано фізичний контролер diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index eacb996107..711dcd6193 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -341,6 +341,10 @@ 时间 CPU 温度 GPU 温度 + 电量警告 + 电量限制 + 电池温度警告 + 电池温度限制 触摸板支持 使用控制器时隐藏屏幕控制器 当实体控制器连接时自动隐藏屏幕控制器 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index eaf22f48e1..f05022fbfa 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -341,6 +341,10 @@ 時間 CPU 溫度 GPU 溫度 + 電量警告 + 電量限制 + 電池溫度警告 + 電池溫度限制 觸摸板支援 使用控制器時隱藏螢幕控制器 當實體控制器連接時自動隱藏螢幕控制器 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bf6b2cb92e..cbf7f1be67 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -349,6 +349,10 @@ Clock time CPU temperature GPU temperature + Battery level warning + Battery level limit + Battery temp warning + Battery temp limit Touchpad Help Hide on-screen controls with controller Automatically hide on-screen controls when a physical controller is connected