aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/hle/service/am/applet_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/am/applet_manager.cpp')
-rw-r--r--src/core/hle/service/am/applet_manager.cpp124
1 files changed, 41 insertions, 83 deletions
diff --git a/src/core/hle/service/am/applet_manager.cpp b/src/core/hle/service/am/applet_manager.cpp
index 2e109181d..c6b7ec8bb 100644
--- a/src/core/hle/service/am/applet_manager.cpp
+++ b/src/core/hle/service/am/applet_manager.cpp
@@ -13,6 +13,7 @@
#include "core/hle/service/am/frontend/applet_mii_edit_types.h"
#include "core/hle/service/am/frontend/applet_software_keyboard_types.h"
#include "core/hle/service/am/service/storage.h"
+#include "core/hle/service/am/window_system.h"
#include "hid_core/hid_types.h"
namespace Service::AM {
@@ -225,49 +226,46 @@ void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& chan
} // namespace
AppletManager::AppletManager(Core::System& system) : m_system(system) {}
-AppletManager::~AppletManager() {
- this->Reset();
-}
-
-void AppletManager::InsertApplet(std::shared_ptr<Applet> applet) {
- std::scoped_lock lk{m_lock};
+AppletManager::~AppletManager() = default;
- m_applets.emplace(applet->aruid, std::move(applet));
-}
-
-void AppletManager::TerminateAndRemoveApplet(AppletResourceUserId aruid) {
- std::shared_ptr<Applet> applet;
- bool should_stop = false;
+void AppletManager::CreateAndInsertByFrontendAppletParameters(
+ std::unique_ptr<Process> process, const FrontendAppletParameters& params) {
{
std::scoped_lock lk{m_lock};
+ m_pending_process = std::move(process);
+ m_pending_parameters = params;
+ }
+ m_cv.notify_all();
+}
- const auto it = m_applets.find(aruid);
- if (it == m_applets.end()) {
- return;
- }
-
- applet = it->second;
- m_applets.erase(it);
+void AppletManager::RequestExit() {
+ std::scoped_lock lk{m_lock};
+ if (m_window_system) {
+ m_window_system->OnExitRequested();
+ }
+}
- should_stop = m_applets.empty();
+void AppletManager::OperationModeChanged() {
+ std::scoped_lock lk{m_lock};
+ if (m_window_system) {
+ m_window_system->OnOperationModeChanged();
}
+}
- // Terminate process.
- applet->process->Terminate();
+void AppletManager::SetWindowSystem(WindowSystem* window_system) {
+ std::unique_lock lk{m_lock};
- // If there were no applets left, stop emulation.
- if (should_stop) {
- m_system.Exit();
+ m_window_system = window_system;
+ if (!m_window_system) {
+ return;
}
-}
-void AppletManager::CreateAndInsertByFrontendAppletParameters(
- AppletResourceUserId aruid, const FrontendAppletParameters& params) {
- // TODO: this should be run inside AM so that the events will have a parent process
- // TODO: have am create the guest process
- auto applet = std::make_shared<Applet>(m_system, std::make_unique<Process>(m_system));
+ m_cv.wait(lk, [&] { return m_pending_process != nullptr; });
+
+ const auto& params = m_pending_parameters;
+ auto applet = std::make_shared<Applet>(m_system, std::move(m_pending_process),
+ params.applet_id == AppletId::Application);
- applet->aruid = aruid;
applet->program_id = params.program_id;
applet->applet_id = params.applet_id;
applet->type = params.applet_type;
@@ -322,59 +320,19 @@ void AppletManager::CreateAndInsertByFrontendAppletParameters(
}
// Applet was started by frontend, so it is foreground.
- applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground);
- applet->message_queue.PushMessage(AppletMessage::FocusStateChanged);
- applet->focus_state = FocusState::InFocus;
-
- this->InsertApplet(std::move(applet));
-}
-
-std::shared_ptr<Applet> AppletManager::GetByAppletResourceUserId(AppletResourceUserId aruid) const {
- std::scoped_lock lk{m_lock};
-
- if (const auto it = m_applets.find(aruid); it != m_applets.end()) {
- return it->second;
- }
-
- return {};
-}
-
-void AppletManager::Reset() {
- std::scoped_lock lk{m_lock};
-
- m_applets.clear();
-}
-
-void AppletManager::RequestExit() {
- std::scoped_lock lk{m_lock};
-
- for (const auto& [aruid, applet] : m_applets) {
- applet->message_queue.RequestExit();
+ applet->lifecycle_manager.SetFocusState(FocusState::InFocus);
+
+ if (applet->applet_id == AppletId::QLaunch) {
+ applet->lifecycle_manager.SetFocusHandlingMode(false);
+ applet->lifecycle_manager.SetOutOfFocusSuspendingEnabled(false);
+ m_window_system->TrackApplet(applet, false);
+ m_window_system->RequestHomeMenuToGetForeground();
+ } else {
+ m_window_system->TrackApplet(applet, true);
+ m_window_system->RequestApplicationToGetForeground();
}
-}
-
-void AppletManager::RequestResume() {
- std::scoped_lock lk{m_lock};
- for (const auto& [aruid, applet] : m_applets) {
- applet->message_queue.RequestResume();
- }
-}
-
-void AppletManager::OperationModeChanged() {
- std::scoped_lock lk{m_lock};
-
- for (const auto& [aruid, applet] : m_applets) {
- applet->message_queue.OperationModeChanged();
- }
-}
-
-void AppletManager::FocusStateChanged() {
- std::scoped_lock lk{m_lock};
-
- for (const auto& [aruid, applet] : m_applets) {
- applet->message_queue.FocusStateChanged();
- }
+ applet->process->Run();
}
} // namespace Service::AM