aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/hle/service/am/lifecycle_manager.h
diff options
context:
space:
mode:
authoryuzubot <[email protected]>2024-03-04 13:02:54 +0000
committeryuzubot <[email protected]>2024-03-04 13:02:54 +0000
commit537296095ab24eddcb196b5ef98004f91de9c8c2 (patch)
treee75e9e2441dc3f8657cc42f2daaae08737949c2b /src/core/hle/service/am/lifecycle_manager.h
parent2ddac7b02b660bbc7bdfe4fef240699df6d52e64 (diff)
downloadyuzu-mainline-master.tar.gz
yuzu-mainline-master.zip
"Merge Tagged PR 13018"HEADmaster
Diffstat (limited to 'src/core/hle/service/am/lifecycle_manager.h')
-rw-r--r--src/core/hle/service/am/lifecycle_manager.h183
1 files changed, 183 insertions, 0 deletions
diff --git a/src/core/hle/service/am/lifecycle_manager.h b/src/core/hle/service/am/lifecycle_manager.h
new file mode 100644
index 000000000..7c70434a1
--- /dev/null
+++ b/src/core/hle/service/am/lifecycle_manager.h
@@ -0,0 +1,183 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <list>
+
+#include "core/hle/service/am/am_types.h"
+#include "core/hle/service/os/event.h"
+
+namespace Core {
+class System;
+}
+
+namespace Service::AM {
+
+enum class ActivityState : u32 {
+ ForegroundVisible = 0,
+ ForegroundObscured = 1,
+ BackgroundVisible = 2,
+ BackgroundObscured = 3,
+};
+
+enum class FocusHandlingMode : u32 {
+ AlwaysSuspend = 0,
+ SuspendHomeSleep = 1,
+ NoSuspend = 2,
+};
+
+enum class SuspendMode : u32 {
+ NoOverride = 0,
+ ForceResume = 1,
+ ForceSuspend = 2,
+};
+
+class LifecycleManager {
+public:
+ explicit LifecycleManager(Core::System& system, KernelHelpers::ServiceContext& context,
+ bool is_application);
+ ~LifecycleManager();
+
+public:
+ Event& GetSystemEvent();
+ Event& GetOperationModeChangedSystemEvent();
+
+public:
+ bool IsApplication() {
+ return m_is_application;
+ }
+
+ bool GetForcedSuspend() {
+ return m_forced_suspend;
+ }
+
+ bool GetExitRequested() {
+ return m_has_requested_exit;
+ }
+
+ ActivityState GetActivityState() {
+ return m_activity_state;
+ }
+
+ FocusState GetAndClearFocusState() {
+ m_acknowledged_focus_state = m_requested_focus_state;
+ return m_acknowledged_focus_state;
+ }
+
+ void SetFocusState(FocusState state) {
+ if (m_requested_focus_state != state) {
+ m_has_focus_state_changed = true;
+ }
+ m_requested_focus_state = state;
+ this->SignalSystemEventIfNeeded();
+ }
+
+ void RequestExit() {
+ m_has_requested_exit = true;
+ this->SignalSystemEventIfNeeded();
+ }
+
+ void RequestResumeNotification() {
+ // NOTE: this appears to be a bug in am.
+ // If an applet makes a concurrent request to receive resume notifications
+ // while it is being suspended, the first resume notification will be lost.
+ // This is not the case with other notification types.
+ if (m_resume_notification_enabled) {
+ m_has_resume = true;
+ }
+ }
+
+ void OnOperationAndPerformanceModeChanged();
+
+public:
+ void SetFocusStateChangedNotificationEnabled(bool enabled) {
+ m_focus_state_changed_notification_enabled = enabled;
+ this->SignalSystemEventIfNeeded();
+ }
+
+ void SetOperationModeChangedNotificationEnabled(bool enabled) {
+ m_operation_mode_changed_notification_enabled = enabled;
+ this->SignalSystemEventIfNeeded();
+ }
+
+ void SetPerformanceModeChangedNotificationEnabled(bool enabled) {
+ m_performance_mode_changed_notification_enabled = enabled;
+ this->SignalSystemEventIfNeeded();
+ }
+
+ void SetResumeNotificationEnabled(bool enabled) {
+ m_resume_notification_enabled = enabled;
+ }
+
+ void SetActivityState(ActivityState state) {
+ m_activity_state = state;
+ }
+
+ void SetSuspendMode(SuspendMode mode) {
+ m_suspend_mode = mode;
+ }
+
+ void SetForcedSuspend(bool enabled) {
+ m_forced_suspend = enabled;
+ }
+
+public:
+ void SetFocusHandlingMode(bool suspend);
+ void SetOutOfFocusSuspendingEnabled(bool enabled);
+ void RemoveForceResumeIfPossible();
+ bool IsRunnable() const;
+ bool UpdateRequestedFocusState();
+ void SignalSystemEventIfNeeded();
+
+public:
+ void PushUnorderedMessage(AppletMessage message);
+ bool PopMessage(AppletMessage* out_message);
+
+private:
+ FocusState GetFocusStateWhileForegroundObscured() const;
+ FocusState GetFocusStateWhileBackground(bool is_obscured) const;
+
+private:
+ AppletMessage PopMessageInOrderOfPriority();
+ bool ShouldSignalSystemEvent();
+
+private:
+ Event m_system_event;
+ Event m_operation_mode_changed_system_event;
+
+ std::list<AppletMessage> m_unordered_messages{};
+
+ bool m_is_application{};
+ bool m_focus_state_changed_notification_enabled{true};
+ bool m_operation_mode_changed_notification_enabled{true};
+ bool m_performance_mode_changed_notification_enabled{true};
+ bool m_resume_notification_enabled{};
+
+ bool m_requested_request_to_display_state{};
+ bool m_acknowledged_request_to_display_state{};
+ bool m_has_resume{};
+ bool m_has_focus_state_changed{true};
+ bool m_has_album_recording_saved{};
+ bool m_has_album_screen_shot_taken{};
+ bool m_has_auto_power_down{};
+ bool m_has_sleep_required_by_low_battery{};
+ bool m_has_sleep_required_by_high_temperature{};
+ bool m_has_sd_card_removed{};
+ bool m_has_performance_mode_changed{};
+ bool m_has_operation_mode_changed{};
+ bool m_has_requested_request_to_prepare_sleep{};
+ bool m_has_acknowledged_request_to_prepare_sleep{};
+ bool m_has_requested_exit{};
+ bool m_has_acknowledged_exit{};
+ bool m_applet_message_available{};
+
+ bool m_forced_suspend{};
+ FocusHandlingMode m_focus_handling_mode{FocusHandlingMode::SuspendHomeSleep};
+ ActivityState m_activity_state{ActivityState::ForegroundVisible};
+ SuspendMode m_suspend_mode{SuspendMode::NoOverride};
+ FocusState m_requested_focus_state{};
+ FocusState m_acknowledged_focus_state{};
+};
+
+} // namespace Service::AM