[android] add power consumption and battery status overlay (#22)

- adds the option to show power draw in amperes
- shows if the battery is charging

Signed-off-by: Aleksandr Popovich <alekpopo@pm.me>

Co-authored-by: Aleksandr Popovich <alekpopo@pm.me>
Reviewed-on: https://git.bixed.xyz/Bix/eden/pulls/22
This commit is contained in:
crueter 2025-07-08 21:12:02 +00:00
parent 9d60900ecf
commit 347d54bc26
10 changed files with 156 additions and 69 deletions

View file

@ -58,7 +58,9 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
SHOW_APP_RAM_USAGE("show_app_ram_usage"), SHOW_APP_RAM_USAGE("show_app_ram_usage"),
SHOW_SYSTEM_RAM_USAGE("show_system_ram_usage"), SHOW_SYSTEM_RAM_USAGE("show_system_ram_usage"),
SHOW_BAT_TEMPERATURE("show_bat_temperature"), SHOW_BAT_TEMPERATURE("show_bat_temperature"),
SHOW_POWER_INFO("show_power_info"),
SHOW_SHADERS_BUILDING("show_shaders_building"), SHOW_SHADERS_BUILDING("show_shaders_building"),
DEBUG_FLUSH_BY_LINE("flush_lines"), DEBUG_FLUSH_BY_LINE("flush_lines"),
USE_LRU_CACHE("use_lru_cache"),; USE_LRU_CACHE("use_lru_cache"),;

View file

@ -42,7 +42,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
FAST_CPU_TIME("fast_cpu_time"), FAST_CPU_TIME("fast_cpu_time"),
CPU_TICKS("cpu_ticks"), CPU_TICKS("cpu_ticks"),
FAST_GPU_TIME("fast_gpu_time"), FAST_GPU_TIME("fast_gpu_time"),
BAT_TEMPERATURE_UNIT("bat_temperature_unit"),
CABINET_APPLET("cabinet_applet_mode"), CABINET_APPLET("cabinet_applet_mode"),
CONTROLLER_APPLET("controller_applet_mode"), CONTROLLER_APPLET("controller_applet_mode"),
DATA_ERASE_APPLET("data_erase_applet_mode"), DATA_ERASE_APPLET("data_erase_applet_mode"),

View file

@ -443,6 +443,21 @@ abstract class SettingsItem(
descriptionId = R.string.show_bat_temperature_description descriptionId = R.string.show_bat_temperature_description
) )
) )
put(
SingleChoiceSetting(
IntSetting.BAT_TEMPERATURE_UNIT,
R.string.bat_temperature_unit,
choicesId = R.array.temperatureUnitEntries,
valuesId = R.array.temperatureUnitValues
)
)
put(
SwitchSetting(
BooleanSetting.SHOW_POWER_INFO,
R.string.show_power_info,
descriptionId = R.string.show_power_info_description
)
)
put( put(
SwitchSetting( SwitchSetting(
BooleanSetting.SHOW_SHADERS_BUILDING, BooleanSetting.SHOW_SHADERS_BUILDING,

View file

@ -260,6 +260,8 @@ class SettingsFragmentPresenter(
add(BooleanSetting.SHOW_APP_RAM_USAGE.key) add(BooleanSetting.SHOW_APP_RAM_USAGE.key)
add(BooleanSetting.SHOW_SYSTEM_RAM_USAGE.key) add(BooleanSetting.SHOW_SYSTEM_RAM_USAGE.key)
add(BooleanSetting.SHOW_BAT_TEMPERATURE.key) add(BooleanSetting.SHOW_BAT_TEMPERATURE.key)
add(IntSetting.BAT_TEMPERATURE_UNIT.key)
add(BooleanSetting.SHOW_POWER_INFO.key)
add(BooleanSetting.SHOW_SHADERS_BUILDING.key) add(BooleanSetting.SHOW_SHADERS_BUILDING.key)
} }
} }

View file

@ -17,6 +17,7 @@ import android.content.pm.ActivityInfo
import android.content.res.Configuration import android.content.res.Configuration
import android.net.Uri import android.net.Uri
import android.os.BatteryManager import android.os.BatteryManager
import android.os.BatteryManager.*
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
@ -574,12 +575,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
if (emulationViewModel.emulationStarted.value && if (emulationViewModel.emulationStarted.value &&
!emulationViewModel.isEmulationStopping.value !emulationViewModel.isEmulationStopping.value
) { ) {
val needsGlobal = NativeConfig.isPerGameConfigLoaded()
sb.setLength(0) sb.setLength(0)
val perfStats = NativeLibrary.getPerfStats() val perfStats = NativeLibrary.getPerfStats()
val actualFps = perfStats[FPS] val actualFps = perfStats[FPS]
if (BooleanSetting.SHOW_FPS.getBoolean(NativeConfig.isPerGameConfigLoaded())) { if (BooleanSetting.SHOW_FPS.getBoolean(needsGlobal)) {
val enableFrameInterpolation = val enableFrameInterpolation =
BooleanSetting.FRAME_INTERPOLATION.getBoolean() BooleanSetting.FRAME_INTERPOLATION.getBoolean()
// val enableFrameSkipping = BooleanSetting.FRAME_SKIPPING.getBoolean() // val enableFrameSkipping = BooleanSetting.FRAME_SKIPPING.getBoolean()
@ -597,7 +599,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
sb.append(fpsText) sb.append(fpsText)
} }
if (BooleanSetting.SHOW_FRAMETIME.getBoolean(NativeConfig.isPerGameConfigLoaded())) { if (BooleanSetting.SHOW_FRAMETIME.getBoolean(needsGlobal)) {
if (sb.isNotEmpty()) sb.append(" | ") if (sb.isNotEmpty()) sb.append(" | ")
sb.append( sb.append(
String.format( String.format(
@ -607,13 +609,14 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
) )
} }
if (BooleanSetting.SHOW_APP_RAM_USAGE.getBoolean(NativeConfig.isPerGameConfigLoaded())) { if (BooleanSetting.SHOW_APP_RAM_USAGE.getBoolean(needsGlobal)) {
if (sb.isNotEmpty()) sb.append(" | ") if (sb.isNotEmpty()) sb.append(" | ")
val appRamUsage = File("/proc/self/statm").readLines()[0].split(' ')[1].toLong() * 4096 / 1000000 val appRamUsage =
File("/proc/self/statm").readLines()[0].split(' ')[1].toLong() * 4096 / 1000000
sb.append(getString(R.string.process_ram, appRamUsage)) sb.append(getString(R.string.process_ram, appRamUsage))
} }
if (BooleanSetting.SHOW_SYSTEM_RAM_USAGE.getBoolean(NativeConfig.isPerGameConfigLoaded())) { if (BooleanSetting.SHOW_SYSTEM_RAM_USAGE.getBoolean(needsGlobal)) {
if (sb.isNotEmpty()) sb.append(" | ") if (sb.isNotEmpty()) sb.append(" | ")
context?.let { ctx -> context?.let { ctx ->
val activityManager = val activityManager =
@ -625,16 +628,35 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
} }
} }
if (BooleanSetting.SHOW_BAT_TEMPERATURE.getBoolean(NativeConfig.isPerGameConfigLoaded())) { if (BooleanSetting.SHOW_BAT_TEMPERATURE.getBoolean(needsGlobal)) {
if (sb.isNotEmpty()) sb.append(" | ") if (sb.isNotEmpty()) sb.append(" | ")
val batteryTemp = getBatteryTemperature() val batteryTemp = getBatteryTemperature()
val tempF = celsiusToFahrenheit(batteryTemp) when (IntSetting.BAT_TEMPERATURE_UNIT.getInt(needsGlobal)) {
sb.append(String.format("%.1f°C/%.1f°F", batteryTemp, tempF)) 0 -> sb.append(String.format("%.1f°C", batteryTemp))
1 -> sb.append(String.format("%.1f°F", celsiusToFahrenheit(batteryTemp)))
}
}
if (BooleanSetting.SHOW_POWER_INFO.getBoolean(needsGlobal)) {
if (sb.isNotEmpty()) sb.append(" | ")
val battery: BatteryManager =
requireContext().getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val capacity = battery.getIntProperty(BATTERY_PROPERTY_CAPACITY)
val nowUAmps = battery.getIntProperty(BATTERY_PROPERTY_CURRENT_NOW)
sb.append(String.format("%.1fA (%d%%)", nowUAmps / 1000000.0, capacity))
if (battery.isCharging || nowUAmps > 0.0) {
sb.append(" ${getString(R.string.charging)}")
}
} }
val shadersBuilding = NativeLibrary.getShadersBuilding() val shadersBuilding = NativeLibrary.getShadersBuilding()
if (BooleanSetting.SHOW_SHADERS_BUILDING.getBoolean(NativeConfig.isPerGameConfigLoaded()) && shadersBuilding != 0) { if (BooleanSetting.SHOW_SHADERS_BUILDING.getBoolean(needsGlobal) && shadersBuilding != 0) {
if (sb.isNotEmpty()) sb.append(" | ") if (sb.isNotEmpty()) sb.append(" | ")
val prefix = getString(R.string.shaders_prefix) val prefix = getString(R.string.shaders_prefix)
@ -642,7 +664,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
sb.append(String.format("$prefix %d $suffix", shadersBuilding)) sb.append(String.format("$prefix %d $suffix", shadersBuilding))
} }
if (BooleanSetting.PERF_OVERLAY_BACKGROUND.getBoolean(NativeConfig.isPerGameConfigLoaded())) { if (BooleanSetting.PERF_OVERLAY_BACKGROUND.getBoolean(needsGlobal)) {
binding.showStatsOverlayText.setBackgroundResource(R.color.yuzu_transparent_black) binding.showStatsOverlayText.setBackgroundResource(R.color.yuzu_transparent_black)
} else { } else {
binding.showStatsOverlayText.setBackgroundResource(0) binding.showStatsOverlayText.setBackgroundResource(0)

View file

@ -9,6 +9,7 @@
#include <common/settings_common.h> #include <common/settings_common.h>
#include "common/common_types.h" #include "common/common_types.h"
#include "common/settings_setting.h" #include "common/settings_setting.h"
#include "common/settings_enums.h"
namespace AndroidSettings { namespace AndroidSettings {
@ -80,7 +81,8 @@ namespace AndroidSettings {
true}; true};
Settings::Setting<bool> perf_overlay_background{linkage, false, "perf_overlay_background", Settings::Setting<bool> perf_overlay_background{linkage, false, "perf_overlay_background",
Settings::Category::Overlay, Settings::Category::Overlay,
Settings::Specialization::Default, true, true, Settings::Specialization::Default, true,
true,
&show_performance_overlay}; &show_performance_overlay};
Settings::Setting<s32> perf_overlay_position{linkage, 0, "perf_overlay_position", Settings::Setting<s32> perf_overlay_position{linkage, 0, "perf_overlay_position",
Settings::Category::Overlay, Settings::Category::Overlay,
@ -107,10 +109,23 @@ namespace AndroidSettings {
Settings::Category::Overlay, Settings::Category::Overlay,
Settings::Specialization::Default, true, true, Settings::Specialization::Default, true, true,
&show_performance_overlay}; &show_performance_overlay};
Settings::Setting<Settings::TemperatureUnits> bat_temperature_unit{linkage,
Settings::TemperatureUnits::Celsius,
"bat_temperature_unit",
Settings::Category::Overlay,
Settings::Specialization::Default,
true, true,
&show_bat_temperature};
Settings::Setting<bool> show_power_info{linkage, false, "show_power_info",
Settings::Category::Overlay,
Settings::Specialization::Default, true, true,
&show_performance_overlay};
Settings::Setting<bool> show_shaders_building{linkage, true, "show_shaders_building", Settings::Setting<bool> show_shaders_building{linkage, true, "show_shaders_building",
Settings::Category::Overlay, Settings::Category::Overlay,
Settings::Specialization::Default, true, true, Settings::Specialization::Default, true, true,
&show_performance_overlay}; &show_performance_overlay};
Settings::Setting<bool> show_input_overlay{linkage, true, "show_input_overlay", Settings::Setting<bool> show_input_overlay{linkage, true, "show_input_overlay",
Settings::Category::Overlay}; Settings::Category::Overlay};
Settings::Setting<bool> touchscreen{linkage, true, "touchscreen", Settings::Setting<bool> touchscreen{linkage, true, "touchscreen",
@ -127,12 +142,12 @@ namespace AndroidSettings {
Settings::Setting<bool> show_device_model{linkage, true, "show_device_model", Settings::Setting<bool> show_device_model{linkage, true, "show_device_model",
Settings::Category::Overlay, Settings::Category::Overlay,
Settings::Specialization::Default, true, true, Settings::Specialization::Default, true, true,
&show_soc_overlay}; &show_performance_overlay};
Settings::Setting<bool> show_gpu_model{linkage, true, "show_gpu_model", Settings::Setting<bool> show_gpu_model{linkage, true, "show_gpu_model",
Settings::Category::Overlay, Settings::Category::Overlay,
Settings::Specialization::Default, true, true, Settings::Specialization::Default, true, true,
&show_soc_overlay}; &show_performance_overlay};
Settings::Setting<bool> show_soc_model{linkage, true, "show_soc_model", Settings::Setting<bool> show_soc_model{linkage, true, "show_soc_model",
Settings::Category::Overlay, Settings::Category::Overlay,
@ -142,11 +157,12 @@ namespace AndroidSettings {
Settings::Setting<bool> show_fw_version{linkage, true, "show_firmware_version", Settings::Setting<bool> show_fw_version{linkage, true, "show_firmware_version",
Settings::Category::Overlay, Settings::Category::Overlay,
Settings::Specialization::Default, true, true, Settings::Specialization::Default, true, true,
&show_soc_overlay}; &show_performance_overlay};
Settings::Setting<bool> soc_overlay_background{linkage, false, "soc_overlay_background", Settings::Setting<bool> soc_overlay_background{linkage, false, "soc_overlay_background",
Settings::Category::Overlay, Settings::Category::Overlay,
Settings::Specialization::Default, true, true, Settings::Specialization::Default, true,
true,
&show_soc_overlay}; &show_soc_overlay};
Settings::Setting<s32> soc_overlay_position{linkage, 2, "soc_overlay_position", Settings::Setting<s32> soc_overlay_position{linkage, 2, "soc_overlay_position",
Settings::Category::Overlay, Settings::Category::Overlay,

View file

@ -14,6 +14,8 @@
<string name="shaders_prefix">Зграда</string> <string name="shaders_prefix">Зграда</string>
<string name="shaders_suffix">Схадер (с)</string> <string name="shaders_suffix">Схадер (с)</string>
<string name="system_info_label">Систем:</string> <string name="system_info_label">Систем:</string>
<string name="charging">(Пуњење)</string>
<string name="show_stats_overlay">Покажи Статистика перформанси Статистика</string> <string name="show_stats_overlay">Покажи Статистика перформанси Статистика</string>
<string name="stats_overlay_customization">Прилагођавање</string> <string name="stats_overlay_customization">Прилагођавање</string>
<string name="stats_overlay_items">Видљивост</string> <string name="stats_overlay_items">Видљивост</string>
@ -31,7 +33,10 @@
<string name="show_system_ram_usage">Прикажи употребу система меморије</string> <string name="show_system_ram_usage">Прикажи употребу система меморије</string>
<string name="show_system_ram_usage_description">Прикажите износ РАМ-а који користи систем</string> <string name="show_system_ram_usage_description">Прикажите износ РАМ-а који користи систем</string>
<string name="show_bat_temperature">Прикажи температуру батерије</string> <string name="show_bat_temperature">Прикажи температуру батерије</string>
<string name="show_bat_temperature_description">Прикажи тренутну температуру батерије у Целзијусу и Фахренхеиту</string> <string name="show_bat_temperature_description">Прикажи тренутну температуру батерије</string>
<string name="bat_temperature_unit">Јединице за температуру батерије</string>
<string name="show_power_info">Прикажи информације о батерији</string>
<string name="show_power_info_description">Приказ тренутне потрошње енергије и преостали капацитет батерије</string>
<string name="show_shaders_building">Прикажи Схадерс Буилдинг</string> <string name="show_shaders_building">Прикажи Схадерс Буилдинг</string>
<string name="show_shaders_building_description">Прикажи тренутни број саграђених Схадера</string> <string name="show_shaders_building_description">Прикажи тренутни број саграђених Схадера</string>
<string name="overlay_position">Положај прекривања</string> <string name="overlay_position">Положај прекривања</string>
@ -791,6 +796,10 @@
<string name="gpu_medium">Средња (256)</string> <string name="gpu_medium">Средња (256)</string>
<string name="gpu_high">Висок (512)</string> <string name="gpu_high">Висок (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Целзијус</string>
<string name="temperature_fahrenheit">Фаренхајт</string>
<!-- Language Names --> <!-- Language Names -->
<string name="language_japanese" translatable="false">日本語</string> <string name="language_japanese" translatable="false">日本語</string>
<string name="language_english" translatable="false">English</string> <string name="language_english" translatable="false">English</string>

View file

@ -471,4 +471,14 @@
<item>1</item> <item>1</item>
<item>2</item> <item>2</item>
</integer-array> </integer-array>
<string-array name="temperatureUnitEntries">
<item>@string/temperature_celsius</item>
<item>@string/temperature_fahrenheit</item>
</string-array>
<integer-array name="temperatureUnitValues">
<item>0</item>
<item>1</item>
</integer-array>
</resources> </resources>

View file

@ -14,6 +14,8 @@
<string name="process_ram">Process RAM: %1$d MB</string> <string name="process_ram">Process RAM: %1$d MB</string>
<string name="shaders_prefix">Building</string> <string name="shaders_prefix">Building</string>
<string name="shaders_suffix">Shader(s)</string> <string name="shaders_suffix">Shader(s)</string>
<string name="charging">(Charging)</string>
<string name="system_info_label">System:</string> <string name="system_info_label">System:</string>
<string name="show_stats_overlay">Show Performance Stats Overlay</string> <string name="show_stats_overlay">Show Performance Stats Overlay</string>
<string name="stats_overlay_customization">Customization</string> <string name="stats_overlay_customization">Customization</string>
@ -32,7 +34,10 @@
<string name="show_system_ram_usage">Show System Memory Usage</string> <string name="show_system_ram_usage">Show System Memory Usage</string>
<string name="show_system_ram_usage_description">Display the amount of RAM used by the system</string> <string name="show_system_ram_usage_description">Display the amount of RAM used by the system</string>
<string name="show_bat_temperature">Show Battery Temperature</string> <string name="show_bat_temperature">Show Battery Temperature</string>
<string name="show_bat_temperature_description">Display current Battery temperature in Celsius and Fahrenheit</string> <string name="show_bat_temperature_description">Display current battery temperature</string>
<string name="bat_temperature_unit">Battery Temperature Units</string>
<string name="show_power_info">Show Battery Info</string>
<string name="show_power_info_description">Display current power draw and remaining capacity on battery</string>
<string name="show_shaders_building">Show Shaders Building</string> <string name="show_shaders_building">Show Shaders Building</string>
<string name="show_shaders_building_description">Display current number of shaders being built</string> <string name="show_shaders_building_description">Display current number of shaders being built</string>
<string name="overlay_position">Overlay Position</string> <string name="overlay_position">Overlay Position</string>
@ -818,6 +823,10 @@
<string name="gpu_medium">Medium (256)</string> <string name="gpu_medium">Medium (256)</string>
<string name="gpu_high">High (512)</string> <string name="gpu_high">High (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
<!-- Language Names --> <!-- Language Names -->
<string name="language_japanese" translatable="false">日本語</string> <string name="language_japanese" translatable="false">日本語</string>
<string name="language_english" translatable="false">English</string> <string name="language_english" translatable="false">English</string>

View file

@ -178,6 +178,8 @@ ENUM(SpirvOptimizeMode, Never, OnLoad, Always);
ENUM(GpuOverclock, Low, Medium, High) ENUM(GpuOverclock, Low, Medium, High)
ENUM(TemperatureUnits, Celsius, Fahrenheit)
template <typename Type> template <typename Type>
inline std::string CanonicalizeEnum(Type id) { inline std::string CanonicalizeEnum(Type id) {
const auto group = EnumMetadata<Type>::Canonicalizations(); const auto group = EnumMetadata<Type>::Canonicalizations();