diff options
| author | visarhoxha <vhoxha08@gmail.com> | 2026-09-24 00:30:54 +0200 |
|---|---|---|
| committer | visarhoxha <vhoxha08@gmail.com> | 2026-10-19 12:22:32 +0200 |
| commit | f0ef80016182ef0a79fd8b100b35ed906f954044 (patch) | |
| tree | 7f2f1cca208245bc270bd4abfb72e84ca0ca1b3e /Source/Android/jni/HotkeyScheduler.cpp | |
| parent | 301182532074dae57a4b23ff508308485c122ea8 (diff) | |
Android: Avoid constant hotkey polling to save battery
Only poll for hotkeys while EmulationActivity is resumed and at least
one supported hotkey is mapped. Otherwise the scheduler thread waits on
an event instead of polling.
Diffstat (limited to 'Source/Android/jni/HotkeyScheduler.cpp')
| -rw-r--r-- | Source/Android/jni/HotkeyScheduler.cpp | 84 |
1 files changed, 75 insertions, 9 deletions
diff --git a/Source/Android/jni/HotkeyScheduler.cpp b/Source/Android/jni/HotkeyScheduler.cpp index bb360d1e2a..85d981f755 100644 --- a/Source/Android/jni/HotkeyScheduler.cpp +++ b/Source/Android/jni/HotkeyScheduler.cpp @@ -3,6 +3,7 @@ #include "jni/HotkeyScheduler.h" +#include <chrono> #include <cmath> #include <jni.h> #include <thread> @@ -13,6 +14,7 @@ #include "AudioCommon/AudioCommon.h" #include "Common/CommonTypes.h" #include "Common/Config/Config.h" +#include "Common/Event.h" #include "Common/Flag.h" #include "Common/Thread.h" #include "Core/Config/GraphicsSettings.h" @@ -22,6 +24,8 @@ #include "Core/State.h" #include "Core/System.h" #include "InputCommon/ControlReference/ControlReference.h" +#include "InputCommon/ControllerEmu/Control/Control.h" +#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" #include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/VideoConfig.h" @@ -34,6 +38,8 @@ constexpr int POLL_INTERVAL_MS = 5; std::thread s_thread; Common::Flag s_stop_requested; +Common::Flag s_any_hotkey_set; +Common::Event s_wakeup; int s_state_slot = 1; @@ -42,6 +48,43 @@ bool IsHotkey(int id, bool held = false) return HotkeyManagerEmu::IsPressed(id, held); } +bool IsAnyHotkeySet() +{ + InputConfig* const config = HotkeyManagerEmu::GetConfig(); + if (config == nullptr || config->ControllersNeedToBeCreated()) + return false; + + auto* const hotkeys = static_cast<HotkeyManager*>(config->GetController(0)); + + for (const int hotkey : GetSupportedHotkeys()) + { + const int group = hotkeys->FindGroupByID(hotkey); + const int index = hotkeys->GetIndexForGroup(group, hotkey); + const auto* const control_group = + HotkeyManagerEmu::GetHotkeyGroup(static_cast<HotkeyGroup>(group)); + + if (!control_group->controls[index]->control_ref->GetExpression().empty()) + return true; + } + + return false; +} + +bool ShouldPoll() +{ + if (!s_any_hotkey_set.IsSet() || !HotkeyManagerEmu::IsEnabled()) + return false; + + return Core::GetState(Core::System::GetInstance()) != Core::State::Stopping; +} + +// Buttons already held when polling resumes must not count as new presses +void ConsumePendingPresses() +{ + for (const int hotkey : GetSupportedHotkeys()) + IsHotkey(hotkey); +} + void ShowVolumeOSD() { OSD::AddMessage( @@ -196,19 +239,24 @@ void Run() { Common::SetCurrentThreadName("HotkeyScheduler"); + bool was_polling = false; + while (!s_stop_requested.IsSet()) { - Common::SleepCurrentThread(POLL_INTERVAL_MS); + if (!ShouldPoll()) + { + was_polling = false; + s_wakeup.Wait(); + continue; + } - ControllerInterface::SetCurrentInputChannel(ciface::InputChannel::Host); - g_controller_interface.UpdateInput(); + s_wakeup.WaitFor(std::chrono::milliseconds(POLL_INTERVAL_MS)); - if (!HotkeyManagerEmu::IsEnabled()) - continue; + if (s_stop_requested.IsSet()) + break; - Core::System& system = Core::System::GetInstance(); - if (Core::GetState(system) == Core::State::Stopping) - continue; + ControllerInterface::SetCurrentInputChannel(ciface::InputChannel::Host); + g_controller_interface.UpdateInput(); ControlReference::SetInputGate(true); @@ -217,6 +265,15 @@ void Run() HotkeyManagerEmu::GetStatus(false); HotkeyManagerEmu::GetStatus(true); + if (!was_polling) + { + ConsumePendingPresses(); + was_polling = true; + continue; + } + + Core::System& system = Core::System::GetInstance(); + HandleGeneralHotkeys(); HandleEmulationSpeedHotkeys(); HandleVolumeHotkeys(system); @@ -231,9 +288,10 @@ void Start() if (s_thread.joinable()) return; - HotkeyManagerEmu::Enable(true); s_state_slot = 1; + s_any_hotkey_set.Set(IsAnyHotkeySet()); s_stop_requested.Clear(); + s_wakeup.Reset(); s_thread = std::thread(Run); } @@ -243,11 +301,18 @@ void Stop() return; s_stop_requested.Set(); + s_wakeup.Set(); s_thread.join(); Core::SetIsThrottlerTempDisabled(false); } +void RefreshActiveHotkeys() +{ + s_any_hotkey_set.Set(IsAnyHotkeySet()); + s_wakeup.Set(); +} + const std::vector<int>& GetSupportedHotkeys() { static const std::vector<int> supported = [] { @@ -294,5 +359,6 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_features_input_model_Hotke JNIEnv*, jclass, jboolean enabled) { HotkeyManagerEmu::Enable(enabled == JNI_TRUE); + HotkeyScheduler::RefreshActiveHotkeys(); } } |
