From b2e140b03284fac8fecc7f5bd86f538b76dadc8b Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 18:26:32 -0500
Subject: [PATCH 01/24] am: rewrite appletAE, appletOE

---
 src/android/app/src/main/jni/native.cpp       |  2 -
 src/core/CMakeLists.txt                       |  8 +-
 src/core/hle/service/am/am.cpp                | 12 +--
 src/core/hle/service/am/am_types.h            |  6 ++
 src/core/hle/service/am/applet_ae.cpp         | 73 -----------------
 src/core/hle/service/am/applet_ae.h           | 39 ---------
 src/core/hle/service/am/applet_oe.cpp         | 42 ----------
 src/core/hle/service/am/applet_oe.h           | 37 ---------
 src/core/hle/service/am/frontend/applets.cpp  |  3 -
 .../all_system_applet_proxies_service.cpp     | 80 +++++++++++++++++++
 .../all_system_applet_proxies_service.h       | 47 +++++++++++
 .../am/service/application_proxy_service.cpp  | 42 ++++++++++
 .../am/service/application_proxy_service.h    | 35 ++++++++
 src/yuzu/configuration/configure_input.cpp    |  3 -
 src/yuzu/main.cpp                             |  3 -
 15 files changed, 220 insertions(+), 212 deletions(-)
 delete mode 100644 src/core/hle/service/am/applet_ae.cpp
 delete mode 100644 src/core/hle/service/am/applet_ae.h
 delete mode 100644 src/core/hle/service/am/applet_oe.cpp
 delete mode 100644 src/core/hle/service/am/applet_oe.h
 create mode 100644 src/core/hle/service/am/service/all_system_applet_proxies_service.cpp
 create mode 100644 src/core/hle/service/am/service/all_system_applet_proxies_service.h
 create mode 100644 src/core/hle/service/am/service/application_proxy_service.cpp
 create mode 100644 src/core/hle/service/am/service/application_proxy_service.h

diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index 4acc60956..a4d8454e8 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -49,9 +49,7 @@
 #include "core/frontend/applets/profile_select.h"
 #include "core/frontend/applets/software_keyboard.h"
 #include "core/frontend/applets/web_browser.h"
-#include "core/hle/service/am/applet_ae.h"
 #include "core/hle/service/am/applet_manager.h"
-#include "core/hle/service/am/applet_oe.h"
 #include "core/hle/service/am/frontend/applets.h"
 #include "core/hle/service/filesystem/filesystem.h"
 #include "core/loader/loader.h"
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 2d5490968..5ae31932c 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -417,14 +417,10 @@ add_library(core STATIC
     hle/service/am/am_types.h
     hle/service/am/applet.cpp
     hle/service/am/applet.h
-    hle/service/am/applet_ae.cpp
-    hle/service/am/applet_ae.h
     hle/service/am/applet_manager.cpp
     hle/service/am/applet_data_broker.cpp
     hle/service/am/applet_data_broker.h
     hle/service/am/applet_manager.h
-    hle/service/am/applet_oe.cpp
-    hle/service/am/applet_oe.h
     hle/service/am/applet_common_functions.cpp
     hle/service/am/applet_common_functions.h
     hle/service/am/applet_message_queue.cpp
@@ -473,6 +469,10 @@ add_library(core STATIC
     hle/service/am/process.h
     hle/service/am/self_controller.cpp
     hle/service/am/self_controller.h
+    hle/service/am/service/all_system_applet_proxies_service.cpp
+    hle/service/am/service/all_system_applet_proxies_service.h
+    hle/service/am/service/application_proxy_service.cpp
+    hle/service/am/service/application_proxy_service.h
     hle/service/am/system_applet_proxy.cpp
     hle/service/am/system_applet_proxy.h
     hle/service/am/system_buffer_manager.cpp
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 8f90eba34..da0f9e3df 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -2,10 +2,10 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/am.h"
-#include "core/hle/service/am/applet_ae.h"
-#include "core/hle/service/am/applet_oe.h"
 #include "core/hle/service/am/idle.h"
 #include "core/hle/service/am/omm.h"
+#include "core/hle/service/am/service/all_system_applet_proxies_service.h"
+#include "core/hle/service/am/service/application_proxy_service.h"
 #include "core/hle/service/am/spsm.h"
 #include "core/hle/service/server_manager.h"
 
@@ -14,10 +14,10 @@ namespace Service::AM {
 void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) {
     auto server_manager = std::make_unique<ServerManager>(system);
 
-    server_manager->RegisterNamedService("appletAE",
-                                         std::make_shared<AppletAE>(nvnflinger, system));
-    server_manager->RegisterNamedService("appletOE",
-                                         std::make_shared<AppletOE>(nvnflinger, system));
+    server_manager->RegisterNamedService(
+        "appletAE", std::make_shared<IAllSystemAppletProxiesService>(system, nvnflinger));
+    server_manager->RegisterNamedService(
+        "appletOE", std::make_shared<IApplicationProxyService>(system, nvnflinger));
     server_manager->RegisterNamedService("idle:sys", std::make_shared<IdleSys>(system));
     server_manager->RegisterNamedService("omm", std::make_shared<OMM>(system));
     server_manager->RegisterNamedService("spsm", std::make_shared<SPSM>(system));
diff --git a/src/core/hle/service/am/am_types.h b/src/core/hle/service/am/am_types.h
index 8c33feb15..749081e3d 100644
--- a/src/core/hle/service/am/am_types.h
+++ b/src/core/hle/service/am/am_types.h
@@ -169,6 +169,12 @@ struct AppletIdentityInfo {
 };
 static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size.");
 
+struct AppletAttribute {
+    u8 flag;
+    INSERT_PADDING_BYTES_NOINIT(0x7F);
+};
+static_assert(sizeof(AppletAttribute) == 0x80, "AppletAttribute has incorrect size.");
+
 using AppletResourceUserId = u64;
 using ProgramId = u64;
 
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp
deleted file mode 100644
index 1b715dea6..000000000
--- a/src/core/hle/service/am/applet_ae.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/am/applet_ae.h"
-#include "core/hle/service/am/applet_manager.h"
-#include "core/hle/service/am/library_applet_proxy.h"
-#include "core/hle/service/am/system_applet_proxy.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-AppletAE::AppletAE(Nvnflinger::Nvnflinger& nvnflinger_, Core::System& system_)
-    : ServiceFramework{system_, "appletAE"}, nvnflinger{nvnflinger_} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"},
-        {200, &AppletAE::OpenLibraryAppletProxyOld, "OpenLibraryAppletProxyOld"},
-        {201, &AppletAE::OpenLibraryAppletProxy, "OpenLibraryAppletProxy"},
-        {300, nullptr, "OpenOverlayAppletProxy"},
-        {350, nullptr, "OpenSystemApplicationProxy"},
-        {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"},
-        {410, nullptr, "GetSystemAppletControllerForDebug"},
-        {1000, nullptr, "GetDebugFunctions"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-AppletAE::~AppletAE() = default;
-
-void AppletAE::OpenSystemAppletProxy(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    if (const auto applet = GetAppletFromContext(ctx)) {
-        IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-        rb.Push(ResultSuccess);
-        rb.PushIpcInterface<ISystemAppletProxy>(nvnflinger, applet, system);
-    } else {
-        UNIMPLEMENTED();
-
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(ResultUnknown);
-    }
-}
-
-void AppletAE::OpenLibraryAppletProxy(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    if (const auto applet = GetAppletFromContext(ctx)) {
-        IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-        rb.Push(ResultSuccess);
-        rb.PushIpcInterface<ILibraryAppletProxy>(nvnflinger, applet, system);
-    } else {
-        UNIMPLEMENTED();
-
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(ResultUnknown);
-    }
-}
-
-void AppletAE::OpenLibraryAppletProxyOld(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    return OpenLibraryAppletProxy(ctx);
-}
-
-std::shared_ptr<Applet> AppletAE::GetAppletFromContext(HLERequestContext& ctx) {
-    const auto aruid = ctx.GetPID();
-    return system.GetAppletManager().GetByAppletResourceUserId(aruid);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/applet_ae.h b/src/core/hle/service/am/applet_ae.h
deleted file mode 100644
index 3d7961fa1..000000000
--- a/src/core/hle/service/am/applet_ae.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <memory>
-
-#include "core/hle/service/service.h"
-
-namespace Service {
-namespace FileSystem {
-class FileSystemController;
-}
-
-namespace Nvnflinger {
-class Nvnflinger;
-}
-
-namespace AM {
-
-struct Applet;
-
-class AppletAE final : public ServiceFramework<AppletAE> {
-public:
-    explicit AppletAE(Nvnflinger::Nvnflinger& nvnflinger_, Core::System& system_);
-    ~AppletAE() override;
-
-private:
-    void OpenSystemAppletProxy(HLERequestContext& ctx);
-    void OpenLibraryAppletProxy(HLERequestContext& ctx);
-    void OpenLibraryAppletProxyOld(HLERequestContext& ctx);
-
-    std::shared_ptr<Applet> GetAppletFromContext(HLERequestContext& ctx);
-
-    Nvnflinger::Nvnflinger& nvnflinger;
-};
-
-} // namespace AM
-} // namespace Service
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp
deleted file mode 100644
index 56bafd162..000000000
--- a/src/core/hle/service/am/applet_oe.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/am/am.h"
-#include "core/hle/service/am/applet_manager.h"
-#include "core/hle/service/am/applet_oe.h"
-#include "core/hle/service/am/application_proxy.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-AppletOE::AppletOE(Nvnflinger::Nvnflinger& nvnflinger_, Core::System& system_)
-    : ServiceFramework{system_, "appletOE"}, nvnflinger{nvnflinger_} {
-    static const FunctionInfo functions[] = {
-        {0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"},
-    };
-    RegisterHandlers(functions);
-}
-
-AppletOE::~AppletOE() = default;
-
-void AppletOE::OpenApplicationProxy(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    if (const auto applet = GetAppletFromContext(ctx)) {
-        IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-        rb.Push(ResultSuccess);
-        rb.PushIpcInterface<IApplicationProxy>(nvnflinger, applet, system);
-    } else {
-        UNIMPLEMENTED();
-
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(ResultUnknown);
-    }
-}
-
-std::shared_ptr<Applet> AppletOE::GetAppletFromContext(HLERequestContext& ctx) {
-    const auto aruid = ctx.GetPID();
-    return system.GetAppletManager().GetByAppletResourceUserId(aruid);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/applet_oe.h b/src/core/hle/service/am/applet_oe.h
deleted file mode 100644
index f2ba1c924..000000000
--- a/src/core/hle/service/am/applet_oe.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <memory>
-
-#include "core/hle/service/service.h"
-
-namespace Service {
-namespace FileSystem {
-class FileSystemController;
-}
-
-namespace Nvnflinger {
-class Nvnflinger;
-}
-
-namespace AM {
-
-struct Applet;
-
-class AppletOE final : public ServiceFramework<AppletOE> {
-public:
-    explicit AppletOE(Nvnflinger::Nvnflinger& nvnflinger_, Core::System& system_);
-    ~AppletOE() override;
-
-private:
-    void OpenApplicationProxy(HLERequestContext& ctx);
-
-    std::shared_ptr<Applet> GetAppletFromContext(HLERequestContext& ctx);
-
-    Nvnflinger::Nvnflinger& nvnflinger;
-};
-
-} // namespace AM
-} // namespace Service
diff --git a/src/core/hle/service/am/frontend/applets.cpp b/src/core/hle/service/am/frontend/applets.cpp
index db2b04575..944d8b105 100644
--- a/src/core/hle/service/am/frontend/applets.cpp
+++ b/src/core/hle/service/am/frontend/applets.cpp
@@ -15,11 +15,8 @@
 #include "core/frontend/applets/web_browser.h"
 #include "core/hle/kernel/k_event.h"
 #include "core/hle/service/am/am.h"
-#include "core/hle/service/am/applet_ae.h"
 #include "core/hle/service/am/applet_data_broker.h"
 #include "core/hle/service/am/applet_manager.h"
-#include "core/hle/service/am/applet_message_queue.h"
-#include "core/hle/service/am/applet_oe.h"
 #include "core/hle/service/am/frontend/applet_cabinet.h"
 #include "core/hle/service/am/frontend/applet_controller.h"
 #include "core/hle/service/am/frontend/applet_error.h"
diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp
new file mode 100644
index 000000000..66c23a749
--- /dev/null
+++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp
@@ -0,0 +1,80 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/core.h"
+#include "core/hle/service/am/applet_manager.h"
+#include "core/hle/service/am/library_applet_proxy.h"
+#include "core/hle/service/am/service/all_system_applet_proxies_service.h"
+#include "core/hle/service/am/system_applet_proxy.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_,
+                                                               Nvnflinger::Nvnflinger& nvnflinger)
+    : ServiceFramework{system_, "appletAE"}, m_nvnflinger{nvnflinger} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"},
+        {200, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld>, "OpenLibraryAppletProxyOld"},
+        {201, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxy>, "OpenLibraryAppletProxy"},
+        {300, nullptr, "OpenOverlayAppletProxy"},
+        {350, nullptr, "OpenSystemApplicationProxy"},
+        {400, nullptr, "CreateSelfLibraryAppletCreatorForDevelop"},
+        {410, nullptr, "GetSystemAppletControllerForDebug"},
+        {1000, nullptr, "GetDebugFunctions"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IAllSystemAppletProxiesService::~IAllSystemAppletProxiesService() = default;
+
+Result IAllSystemAppletProxiesService::OpenSystemAppletProxy(
+    Out<SharedPointer<ISystemAppletProxy>> out_system_applet_proxy, ClientProcessId pid,
+    InCopyHandle<Kernel::KProcess> process_handle) {
+    LOG_DEBUG(Service_AM, "called");
+
+    if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
+        *out_system_applet_proxy =
+            std::make_shared<ISystemAppletProxy>(m_nvnflinger, applet, system);
+        R_SUCCEED();
+    } else {
+        UNIMPLEMENTED();
+        R_THROW(ResultUnknown);
+    }
+}
+
+Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy(
+    Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid,
+    InCopyHandle<Kernel::KProcess> process_handle,
+    InLargeData<AppletAttribute, BufferAttr_HipcMapAlias> attribute) {
+    LOG_DEBUG(Service_AM, "called");
+
+    if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
+        *out_library_applet_proxy =
+            std::make_shared<ILibraryAppletProxy>(m_nvnflinger, applet, system);
+        R_SUCCEED();
+    } else {
+        UNIMPLEMENTED();
+        R_THROW(ResultUnknown);
+    }
+}
+
+Result IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld(
+    Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid,
+    InCopyHandle<Kernel::KProcess> process_handle) {
+    LOG_DEBUG(Service_AM, "called");
+
+    AppletAttribute attribute{};
+    R_RETURN(
+        this->OpenLibraryAppletProxy(out_library_applet_proxy, pid, process_handle, attribute));
+}
+
+std::shared_ptr<Applet> IAllSystemAppletProxiesService::GetAppletFromProcessId(
+    ProcessId process_id) {
+    return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid);
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.h b/src/core/hle/service/am/service/all_system_applet_proxies_service.h
new file mode 100644
index 000000000..38b1ca2ea
--- /dev/null
+++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.h
@@ -0,0 +1,47 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace Service {
+
+namespace Nvnflinger {
+class Nvnflinger;
+}
+
+namespace AM {
+
+struct Applet;
+struct AppletAttribute;
+class ILibraryAppletProxy;
+class ISystemAppletProxy;
+
+class IAllSystemAppletProxiesService final
+    : public ServiceFramework<IAllSystemAppletProxiesService> {
+public:
+    explicit IAllSystemAppletProxiesService(Core::System& system_,
+                                            Nvnflinger::Nvnflinger& nvnflinger);
+    ~IAllSystemAppletProxiesService() override;
+
+private:
+    Result OpenSystemAppletProxy(Out<SharedPointer<ISystemAppletProxy>> out_system_applet_proxy,
+                                 ClientProcessId pid,
+                                 InCopyHandle<Kernel::KProcess> process_handle);
+    Result OpenLibraryAppletProxy(Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy,
+                                  ClientProcessId pid,
+                                  InCopyHandle<Kernel::KProcess> process_handle,
+                                  InLargeData<AppletAttribute, BufferAttr_HipcMapAlias> attribute);
+    Result OpenLibraryAppletProxyOld(
+        Out<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid,
+        InCopyHandle<Kernel::KProcess> process_handle);
+
+private:
+    std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);
+    Nvnflinger::Nvnflinger& m_nvnflinger;
+};
+
+} // namespace AM
+} // namespace Service
diff --git a/src/core/hle/service/am/service/application_proxy_service.cpp b/src/core/hle/service/am/service/application_proxy_service.cpp
new file mode 100644
index 000000000..b8532d047
--- /dev/null
+++ b/src/core/hle/service/am/service/application_proxy_service.cpp
@@ -0,0 +1,42 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/core.h"
+#include "core/hle/service/am/am.h"
+#include "core/hle/service/am/applet_manager.h"
+#include "core/hle/service/am/application_proxy.h"
+#include "core/hle/service/am/service/application_proxy_service.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+IApplicationProxyService::IApplicationProxyService(Core::System& system_,
+                                                   Nvnflinger::Nvnflinger& nvnflinger)
+    : ServiceFramework{system_, "appletOE"}, m_nvnflinger{nvnflinger} {
+    static const FunctionInfo functions[] = {
+        {0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"},
+    };
+    RegisterHandlers(functions);
+}
+
+IApplicationProxyService::~IApplicationProxyService() = default;
+
+Result IApplicationProxyService::OpenApplicationProxy(
+    Out<SharedPointer<IApplicationProxy>> out_application_proxy, ClientProcessId pid,
+    InCopyHandle<Kernel::KProcess> process_handle) {
+    LOG_DEBUG(Service_AM, "called");
+
+    if (const auto applet = this->GetAppletFromProcessId(pid)) {
+        *out_application_proxy = std::make_shared<IApplicationProxy>(m_nvnflinger, applet, system);
+        R_SUCCEED();
+    } else {
+        UNIMPLEMENTED();
+        R_THROW(ResultUnknown);
+    }
+}
+
+std::shared_ptr<Applet> IApplicationProxyService::GetAppletFromProcessId(ProcessId process_id) {
+    return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid);
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_proxy_service.h b/src/core/hle/service/am/service/application_proxy_service.h
new file mode 100644
index 000000000..1c1d32d0b
--- /dev/null
+++ b/src/core/hle/service/am/service/application_proxy_service.h
@@ -0,0 +1,35 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace Service {
+
+namespace Nvnflinger {
+class Nvnflinger;
+}
+
+namespace AM {
+
+struct Applet;
+class IApplicationProxy;
+
+class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> {
+public:
+    explicit IApplicationProxyService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger);
+    ~IApplicationProxyService() override;
+
+private:
+    Result OpenApplicationProxy(Out<SharedPointer<IApplicationProxy>> out_application_proxy,
+                                ClientProcessId pid, InCopyHandle<Kernel::KProcess> process_handle);
+
+private:
+    std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);
+    Nvnflinger::Nvnflinger& m_nvnflinger;
+};
+
+} // namespace AM
+} // namespace Service
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index e28df10bd..28c3baf08 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -8,10 +8,7 @@
 #include "common/settings_enums.h"
 #include "core/core.h"
 #include "core/hle/service/am/am.h"
-#include "core/hle/service/am/applet_ae.h"
 #include "core/hle/service/am/applet_manager.h"
-#include "core/hle/service/am/applet_message_queue.h"
-#include "core/hle/service/am/applet_oe.h"
 #include "core/hle/service/sm/sm.h"
 #include "hid_core/frontend/emulated_controller.h"
 #include "hid_core/hid_core.h"
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 13381fea8..dfa50006a 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -44,9 +44,6 @@
 #include "core/frontend/applets/mii_edit.h"
 #include "core/frontend/applets/software_keyboard.h"
 #include "core/hle/service/acc/profile_manager.h"
-#include "core/hle/service/am/applet_ae.h"
-#include "core/hle/service/am/applet_message_queue.h"
-#include "core/hle/service/am/applet_oe.h"
 #include "core/hle/service/am/frontend/applets.h"
 #include "core/hle/service/set/system_settings_server.h"
 #include "frontend_common/content_manager.h"

From c7e97b22fb6fd14800ad374a13ad21d6a4c829f1 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 18:31:29 -0500
Subject: [PATCH 02/24] am: rewrite IApplicationProxy

---
 src/core/CMakeLists.txt                       |   4 +-
 src/core/hle/service/am/application_proxy.cpp | 115 ------------------
 src/core/hle/service/am/application_proxy.h   |  33 -----
 .../service/am/service/application_proxy.cpp  | 106 ++++++++++++++++
 .../service/am/service/application_proxy.h    |  48 ++++++++
 .../am/service/application_proxy_service.cpp  |   5 +-
 6 files changed, 159 insertions(+), 152 deletions(-)
 delete mode 100644 src/core/hle/service/am/application_proxy.cpp
 delete mode 100644 src/core/hle/service/am/application_proxy.h
 create mode 100644 src/core/hle/service/am/service/application_proxy.cpp
 create mode 100644 src/core/hle/service/am/service/application_proxy.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 5ae31932c..e2486f2cd 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -429,8 +429,6 @@ add_library(core STATIC
     hle/service/am/application_creator.h
     hle/service/am/application_functions.cpp
     hle/service/am/application_functions.h
-    hle/service/am/application_proxy.cpp
-    hle/service/am/application_proxy.h
     hle/service/am/audio_controller.cpp
     hle/service/am/audio_controller.h
     hle/service/am/common_state_getter.cpp
@@ -473,6 +471,8 @@ add_library(core STATIC
     hle/service/am/service/all_system_applet_proxies_service.h
     hle/service/am/service/application_proxy_service.cpp
     hle/service/am/service/application_proxy_service.h
+    hle/service/am/service/application_proxy.cpp
+    hle/service/am/service/application_proxy.h
     hle/service/am/system_applet_proxy.cpp
     hle/service/am/system_applet_proxy.h
     hle/service/am/system_buffer_manager.cpp
diff --git a/src/core/hle/service/am/application_proxy.cpp b/src/core/hle/service/am/application_proxy.cpp
deleted file mode 100644
index a6fd6d37f..000000000
--- a/src/core/hle/service/am/application_proxy.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/am/applet_common_functions.h"
-#include "core/hle/service/am/application_functions.h"
-#include "core/hle/service/am/application_proxy.h"
-#include "core/hle/service/am/audio_controller.h"
-#include "core/hle/service/am/common_state_getter.h"
-#include "core/hle/service/am/debug_functions.h"
-#include "core/hle/service/am/display_controller.h"
-#include "core/hle/service/am/library_applet_creator.h"
-#include "core/hle/service/am/library_applet_self_accessor.h"
-#include "core/hle/service/am/process_winding_controller.h"
-#include "core/hle/service/am/self_controller.h"
-#include "core/hle/service/am/window_controller.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-IApplicationProxy::IApplicationProxy(Nvnflinger::Nvnflinger& nvnflinger_,
-                                     std::shared_ptr<Applet> applet_, Core::System& system_)
-    : ServiceFramework{system_, "IApplicationProxy"}, nvnflinger{nvnflinger_}, applet{std::move(
-                                                                                   applet_)} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"},
-        {1, &IApplicationProxy::GetSelfController, "GetSelfController"},
-        {2, &IApplicationProxy::GetWindowController, "GetWindowController"},
-        {3, &IApplicationProxy::GetAudioController, "GetAudioController"},
-        {4, &IApplicationProxy::GetDisplayController, "GetDisplayController"},
-        {10, &IApplicationProxy::GetProcessWindingController, "GetProcessWindingController"},
-        {11, &IApplicationProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"},
-        {20, &IApplicationProxy::GetApplicationFunctions, "GetApplicationFunctions"},
-        {1000, &IApplicationProxy::GetDebugFunctions, "GetDebugFunctions"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-IApplicationProxy::~IApplicationProxy() = default;
-
-void IApplicationProxy::GetAudioController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IAudioController>(system);
-}
-
-void IApplicationProxy::GetDisplayController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IDisplayController>(system, applet);
-}
-
-void IApplicationProxy::GetProcessWindingController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IProcessWindingController>(system, applet);
-}
-
-void IApplicationProxy::GetDebugFunctions(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IDebugFunctions>(system);
-}
-
-void IApplicationProxy::GetWindowController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IWindowController>(system, applet);
-}
-
-void IApplicationProxy::GetSelfController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ISelfController>(system, applet, nvnflinger);
-}
-
-void IApplicationProxy::GetCommonStateGetter(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ICommonStateGetter>(system, applet);
-}
-
-void IApplicationProxy::GetLibraryAppletCreator(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ILibraryAppletCreator>(system, applet);
-}
-
-void IApplicationProxy::GetApplicationFunctions(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IApplicationFunctions>(system, applet);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/application_proxy.h b/src/core/hle/service/am/application_proxy.h
deleted file mode 100644
index eb98b095c..000000000
--- a/src/core/hle/service/am/application_proxy.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-struct Applet;
-
-class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
-public:
-    explicit IApplicationProxy(Nvnflinger::Nvnflinger& nvnflinger_,
-                               std::shared_ptr<Applet> msg_queue_, Core::System& system_);
-    ~IApplicationProxy();
-
-private:
-    void GetAudioController(HLERequestContext& ctx);
-    void GetDisplayController(HLERequestContext& ctx);
-    void GetProcessWindingController(HLERequestContext& ctx);
-    void GetDebugFunctions(HLERequestContext& ctx);
-    void GetWindowController(HLERequestContext& ctx);
-    void GetSelfController(HLERequestContext& ctx);
-    void GetCommonStateGetter(HLERequestContext& ctx);
-    void GetLibraryAppletCreator(HLERequestContext& ctx);
-    void GetApplicationFunctions(HLERequestContext& ctx);
-
-    Nvnflinger::Nvnflinger& nvnflinger;
-    std::shared_ptr<Applet> applet;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
new file mode 100644
index 000000000..d1f87709e
--- /dev/null
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -0,0 +1,106 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/am/applet_common_functions.h"
+#include "core/hle/service/am/application_functions.h"
+#include "core/hle/service/am/audio_controller.h"
+#include "core/hle/service/am/common_state_getter.h"
+#include "core/hle/service/am/debug_functions.h"
+#include "core/hle/service/am/display_controller.h"
+#include "core/hle/service/am/library_applet_creator.h"
+#include "core/hle/service/am/library_applet_self_accessor.h"
+#include "core/hle/service/am/process_winding_controller.h"
+#include "core/hle/service/am/self_controller.h"
+#include "core/hle/service/am/service/application_proxy.h"
+#include "core/hle/service/am/window_controller.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
+                                     Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger)
+    : ServiceFramework{system_, "IApplicationProxy"},
+      m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
+        {1, D<&IApplicationProxy::GetSelfController>, "GetSelfController"},
+        {2, D<&IApplicationProxy::GetWindowController>, "GetWindowController"},
+        {3, D<&IApplicationProxy::GetAudioController>, "GetAudioController"},
+        {4, D<&IApplicationProxy::GetDisplayController>, "GetDisplayController"},
+        {10, D<&IApplicationProxy::GetProcessWindingController>, "GetProcessWindingController"},
+        {11, D<&IApplicationProxy::GetLibraryAppletCreator>, "GetLibraryAppletCreator"},
+        {20, D<&IApplicationProxy::GetApplicationFunctions>, "GetApplicationFunctions"},
+        {1000, D<&IApplicationProxy::GetDebugFunctions>, "GetDebugFunctions"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IApplicationProxy::~IApplicationProxy() = default;
+
+Result IApplicationProxy::GetAudioController(
+    Out<SharedPointer<IAudioController>> out_audio_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_audio_controller = std::make_shared<IAudioController>(system);
+    R_SUCCEED();
+}
+
+Result IApplicationProxy::GetDisplayController(
+    Out<SharedPointer<IDisplayController>> out_display_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_display_controller = std::make_shared<IDisplayController>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result IApplicationProxy::GetProcessWindingController(
+    Out<SharedPointer<IProcessWindingController>> out_process_winding_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_process_winding_controller = std::make_shared<IProcessWindingController>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result IApplicationProxy::GetDebugFunctions(
+    Out<SharedPointer<IDebugFunctions>> out_debug_functions) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_debug_functions = std::make_shared<IDebugFunctions>(system);
+    R_SUCCEED();
+}
+
+Result IApplicationProxy::GetWindowController(
+    Out<SharedPointer<IWindowController>> out_window_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_window_controller = std::make_shared<IWindowController>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result IApplicationProxy::GetSelfController(
+    Out<SharedPointer<ISelfController>> out_self_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_nvnflinger);
+    R_SUCCEED();
+}
+
+Result IApplicationProxy::GetCommonStateGetter(
+    Out<SharedPointer<ICommonStateGetter>> out_common_state_getter) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_common_state_getter = std::make_shared<ICommonStateGetter>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result IApplicationProxy::GetLibraryAppletCreator(
+    Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result IApplicationProxy::GetApplicationFunctions(
+    Out<SharedPointer<IApplicationFunctions>> out_application_functions) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_application_functions = std::make_shared<IApplicationFunctions>(system, m_applet);
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_proxy.h b/src/core/hle/service/am/service/application_proxy.h
new file mode 100644
index 000000000..1ebc593ba
--- /dev/null
+++ b/src/core/hle/service/am/service/application_proxy.h
@@ -0,0 +1,48 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+struct Applet;
+class IAudioController;
+class IApplicationFunctions;
+class ICommonStateGetter;
+class IDebugFunctions;
+class IDisplayController;
+class ILibraryAppletCreator;
+class IProcessWindingController;
+class ISelfController;
+class IWindowController;
+
+class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
+public:
+    explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
+                               Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger);
+    ~IApplicationProxy();
+
+private:
+    Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller);
+    Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller);
+    Result GetProcessWindingController(
+        Out<SharedPointer<IProcessWindingController>> out_process_winding_controller);
+    Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions);
+    Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller);
+    Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller);
+    Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter);
+    Result GetLibraryAppletCreator(
+        Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator);
+    Result GetApplicationFunctions(
+        Out<SharedPointer<IApplicationFunctions>> out_application_functions);
+
+private:
+    Nvnflinger::Nvnflinger& m_nvnflinger;
+    Kernel::KProcess* const m_process;
+    const std::shared_ptr<Applet> m_applet;
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_proxy_service.cpp b/src/core/hle/service/am/service/application_proxy_service.cpp
index b8532d047..36d4478df 100644
--- a/src/core/hle/service/am/service/application_proxy_service.cpp
+++ b/src/core/hle/service/am/service/application_proxy_service.cpp
@@ -4,7 +4,7 @@
 #include "core/core.h"
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/applet_manager.h"
-#include "core/hle/service/am/application_proxy.h"
+#include "core/hle/service/am/service/application_proxy.h"
 #include "core/hle/service/am/service/application_proxy_service.h"
 #include "core/hle/service/cmif_serialization.h"
 
@@ -27,7 +27,8 @@ Result IApplicationProxyService::OpenApplicationProxy(
     LOG_DEBUG(Service_AM, "called");
 
     if (const auto applet = this->GetAppletFromProcessId(pid)) {
-        *out_application_proxy = std::make_shared<IApplicationProxy>(m_nvnflinger, applet, system);
+        *out_application_proxy =
+            std::make_shared<IApplicationProxy>(system, applet, process_handle.Get(), m_nvnflinger);
         R_SUCCEED();
     } else {
         UNIMPLEMENTED();

From c809f7193aa91a746503f92248652865172b36fb Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 19:09:49 -0500
Subject: [PATCH 03/24] am: rewrite ILibraryAppletProxy

---
 src/core/CMakeLists.txt                       |   4 +-
 .../hle/service/am/library_applet_proxy.cpp   | 143 ------------------
 .../hle/service/am/library_applet_proxy.h     |  36 -----
 .../all_system_applet_proxies_service.cpp     |   6 +-
 .../am/service/library_applet_proxy.cpp       | 133 ++++++++++++++++
 .../service/am/service/library_applet_proxy.h |  55 +++++++
 6 files changed, 193 insertions(+), 184 deletions(-)
 delete mode 100644 src/core/hle/service/am/library_applet_proxy.cpp
 delete mode 100644 src/core/hle/service/am/library_applet_proxy.h
 create mode 100644 src/core/hle/service/am/service/library_applet_proxy.cpp
 create mode 100644 src/core/hle/service/am/service/library_applet_proxy.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index e2486f2cd..8fd62e45e 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -449,8 +449,6 @@ add_library(core STATIC
     hle/service/am/library_applet_accessor.h
     hle/service/am/library_applet_creator.cpp
     hle/service/am/library_applet_creator.h
-    hle/service/am/library_applet_proxy.cpp
-    hle/service/am/library_applet_proxy.h
     hle/service/am/library_applet_self_accessor.cpp
     hle/service/am/library_applet_self_accessor.h
     hle/service/am/library_applet_storage.cpp
@@ -473,6 +471,8 @@ add_library(core STATIC
     hle/service/am/service/application_proxy_service.h
     hle/service/am/service/application_proxy.cpp
     hle/service/am/service/application_proxy.h
+    hle/service/am/service/library_applet_proxy.cpp
+    hle/service/am/service/library_applet_proxy.h
     hle/service/am/system_applet_proxy.cpp
     hle/service/am/system_applet_proxy.h
     hle/service/am/system_buffer_manager.cpp
diff --git a/src/core/hle/service/am/library_applet_proxy.cpp b/src/core/hle/service/am/library_applet_proxy.cpp
deleted file mode 100644
index d6108fba3..000000000
--- a/src/core/hle/service/am/library_applet_proxy.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/am/applet_common_functions.h"
-#include "core/hle/service/am/audio_controller.h"
-#include "core/hle/service/am/common_state_getter.h"
-#include "core/hle/service/am/debug_functions.h"
-#include "core/hle/service/am/display_controller.h"
-#include "core/hle/service/am/global_state_controller.h"
-#include "core/hle/service/am/home_menu_functions.h"
-#include "core/hle/service/am/library_applet_creator.h"
-#include "core/hle/service/am/library_applet_proxy.h"
-#include "core/hle/service/am/library_applet_self_accessor.h"
-#include "core/hle/service/am/process_winding_controller.h"
-#include "core/hle/service/am/self_controller.h"
-#include "core/hle/service/am/window_controller.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-ILibraryAppletProxy::ILibraryAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_,
-                                         std::shared_ptr<Applet> applet_, Core::System& system_)
-    : ServiceFramework{system_, "ILibraryAppletProxy"}, nvnflinger{nvnflinger_}, applet{std::move(
-                                                                                     applet_)} {
-    // clang-format off
-        static const FunctionInfo functions[] = {
-            {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
-            {1, &ILibraryAppletProxy::GetSelfController, "GetSelfController"},
-            {2, &ILibraryAppletProxy::GetWindowController, "GetWindowController"},
-            {3, &ILibraryAppletProxy::GetAudioController, "GetAudioController"},
-            {4, &ILibraryAppletProxy::GetDisplayController, "GetDisplayController"},
-            {10, &ILibraryAppletProxy::GetProcessWindingController, "GetProcessWindingController"},
-            {11, &ILibraryAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"},
-            {20, &ILibraryAppletProxy::OpenLibraryAppletSelfAccessor, "OpenLibraryAppletSelfAccessor"},
-            {21, &ILibraryAppletProxy::GetAppletCommonFunctions, "GetAppletCommonFunctions"},
-            {22, &ILibraryAppletProxy::GetHomeMenuFunctions, "GetHomeMenuFunctions"},
-            {23, &ILibraryAppletProxy::GetGlobalStateController, "GetGlobalStateController"},
-            {1000, &ILibraryAppletProxy::GetDebugFunctions, "GetDebugFunctions"},
-        };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-ILibraryAppletProxy::~ILibraryAppletProxy() = default;
-
-void ILibraryAppletProxy::GetCommonStateGetter(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ICommonStateGetter>(system, applet);
-}
-
-void ILibraryAppletProxy::GetSelfController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ISelfController>(system, applet, nvnflinger);
-}
-
-void ILibraryAppletProxy::GetWindowController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IWindowController>(system, applet);
-}
-
-void ILibraryAppletProxy::GetAudioController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IAudioController>(system);
-}
-
-void ILibraryAppletProxy::GetDisplayController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IDisplayController>(system, applet);
-}
-
-void ILibraryAppletProxy::GetProcessWindingController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IProcessWindingController>(system, applet);
-}
-
-void ILibraryAppletProxy::GetLibraryAppletCreator(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ILibraryAppletCreator>(system, applet);
-}
-
-void ILibraryAppletProxy::OpenLibraryAppletSelfAccessor(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ILibraryAppletSelfAccessor>(system, applet);
-}
-
-void ILibraryAppletProxy::GetAppletCommonFunctions(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IAppletCommonFunctions>(system, applet);
-}
-
-void ILibraryAppletProxy::GetHomeMenuFunctions(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IHomeMenuFunctions>(system);
-}
-
-void ILibraryAppletProxy::GetGlobalStateController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IGlobalStateController>(system);
-}
-
-void ILibraryAppletProxy::GetDebugFunctions(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IDebugFunctions>(system);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/library_applet_proxy.h b/src/core/hle/service/am/library_applet_proxy.h
deleted file mode 100644
index 8f7a25897..000000000
--- a/src/core/hle/service/am/library_applet_proxy.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-struct Applet;
-
-class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
-public:
-    explicit ILibraryAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_,
-                                 std::shared_ptr<Applet> applet_, Core::System& system_);
-    ~ILibraryAppletProxy();
-
-private:
-    void GetCommonStateGetter(HLERequestContext& ctx);
-    void GetSelfController(HLERequestContext& ctx);
-    void GetWindowController(HLERequestContext& ctx);
-    void GetAudioController(HLERequestContext& ctx);
-    void GetDisplayController(HLERequestContext& ctx);
-    void GetProcessWindingController(HLERequestContext& ctx);
-    void GetLibraryAppletCreator(HLERequestContext& ctx);
-    void OpenLibraryAppletSelfAccessor(HLERequestContext& ctx);
-    void GetAppletCommonFunctions(HLERequestContext& ctx);
-    void GetHomeMenuFunctions(HLERequestContext& ctx);
-    void GetGlobalStateController(HLERequestContext& ctx);
-    void GetDebugFunctions(HLERequestContext& ctx);
-
-    Nvnflinger::Nvnflinger& nvnflinger;
-    std::shared_ptr<Applet> applet;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp
index 66c23a749..dfefc9310 100644
--- a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp
+++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp
@@ -3,8 +3,8 @@
 
 #include "core/core.h"
 #include "core/hle/service/am/applet_manager.h"
-#include "core/hle/service/am/library_applet_proxy.h"
 #include "core/hle/service/am/service/all_system_applet_proxies_service.h"
+#include "core/hle/service/am/service/library_applet_proxy.h"
 #include "core/hle/service/am/system_applet_proxy.h"
 #include "core/hle/service/cmif_serialization.h"
 
@@ -53,8 +53,8 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy(
     LOG_DEBUG(Service_AM, "called");
 
     if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
-        *out_library_applet_proxy =
-            std::make_shared<ILibraryAppletProxy>(m_nvnflinger, applet, system);
+        *out_library_applet_proxy = std::make_shared<ILibraryAppletProxy>(
+            system, applet, process_handle.Get(), m_nvnflinger);
         R_SUCCEED();
     } else {
         UNIMPLEMENTED();
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
new file mode 100644
index 000000000..9a0d363ac
--- /dev/null
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -0,0 +1,133 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/am/applet_common_functions.h"
+#include "core/hle/service/am/audio_controller.h"
+#include "core/hle/service/am/common_state_getter.h"
+#include "core/hle/service/am/debug_functions.h"
+#include "core/hle/service/am/display_controller.h"
+#include "core/hle/service/am/global_state_controller.h"
+#include "core/hle/service/am/home_menu_functions.h"
+#include "core/hle/service/am/library_applet_creator.h"
+#include "core/hle/service/am/library_applet_self_accessor.h"
+#include "core/hle/service/am/process_winding_controller.h"
+#include "core/hle/service/am/self_controller.h"
+#include "core/hle/service/am/service/library_applet_proxy.h"
+#include "core/hle/service/am/window_controller.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
+                                         Kernel::KProcess* process,
+                                         Nvnflinger::Nvnflinger& nvnflinger)
+    : ServiceFramework{system_, "ILibraryAppletProxy"},
+      m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
+        {1, D<&ILibraryAppletProxy::GetSelfController>, "GetSelfController"},
+        {2, D<&ILibraryAppletProxy::GetWindowController>, "GetWindowController"},
+        {3, D<&ILibraryAppletProxy::GetAudioController>, "GetAudioController"},
+        {4, D<&ILibraryAppletProxy::GetDisplayController>, "GetDisplayController"},
+        {10, D<&ILibraryAppletProxy::GetProcessWindingController>, "GetProcessWindingController"},
+        {11, D<&ILibraryAppletProxy::GetLibraryAppletCreator>, "GetLibraryAppletCreator"},
+        {20, D<&ILibraryAppletProxy::OpenLibraryAppletSelfAccessor>, "OpenLibraryAppletSelfAccessor"},
+        {21, D<&ILibraryAppletProxy::GetAppletCommonFunctions>, "GetAppletCommonFunctions"},
+        {22, D<&ILibraryAppletProxy::GetHomeMenuFunctions>, "GetHomeMenuFunctions"},
+        {23, D<&ILibraryAppletProxy::GetGlobalStateController>, "GetGlobalStateController"},
+        {1000, D<&ILibraryAppletProxy::GetDebugFunctions>, "GetDebugFunctions"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+ILibraryAppletProxy::~ILibraryAppletProxy() = default;
+
+Result ILibraryAppletProxy::GetAudioController(
+    Out<SharedPointer<IAudioController>> out_audio_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_audio_controller = std::make_shared<IAudioController>(system);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletProxy::GetDisplayController(
+    Out<SharedPointer<IDisplayController>> out_display_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_display_controller = std::make_shared<IDisplayController>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletProxy::GetProcessWindingController(
+    Out<SharedPointer<IProcessWindingController>> out_process_winding_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_process_winding_controller = std::make_shared<IProcessWindingController>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletProxy::GetDebugFunctions(
+    Out<SharedPointer<IDebugFunctions>> out_debug_functions) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_debug_functions = std::make_shared<IDebugFunctions>(system);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletProxy::GetWindowController(
+    Out<SharedPointer<IWindowController>> out_window_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_window_controller = std::make_shared<IWindowController>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletProxy::GetSelfController(
+    Out<SharedPointer<ISelfController>> out_self_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_nvnflinger);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletProxy::GetCommonStateGetter(
+    Out<SharedPointer<ICommonStateGetter>> out_common_state_getter) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_common_state_getter = std::make_shared<ICommonStateGetter>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletProxy::GetLibraryAppletCreator(
+    Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletProxy::OpenLibraryAppletSelfAccessor(
+    Out<SharedPointer<ILibraryAppletSelfAccessor>> out_library_applet_self_accessor) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_library_applet_self_accessor =
+        std::make_shared<ILibraryAppletSelfAccessor>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletProxy::GetAppletCommonFunctions(
+    Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_applet_common_functions = std::make_shared<IAppletCommonFunctions>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletProxy::GetHomeMenuFunctions(
+    Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletProxy::GetGlobalStateController(
+    Out<SharedPointer<IGlobalStateController>> out_global_state_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_global_state_controller = std::make_shared<IGlobalStateController>(system);
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/library_applet_proxy.h b/src/core/hle/service/am/service/library_applet_proxy.h
new file mode 100644
index 000000000..23e64e295
--- /dev/null
+++ b/src/core/hle/service/am/service/library_applet_proxy.h
@@ -0,0 +1,55 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+struct Applet;
+class IAppletCommonFunctions;
+class IAudioController;
+class ICommonStateGetter;
+class IDebugFunctions;
+class IDisplayController;
+class IHomeMenuFunctions;
+class IGlobalStateController;
+class ILibraryAppletCreator;
+class ILibraryAppletSelfAccessor;
+class IProcessWindingController;
+class ISelfController;
+class IWindowController;
+
+class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
+public:
+    explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
+                                 Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger);
+    ~ILibraryAppletProxy();
+
+private:
+    Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller);
+    Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller);
+    Result GetProcessWindingController(
+        Out<SharedPointer<IProcessWindingController>> out_process_winding_controller);
+    Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions);
+    Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller);
+    Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller);
+    Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter);
+    Result GetLibraryAppletCreator(
+        Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator);
+    Result OpenLibraryAppletSelfAccessor(
+        Out<SharedPointer<ILibraryAppletSelfAccessor>> out_library_applet_self_accessor);
+    Result GetAppletCommonFunctions(
+        Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions);
+    Result GetHomeMenuFunctions(Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions);
+    Result GetGlobalStateController(
+        Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
+
+    Nvnflinger::Nvnflinger& m_nvnflinger;
+    Kernel::KProcess* const m_process;
+    const std::shared_ptr<Applet> m_applet;
+};
+
+} // namespace Service::AM

From 6fd6c65fd40d2e719cbb62b7e05468d632c04d88 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 19:16:36 -0500
Subject: [PATCH 04/24] am: rewrite ISystemAppletProxy

---
 src/core/CMakeLists.txt                       |   4 +-
 .../all_system_applet_proxies_service.cpp     |   6 +-
 .../am/service/system_applet_proxy.cpp        | 132 +++++++++++++++++
 .../service/am/service/system_applet_proxy.h  |  54 +++++++
 .../hle/service/am/system_applet_proxy.cpp    | 136 ------------------
 src/core/hle/service/am/system_applet_proxy.h |  36 -----
 6 files changed, 191 insertions(+), 177 deletions(-)
 create mode 100644 src/core/hle/service/am/service/system_applet_proxy.cpp
 create mode 100644 src/core/hle/service/am/service/system_applet_proxy.h
 delete mode 100644 src/core/hle/service/am/system_applet_proxy.cpp
 delete mode 100644 src/core/hle/service/am/system_applet_proxy.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 8fd62e45e..4486a355c 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -473,8 +473,8 @@ add_library(core STATIC
     hle/service/am/service/application_proxy.h
     hle/service/am/service/library_applet_proxy.cpp
     hle/service/am/service/library_applet_proxy.h
-    hle/service/am/system_applet_proxy.cpp
-    hle/service/am/system_applet_proxy.h
+    hle/service/am/service/system_applet_proxy.cpp
+    hle/service/am/service/system_applet_proxy.h
     hle/service/am/system_buffer_manager.cpp
     hle/service/am/system_buffer_manager.h
     hle/service/am/spsm.cpp
diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp
index dfefc9310..eebd90ba2 100644
--- a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp
+++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp
@@ -5,7 +5,7 @@
 #include "core/hle/service/am/applet_manager.h"
 #include "core/hle/service/am/service/all_system_applet_proxies_service.h"
 #include "core/hle/service/am/service/library_applet_proxy.h"
-#include "core/hle/service/am/system_applet_proxy.h"
+#include "core/hle/service/am/service/system_applet_proxy.h"
 #include "core/hle/service/cmif_serialization.h"
 
 namespace Service::AM {
@@ -37,8 +37,8 @@ Result IAllSystemAppletProxiesService::OpenSystemAppletProxy(
     LOG_DEBUG(Service_AM, "called");
 
     if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
-        *out_system_applet_proxy =
-            std::make_shared<ISystemAppletProxy>(m_nvnflinger, applet, system);
+        *out_system_applet_proxy = std::make_shared<ISystemAppletProxy>(
+            system, applet, process_handle.Get(), m_nvnflinger);
         R_SUCCEED();
     } else {
         UNIMPLEMENTED();
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
new file mode 100644
index 000000000..0a69d1502
--- /dev/null
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -0,0 +1,132 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/am/applet_common_functions.h"
+#include "core/hle/service/am/application_creator.h"
+#include "core/hle/service/am/audio_controller.h"
+#include "core/hle/service/am/common_state_getter.h"
+#include "core/hle/service/am/debug_functions.h"
+#include "core/hle/service/am/display_controller.h"
+#include "core/hle/service/am/global_state_controller.h"
+#include "core/hle/service/am/home_menu_functions.h"
+#include "core/hle/service/am/library_applet_creator.h"
+#include "core/hle/service/am/library_applet_self_accessor.h"
+#include "core/hle/service/am/process_winding_controller.h"
+#include "core/hle/service/am/self_controller.h"
+#include "core/hle/service/am/service/system_applet_proxy.h"
+#include "core/hle/service/am/window_controller.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
+                                       Kernel::KProcess* process,
+                                       Nvnflinger::Nvnflinger& nvnflinger)
+    : ServiceFramework{system_, "ISystemAppletProxy"},
+      m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
+        {1, D<&ISystemAppletProxy::GetSelfController>, "GetSelfController"},
+        {2, D<&ISystemAppletProxy::GetWindowController>, "GetWindowController"},
+        {3, D<&ISystemAppletProxy::GetAudioController>, "GetAudioController"},
+        {4, D<&ISystemAppletProxy::GetDisplayController>, "GetDisplayController"},
+        {10, D<&ISystemAppletProxy::GetProcessWindingController>, "GetProcessWindingController"},
+        {11, D<&ISystemAppletProxy::GetLibraryAppletCreator>, "GetLibraryAppletCreator"},
+        {20, D<&ISystemAppletProxy::GetHomeMenuFunctions>, "GetHomeMenuFunctions"},
+        {21, D<&ISystemAppletProxy::GetGlobalStateController>, "GetGlobalStateController"},
+        {22, D<&ISystemAppletProxy::GetApplicationCreator>, "GetApplicationCreator"},
+        {23, D<&ISystemAppletProxy::GetAppletCommonFunctions>, "GetAppletCommonFunctions"},
+        {1000, D<&ISystemAppletProxy::GetDebugFunctions>, "GetDebugFunctions"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+ISystemAppletProxy::~ISystemAppletProxy() = default;
+
+Result ISystemAppletProxy::GetAudioController(
+    Out<SharedPointer<IAudioController>> out_audio_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_audio_controller = std::make_shared<IAudioController>(system);
+    R_SUCCEED();
+}
+
+Result ISystemAppletProxy::GetDisplayController(
+    Out<SharedPointer<IDisplayController>> out_display_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_display_controller = std::make_shared<IDisplayController>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result ISystemAppletProxy::GetProcessWindingController(
+    Out<SharedPointer<IProcessWindingController>> out_process_winding_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_process_winding_controller = std::make_shared<IProcessWindingController>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result ISystemAppletProxy::GetDebugFunctions(
+    Out<SharedPointer<IDebugFunctions>> out_debug_functions) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_debug_functions = std::make_shared<IDebugFunctions>(system);
+    R_SUCCEED();
+}
+
+Result ISystemAppletProxy::GetWindowController(
+    Out<SharedPointer<IWindowController>> out_window_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_window_controller = std::make_shared<IWindowController>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result ISystemAppletProxy::GetSelfController(
+    Out<SharedPointer<ISelfController>> out_self_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_nvnflinger);
+    R_SUCCEED();
+}
+
+Result ISystemAppletProxy::GetCommonStateGetter(
+    Out<SharedPointer<ICommonStateGetter>> out_common_state_getter) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_common_state_getter = std::make_shared<ICommonStateGetter>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result ISystemAppletProxy::GetLibraryAppletCreator(
+    Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result ISystemAppletProxy::GetApplicationCreator(
+    Out<SharedPointer<IApplicationCreator>> out_application_creator) {
+    LOG_ERROR(Service_AM, "called");
+    R_THROW(ResultUnknown);
+}
+
+Result ISystemAppletProxy::GetAppletCommonFunctions(
+    Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_applet_common_functions = std::make_shared<IAppletCommonFunctions>(system, m_applet);
+    R_SUCCEED();
+}
+
+Result ISystemAppletProxy::GetHomeMenuFunctions(
+    Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system);
+    R_SUCCEED();
+}
+
+Result ISystemAppletProxy::GetGlobalStateController(
+    Out<SharedPointer<IGlobalStateController>> out_global_state_controller) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_global_state_controller = std::make_shared<IGlobalStateController>(system);
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/system_applet_proxy.h b/src/core/hle/service/am/service/system_applet_proxy.h
new file mode 100644
index 000000000..3d5040315
--- /dev/null
+++ b/src/core/hle/service/am/service/system_applet_proxy.h
@@ -0,0 +1,54 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+struct Applet;
+class IAppletCommonFunctions;
+class IApplicationCreator;
+class IAudioController;
+class ICommonStateGetter;
+class IDebugFunctions;
+class IDisplayController;
+class IHomeMenuFunctions;
+class IGlobalStateController;
+class ILibraryAppletCreator;
+class IProcessWindingController;
+class ISelfController;
+class IWindowController;
+
+class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
+public:
+    explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet,
+                                Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger);
+    ~ISystemAppletProxy();
+
+private:
+    Result GetAudioController(Out<SharedPointer<IAudioController>> out_audio_controller);
+    Result GetDisplayController(Out<SharedPointer<IDisplayController>> out_display_controller);
+    Result GetProcessWindingController(
+        Out<SharedPointer<IProcessWindingController>> out_process_winding_controller);
+    Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions);
+    Result GetWindowController(Out<SharedPointer<IWindowController>> out_window_controller);
+    Result GetSelfController(Out<SharedPointer<ISelfController>> out_self_controller);
+    Result GetCommonStateGetter(Out<SharedPointer<ICommonStateGetter>> out_common_state_getter);
+    Result GetLibraryAppletCreator(
+        Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator);
+    Result GetApplicationCreator(Out<SharedPointer<IApplicationCreator>> out_application_creator);
+    Result GetAppletCommonFunctions(
+        Out<SharedPointer<IAppletCommonFunctions>> out_applet_common_functions);
+    Result GetHomeMenuFunctions(Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions);
+    Result GetGlobalStateController(
+        Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
+
+    Nvnflinger::Nvnflinger& m_nvnflinger;
+    Kernel::KProcess* const m_process;
+    const std::shared_ptr<Applet> m_applet;
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/system_applet_proxy.cpp b/src/core/hle/service/am/system_applet_proxy.cpp
deleted file mode 100644
index 38643408e..000000000
--- a/src/core/hle/service/am/system_applet_proxy.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/am/applet_common_functions.h"
-#include "core/hle/service/am/application_creator.h"
-#include "core/hle/service/am/audio_controller.h"
-#include "core/hle/service/am/common_state_getter.h"
-#include "core/hle/service/am/debug_functions.h"
-#include "core/hle/service/am/display_controller.h"
-#include "core/hle/service/am/global_state_controller.h"
-#include "core/hle/service/am/home_menu_functions.h"
-#include "core/hle/service/am/library_applet_creator.h"
-#include "core/hle/service/am/library_applet_self_accessor.h"
-#include "core/hle/service/am/process_winding_controller.h"
-#include "core/hle/service/am/self_controller.h"
-#include "core/hle/service/am/system_applet_proxy.h"
-#include "core/hle/service/am/window_controller.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-ISystemAppletProxy::ISystemAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_,
-                                       std::shared_ptr<Applet> applet_, Core::System& system_)
-    : ServiceFramework{system_, "ISystemAppletProxy"}, nvnflinger{nvnflinger_}, applet{std::move(
-                                                                                    applet_)} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
-        {1, &ISystemAppletProxy::GetSelfController, "GetSelfController"},
-        {2, &ISystemAppletProxy::GetWindowController, "GetWindowController"},
-        {3, &ISystemAppletProxy::GetAudioController, "GetAudioController"},
-        {4, &ISystemAppletProxy::GetDisplayController, "GetDisplayController"},
-        {10, nullptr, "GetProcessWindingController"},
-        {11, &ISystemAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"},
-        {20, &ISystemAppletProxy::GetHomeMenuFunctions, "GetHomeMenuFunctions"},
-        {21, &ISystemAppletProxy::GetGlobalStateController, "GetGlobalStateController"},
-        {22, &ISystemAppletProxy::GetApplicationCreator, "GetApplicationCreator"},
-        {23,  &ISystemAppletProxy::GetAppletCommonFunctions, "GetAppletCommonFunctions"},
-        {1000, &ISystemAppletProxy::GetDebugFunctions, "GetDebugFunctions"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-ISystemAppletProxy::~ISystemAppletProxy() = default;
-
-void ISystemAppletProxy::GetCommonStateGetter(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ICommonStateGetter>(system, applet);
-}
-
-void ISystemAppletProxy::GetSelfController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ISelfController>(system, applet, nvnflinger);
-}
-
-void ISystemAppletProxy::GetWindowController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IWindowController>(system, applet);
-}
-
-void ISystemAppletProxy::GetAudioController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IAudioController>(system);
-}
-
-void ISystemAppletProxy::GetDisplayController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IDisplayController>(system, applet);
-}
-
-void ISystemAppletProxy::GetLibraryAppletCreator(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ILibraryAppletCreator>(system, applet);
-}
-
-void ISystemAppletProxy::GetHomeMenuFunctions(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IHomeMenuFunctions>(system);
-}
-
-void ISystemAppletProxy::GetGlobalStateController(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IGlobalStateController>(system);
-}
-
-void ISystemAppletProxy::GetApplicationCreator(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IApplicationCreator>(system);
-}
-
-void ISystemAppletProxy::GetAppletCommonFunctions(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IAppletCommonFunctions>(system, applet);
-}
-
-void ISystemAppletProxy::GetDebugFunctions(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IDebugFunctions>(system);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/system_applet_proxy.h b/src/core/hle/service/am/system_applet_proxy.h
deleted file mode 100644
index 0390cd1e5..000000000
--- a/src/core/hle/service/am/system_applet_proxy.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/am/applet_message_queue.h"
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-struct Applet;
-
-class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
-public:
-    explicit ISystemAppletProxy(Nvnflinger::Nvnflinger& nvnflinger_,
-                                std::shared_ptr<Applet> applet_, Core::System& system_);
-    ~ISystemAppletProxy();
-
-private:
-    void GetCommonStateGetter(HLERequestContext& ctx);
-    void GetSelfController(HLERequestContext& ctx);
-    void GetWindowController(HLERequestContext& ctx);
-    void GetAudioController(HLERequestContext& ctx);
-    void GetDisplayController(HLERequestContext& ctx);
-    void GetLibraryAppletCreator(HLERequestContext& ctx);
-    void GetHomeMenuFunctions(HLERequestContext& ctx);
-    void GetGlobalStateController(HLERequestContext& ctx);
-    void GetApplicationCreator(HLERequestContext& ctx);
-    void GetAppletCommonFunctions(HLERequestContext& ctx);
-    void GetDebugFunctions(HLERequestContext& ctx);
-
-    Nvnflinger::Nvnflinger& nvnflinger;
-    std::shared_ptr<Applet> applet;
-};
-
-} // namespace Service::AM

From 590e86792c496366fd4811c530a20ee91f6bfa8d Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 19:20:41 -0500
Subject: [PATCH 05/24] am: rewrite IAudioController

---
 src/core/CMakeLists.txt                       |  4 +-
 src/core/hle/service/am/audio_controller.cpp  | 91 -------------------
 src/core/hle/service/am/audio_controller.h    | 36 --------
 .../service/am/service/application_proxy.cpp  |  2 +-
 .../service/am/service/audio_controller.cpp   | 69 ++++++++++++++
 .../hle/service/am/service/audio_controller.h | 37 ++++++++
 .../am/service/library_applet_proxy.cpp       |  2 +-
 .../am/service/system_applet_proxy.cpp        |  2 +-
 8 files changed, 111 insertions(+), 132 deletions(-)
 delete mode 100644 src/core/hle/service/am/audio_controller.cpp
 delete mode 100644 src/core/hle/service/am/audio_controller.h
 create mode 100644 src/core/hle/service/am/service/audio_controller.cpp
 create mode 100644 src/core/hle/service/am/service/audio_controller.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 4486a355c..8e4928e08 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -429,8 +429,6 @@ add_library(core STATIC
     hle/service/am/application_creator.h
     hle/service/am/application_functions.cpp
     hle/service/am/application_functions.h
-    hle/service/am/audio_controller.cpp
-    hle/service/am/audio_controller.h
     hle/service/am/common_state_getter.cpp
     hle/service/am/common_state_getter.h
     hle/service/am/debug_functions.cpp
@@ -471,6 +469,8 @@ add_library(core STATIC
     hle/service/am/service/application_proxy_service.h
     hle/service/am/service/application_proxy.cpp
     hle/service/am/service/application_proxy.h
+    hle/service/am/service/audio_controller.cpp
+    hle/service/am/service/audio_controller.h
     hle/service/am/service/library_applet_proxy.cpp
     hle/service/am/service/library_applet_proxy.h
     hle/service/am/service/system_applet_proxy.cpp
diff --git a/src/core/hle/service/am/audio_controller.cpp b/src/core/hle/service/am/audio_controller.cpp
deleted file mode 100644
index ae75db174..000000000
--- a/src/core/hle/service/am/audio_controller.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/am/audio_controller.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-IAudioController::IAudioController(Core::System& system_)
-    : ServiceFramework{system_, "IAudioController"} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {0, &IAudioController::SetExpectedMasterVolume, "SetExpectedMasterVolume"},
-        {1, &IAudioController::GetMainAppletExpectedMasterVolume, "GetMainAppletExpectedMasterVolume"},
-        {2, &IAudioController::GetLibraryAppletExpectedMasterVolume, "GetLibraryAppletExpectedMasterVolume"},
-        {3, &IAudioController::ChangeMainAppletMasterVolume, "ChangeMainAppletMasterVolume"},
-        {4, &IAudioController::SetTransparentAudioRate, "SetTransparentVolumeRate"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-IAudioController::~IAudioController() = default;
-
-void IAudioController::SetExpectedMasterVolume(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const float main_applet_volume_tmp = rp.Pop<float>();
-    const float library_applet_volume_tmp = rp.Pop<float>();
-
-    LOG_DEBUG(Service_AM, "called. main_applet_volume={}, library_applet_volume={}",
-              main_applet_volume_tmp, library_applet_volume_tmp);
-
-    // Ensure the volume values remain within the 0-100% range
-    main_applet_volume = std::clamp(main_applet_volume_tmp, min_allowed_volume, max_allowed_volume);
-    library_applet_volume =
-        std::clamp(library_applet_volume_tmp, min_allowed_volume, max_allowed_volume);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IAudioController::GetMainAppletExpectedMasterVolume(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called. main_applet_volume={}", main_applet_volume);
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push(main_applet_volume);
-}
-
-void IAudioController::GetLibraryAppletExpectedMasterVolume(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called. library_applet_volume={}", library_applet_volume);
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push(library_applet_volume);
-}
-
-void IAudioController::ChangeMainAppletMasterVolume(HLERequestContext& ctx) {
-    struct Parameters {
-        float volume;
-        s64 fade_time_ns;
-    };
-    static_assert(sizeof(Parameters) == 16);
-
-    IPC::RequestParser rp{ctx};
-    const auto parameters = rp.PopRaw<Parameters>();
-
-    LOG_DEBUG(Service_AM, "called. volume={}, fade_time_ns={}", parameters.volume,
-              parameters.fade_time_ns);
-
-    main_applet_volume = std::clamp(parameters.volume, min_allowed_volume, max_allowed_volume);
-    fade_time_ns = std::chrono::nanoseconds{parameters.fade_time_ns};
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IAudioController::SetTransparentAudioRate(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const float transparent_volume_rate_tmp = rp.Pop<float>();
-
-    LOG_DEBUG(Service_AM, "called. transparent_volume_rate={}", transparent_volume_rate_tmp);
-
-    // Clamp volume range to 0-100%.
-    transparent_volume_rate =
-        std::clamp(transparent_volume_rate_tmp, min_allowed_volume, max_allowed_volume);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/audio_controller.h b/src/core/hle/service/am/audio_controller.h
deleted file mode 100644
index a47e3bad8..000000000
--- a/src/core/hle/service/am/audio_controller.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-class IAudioController final : public ServiceFramework<IAudioController> {
-public:
-    explicit IAudioController(Core::System& system_);
-    ~IAudioController() override;
-
-private:
-    void SetExpectedMasterVolume(HLERequestContext& ctx);
-    void GetMainAppletExpectedMasterVolume(HLERequestContext& ctx);
-    void GetLibraryAppletExpectedMasterVolume(HLERequestContext& ctx);
-    void ChangeMainAppletMasterVolume(HLERequestContext& ctx);
-    void SetTransparentAudioRate(HLERequestContext& ctx);
-
-    static constexpr float min_allowed_volume = 0.0f;
-    static constexpr float max_allowed_volume = 1.0f;
-
-    float main_applet_volume{0.25f};
-    float library_applet_volume{max_allowed_volume};
-    float transparent_volume_rate{min_allowed_volume};
-
-    // Volume transition fade time in nanoseconds.
-    // e.g. If the main applet volume was 0% and was changed to 50%
-    //      with a fade of 50ns, then over the course of 50ns,
-    //      the volume will gradually fade up to 50%
-    std::chrono::nanoseconds fade_time_ns{0};
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index d1f87709e..d28321a4a 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -3,7 +3,6 @@
 
 #include "core/hle/service/am/applet_common_functions.h"
 #include "core/hle/service/am/application_functions.h"
-#include "core/hle/service/am/audio_controller.h"
 #include "core/hle/service/am/common_state_getter.h"
 #include "core/hle/service/am/debug_functions.h"
 #include "core/hle/service/am/display_controller.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/application_proxy.h"
+#include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
diff --git a/src/core/hle/service/am/service/audio_controller.cpp b/src/core/hle/service/am/service/audio_controller.cpp
new file mode 100644
index 000000000..ad731c7bd
--- /dev/null
+++ b/src/core/hle/service/am/service/audio_controller.cpp
@@ -0,0 +1,69 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/am/service/audio_controller.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+IAudioController::IAudioController(Core::System& system_)
+    : ServiceFramework{system_, "IAudioController"} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, D<&IAudioController::SetExpectedMasterVolume>, "SetExpectedMasterVolume"},
+        {1, D<&IAudioController::GetMainAppletExpectedMasterVolume>, "GetMainAppletExpectedMasterVolume"},
+        {2, D<&IAudioController::GetLibraryAppletExpectedMasterVolume>, "GetLibraryAppletExpectedMasterVolume"},
+        {3, D<&IAudioController::ChangeMainAppletMasterVolume>, "ChangeMainAppletMasterVolume"},
+        {4, D<&IAudioController::SetTransparentVolumeRate>, "SetTransparentVolumeRate"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IAudioController::~IAudioController() = default;
+
+Result IAudioController::SetExpectedMasterVolume(f32 main_applet_volume,
+                                                 f32 library_applet_volume) {
+    LOG_DEBUG(Service_AM, "called. main_applet_volume={}, library_applet_volume={}",
+              main_applet_volume, library_applet_volume);
+
+    // Ensure the volume values remain within the 0-100% range
+    m_main_applet_volume = std::clamp(main_applet_volume, MinAllowedVolume, MaxAllowedVolume);
+    m_library_applet_volume = std::clamp(library_applet_volume, MinAllowedVolume, MaxAllowedVolume);
+
+    R_SUCCEED();
+}
+
+Result IAudioController::GetMainAppletExpectedMasterVolume(Out<f32> out_main_applet_volume) {
+    LOG_DEBUG(Service_AM, "called. main_applet_volume={}", m_main_applet_volume);
+    *out_main_applet_volume = m_main_applet_volume;
+    R_SUCCEED();
+}
+
+Result IAudioController::GetLibraryAppletExpectedMasterVolume(Out<f32> out_library_applet_volume) {
+    LOG_DEBUG(Service_AM, "called. library_applet_volume={}", m_library_applet_volume);
+    *out_library_applet_volume = m_library_applet_volume;
+    R_SUCCEED();
+}
+
+Result IAudioController::ChangeMainAppletMasterVolume(f32 volume, s64 fade_time_ns) {
+    LOG_DEBUG(Service_AM, "called. volume={}, fade_time_ns={}", volume, fade_time_ns);
+
+    m_main_applet_volume = std::clamp(volume, MinAllowedVolume, MaxAllowedVolume);
+    m_fade_time_ns = std::chrono::nanoseconds{fade_time_ns};
+
+    R_SUCCEED();
+}
+
+Result IAudioController::SetTransparentVolumeRate(f32 transparent_volume_rate) {
+    LOG_DEBUG(Service_AM, "called. transparent_volume_rate={}", transparent_volume_rate);
+
+    // Clamp volume range to 0-100%.
+    m_transparent_volume_rate =
+        std::clamp(transparent_volume_rate, MinAllowedVolume, MaxAllowedVolume);
+
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/audio_controller.h b/src/core/hle/service/am/service/audio_controller.h
new file mode 100644
index 000000000..4b0f3f9ae
--- /dev/null
+++ b/src/core/hle/service/am/service/audio_controller.h
@@ -0,0 +1,37 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+class IAudioController final : public ServiceFramework<IAudioController> {
+public:
+    explicit IAudioController(Core::System& system_);
+    ~IAudioController() override;
+
+private:
+    Result SetExpectedMasterVolume(f32 main_applet_volume, f32 library_applet_volume);
+    Result GetMainAppletExpectedMasterVolume(Out<f32> out_main_applet_volume);
+    Result GetLibraryAppletExpectedMasterVolume(Out<f32> out_library_applet_volume);
+    Result ChangeMainAppletMasterVolume(f32 volume, s64 fade_time_ns);
+    Result SetTransparentVolumeRate(f32 transparent_volume_rate);
+
+    static constexpr float MinAllowedVolume = 0.0f;
+    static constexpr float MaxAllowedVolume = 1.0f;
+
+    float m_main_applet_volume{0.25f};
+    float m_library_applet_volume{MaxAllowedVolume};
+    float m_transparent_volume_rate{MinAllowedVolume};
+
+    // Volume transition fade time in nanoseconds.
+    // e.g. If the main applet volume was 0% and was changed to 50%
+    //      with a fade of 50ns, then over the course of 50ns,
+    //      the volume will gradually fade up to 50%
+    std::chrono::nanoseconds m_fade_time_ns{0};
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index 9a0d363ac..dd0f8ff11 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -2,7 +2,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/applet_common_functions.h"
-#include "core/hle/service/am/audio_controller.h"
 #include "core/hle/service/am/common_state_getter.h"
 #include "core/hle/service/am/debug_functions.h"
 #include "core/hle/service/am/display_controller.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/library_applet_self_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
+#include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/library_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index 0a69d1502..cc1f83fef 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -3,7 +3,6 @@
 
 #include "core/hle/service/am/applet_common_functions.h"
 #include "core/hle/service/am/application_creator.h"
-#include "core/hle/service/am/audio_controller.h"
 #include "core/hle/service/am/common_state_getter.h"
 #include "core/hle/service/am/debug_functions.h"
 #include "core/hle/service/am/display_controller.h"
@@ -13,6 +12,7 @@
 #include "core/hle/service/am/library_applet_self_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
+#include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/system_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"

From af35057212949c4a1088157b4f2e6e592f23f5ee Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 19:23:26 -0500
Subject: [PATCH 06/24] am: rewrite IAppletCommonFunctions

---
 src/core/CMakeLists.txt                       |  4 +--
 .../{ => service}/applet_common_functions.cpp | 36 +++++++++----------
 .../{ => service}/applet_common_functions.h   |  6 ++--
 .../service/am/service/application_proxy.cpp  |  2 +-
 .../am/service/library_applet_proxy.cpp       |  2 +-
 .../am/service/system_applet_proxy.cpp        |  2 +-
 6 files changed, 27 insertions(+), 25 deletions(-)
 rename src/core/hle/service/am/{ => service}/applet_common_functions.cpp (63%)
 rename src/core/hle/service/am/{ => service}/applet_common_functions.h (67%)

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 8e4928e08..236051515 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -421,8 +421,6 @@ add_library(core STATIC
     hle/service/am/applet_data_broker.cpp
     hle/service/am/applet_data_broker.h
     hle/service/am/applet_manager.h
-    hle/service/am/applet_common_functions.cpp
-    hle/service/am/applet_common_functions.h
     hle/service/am/applet_message_queue.cpp
     hle/service/am/applet_message_queue.h
     hle/service/am/application_creator.cpp
@@ -465,6 +463,8 @@ add_library(core STATIC
     hle/service/am/self_controller.h
     hle/service/am/service/all_system_applet_proxies_service.cpp
     hle/service/am/service/all_system_applet_proxies_service.h
+    hle/service/am/service/applet_common_functions.cpp
+    hle/service/am/service/applet_common_functions.h
     hle/service/am/service/application_proxy_service.cpp
     hle/service/am/service/application_proxy_service.h
     hle/service/am/service/application_proxy.cpp
diff --git a/src/core/hle/service/am/applet_common_functions.cpp b/src/core/hle/service/am/service/applet_common_functions.cpp
similarity index 63%
rename from src/core/hle/service/am/applet_common_functions.cpp
rename to src/core/hle/service/am/service/applet_common_functions.cpp
index 130614ae5..0f29ab285 100644
--- a/src/core/hle/service/am/applet_common_functions.cpp
+++ b/src/core/hle/service/am/service/applet_common_functions.cpp
@@ -2,8 +2,8 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/applet.h"
-#include "core/hle/service/am/applet_common_functions.h"
-#include "core/hle/service/ipc_helpers.h"
+#include "core/hle/service/am/service/applet_common_functions.h"
+#include "core/hle/service/cmif_serialization.h"
 
 namespace Service::AM {
 
@@ -20,18 +20,18 @@ IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_,
         {40, nullptr, "GetDisplayLogicalResolution"},
         {42, nullptr, "SetDisplayMagnification"},
         {50, nullptr, "SetHomeButtonDoubleClickEnabled"},
-        {51, nullptr, "GetHomeButtonDoubleClickEnabled"},
+        {51, D<&IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled>, "GetHomeButtonDoubleClickEnabled"},
         {52, nullptr, "IsHomeButtonShortPressedBlocked"},
         {60, nullptr, "IsVrModeCurtainRequired"},
         {61, nullptr, "IsSleepRequiredByHighTemperature"},
         {62, nullptr, "IsSleepRequiredByLowBattery"},
-        {70, &IAppletCommonFunctions::SetCpuBoostRequestPriority, "SetCpuBoostRequestPriority"},
+        {70, D<&IAppletCommonFunctions::SetCpuBoostRequestPriority>, "SetCpuBoostRequestPriority"},
         {80, nullptr, "SetHandlingCaptureButtonShortPressedMessageEnabledForApplet"},
         {81, nullptr, "SetHandlingCaptureButtonLongPressedMessageEnabledForApplet"},
         {90, nullptr, "OpenNamedChannelAsParent"},
         {91, nullptr, "OpenNamedChannelAsChild"},
         {100, nullptr, "SetApplicationCoreUsageMode"},
-        {300, &IAppletCommonFunctions::GetCurrentApplicationId, "GetCurrentApplicationId"},
+        {300, D<&IAppletCommonFunctions::GetCurrentApplicationId>, "GetCurrentApplicationId"},
     };
     // clang-format on
 
@@ -40,24 +40,24 @@ IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_,
 
 IAppletCommonFunctions::~IAppletCommonFunctions() = default;
 
-void IAppletCommonFunctions::SetCpuBoostRequestPriority(HLERequestContext& ctx) {
+Result IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled(
+    Out<bool> out_home_button_double_click_enabled) {
     LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::RequestParser rp{ctx};
-
-    std::scoped_lock lk{applet->lock};
-    applet->cpu_boost_request_priority = rp.Pop<s32>();
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
+    *out_home_button_double_click_enabled = false;
+    R_SUCCEED();
 }
 
-void IAppletCommonFunctions::GetCurrentApplicationId(HLERequestContext& ctx) {
+Result IAppletCommonFunctions::SetCpuBoostRequestPriority(s32 priority) {
     LOG_WARNING(Service_AM, "(STUBBED) called");
+    std::scoped_lock lk{applet->lock};
+    applet->cpu_boost_request_priority = priority;
+    R_SUCCEED();
+}
 
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.Push<u64>(system.GetApplicationProcessProgramID() & ~0xFFFULL);
+Result IAppletCommonFunctions::GetCurrentApplicationId(Out<u64> out_application_id) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_application_id = system.GetApplicationProcessProgramID() & ~0xFFFULL;
+    R_SUCCEED();
 }
 
 } // namespace Service::AM
diff --git a/src/core/hle/service/am/applet_common_functions.h b/src/core/hle/service/am/service/applet_common_functions.h
similarity index 67%
rename from src/core/hle/service/am/applet_common_functions.h
rename to src/core/hle/service/am/service/applet_common_functions.h
index b86adf5cb..4424fc83d 100644
--- a/src/core/hle/service/am/applet_common_functions.h
+++ b/src/core/hle/service/am/service/applet_common_functions.h
@@ -3,6 +3,7 @@
 
 #pragma once
 
+#include "core/hle/service/cmif_types.h"
 #include "core/hle/service/service.h"
 
 namespace Service::AM {
@@ -15,8 +16,9 @@ public:
     ~IAppletCommonFunctions() override;
 
 private:
-    void SetCpuBoostRequestPriority(HLERequestContext& ctx);
-    void GetCurrentApplicationId(HLERequestContext& ctx);
+    Result GetHomeButtonDoubleClickEnabled(Out<bool> out_home_button_double_click_enabled);
+    Result SetCpuBoostRequestPriority(s32 priority);
+    Result GetCurrentApplicationId(Out<u64> out_application_id);
 
     const std::shared_ptr<Applet> applet;
 };
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index d28321a4a..b22960610 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/applet_common_functions.h"
 #include "core/hle/service/am/application_functions.h"
 #include "core/hle/service/am/common_state_getter.h"
 #include "core/hle/service/am/debug_functions.h"
@@ -10,6 +9,7 @@
 #include "core/hle/service/am/library_applet_self_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
+#include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/application_proxy.h"
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/window_controller.h"
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index dd0f8ff11..c4ea9392a 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/applet_common_functions.h"
 #include "core/hle/service/am/common_state_getter.h"
 #include "core/hle/service/am/debug_functions.h"
 #include "core/hle/service/am/display_controller.h"
@@ -11,6 +10,7 @@
 #include "core/hle/service/am/library_applet_self_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
+#include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/library_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index cc1f83fef..c63b53ac8 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/applet_common_functions.h"
 #include "core/hle/service/am/application_creator.h"
 #include "core/hle/service/am/common_state_getter.h"
 #include "core/hle/service/am/debug_functions.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/library_applet_self_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
+#include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/system_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"

From 44e7e85f231b611130f71405b5258f5250e8785b Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 19:31:01 -0500
Subject: [PATCH 07/24] am: rewrite IApplicationFunctions

---
 src/core/CMakeLists.txt                       |   4 +-
 src/core/hle/service/am/am_types.h            |  38 +-
 src/core/hle/service/am/applet.h              |   4 +-
 .../hle/service/am/application_functions.cpp  | 594 ------------------
 .../hle/service/am/application_functions.h    |  58 --
 .../am/service/application_functions.cpp      | 465 ++++++++++++++
 .../am/service/application_functions.h        |  83 +++
 .../service/am/service/application_proxy.cpp  |   2 +-
 8 files changed, 590 insertions(+), 658 deletions(-)
 delete mode 100644 src/core/hle/service/am/application_functions.cpp
 delete mode 100644 src/core/hle/service/am/application_functions.h
 create mode 100644 src/core/hle/service/am/service/application_functions.cpp
 create mode 100644 src/core/hle/service/am/service/application_functions.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 236051515..5d3f4cf1d 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -425,8 +425,6 @@ add_library(core STATIC
     hle/service/am/applet_message_queue.h
     hle/service/am/application_creator.cpp
     hle/service/am/application_creator.h
-    hle/service/am/application_functions.cpp
-    hle/service/am/application_functions.h
     hle/service/am/common_state_getter.cpp
     hle/service/am/common_state_getter.h
     hle/service/am/debug_functions.cpp
@@ -465,6 +463,8 @@ add_library(core STATIC
     hle/service/am/service/all_system_applet_proxies_service.h
     hle/service/am/service/applet_common_functions.cpp
     hle/service/am/service/applet_common_functions.h
+    hle/service/am/service/application_functions.cpp
+    hle/service/am/service/application_functions.h
     hle/service/am/service/application_proxy_service.cpp
     hle/service/am/service/application_proxy_service.h
     hle/service/am/service/application_proxy.cpp
diff --git a/src/core/hle/service/am/am_types.h b/src/core/hle/service/am/am_types.h
index 749081e3d..bf2272c0e 100644
--- a/src/core/hle/service/am/am_types.h
+++ b/src/core/hle/service/am/am_types.h
@@ -18,7 +18,7 @@ enum class AppletType {
     SystemApplet,
 };
 
-enum class GameplayRecordingState : u32 {
+enum class GamePlayRecordingState : u32 {
     Disabled,
     Enabled,
 };
@@ -136,6 +136,11 @@ enum class LibraryAppletMode : u32 {
     AllForegroundInitiallyHidden = 4,
 };
 
+enum class LaunchParameterKind : u32 {
+    UserChannel = 1,
+    AccountPreselectedUser = 2,
+};
+
 enum class CommonArgumentVersion : u32 {
     Version0,
     Version1,
@@ -152,6 +157,22 @@ enum class ThemeColor : u32 {
     BasicBlack = 3,
 };
 
+enum class InputDetectionPolicy : u32 {
+    Unknown0 = 0,
+    Unknown1 = 1,
+};
+
+enum class WindowOriginMode : u32 {
+    LowerLeft = 0,
+    UpperLeft = 1,
+};
+
+enum class ProgramSpecifyKind : u32 {
+    ExecuteProgram = 0,
+    JumpToSubApplicationProgramForDevelopment = 1,
+    RestartProgram = 2,
+};
+
 struct CommonArguments {
     CommonArgumentVersion arguments_version;
     CommonArgumentSize size;
@@ -175,6 +196,21 @@ struct AppletAttribute {
 };
 static_assert(sizeof(AppletAttribute) == 0x80, "AppletAttribute has incorrect size.");
 
+// This is nn::oe::DisplayVersion
+struct DisplayVersion {
+    std::array<char, 0x10> string;
+};
+static_assert(sizeof(DisplayVersion) == 0x10, "DisplayVersion has incorrect size.");
+
+// This is nn::pdm::ApplicationPlayStatistics
+struct ApplicationPlayStatistics {
+    u64 application_id;
+    u64 play_time_ns;
+    u64 launch_count;
+};
+static_assert(sizeof(ApplicationPlayStatistics) == 0x18,
+              "ApplicationPlayStatistics has incorrect size.");
+
 using AppletResourceUserId = u64;
 using ProgramId = u64;
 
diff --git a/src/core/hle/service/am/applet.h b/src/core/hle/service/am/applet.h
index b29ecdfed..6c593ab1a 100644
--- a/src/core/hle/service/am/applet.h
+++ b/src/core/hle/service/am/applet.h
@@ -76,8 +76,8 @@ struct Applet {
     u32 application_core_usage_mode{};
 
     // Application functions
-    bool gameplay_recording_supported{};
-    GameplayRecordingState gameplay_recording_state{GameplayRecordingState::Disabled};
+    bool game_play_recording_supported{};
+    GamePlayRecordingState game_play_recording_state{GamePlayRecordingState::Disabled};
     bool jit_service_launched{};
     bool is_running{};
     bool application_crash_report_enabled{};
diff --git a/src/core/hle/service/am/application_functions.cpp b/src/core/hle/service/am/application_functions.cpp
deleted file mode 100644
index 51c5be2d1..000000000
--- a/src/core/hle/service/am/application_functions.cpp
+++ /dev/null
@@ -1,594 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/settings.h"
-#include "common/uuid.h"
-#include "core/file_sys/control_metadata.h"
-#include "core/file_sys/patch_manager.h"
-#include "core/file_sys/registered_cache.h"
-#include "core/file_sys/savedata_factory.h"
-#include "core/hle/service/acc/profile_manager.h"
-#include "core/hle/service/am/am_results.h"
-#include "core/hle/service/am/applet.h"
-#include "core/hle/service/am/application_functions.h"
-#include "core/hle/service/am/storage.h"
-#include "core/hle/service/filesystem/filesystem.h"
-#include "core/hle/service/filesystem/save_data_controller.h"
-#include "core/hle/service/ipc_helpers.h"
-#include "core/hle/service/ns/ns.h"
-#include "core/hle/service/sm/sm.h"
-
-namespace Service::AM {
-
-enum class LaunchParameterKind : u32 {
-    UserChannel = 1,
-    AccountPreselectedUser = 2,
-};
-
-IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet_)
-    : ServiceFramework{system_, "IApplicationFunctions"}, applet{std::move(applet_)} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
-        {10, nullptr, "CreateApplicationAndPushAndRequestToStart"},
-        {11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"},
-        {12, nullptr, "CreateApplicationAndRequestToStart"},
-        {13, &IApplicationFunctions::CreateApplicationAndRequestToStartForQuest, "CreateApplicationAndRequestToStartForQuest"},
-        {14, nullptr, "CreateApplicationWithAttributeAndPushAndRequestToStartForQuest"},
-        {15, nullptr, "CreateApplicationWithAttributeAndRequestToStartForQuest"},
-        {20, &IApplicationFunctions::EnsureSaveData, "EnsureSaveData"},
-        {21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"},
-        {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
-        {23, &IApplicationFunctions::GetDisplayVersion, "GetDisplayVersion"},
-        {24, nullptr, "GetLaunchStorageInfoForDebug"},
-        {25, &IApplicationFunctions::ExtendSaveData, "ExtendSaveData"},
-        {26, &IApplicationFunctions::GetSaveDataSize, "GetSaveDataSize"},
-        {27, &IApplicationFunctions::CreateCacheStorage, "CreateCacheStorage"},
-        {28, &IApplicationFunctions::GetSaveDataSizeMax, "GetSaveDataSizeMax"},
-        {29, nullptr, "GetCacheStorageMax"},
-        {30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"},
-        {31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"},
-        {32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"},
-        {33, &IApplicationFunctions::EndBlockingHomeButton, "EndBlockingHomeButton"},
-        {34, nullptr, "SelectApplicationLicense"},
-        {35, nullptr, "GetDeviceSaveDataSizeMax"},
-        {36, nullptr, "GetLimitedApplicationLicense"},
-        {37, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"},
-        {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
-        {50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"},
-        {60, nullptr, "SetMediaPlaybackStateForApplication"},
-        {65, &IApplicationFunctions::IsGamePlayRecordingSupported, "IsGamePlayRecordingSupported"},
-        {66, &IApplicationFunctions::InitializeGamePlayRecording, "InitializeGamePlayRecording"},
-        {67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
-        {68, nullptr, "RequestFlushGamePlayingMovieForDebug"},
-        {70, nullptr, "RequestToShutdown"},
-        {71, nullptr, "RequestToReboot"},
-        {72, nullptr, "RequestToSleep"},
-        {80, nullptr, "ExitAndRequestToShowThanksMessage"},
-        {90, &IApplicationFunctions::EnableApplicationCrashReport, "EnableApplicationCrashReport"},
-        {100, &IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer, "InitializeApplicationCopyrightFrameBuffer"},
-        {101, &IApplicationFunctions::SetApplicationCopyrightImage, "SetApplicationCopyrightImage"},
-        {102, &IApplicationFunctions::SetApplicationCopyrightVisibility, "SetApplicationCopyrightVisibility"},
-        {110, &IApplicationFunctions::QueryApplicationPlayStatistics, "QueryApplicationPlayStatistics"},
-        {111, &IApplicationFunctions::QueryApplicationPlayStatisticsByUid, "QueryApplicationPlayStatisticsByUid"},
-        {120, &IApplicationFunctions::ExecuteProgram, "ExecuteProgram"},
-        {121, &IApplicationFunctions::ClearUserChannel, "ClearUserChannel"},
-        {122, &IApplicationFunctions::UnpopToUserChannel, "UnpopToUserChannel"},
-        {123, &IApplicationFunctions::GetPreviousProgramIndex, "GetPreviousProgramIndex"},
-        {124, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
-        {130, &IApplicationFunctions::GetGpuErrorDetectedSystemEvent, "GetGpuErrorDetectedSystemEvent"},
-        {131, nullptr, "SetDelayTimeToAbortOnGpuError"},
-        {140, &IApplicationFunctions::GetFriendInvitationStorageChannelEvent, "GetFriendInvitationStorageChannelEvent"},
-        {141, &IApplicationFunctions::TryPopFromFriendInvitationStorageChannel, "TryPopFromFriendInvitationStorageChannel"},
-        {150, &IApplicationFunctions::GetNotificationStorageChannelEvent, "GetNotificationStorageChannelEvent"},
-        {151, nullptr, "TryPopFromNotificationStorageChannel"},
-        {160, &IApplicationFunctions::GetHealthWarningDisappearedSystemEvent, "GetHealthWarningDisappearedSystemEvent"},
-        {170, nullptr, "SetHdcpAuthenticationActivated"},
-        {180, nullptr, "GetLaunchRequiredVersion"},
-        {181, nullptr, "UpgradeLaunchRequiredVersion"},
-        {190, nullptr, "SendServerMaintenanceOverlayNotification"},
-        {200, nullptr, "GetLastApplicationExitReason"},
-        {500, nullptr, "StartContinuousRecordingFlushForDebug"},
-        {1000, nullptr, "CreateMovieMaker"},
-        {1001, &IApplicationFunctions::PrepareForJit, "PrepareForJit"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-IApplicationFunctions::~IApplicationFunctions() = default;
-
-void IApplicationFunctions::EnableApplicationCrashReport(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-    applet->application_crash_report_enabled = true;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IApplicationFunctions::SetApplicationCopyrightImage(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IApplicationFunctions::SetApplicationCopyrightVisibility(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto is_visible = rp.Pop<bool>();
-
-    LOG_WARNING(Service_AM, "(STUBBED) called, is_visible={}", is_visible);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-    applet->home_button_long_pressed_blocked = true;
-    applet->home_button_short_pressed_blocked = true;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-    applet->home_button_long_pressed_blocked = false;
-    applet->home_button_short_pressed_blocked = false;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IApplicationFunctions::BeginBlockingHomeButton(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-    applet->home_button_long_pressed_blocked = true;
-    applet->home_button_short_pressed_blocked = true;
-    applet->home_button_double_click_enabled = true;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IApplicationFunctions::EndBlockingHomeButton(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-    applet->home_button_long_pressed_blocked = false;
-    applet->home_button_short_pressed_blocked = false;
-    applet->home_button_double_click_enabled = false;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IApplicationFunctions::PopLaunchParameter(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto kind = rp.PopEnum<LaunchParameterKind>();
-
-    LOG_INFO(Service_AM, "called, kind={:08X}", kind);
-
-    std::scoped_lock lk{applet->lock};
-
-    auto& channel = kind == LaunchParameterKind::UserChannel
-                        ? applet->user_channel_launch_parameter
-                        : applet->preselected_user_launch_parameter;
-
-    if (channel.empty()) {
-        LOG_WARNING(Service_AM, "Attempted to pop parameter {} but none was found!", kind);
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(AM::ResultNoDataInChannel);
-        return;
-    }
-
-    auto data = channel.back();
-    channel.pop_back();
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IStorage>(system, std::move(data));
-}
-
-void IApplicationFunctions::CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IApplicationFunctions::EnsureSaveData(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    u128 user_id = rp.PopRaw<u128>();
-
-    LOG_DEBUG(Service_AM, "called, uid={:016X}{:016X}", user_id[1], user_id[0]);
-
-    FileSys::SaveDataAttribute attribute{};
-    attribute.title_id = applet->program_id;
-    attribute.user_id = user_id;
-    attribute.type = FileSys::SaveDataType::SaveData;
-
-    FileSys::VirtualDir save_data{};
-    const auto res = system.GetFileSystemController().OpenSaveDataController()->CreateSaveData(
-        &save_data, FileSys::SaveDataSpaceId::NandUser, attribute);
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(res);
-    rb.Push<u64>(0);
-}
-
-void IApplicationFunctions::SetTerminateResult(HLERequestContext& ctx) {
-    // Takes an input u32 Result, no output.
-    // For example, in some cases official apps use this with error 0x2A2 then
-    // uses svcBreak.
-
-    IPC::RequestParser rp{ctx};
-    u32 result = rp.Pop<u32>();
-    LOG_WARNING(Service_AM, "(STUBBED) called, result=0x{:08X}", result);
-
-    std::scoped_lock lk{applet->lock};
-    applet->terminate_result = Result(result);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IApplicationFunctions::GetDisplayVersion(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    std::array<u8, 0x10> version_string{};
-
-    const auto res = [this] {
-        const FileSys::PatchManager pm{applet->program_id, system.GetFileSystemController(),
-                                       system.GetContentProvider()};
-        auto metadata = pm.GetControlMetadata();
-        if (metadata.first != nullptr) {
-            return metadata;
-        }
-
-        const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(applet->program_id),
-                                              system.GetFileSystemController(),
-                                              system.GetContentProvider()};
-        return pm_update.GetControlMetadata();
-    }();
-
-    if (res.first != nullptr) {
-        const auto& version = res.first->GetVersionString();
-        std::copy(version.begin(), version.end(), version_string.begin());
-    } else {
-        static constexpr char default_version[]{"1.0.0"};
-        std::memcpy(version_string.data(), default_version, sizeof(default_version));
-    }
-
-    IPC::ResponseBuilder rb{ctx, 6};
-    rb.Push(ResultSuccess);
-    rb.PushRaw(version_string);
-}
-
-void IApplicationFunctions::GetDesiredLanguage(HLERequestContext& ctx) {
-    // TODO(bunnei): This should be configurable
-    LOG_DEBUG(Service_AM, "called");
-
-    // Get supported languages from NACP, if possible
-    // Default to 0 (all languages supported)
-    u32 supported_languages = 0;
-
-    const auto res = [this] {
-        const FileSys::PatchManager pm{applet->program_id, system.GetFileSystemController(),
-                                       system.GetContentProvider()};
-        auto metadata = pm.GetControlMetadata();
-        if (metadata.first != nullptr) {
-            return metadata;
-        }
-
-        const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(applet->program_id),
-                                              system.GetFileSystemController(),
-                                              system.GetContentProvider()};
-        return pm_update.GetControlMetadata();
-    }();
-
-    if (res.first != nullptr) {
-        supported_languages = res.first->GetSupportedLanguages();
-    }
-
-    // Call IApplicationManagerInterface implementation.
-    auto& service_manager = system.ServiceManager();
-    auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2");
-    auto app_man = ns_am2->GetApplicationManagerInterface();
-
-    // Get desired application language
-    u8 desired_language{};
-    const auto res_lang =
-        app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages);
-    if (res_lang != ResultSuccess) {
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(res_lang);
-        return;
-    }
-
-    // Convert to settings language code.
-    u64 language_code{};
-    const auto res_code =
-        app_man->ConvertApplicationLanguageToLanguageCode(&language_code, desired_language);
-    if (res_code != ResultSuccess) {
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(res_code);
-        return;
-    }
-
-    LOG_DEBUG(Service_AM, "got desired_language={:016X}", language_code);
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.Push(language_code);
-}
-
-void IApplicationFunctions::IsGamePlayRecordingSupported(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push(applet->gameplay_recording_supported);
-}
-
-void IApplicationFunctions::InitializeGamePlayRecording(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IApplicationFunctions::SetGamePlayRecordingState(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::RequestParser rp{ctx};
-
-    std::scoped_lock lk{applet->lock};
-    applet->gameplay_recording_state = rp.PopRaw<GameplayRecordingState>();
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IApplicationFunctions::NotifyRunning(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-    applet->is_running = true;
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
-}
-
-void IApplicationFunctions::GetPseudoDeviceId(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 6};
-    rb.Push(ResultSuccess);
-
-    // Returns a 128-bit UUID
-    rb.Push<u64>(0);
-    rb.Push<u64>(0);
-}
-
-void IApplicationFunctions::ExtendSaveData(HLERequestContext& ctx) {
-    struct Parameters {
-        FileSys::SaveDataType type;
-        u128 user_id;
-        u64 new_normal_size;
-        u64 new_journal_size;
-    };
-    static_assert(sizeof(Parameters) == 40);
-
-    IPC::RequestParser rp{ctx};
-    const auto [type, user_id, new_normal_size, new_journal_size] = rp.PopRaw<Parameters>();
-
-    LOG_DEBUG(Service_AM,
-              "called with type={:02X}, user_id={:016X}{:016X}, new_normal={:016X}, "
-              "new_journal={:016X}",
-              static_cast<u8>(type), user_id[1], user_id[0], new_normal_size, new_journal_size);
-
-    system.GetFileSystemController().OpenSaveDataController()->WriteSaveDataSize(
-        type, applet->program_id, user_id, {new_normal_size, new_journal_size});
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-
-    // The following value is used upon failure to help the system recover.
-    // Since we always succeed, this should be 0.
-    rb.Push<u64>(0);
-}
-
-void IApplicationFunctions::GetSaveDataSize(HLERequestContext& ctx) {
-    struct Parameters {
-        FileSys::SaveDataType type;
-        u128 user_id;
-    };
-    static_assert(sizeof(Parameters) == 24);
-
-    IPC::RequestParser rp{ctx};
-    const auto [type, user_id] = rp.PopRaw<Parameters>();
-
-    LOG_DEBUG(Service_AM, "called with type={:02X}, user_id={:016X}{:016X}", type, user_id[1],
-              user_id[0]);
-
-    const auto size = system.GetFileSystemController().OpenSaveDataController()->ReadSaveDataSize(
-        type, applet->program_id, user_id);
-
-    IPC::ResponseBuilder rb{ctx, 6};
-    rb.Push(ResultSuccess);
-    rb.Push(size.normal);
-    rb.Push(size.journal);
-}
-
-void IApplicationFunctions::CreateCacheStorage(HLERequestContext& ctx) {
-    struct InputParameters {
-        u16 index;
-        s64 size;
-        s64 journal_size;
-    };
-    static_assert(sizeof(InputParameters) == 24);
-
-    struct OutputParameters {
-        u32 storage_target;
-        u64 required_size;
-    };
-    static_assert(sizeof(OutputParameters) == 16);
-
-    IPC::RequestParser rp{ctx};
-    const auto params = rp.PopRaw<InputParameters>();
-
-    LOG_WARNING(Service_AM, "(STUBBED) called with index={}, size={:#x}, journal_size={:#x}",
-                params.index, params.size, params.journal_size);
-
-    const OutputParameters resp{
-        .storage_target = 1,
-        .required_size = 0,
-    };
-
-    IPC::ResponseBuilder rb{ctx, 6};
-    rb.Push(ResultSuccess);
-    rb.PushRaw(resp);
-}
-
-void IApplicationFunctions::GetSaveDataSizeMax(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    constexpr u64 size_max_normal = 0xFFFFFFF;
-    constexpr u64 size_max_journal = 0xFFFFFFF;
-
-    IPC::ResponseBuilder rb{ctx, 6};
-    rb.Push(ResultSuccess);
-    rb.Push(size_max_normal);
-    rb.Push(size_max_journal);
-}
-
-void IApplicationFunctions::QueryApplicationPlayStatistics(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push<u32>(0);
-}
-
-void IApplicationFunctions::QueryApplicationPlayStatisticsByUid(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push<u32>(0);
-}
-
-void IApplicationFunctions::ExecuteProgram(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::RequestParser rp{ctx};
-    [[maybe_unused]] const auto unk_1 = rp.Pop<u32>();
-    [[maybe_unused]] const auto unk_2 = rp.Pop<u32>();
-    const auto program_index = rp.Pop<u64>();
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-
-    // Swap user channel ownership into the system so that it will be preserved
-    system.GetUserChannel().swap(applet->user_channel_launch_parameter);
-    system.ExecuteProgram(program_index);
-}
-
-void IApplicationFunctions::ClearUserChannel(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    applet->user_channel_launch_parameter.clear();
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IApplicationFunctions::UnpopToUserChannel(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::RequestParser rp{ctx};
-    const auto storage = rp.PopIpcInterface<IStorage>().lock();
-    if (storage) {
-        applet->user_channel_launch_parameter.push_back(storage->GetData());
-    }
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IApplicationFunctions::GetPreviousProgramIndex(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push<s32>(applet->previous_program_index);
-}
-
-void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(applet->gpu_error_detected_event.GetHandle());
-}
-
-void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(applet->friend_invitation_storage_channel_event.GetHandle());
-}
-
-void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(AM::ResultNoDataInChannel);
-}
-
-void IApplicationFunctions::GetNotificationStorageChannelEvent(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(applet->notification_storage_channel_event.GetHandle());
-}
-
-void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(applet->health_warning_disappeared_system_event.GetHandle());
-}
-
-void IApplicationFunctions::PrepareForJit(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-    applet->jit_service_launched = true;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/application_functions.h b/src/core/hle/service/am/application_functions.h
deleted file mode 100644
index 55eb21d39..000000000
--- a/src/core/hle/service/am/application_functions.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/kernel_helpers.h"
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-struct Applet;
-
-class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
-public:
-    explicit IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet_);
-    ~IApplicationFunctions() override;
-
-private:
-    void PopLaunchParameter(HLERequestContext& ctx);
-    void CreateApplicationAndRequestToStartForQuest(HLERequestContext& ctx);
-    void EnsureSaveData(HLERequestContext& ctx);
-    void SetTerminateResult(HLERequestContext& ctx);
-    void GetDisplayVersion(HLERequestContext& ctx);
-    void GetDesiredLanguage(HLERequestContext& ctx);
-    void IsGamePlayRecordingSupported(HLERequestContext& ctx);
-    void InitializeGamePlayRecording(HLERequestContext& ctx);
-    void SetGamePlayRecordingState(HLERequestContext& ctx);
-    void NotifyRunning(HLERequestContext& ctx);
-    void GetPseudoDeviceId(HLERequestContext& ctx);
-    void ExtendSaveData(HLERequestContext& ctx);
-    void GetSaveDataSize(HLERequestContext& ctx);
-    void CreateCacheStorage(HLERequestContext& ctx);
-    void GetSaveDataSizeMax(HLERequestContext& ctx);
-    void BeginBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx);
-    void EndBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx);
-    void BeginBlockingHomeButton(HLERequestContext& ctx);
-    void EndBlockingHomeButton(HLERequestContext& ctx);
-    void EnableApplicationCrashReport(HLERequestContext& ctx);
-    void InitializeApplicationCopyrightFrameBuffer(HLERequestContext& ctx);
-    void SetApplicationCopyrightImage(HLERequestContext& ctx);
-    void SetApplicationCopyrightVisibility(HLERequestContext& ctx);
-    void QueryApplicationPlayStatistics(HLERequestContext& ctx);
-    void QueryApplicationPlayStatisticsByUid(HLERequestContext& ctx);
-    void ExecuteProgram(HLERequestContext& ctx);
-    void ClearUserChannel(HLERequestContext& ctx);
-    void UnpopToUserChannel(HLERequestContext& ctx);
-    void GetPreviousProgramIndex(HLERequestContext& ctx);
-    void GetGpuErrorDetectedSystemEvent(HLERequestContext& ctx);
-    void GetFriendInvitationStorageChannelEvent(HLERequestContext& ctx);
-    void TryPopFromFriendInvitationStorageChannel(HLERequestContext& ctx);
-    void GetNotificationStorageChannelEvent(HLERequestContext& ctx);
-    void GetHealthWarningDisappearedSystemEvent(HLERequestContext& ctx);
-    void PrepareForJit(HLERequestContext& ctx);
-
-    const std::shared_ptr<Applet> applet;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp
new file mode 100644
index 000000000..346ab42ab
--- /dev/null
+++ b/src/core/hle/service/am/service/application_functions.cpp
@@ -0,0 +1,465 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/settings.h"
+#include "common/uuid.h"
+#include "core/file_sys/control_metadata.h"
+#include "core/file_sys/patch_manager.h"
+#include "core/file_sys/registered_cache.h"
+#include "core/file_sys/savedata_factory.h"
+#include "core/hle/kernel/k_transfer_memory.h"
+#include "core/hle/service/am/am_results.h"
+#include "core/hle/service/am/applet.h"
+#include "core/hle/service/am/service/application_functions.h"
+#include "core/hle/service/am/storage.h"
+#include "core/hle/service/cmif_serialization.h"
+#include "core/hle/service/filesystem/filesystem.h"
+#include "core/hle/service/filesystem/save_data_controller.h"
+#include "core/hle/service/ns/ns.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::AM {
+
+IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet)
+    : ServiceFramework{system_, "IApplicationFunctions"}, m_applet{std::move(applet)} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {1, D<&IApplicationFunctions::PopLaunchParameter>, "PopLaunchParameter"},
+        {10, nullptr, "CreateApplicationAndPushAndRequestToStart"},
+        {11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"},
+        {12, nullptr, "CreateApplicationAndRequestToStart"},
+        {13, nullptr, "CreateApplicationAndRequestToStartForQuest"},
+        {14, nullptr, "CreateApplicationWithAttributeAndPushAndRequestToStartForQuest"},
+        {15, nullptr, "CreateApplicationWithAttributeAndRequestToStartForQuest"},
+        {20, D<&IApplicationFunctions::EnsureSaveData>, "EnsureSaveData"},
+        {21, D<&IApplicationFunctions::GetDesiredLanguage>, "GetDesiredLanguage"},
+        {22, D<&IApplicationFunctions::SetTerminateResult>, "SetTerminateResult"},
+        {23, D<&IApplicationFunctions::GetDisplayVersion>, "GetDisplayVersion"},
+        {24, nullptr, "GetLaunchStorageInfoForDebug"},
+        {25, D<&IApplicationFunctions::ExtendSaveData>, "ExtendSaveData"},
+        {26, D<&IApplicationFunctions::GetSaveDataSize>, "GetSaveDataSize"},
+        {27, D<&IApplicationFunctions::CreateCacheStorage>, "CreateCacheStorage"},
+        {28, D<&IApplicationFunctions::GetSaveDataSizeMax>, "GetSaveDataSizeMax"},
+        {29, nullptr, "GetCacheStorageMax"},
+        {30, D<&IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed>, "BeginBlockingHomeButtonShortAndLongPressed"},
+        {31, D<&IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed>, "EndBlockingHomeButtonShortAndLongPressed"},
+        {32, D<&IApplicationFunctions::BeginBlockingHomeButton>, "BeginBlockingHomeButton"},
+        {33, D<&IApplicationFunctions::EndBlockingHomeButton>, "EndBlockingHomeButton"},
+        {34, nullptr, "SelectApplicationLicense"},
+        {35, nullptr, "GetDeviceSaveDataSizeMax"},
+        {36, nullptr, "GetLimitedApplicationLicense"},
+        {37, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"},
+        {40, D<&IApplicationFunctions::NotifyRunning>, "NotifyRunning"},
+        {50, D<&IApplicationFunctions::GetPseudoDeviceId>, "GetPseudoDeviceId"},
+        {60, nullptr, "SetMediaPlaybackStateForApplication"},
+        {65, D<&IApplicationFunctions::IsGamePlayRecordingSupported>, "IsGamePlayRecordingSupported"},
+        {66, D<&IApplicationFunctions::InitializeGamePlayRecording>, "InitializeGamePlayRecording"},
+        {67, D<&IApplicationFunctions::SetGamePlayRecordingState>, "SetGamePlayRecordingState"},
+        {68, nullptr, "RequestFlushGamePlayingMovieForDebug"},
+        {70, nullptr, "RequestToShutdown"},
+        {71, nullptr, "RequestToReboot"},
+        {72, nullptr, "RequestToSleep"},
+        {80, nullptr, "ExitAndRequestToShowThanksMessage"},
+        {90, D<&IApplicationFunctions::EnableApplicationCrashReport>, "EnableApplicationCrashReport"},
+        {100, D<&IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer>, "InitializeApplicationCopyrightFrameBuffer"},
+        {101, D<&IApplicationFunctions::SetApplicationCopyrightImage>, "SetApplicationCopyrightImage"},
+        {102, D<&IApplicationFunctions::SetApplicationCopyrightVisibility>, "SetApplicationCopyrightVisibility"},
+        {110, D<&IApplicationFunctions::QueryApplicationPlayStatistics>, "QueryApplicationPlayStatistics"},
+        {111, D<&IApplicationFunctions::QueryApplicationPlayStatisticsByUid>, "QueryApplicationPlayStatisticsByUid"},
+        {120, D<&IApplicationFunctions::ExecuteProgram>, "ExecuteProgram"},
+        {121, D<&IApplicationFunctions::ClearUserChannel>, "ClearUserChannel"},
+        {122, D<&IApplicationFunctions::UnpopToUserChannel>, "UnpopToUserChannel"},
+        {123, D<&IApplicationFunctions::GetPreviousProgramIndex>, "GetPreviousProgramIndex"},
+        {124, nullptr, "EnableApplicationAllThreadDumpOnCrash"},
+        {130, D<&IApplicationFunctions::GetGpuErrorDetectedSystemEvent>, "GetGpuErrorDetectedSystemEvent"},
+        {131, nullptr, "SetDelayTimeToAbortOnGpuError"},
+        {140, D<&IApplicationFunctions::GetFriendInvitationStorageChannelEvent>, "GetFriendInvitationStorageChannelEvent"},
+        {141, D<&IApplicationFunctions::TryPopFromFriendInvitationStorageChannel>, "TryPopFromFriendInvitationStorageChannel"},
+        {150, D<&IApplicationFunctions::GetNotificationStorageChannelEvent>, "GetNotificationStorageChannelEvent"},
+        {151, nullptr, "TryPopFromNotificationStorageChannel"},
+        {160, D<&IApplicationFunctions::GetHealthWarningDisappearedSystemEvent>, "GetHealthWarningDisappearedSystemEvent"},
+        {170, nullptr, "SetHdcpAuthenticationActivated"},
+        {180, nullptr, "GetLaunchRequiredVersion"},
+        {181, nullptr, "UpgradeLaunchRequiredVersion"},
+        {190, nullptr, "SendServerMaintenanceOverlayNotification"},
+        {200, nullptr, "GetLastApplicationExitReason"},
+        {500, nullptr, "StartContinuousRecordingFlushForDebug"},
+        {1000, nullptr, "CreateMovieMaker"},
+        {1001, D<&IApplicationFunctions::PrepareForJit>, "PrepareForJit"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IApplicationFunctions::~IApplicationFunctions() = default;
+
+Result IApplicationFunctions::PopLaunchParameter(Out<SharedPointer<IStorage>> out_storage,
+                                                 LaunchParameterKind launch_parameter_kind) {
+    LOG_INFO(Service_AM, "called, kind={}", launch_parameter_kind);
+
+    std::scoped_lock lk{m_applet->lock};
+
+    auto& channel = launch_parameter_kind == LaunchParameterKind::UserChannel
+                        ? m_applet->user_channel_launch_parameter
+                        : m_applet->preselected_user_launch_parameter;
+
+    if (channel.empty()) {
+        LOG_WARNING(Service_AM, "Attempted to pop parameter {} but none was found!",
+                    launch_parameter_kind);
+        R_THROW(AM::ResultNoDataInChannel);
+    }
+
+    auto data = channel.back();
+    channel.pop_back();
+
+    *out_storage = std::make_shared<IStorage>(system, std::move(data));
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::EnsureSaveData(Out<u64> out_size, Common::UUID user_id) {
+    LOG_INFO(Service_AM, "called, uid={}", user_id.FormattedString());
+
+    FileSys::SaveDataAttribute attribute{};
+    attribute.title_id = m_applet->program_id;
+    attribute.user_id = user_id.AsU128();
+    attribute.type = FileSys::SaveDataType::SaveData;
+
+    FileSys::VirtualDir save_data{};
+    R_TRY(system.GetFileSystemController().OpenSaveDataController()->CreateSaveData(
+        &save_data, FileSys::SaveDataSpaceId::NandUser, attribute));
+
+    *out_size = 0;
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::GetDesiredLanguage(Out<u64> out_language_code) {
+    // FIXME: all of this stuff belongs to ns
+    // TODO(bunnei): This should be configurable
+    LOG_DEBUG(Service_AM, "called");
+
+    // Get supported languages from NACP, if possible
+    // Default to 0 (all languages supported)
+    u32 supported_languages = 0;
+
+    const auto res = [this] {
+        const FileSys::PatchManager pm{m_applet->program_id, system.GetFileSystemController(),
+                                       system.GetContentProvider()};
+        auto metadata = pm.GetControlMetadata();
+        if (metadata.first != nullptr) {
+            return metadata;
+        }
+
+        const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(m_applet->program_id),
+                                              system.GetFileSystemController(),
+                                              system.GetContentProvider()};
+        return pm_update.GetControlMetadata();
+    }();
+
+    if (res.first != nullptr) {
+        supported_languages = res.first->GetSupportedLanguages();
+    }
+
+    // Call IApplicationManagerInterface implementation.
+    auto& service_manager = system.ServiceManager();
+    auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2");
+    auto app_man = ns_am2->GetApplicationManagerInterface();
+
+    // Get desired application language
+    u8 desired_language{};
+    R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages));
+
+    // Convert to settings language code.
+    R_TRY(app_man->ConvertApplicationLanguageToLanguageCode(out_language_code, desired_language));
+
+    LOG_DEBUG(Service_AM, "got desired_language={:016X}", *out_language_code);
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::SetTerminateResult(Result terminate_result) {
+    LOG_INFO(Service_AM, "(STUBBED) called, result={:#x} ({}-{})", terminate_result.GetInnerValue(),
+             static_cast<u32>(terminate_result.GetModule()) + 2000,
+             terminate_result.GetDescription());
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->terminate_result = terminate_result;
+
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::GetDisplayVersion(Out<DisplayVersion> out_display_version) {
+    LOG_DEBUG(Service_AM, "called");
+
+    const auto res = [this] {
+        const FileSys::PatchManager pm{m_applet->program_id, system.GetFileSystemController(),
+                                       system.GetContentProvider()};
+        auto metadata = pm.GetControlMetadata();
+        if (metadata.first != nullptr) {
+            return metadata;
+        }
+
+        const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(m_applet->program_id),
+                                              system.GetFileSystemController(),
+                                              system.GetContentProvider()};
+        return pm_update.GetControlMetadata();
+    }();
+
+    if (res.first != nullptr) {
+        const auto& version = res.first->GetVersionString();
+        std::memcpy(out_display_version->string.data(), version.data(),
+                    std::min(version.size(), out_display_version->string.size()));
+    } else {
+        static constexpr char default_version[]{"1.0.0"};
+        std::memcpy(out_display_version->string.data(), default_version, sizeof(default_version));
+    }
+
+    out_display_version->string[out_display_version->string.size() - 1] = '\0';
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::ExtendSaveData(Out<u64> out_required_size, FileSys::SaveDataType type,
+                                             Common::UUID user_id, u64 normal_size,
+                                             u64 journal_size) {
+    LOG_DEBUG(Service_AM, "called with type={} user_id={} normal={:#x} journal={:#x}",
+              static_cast<u8>(type), user_id.FormattedString(), normal_size, journal_size);
+
+    system.GetFileSystemController().OpenSaveDataController()->WriteSaveDataSize(
+        type, m_applet->program_id, user_id.AsU128(), {normal_size, journal_size});
+
+    // The following value is used to indicate the amount of space remaining on failure
+    // due to running out of space. Since we always succeed, this should be 0.
+    *out_required_size = 0;
+
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::GetSaveDataSize(Out<u64> out_normal_size, Out<u64> out_journal_size,
+                                              FileSys::SaveDataType type, Common::UUID user_id) {
+    LOG_DEBUG(Service_AM, "called with type={} user_id={}", type, user_id.FormattedString());
+
+    const auto size = system.GetFileSystemController().OpenSaveDataController()->ReadSaveDataSize(
+        type, m_applet->program_id, user_id.AsU128());
+
+    *out_normal_size = size.normal;
+    *out_journal_size = size.journal;
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::CreateCacheStorage(Out<u32> out_target_media,
+                                                 Out<u64> out_required_size, u16 index,
+                                                 u64 normal_size, u64 journal_size) {
+    LOG_WARNING(Service_AM, "(STUBBED) called with index={} size={:#x} journal_size={:#x}", index,
+                normal_size, journal_size);
+
+    *out_target_media = 1; // Nand
+    *out_required_size = 0;
+
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::GetSaveDataSizeMax(Out<u64> out_max_normal_size,
+                                                 Out<u64> out_max_journal_size) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    *out_max_normal_size = 0xFFFFFFF;
+    *out_max_journal_size = 0xFFFFFFF;
+
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed(s64 unused) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->home_button_long_pressed_blocked = true;
+    m_applet->home_button_short_pressed_blocked = true;
+
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->home_button_long_pressed_blocked = false;
+    m_applet->home_button_short_pressed_blocked = false;
+
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::BeginBlockingHomeButton(s64 timeout_ns) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, timeout_ns={}", timeout_ns);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->home_button_long_pressed_blocked = true;
+    m_applet->home_button_short_pressed_blocked = true;
+    m_applet->home_button_double_click_enabled = true;
+
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::EndBlockingHomeButton() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->home_button_long_pressed_blocked = false;
+    m_applet->home_button_short_pressed_blocked = false;
+    m_applet->home_button_double_click_enabled = false;
+
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::NotifyRunning(Out<bool> out_became_running) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_became_running = true;
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::GetPseudoDeviceId(Out<Common::UUID> out_pseudo_device_id) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_pseudo_device_id = {};
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::IsGamePlayRecordingSupported(
+    Out<bool> out_is_game_play_recording_supported) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_is_game_play_recording_supported = m_applet->game_play_recording_supported;
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::InitializeGamePlayRecording(
+    u64 transfer_memory_size, InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::SetGamePlayRecordingState(
+    GamePlayRecordingState game_play_recording_state) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->game_play_recording_state = game_play_recording_state;
+
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::EnableApplicationCrashReport(bool enabled) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->application_crash_report_enabled = enabled;
+
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer(
+    s32 width, s32 height, u64 transfer_memory_size,
+    InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::SetApplicationCopyrightImage(
+    s32 x, s32 y, s32 width, s32 height, WindowOriginMode window_origin_mode,
+    InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias> image_data) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::SetApplicationCopyrightVisibility(bool visible) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, is_visible={}", visible);
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::QueryApplicationPlayStatistics(
+    Out<s32> out_entries,
+    OutArray<ApplicationPlayStatistics, BufferAttr_HipcMapAlias> out_play_statistics,
+    InArray<u64, BufferAttr_HipcMapAlias> application_ids) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_entries = 0;
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::QueryApplicationPlayStatisticsByUid(
+    Out<s32> out_entries,
+    OutArray<ApplicationPlayStatistics, BufferAttr_HipcMapAlias> out_play_statistics,
+    Common::UUID user_id, InArray<u64, BufferAttr_HipcMapAlias> application_ids) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_entries = 0;
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::ExecuteProgram(ProgramSpecifyKind kind, u64 value) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, kind={}, value={}", kind, value);
+    ASSERT(kind == ProgramSpecifyKind::ExecuteProgram ||
+           kind == ProgramSpecifyKind::RestartProgram);
+
+    // Copy user channel ownership into the system so that it will be preserved
+    system.GetUserChannel() = m_applet->user_channel_launch_parameter;
+    system.ExecuteProgram(value);
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::ClearUserChannel() {
+    LOG_DEBUG(Service_AM, "called");
+    m_applet->user_channel_launch_parameter.clear();
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::UnpopToUserChannel(SharedPointer<IStorage> storage) {
+    LOG_DEBUG(Service_AM, "called");
+    m_applet->user_channel_launch_parameter.push_back(storage->GetData());
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::GetPreviousProgramIndex(Out<s32> out_previous_program_index) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_previous_program_index = m_applet->previous_program_index;
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::GetGpuErrorDetectedSystemEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_event = m_applet->gpu_error_detected_event.GetHandle();
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::GetFriendInvitationStorageChannelEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_event = m_applet->friend_invitation_storage_channel_event.GetHandle();
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::TryPopFromFriendInvitationStorageChannel(
+    Out<SharedPointer<IStorage>> out_storage) {
+    LOG_INFO(Service_AM, "(STUBBED) called");
+    R_THROW(AM::ResultNoDataInChannel);
+}
+
+Result IApplicationFunctions::GetNotificationStorageChannelEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_event = m_applet->notification_storage_channel_event.GetHandle();
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_event = m_applet->health_warning_disappeared_system_event.GetHandle();
+    R_SUCCEED();
+}
+
+Result IApplicationFunctions::PrepareForJit() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->jit_service_launched = true;
+
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_functions.h b/src/core/hle/service/am/service/application_functions.h
new file mode 100644
index 000000000..3548202f8
--- /dev/null
+++ b/src/core/hle/service/am/service/application_functions.h
@@ -0,0 +1,83 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "common/uuid.h"
+#include "core/hle/service/am/am_types.h"
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace FileSys {
+enum class SaveDataType : u8;
+}
+
+namespace Kernel {
+class KReadableEvent;
+}
+
+namespace Service::AM {
+
+struct Applet;
+class IStorage;
+
+class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
+public:
+    explicit IApplicationFunctions(Core::System& system_, std::shared_ptr<Applet> applet);
+    ~IApplicationFunctions() override;
+
+private:
+    Result PopLaunchParameter(Out<SharedPointer<IStorage>> out_storage,
+                              LaunchParameterKind launch_parameter_kind);
+    Result EnsureSaveData(Out<u64> out_size, Common::UUID user_id);
+    Result GetDesiredLanguage(Out<u64> out_language_code);
+    Result SetTerminateResult(Result terminate_result);
+    Result GetDisplayVersion(Out<DisplayVersion> out_display_version);
+    Result ExtendSaveData(Out<u64> out_required_size, FileSys::SaveDataType type,
+                          Common::UUID user_id, u64 normal_size, u64 journal_size);
+    Result GetSaveDataSize(Out<u64> out_normal_size, Out<u64> out_journal_size,
+                           FileSys::SaveDataType type, Common::UUID user_id);
+    Result CreateCacheStorage(Out<u32> out_target_media, Out<u64> out_required_size, u16 index,
+                              u64 normal_size, u64 journal_size);
+    Result GetSaveDataSizeMax(Out<u64> out_max_normal_size, Out<u64> out_max_journal_size);
+    Result BeginBlockingHomeButtonShortAndLongPressed(s64 unused);
+    Result EndBlockingHomeButtonShortAndLongPressed();
+    Result BeginBlockingHomeButton(s64 timeout_ns);
+    Result EndBlockingHomeButton();
+    Result NotifyRunning(Out<bool> out_became_running);
+    Result GetPseudoDeviceId(Out<Common::UUID> out_pseudo_device_id);
+    Result IsGamePlayRecordingSupported(Out<bool> out_is_game_play_recording_supported);
+    Result InitializeGamePlayRecording(
+        u64 transfer_memory_size, InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle);
+    Result SetGamePlayRecordingState(GamePlayRecordingState game_play_recording_state);
+    Result EnableApplicationCrashReport(bool enabled);
+    Result InitializeApplicationCopyrightFrameBuffer(
+        s32 width, s32 height, u64 transfer_memory_size,
+        InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle);
+    Result SetApplicationCopyrightImage(
+        s32 x, s32 y, s32 width, s32 height, WindowOriginMode window_origin_mode,
+        InBuffer<BufferAttr_HipcMapTransferAllowsNonSecure | BufferAttr_HipcMapAlias> image_data);
+    Result SetApplicationCopyrightVisibility(bool visible);
+    Result QueryApplicationPlayStatistics(
+        Out<s32> out_entries,
+        OutArray<ApplicationPlayStatistics, BufferAttr_HipcMapAlias> out_play_statistics,
+        InArray<u64, BufferAttr_HipcMapAlias> application_ids);
+    Result QueryApplicationPlayStatisticsByUid(
+        Out<s32> out_entries,
+        OutArray<ApplicationPlayStatistics, BufferAttr_HipcMapAlias> out_play_statistics,
+        Common::UUID user_id, InArray<u64, BufferAttr_HipcMapAlias> application_ids);
+    Result ExecuteProgram(ProgramSpecifyKind kind, u64 value);
+    Result ClearUserChannel();
+    Result UnpopToUserChannel(SharedPointer<IStorage> storage);
+    Result GetPreviousProgramIndex(Out<s32> out_previous_program_index);
+    Result GetGpuErrorDetectedSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result GetFriendInvitationStorageChannelEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result TryPopFromFriendInvitationStorageChannel(Out<SharedPointer<IStorage>> out_storage);
+    Result GetNotificationStorageChannelEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result GetHealthWarningDisappearedSystemEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result PrepareForJit();
+
+    const std::shared_ptr<Applet> m_applet;
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index b22960610..55a4ea72f 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/application_functions.h"
 #include "core/hle/service/am/common_state_getter.h"
 #include "core/hle/service/am/debug_functions.h"
 #include "core/hle/service/am/display_controller.h"
@@ -10,6 +9,7 @@
 #include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
+#include "core/hle/service/am/service/application_functions.h"
 #include "core/hle/service/am/service/application_proxy.h"
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/window_controller.h"

From 96fea99af952490bf8799f0775bfa307e82bbf0f Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 19:38:23 -0500
Subject: [PATCH 08/24] am: rewrite ICommonStateGetter

---
 src/core/CMakeLists.txt                       |   4 +-
 src/core/hle/service/am/am_types.h            |  34 ++
 src/core/hle/service/am/applet_manager.cpp    |   4 +-
 .../hle/service/am/applet_message_queue.cpp   |   2 +-
 .../hle/service/am/applet_message_queue.h     |  35 +-
 .../hle/service/am/common_state_getter.cpp    | 314 ------------------
 src/core/hle/service/am/common_state_getter.h |  77 -----
 .../hle/service/am/library_applet_creator.cpp |   4 +-
 .../service/am/service/application_proxy.cpp  |   2 +-
 .../am/service/common_state_getter.cpp        | 277 +++++++++++++++
 .../service/am/service/common_state_getter.h  |  61 ++++
 .../am/service/library_applet_proxy.cpp       |   2 +-
 .../am/service/system_applet_proxy.cpp        |   2 +-
 src/core/hle/service/am/window_controller.cpp |   4 +-
 14 files changed, 385 insertions(+), 437 deletions(-)
 delete mode 100644 src/core/hle/service/am/common_state_getter.cpp
 delete mode 100644 src/core/hle/service/am/common_state_getter.h
 create mode 100644 src/core/hle/service/am/service/common_state_getter.cpp
 create mode 100644 src/core/hle/service/am/service/common_state_getter.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 5d3f4cf1d..781be7c10 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -425,8 +425,6 @@ add_library(core STATIC
     hle/service/am/applet_message_queue.h
     hle/service/am/application_creator.cpp
     hle/service/am/application_creator.h
-    hle/service/am/common_state_getter.cpp
-    hle/service/am/common_state_getter.h
     hle/service/am/debug_functions.cpp
     hle/service/am/debug_functions.h
     hle/service/am/display_controller.cpp
@@ -471,6 +469,8 @@ add_library(core STATIC
     hle/service/am/service/application_proxy.h
     hle/service/am/service/audio_controller.cpp
     hle/service/am/service/audio_controller.h
+    hle/service/am/service/common_state_getter.cpp
+    hle/service/am/service/common_state_getter.h
     hle/service/am/service/library_applet_proxy.cpp
     hle/service/am/service/library_applet_proxy.h
     hle/service/am/service/system_applet_proxy.cpp
diff --git a/src/core/hle/service/am/am_types.h b/src/core/hle/service/am/am_types.h
index bf2272c0e..093adcdea 100644
--- a/src/core/hle/service/am/am_types.h
+++ b/src/core/hle/service/am/am_types.h
@@ -128,6 +128,40 @@ enum class AppletProgramId : u64 {
     MaxProgramId = 0x0100000000001FFFull,
 };
 
+// This is nn::am::AppletMessage
+enum class AppletMessage : u32 {
+    None = 0,
+    ChangeIntoForeground = 1,
+    ChangeIntoBackground = 2,
+    Exit = 4,
+    ApplicationExited = 6,
+    FocusStateChanged = 15,
+    Resume = 16,
+    DetectShortPressingHomeButton = 20,
+    DetectLongPressingHomeButton = 21,
+    DetectShortPressingPowerButton = 22,
+    DetectMiddlePressingPowerButton = 23,
+    DetectLongPressingPowerButton = 24,
+    RequestToPrepareSleep = 25,
+    FinishedSleepSequence = 26,
+    SleepRequiredByHighTemperature = 27,
+    SleepRequiredByLowBattery = 28,
+    AutoPowerDown = 29,
+    OperationModeChanged = 30,
+    PerformanceModeChanged = 31,
+    DetectReceivingCecSystemStandby = 32,
+    SdCardRemoved = 33,
+    LaunchApplicationRequested = 50,
+    RequestToDisplay = 51,
+    ShowApplicationLogo = 55,
+    HideApplicationLogo = 56,
+    ForceHideApplicationLogo = 57,
+    FloatingApplicationDetected = 60,
+    DetectShortPressingCaptureButton = 90,
+    AlbumScreenShotTaken = 92,
+    AlbumRecordingSaved = 93,
+};
+
 enum class LibraryAppletMode : u32 {
     AllForeground = 0,
     PartialForeground = 1,
diff --git a/src/core/hle/service/am/applet_manager.cpp b/src/core/hle/service/am/applet_manager.cpp
index 52200d5b2..b35d97bc7 100644
--- a/src/core/hle/service/am/applet_manager.cpp
+++ b/src/core/hle/service/am/applet_manager.cpp
@@ -303,8 +303,8 @@ void AppletManager::CreateAndInsertByFrontendAppletParameters(
     }
 
     // Applet was started by frontend, so it is foreground.
-    applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
-    applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
+    applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground);
+    applet->message_queue.PushMessage(AppletMessage::FocusStateChanged);
     applet->focus_state = FocusState::InFocus;
 
     this->InsertApplet(std::move(applet));
diff --git a/src/core/hle/service/am/applet_message_queue.cpp b/src/core/hle/service/am/applet_message_queue.cpp
index 5ed996b70..83c3c5a55 100644
--- a/src/core/hle/service/am/applet_message_queue.cpp
+++ b/src/core/hle/service/am/applet_message_queue.cpp
@@ -33,7 +33,7 @@ void AppletMessageQueue::PushMessage(AppletMessage msg) {
     on_new_message->Signal();
 }
 
-AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() {
+AppletMessage AppletMessageQueue::PopMessage() {
     std::scoped_lock lk{lock};
     if (messages.empty()) {
         on_new_message->Clear();
diff --git a/src/core/hle/service/am/applet_message_queue.h b/src/core/hle/service/am/applet_message_queue.h
index 5cb236d47..429b77d37 100644
--- a/src/core/hle/service/am/applet_message_queue.h
+++ b/src/core/hle/service/am/applet_message_queue.h
@@ -5,6 +5,7 @@
 
 #include <queue>
 
+#include "core/hle/service/am/am_types.h"
 #include "core/hle/service/kernel_helpers.h"
 #include "core/hle/service/service.h"
 
@@ -16,40 +17,6 @@ namespace Service::AM {
 
 class AppletMessageQueue {
 public:
-    // This is nn::am::AppletMessage
-    enum class AppletMessage : u32 {
-        None = 0,
-        ChangeIntoForeground = 1,
-        ChangeIntoBackground = 2,
-        Exit = 4,
-        ApplicationExited = 6,
-        FocusStateChanged = 15,
-        Resume = 16,
-        DetectShortPressingHomeButton = 20,
-        DetectLongPressingHomeButton = 21,
-        DetectShortPressingPowerButton = 22,
-        DetectMiddlePressingPowerButton = 23,
-        DetectLongPressingPowerButton = 24,
-        RequestToPrepareSleep = 25,
-        FinishedSleepSequence = 26,
-        SleepRequiredByHighTemperature = 27,
-        SleepRequiredByLowBattery = 28,
-        AutoPowerDown = 29,
-        OperationModeChanged = 30,
-        PerformanceModeChanged = 31,
-        DetectReceivingCecSystemStandby = 32,
-        SdCardRemoved = 33,
-        LaunchApplicationRequested = 50,
-        RequestToDisplay = 51,
-        ShowApplicationLogo = 55,
-        HideApplicationLogo = 56,
-        ForceHideApplicationLogo = 57,
-        FloatingApplicationDetected = 60,
-        DetectShortPressingCaptureButton = 90,
-        AlbumScreenShotTaken = 92,
-        AlbumRecordingSaved = 93,
-    };
-
     explicit AppletMessageQueue(Core::System& system);
     ~AppletMessageQueue();
 
diff --git a/src/core/hle/service/am/common_state_getter.cpp b/src/core/hle/service/am/common_state_getter.cpp
deleted file mode 100644
index 937ac0beb..000000000
--- a/src/core/hle/service/am/common_state_getter.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/settings.h"
-#include "core/hle/service/am/am_results.h"
-#include "core/hle/service/am/applet.h"
-#include "core/hle/service/am/common_state_getter.h"
-#include "core/hle/service/am/lock_accessor.h"
-#include "core/hle/service/apm/apm_controller.h"
-#include "core/hle/service/apm/apm_interface.h"
-#include "core/hle/service/ipc_helpers.h"
-#include "core/hle/service/pm/pm.h"
-#include "core/hle/service/sm/sm.h"
-#include "core/hle/service/vi/vi.h"
-
-namespace Service::AM {
-
-ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr<Applet> applet_)
-    : ServiceFramework{system_, "ICommonStateGetter"}, applet{std::move(applet_)} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
-        {1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"},
-        {2, nullptr, "GetThisAppletKind"},
-        {3, nullptr, "AllowToEnterSleep"},
-        {4, nullptr, "DisallowToEnterSleep"},
-        {5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"},
-        {6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"},
-        {7, nullptr, "GetCradleStatus"},
-        {8, &ICommonStateGetter::GetBootMode, "GetBootMode"},
-        {9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
-        {10, &ICommonStateGetter::RequestToAcquireSleepLock, "RequestToAcquireSleepLock"},
-        {11, nullptr, "ReleaseSleepLock"},
-        {12, nullptr, "ReleaseSleepLockTransiently"},
-        {13, &ICommonStateGetter::GetAcquiredSleepLockEvent, "GetAcquiredSleepLockEvent"},
-        {14, nullptr, "GetWakeupCount"},
-        {20, nullptr, "PushToGeneralChannel"},
-        {30, nullptr, "GetHomeButtonReaderLockAccessor"},
-        {31, &ICommonStateGetter::GetReaderLockAccessorEx, "GetReaderLockAccessorEx"},
-        {32, nullptr, "GetWriterLockAccessorEx"},
-        {40, nullptr, "GetCradleFwVersion"},
-        {50, &ICommonStateGetter::IsVrModeEnabled, "IsVrModeEnabled"},
-        {51, &ICommonStateGetter::SetVrModeEnabled, "SetVrModeEnabled"},
-        {52, &ICommonStateGetter::SetLcdBacklighOffEnabled, "SetLcdBacklighOffEnabled"},
-        {53, &ICommonStateGetter::BeginVrModeEx, "BeginVrModeEx"},
-        {54, &ICommonStateGetter::EndVrModeEx, "EndVrModeEx"},
-        {55, nullptr, "IsInControllerFirmwareUpdateSection"},
-        {59, nullptr, "SetVrPositionForDebug"},
-        {60, &ICommonStateGetter::GetDefaultDisplayResolution, "GetDefaultDisplayResolution"},
-        {61, &ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent, "GetDefaultDisplayResolutionChangeEvent"},
-        {62, nullptr, "GetHdcpAuthenticationState"},
-        {63, nullptr, "GetHdcpAuthenticationStateChangeEvent"},
-        {64, nullptr, "SetTvPowerStateMatchingMode"},
-        {65, nullptr, "GetApplicationIdByContentActionName"},
-        {66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"},
-        {67, nullptr, "CancelCpuBoostMode"},
-        {68, &ICommonStateGetter::GetBuiltInDisplayType, "GetBuiltInDisplayType"},
-        {80, &ICommonStateGetter::PerformSystemButtonPressingIfInFocus, "PerformSystemButtonPressingIfInFocus"},
-        {90, nullptr, "SetPerformanceConfigurationChangedNotification"},
-        {91, nullptr, "GetCurrentPerformanceConfiguration"},
-        {100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"},
-        {110, nullptr, "OpenMyGpuErrorHandler"},
-        {120, &ICommonStateGetter::GetAppletLaunchedHistory, "GetAppletLaunchedHistory"},
-        {200, nullptr, "GetOperationModeSystemInfo"},
-        {300, &ICommonStateGetter::GetSettingsPlatformRegion, "GetSettingsPlatformRegion"},
-        {400, nullptr, "ActivateMigrationService"},
-        {401, nullptr, "DeactivateMigrationService"},
-        {500, nullptr, "DisableSleepTillShutdown"},
-        {501, nullptr, "SuppressDisablingSleepTemporarily"},
-        {502, nullptr, "IsSleepEnabled"},
-        {503, nullptr, "IsDisablingSleepSuppressed"},
-        {900, &ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-ICommonStateGetter::~ICommonStateGetter() = default;
-
-void ICommonStateGetter::GetBootMode(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push<u8>(static_cast<u8>(Service::PM::SystemBootMode::Normal)); // Normal boot mode
-}
-
-void ICommonStateGetter::GetEventHandle(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(applet->message_queue.GetMessageReceiveEvent());
-}
-
-void ICommonStateGetter::ReceiveMessage(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    const auto message = applet->message_queue.PopMessage();
-    IPC::ResponseBuilder rb{ctx, 3};
-
-    if (message == AppletMessageQueue::AppletMessage::None) {
-        LOG_ERROR(Service_AM, "Message queue is empty");
-        rb.Push(AM::ResultNoMessages);
-        rb.PushEnum<AppletMessageQueue::AppletMessage>(message);
-        return;
-    }
-
-    rb.Push(ResultSuccess);
-    rb.PushEnum<AppletMessageQueue::AppletMessage>(message);
-}
-
-void ICommonStateGetter::GetCurrentFocusState(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push(static_cast<u8>(applet->focus_state));
-}
-
-void ICommonStateGetter::GetOperationMode(HLERequestContext& ctx) {
-    const bool use_docked_mode{Settings::IsDockedMode()};
-    LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode);
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld));
-}
-
-void ICommonStateGetter::GetPerformanceMode(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.PushEnum(system.GetAPMController().GetCurrentPerformanceMode());
-}
-
-void ICommonStateGetter::RequestToAcquireSleepLock(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    // Sleep lock is acquired immediately.
-    applet->sleep_lock_event.Signal();
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ICommonStateGetter::GetReaderLockAccessorEx(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto unknown = rp.Pop<u32>();
-
-    LOG_INFO(Service_AM, "called, unknown={}", unknown);
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ILockAccessor>(system);
-}
-
-void ICommonStateGetter::GetAcquiredSleepLockEvent(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(applet->sleep_lock_event.GetHandle());
-}
-
-void ICommonStateGetter::IsVrModeEnabled(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    std::scoped_lock lk{applet->lock};
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push(applet->vr_mode_enabled);
-}
-
-void ICommonStateGetter::SetVrModeEnabled(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    std::scoped_lock lk{applet->lock};
-    applet->vr_mode_enabled = rp.Pop<bool>();
-    LOG_WARNING(Service_AM, "VR Mode is {}", applet->vr_mode_enabled ? "on" : "off");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ICommonStateGetter::SetLcdBacklighOffEnabled(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto is_lcd_backlight_off_enabled = rp.Pop<bool>();
-
-    LOG_WARNING(Service_AM, "(STUBBED) called. is_lcd_backlight_off_enabled={}",
-                is_lcd_backlight_off_enabled);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ICommonStateGetter::BeginVrModeEx(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-    applet->vr_mode_enabled = true;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ICommonStateGetter::EndVrModeEx(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-    applet->vr_mode_enabled = false;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(applet->message_queue.GetOperationModeChangedEvent());
-}
-
-void ICommonStateGetter::GetDefaultDisplayResolution(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-
-    if (Settings::IsDockedMode()) {
-        rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth));
-        rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight));
-    } else {
-        rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedWidth));
-        rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedHeight));
-    }
-}
-
-void ICommonStateGetter::SetCpuBoostMode(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called, forwarding to APM:SYS");
-
-    const auto& sm = system.ServiceManager();
-    const auto apm_sys = sm.GetService<APM::APM_Sys>("apm:sys");
-    ASSERT(apm_sys != nullptr);
-
-    apm_sys->SetCpuBoostMode(ctx);
-}
-
-void ICommonStateGetter::GetBuiltInDisplayType(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push(0);
-}
-
-void ICommonStateGetter::PerformSystemButtonPressingIfInFocus(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto system_button{rp.PopEnum<SystemButtonType>()};
-
-    LOG_WARNING(Service_AM, "(STUBBED) called, system_button={}", system_button);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ICommonStateGetter::GetAppletLaunchedHistory(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::shared_ptr<Applet> current_applet = applet;
-    std::vector<AppletId> result;
-
-    const size_t count = ctx.GetWriteBufferNumElements<AppletId>();
-    size_t i;
-
-    for (i = 0; i < count && current_applet != nullptr; i++) {
-        result.push_back(current_applet->applet_id);
-        current_applet = current_applet->caller_applet.lock();
-    }
-
-    ctx.WriteBuffer(result);
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push(static_cast<u32>(i));
-}
-
-void ICommonStateGetter::GetSettingsPlatformRegion(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.PushEnum(SysPlatformRegion::Global);
-}
-
-void ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(
-    HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-    applet->request_exit_to_library_applet_at_execute_next_program_enabled = true;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/common_state_getter.h b/src/core/hle/service/am/common_state_getter.h
deleted file mode 100644
index bf652790c..000000000
--- a/src/core/hle/service/am/common_state_getter.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/kernel_helpers.h"
-#include "core/hle/service/service.h"
-
-#include "core/hle/service/am/applet_message_queue.h"
-
-namespace Service::AM {
-
-struct Applet;
-
-class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
-public:
-    explicit ICommonStateGetter(Core::System& system_, std::shared_ptr<Applet> applet_);
-    ~ICommonStateGetter() override;
-
-private:
-    // This is nn::oe::FocusState
-    enum class FocusState : u8 {
-        InFocus = 1,
-        NotInFocus = 2,
-        Background = 3,
-    };
-
-    // This is nn::oe::OperationMode
-    enum class OperationMode : u8 {
-        Handheld = 0,
-        Docked = 1,
-    };
-
-    // This is nn::am::service::SystemButtonType
-    enum class SystemButtonType {
-        None,
-        HomeButtonShortPressing,
-        HomeButtonLongPressing,
-        PowerButtonShortPressing,
-        PowerButtonLongPressing,
-        ShutdownSystem,
-        CaptureButtonShortPressing,
-        CaptureButtonLongPressing,
-    };
-
-    enum class SysPlatformRegion : s32 {
-        Global = 1,
-        Terra = 2,
-    };
-
-    void GetEventHandle(HLERequestContext& ctx);
-    void ReceiveMessage(HLERequestContext& ctx);
-    void GetCurrentFocusState(HLERequestContext& ctx);
-    void RequestToAcquireSleepLock(HLERequestContext& ctx);
-    void GetAcquiredSleepLockEvent(HLERequestContext& ctx);
-    void GetReaderLockAccessorEx(HLERequestContext& ctx);
-    void GetDefaultDisplayResolutionChangeEvent(HLERequestContext& ctx);
-    void GetOperationMode(HLERequestContext& ctx);
-    void GetPerformanceMode(HLERequestContext& ctx);
-    void GetBootMode(HLERequestContext& ctx);
-    void IsVrModeEnabled(HLERequestContext& ctx);
-    void SetVrModeEnabled(HLERequestContext& ctx);
-    void SetLcdBacklighOffEnabled(HLERequestContext& ctx);
-    void BeginVrModeEx(HLERequestContext& ctx);
-    void EndVrModeEx(HLERequestContext& ctx);
-    void GetDefaultDisplayResolution(HLERequestContext& ctx);
-    void SetCpuBoostMode(HLERequestContext& ctx);
-    void GetBuiltInDisplayType(HLERequestContext& ctx);
-    void PerformSystemButtonPressingIfInFocus(HLERequestContext& ctx);
-    void GetAppletLaunchedHistory(HLERequestContext& ctx);
-    void GetSettingsPlatformRegion(HLERequestContext& ctx);
-    void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(HLERequestContext& ctx);
-
-    const std::shared_ptr<Applet> applet;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/library_applet_creator.cpp b/src/core/hle/service/am/library_applet_creator.cpp
index 00d5a0705..f7fdcb5db 100644
--- a/src/core/hle/service/am/library_applet_creator.cpp
+++ b/src/core/hle/service/am/library_applet_creator.cpp
@@ -130,13 +130,13 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
     case LibraryAppletMode::PartialForegroundIndirectDisplay:
         applet->hid_registration.EnableAppletToGetInput(true);
         applet->focus_state = FocusState::InFocus;
-        applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
+        applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground);
         break;
     case LibraryAppletMode::AllForegroundInitiallyHidden:
         applet->hid_registration.EnableAppletToGetInput(false);
         applet->focus_state = FocusState::NotInFocus;
         applet->system_buffer_manager.SetWindowVisibility(false);
-        applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoBackground);
+        applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground);
         break;
     }
 
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index 55a4ea72f..2d46299e0 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/common_state_getter.h"
 #include "core/hle/service/am/debug_functions.h"
 #include "core/hle/service/am/display_controller.h"
 #include "core/hle/service/am/library_applet_creator.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/service/application_functions.h"
 #include "core/hle/service/am/service/application_proxy.h"
 #include "core/hle/service/am/service/audio_controller.h"
+#include "core/hle/service/am/service/common_state_getter.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
diff --git a/src/core/hle/service/am/service/common_state_getter.cpp b/src/core/hle/service/am/service/common_state_getter.cpp
new file mode 100644
index 000000000..ac05b457b
--- /dev/null
+++ b/src/core/hle/service/am/service/common_state_getter.cpp
@@ -0,0 +1,277 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/settings.h"
+#include "core/hle/service/am/am_results.h"
+#include "core/hle/service/am/applet.h"
+#include "core/hle/service/am/lock_accessor.h"
+#include "core/hle/service/am/service/common_state_getter.h"
+#include "core/hle/service/apm/apm_interface.h"
+#include "core/hle/service/cmif_serialization.h"
+#include "core/hle/service/pm/pm.h"
+#include "core/hle/service/sm/sm.h"
+#include "core/hle/service/vi/vi.h"
+
+namespace Service::AM {
+
+ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr<Applet> applet)
+    : ServiceFramework{system_, "ICommonStateGetter"}, m_applet{std::move(applet)} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, D<&ICommonStateGetter::GetEventHandle>, "GetEventHandle"},
+        {1, D<&ICommonStateGetter::ReceiveMessage>, "ReceiveMessage"},
+        {2, nullptr, "GetThisAppletKind"},
+        {3, nullptr, "AllowToEnterSleep"},
+        {4, nullptr, "DisallowToEnterSleep"},
+        {5, D<&ICommonStateGetter::GetOperationMode>, "GetOperationMode"},
+        {6, D<&ICommonStateGetter::GetPerformanceMode>, "GetPerformanceMode"},
+        {7, nullptr, "GetCradleStatus"},
+        {8, D<&ICommonStateGetter::GetBootMode>, "GetBootMode"},
+        {9, D<&ICommonStateGetter::GetCurrentFocusState>, "GetCurrentFocusState"},
+        {10, D<&ICommonStateGetter::RequestToAcquireSleepLock>, "RequestToAcquireSleepLock"},
+        {11, nullptr, "ReleaseSleepLock"},
+        {12, nullptr, "ReleaseSleepLockTransiently"},
+        {13, D<&ICommonStateGetter::GetAcquiredSleepLockEvent>, "GetAcquiredSleepLockEvent"},
+        {14, nullptr, "GetWakeupCount"},
+        {20, nullptr, "PushToGeneralChannel"},
+        {30, nullptr, "GetHomeButtonReaderLockAccessor"},
+        {31, D<&ICommonStateGetter::GetReaderLockAccessorEx>, "GetReaderLockAccessorEx"},
+        {32, D<&ICommonStateGetter::GetWriterLockAccessorEx>, "GetWriterLockAccessorEx"},
+        {40, nullptr, "GetCradleFwVersion"},
+        {50, D<&ICommonStateGetter::IsVrModeEnabled>, "IsVrModeEnabled"},
+        {51, D<&ICommonStateGetter::SetVrModeEnabled>, "SetVrModeEnabled"},
+        {52, D<&ICommonStateGetter::SetLcdBacklighOffEnabled>, "SetLcdBacklighOffEnabled"},
+        {53, D<&ICommonStateGetter::BeginVrModeEx>, "BeginVrModeEx"},
+        {54, D<&ICommonStateGetter::EndVrModeEx>, "EndVrModeEx"},
+        {55, D<&ICommonStateGetter::IsInControllerFirmwareUpdateSection>, "IsInControllerFirmwareUpdateSection"},
+        {59, nullptr, "SetVrPositionForDebug"},
+        {60, D<&ICommonStateGetter::GetDefaultDisplayResolution>, "GetDefaultDisplayResolution"},
+        {61, D<&ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent>, "GetDefaultDisplayResolutionChangeEvent"},
+        {62, nullptr, "GetHdcpAuthenticationState"},
+        {63, nullptr, "GetHdcpAuthenticationStateChangeEvent"},
+        {64, nullptr, "SetTvPowerStateMatchingMode"},
+        {65, nullptr, "GetApplicationIdByContentActionName"},
+        {66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"},
+        {67, nullptr, "CancelCpuBoostMode"},
+        {68, D<&ICommonStateGetter::GetBuiltInDisplayType>, "GetBuiltInDisplayType"},
+        {80, D<&ICommonStateGetter::PerformSystemButtonPressingIfInFocus>, "PerformSystemButtonPressingIfInFocus"},
+        {90, nullptr, "SetPerformanceConfigurationChangedNotification"},
+        {91, nullptr, "GetCurrentPerformanceConfiguration"},
+        {100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"},
+        {110, nullptr, "OpenMyGpuErrorHandler"},
+        {120, D<&ICommonStateGetter::GetAppletLaunchedHistory>, "GetAppletLaunchedHistory"},
+        {200, D<&ICommonStateGetter::GetOperationModeSystemInfo>, "GetOperationModeSystemInfo"},
+        {300, D<&ICommonStateGetter::GetSettingsPlatformRegion>, "GetSettingsPlatformRegion"},
+        {400, nullptr, "ActivateMigrationService"},
+        {401, nullptr, "DeactivateMigrationService"},
+        {500, nullptr, "DisableSleepTillShutdown"},
+        {501, nullptr, "SuppressDisablingSleepTemporarily"},
+        {502, nullptr, "IsSleepEnabled"},
+        {503, nullptr, "IsDisablingSleepSuppressed"},
+        {900, D<&ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled>, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+ICommonStateGetter::~ICommonStateGetter() = default;
+
+Result ICommonStateGetter::GetEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_event = &m_applet->message_queue.GetMessageReceiveEvent();
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::ReceiveMessage(Out<AppletMessage> out_applet_message) {
+    LOG_DEBUG(Service_AM, "called");
+
+    *out_applet_message = m_applet->message_queue.PopMessage();
+    if (*out_applet_message == AppletMessage::None) {
+        LOG_ERROR(Service_AM, "Tried to pop message but none was available!");
+        R_THROW(AM::ResultNoMessages);
+    }
+
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::GetCurrentFocusState(Out<FocusState> out_focus_state) {
+    LOG_DEBUG(Service_AM, "called");
+
+    std::scoped_lock lk{m_applet->lock};
+    *out_focus_state = m_applet->focus_state;
+
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::RequestToAcquireSleepLock() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    // Sleep lock is acquired immediately.
+    m_applet->sleep_lock_event.Signal();
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::GetAcquiredSleepLockEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_WARNING(Service_AM, "called");
+    *out_event = m_applet->sleep_lock_event.GetHandle();
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::GetReaderLockAccessorEx(
+    Out<SharedPointer<ILockAccessor>> out_lock_accessor, u32 button_type) {
+    LOG_INFO(Service_AM, "called, button_type={}", button_type);
+    *out_lock_accessor = std::make_shared<ILockAccessor>(system);
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::GetWriterLockAccessorEx(
+    Out<SharedPointer<ILockAccessor>> out_lock_accessor, u32 button_type) {
+    LOG_INFO(Service_AM, "called, button_type={}", button_type);
+    *out_lock_accessor = std::make_shared<ILockAccessor>(system);
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_event = &m_applet->message_queue.GetOperationModeChangedEvent();
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::GetOperationMode(Out<OperationMode> out_operation_mode) {
+    const bool use_docked_mode{Settings::IsDockedMode()};
+    LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode);
+    *out_operation_mode = use_docked_mode ? OperationMode::Docked : OperationMode::Handheld;
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::GetPerformanceMode(Out<APM::PerformanceMode> out_performance_mode) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_performance_mode = system.GetAPMController().GetCurrentPerformanceMode();
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::GetBootMode(Out<PM::SystemBootMode> out_boot_mode) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_boot_mode = Service::PM::SystemBootMode::Normal;
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::IsVrModeEnabled(Out<bool> out_is_vr_mode_enabled) {
+    LOG_DEBUG(Service_AM, "called");
+
+    std::scoped_lock lk{m_applet->lock};
+    *out_is_vr_mode_enabled = m_applet->vr_mode_enabled;
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::SetVrModeEnabled(bool is_vr_mode_enabled) {
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->vr_mode_enabled = is_vr_mode_enabled;
+    LOG_WARNING(Service_AM, "VR Mode is {}", m_applet->vr_mode_enabled ? "on" : "off");
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::SetLcdBacklighOffEnabled(bool is_lcd_backlight_off_enabled) {
+    LOG_WARNING(Service_AM, "(STUBBED) called. is_lcd_backlight_off_enabled={}",
+                is_lcd_backlight_off_enabled);
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::BeginVrModeEx() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->vr_mode_enabled = true;
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::EndVrModeEx() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->vr_mode_enabled = false;
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::IsInControllerFirmwareUpdateSection(
+    Out<bool> out_is_in_controller_firmware_update_section) {
+    LOG_INFO(Service_AM, "called");
+    *out_is_in_controller_firmware_update_section = false;
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::GetDefaultDisplayResolution(Out<s32> out_width, Out<s32> out_height) {
+    LOG_DEBUG(Service_AM, "called");
+
+    if (Settings::IsDockedMode()) {
+        *out_width = static_cast<u32>(Service::VI::DisplayResolution::DockedWidth);
+        *out_height = static_cast<u32>(Service::VI::DisplayResolution::DockedHeight);
+    } else {
+        *out_width = static_cast<u32>(Service::VI::DisplayResolution::UndockedWidth);
+        *out_height = static_cast<u32>(Service::VI::DisplayResolution::UndockedHeight);
+    }
+
+    R_SUCCEED();
+}
+
+void ICommonStateGetter::SetCpuBoostMode(HLERequestContext& ctx) {
+    LOG_DEBUG(Service_AM, "called, forwarding to APM:SYS");
+
+    const auto& sm = system.ServiceManager();
+    const auto apm_sys = sm.GetService<APM::APM_Sys>("apm:sys");
+    ASSERT(apm_sys != nullptr);
+
+    apm_sys->SetCpuBoostMode(ctx);
+}
+
+Result ICommonStateGetter::GetBuiltInDisplayType(Out<s32> out_display_type) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_display_type = 0;
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::PerformSystemButtonPressingIfInFocus(SystemButtonType type) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, type={}", type);
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::GetOperationModeSystemInfo(Out<u32> out_operation_mode_system_info) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_operation_mode_system_info = 0;
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::GetAppletLaunchedHistory(
+    Out<s32> out_count, OutArray<AppletId, BufferAttr_HipcMapAlias> out_applet_ids) {
+    LOG_INFO(Service_AM, "called");
+
+    std::shared_ptr<Applet> current_applet = m_applet;
+
+    for (*out_count = 0;
+         *out_count < static_cast<s32>(out_applet_ids.size()) && current_applet != nullptr;
+         /* ... */) {
+        out_applet_ids[(*out_count)++] = current_applet->applet_id;
+        current_applet = current_applet->caller_applet.lock();
+    }
+
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::GetSettingsPlatformRegion(
+    Out<SysPlatformRegion> out_settings_platform_region) {
+    LOG_INFO(Service_AM, "called");
+    *out_settings_platform_region = SysPlatformRegion::Global;
+    R_SUCCEED();
+}
+
+Result ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->request_exit_to_library_applet_at_execute_next_program_enabled = true;
+
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/common_state_getter.h b/src/core/hle/service/am/service/common_state_getter.h
new file mode 100644
index 000000000..5a8dca3d6
--- /dev/null
+++ b/src/core/hle/service/am/service/common_state_getter.h
@@ -0,0 +1,61 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/am/am_types.h"
+#include "core/hle/service/apm/apm_controller.h"
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/pm/pm.h"
+#include "core/hle/service/service.h"
+
+namespace Kernel {
+class KReadableEvent;
+}
+
+namespace Service::AM {
+
+struct Applet;
+class ILockAccessor;
+
+class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
+public:
+    explicit ICommonStateGetter(Core::System& system_, std::shared_ptr<Applet> applet_);
+    ~ICommonStateGetter() override;
+
+private:
+    Result GetEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result ReceiveMessage(Out<AppletMessage> out_applet_message);
+    Result GetCurrentFocusState(Out<FocusState> out_focus_state);
+    Result RequestToAcquireSleepLock();
+    Result GetAcquiredSleepLockEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result GetReaderLockAccessorEx(Out<SharedPointer<ILockAccessor>> out_lock_accessor,
+                                   u32 button_type);
+    Result GetWriterLockAccessorEx(Out<SharedPointer<ILockAccessor>> out_lock_accessor,
+                                   u32 button_type);
+    Result GetDefaultDisplayResolutionChangeEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result GetOperationMode(Out<OperationMode> out_operation_mode);
+    Result GetPerformanceMode(Out<APM::PerformanceMode> out_performance_mode);
+    Result GetBootMode(Out<PM::SystemBootMode> out_boot_mode);
+    Result IsVrModeEnabled(Out<bool> out_is_vr_mode_enabled);
+    Result SetVrModeEnabled(bool is_vr_mode_enabled);
+    Result SetLcdBacklighOffEnabled(bool is_lcd_backlight_off_enabled);
+    Result BeginVrModeEx();
+    Result EndVrModeEx();
+    Result IsInControllerFirmwareUpdateSection(
+        Out<bool> out_is_in_controller_firmware_update_section);
+    Result GetDefaultDisplayResolution(Out<s32> out_width, Out<s32> out_height);
+    Result GetBuiltInDisplayType(Out<s32> out_display_type);
+    Result PerformSystemButtonPressingIfInFocus(SystemButtonType type);
+    Result GetOperationModeSystemInfo(Out<u32> out_operation_mode_system_info);
+    Result GetAppletLaunchedHistory(Out<s32> out_count,
+                                    OutArray<AppletId, BufferAttr_HipcMapAlias> out_applet_ids);
+    Result GetSettingsPlatformRegion(Out<SysPlatformRegion> out_settings_platform_region);
+    Result SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled();
+
+    void SetCpuBoostMode(HLERequestContext& ctx);
+
+    const std::shared_ptr<Applet> m_applet;
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index c4ea9392a..28886b0c3 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/common_state_getter.h"
 #include "core/hle/service/am/debug_functions.h"
 #include "core/hle/service/am/display_controller.h"
 #include "core/hle/service/am/global_state_controller.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/audio_controller.h"
+#include "core/hle/service/am/service/common_state_getter.h"
 #include "core/hle/service/am/service/library_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index c63b53ac8..ea23bef94 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -2,7 +2,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/application_creator.h"
-#include "core/hle/service/am/common_state_getter.h"
 #include "core/hle/service/am/debug_functions.h"
 #include "core/hle/service/am/display_controller.h"
 #include "core/hle/service/am/global_state_controller.h"
@@ -13,6 +12,7 @@
 #include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/audio_controller.h"
+#include "core/hle/service/am/service/common_state_getter.h"
 #include "core/hle/service/am/service/system_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
diff --git a/src/core/hle/service/am/window_controller.cpp b/src/core/hle/service/am/window_controller.cpp
index c07ef228b..7347fe9d9 100644
--- a/src/core/hle/service/am/window_controller.cpp
+++ b/src/core/hle/service/am/window_controller.cpp
@@ -63,10 +63,10 @@ void IWindowController::SetAppletWindowVisibility(HLERequestContext& ctx) {
 
     if (visible) {
         applet->focus_state = FocusState::InFocus;
-        applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
+        applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground);
     } else {
         applet->focus_state = FocusState::NotInFocus;
-        applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoBackground);
+        applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground);
     }
 
     IPC::ResponseBuilder rb{ctx, 2};

From eafaa5511d5aaafebd595fe12f7400aad475a452 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 19:41:53 -0500
Subject: [PATCH 09/24] am: move IDebugFunctions

---
 src/core/CMakeLists.txt                                   | 4 ++--
 src/core/hle/service/am/service/application_proxy.cpp     | 2 +-
 src/core/hle/service/am/{ => service}/debug_functions.cpp | 3 +--
 src/core/hle/service/am/{ => service}/debug_functions.h   | 0
 src/core/hle/service/am/service/library_applet_proxy.cpp  | 2 +-
 src/core/hle/service/am/service/system_applet_proxy.cpp   | 2 +-
 6 files changed, 6 insertions(+), 7 deletions(-)
 rename src/core/hle/service/am/{ => service}/debug_functions.cpp (95%)
 rename src/core/hle/service/am/{ => service}/debug_functions.h (100%)

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 781be7c10..ad9831979 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -425,8 +425,6 @@ add_library(core STATIC
     hle/service/am/applet_message_queue.h
     hle/service/am/application_creator.cpp
     hle/service/am/application_creator.h
-    hle/service/am/debug_functions.cpp
-    hle/service/am/debug_functions.h
     hle/service/am/display_controller.cpp
     hle/service/am/display_controller.h
     hle/service/am/global_state_controller.cpp
@@ -471,6 +469,8 @@ add_library(core STATIC
     hle/service/am/service/audio_controller.h
     hle/service/am/service/common_state_getter.cpp
     hle/service/am/service/common_state_getter.h
+    hle/service/am/service/debug_functions.cpp
+    hle/service/am/service/debug_functions.h
     hle/service/am/service/library_applet_proxy.cpp
     hle/service/am/service/library_applet_proxy.h
     hle/service/am/service/system_applet_proxy.cpp
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index 2d46299e0..6cd6df2d0 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/debug_functions.h"
 #include "core/hle/service/am/display_controller.h"
 #include "core/hle/service/am/library_applet_creator.h"
 #include "core/hle/service/am/library_applet_self_accessor.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/service/application_proxy.h"
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/common_state_getter.h"
+#include "core/hle/service/am/service/debug_functions.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
diff --git a/src/core/hle/service/am/debug_functions.cpp b/src/core/hle/service/am/service/debug_functions.cpp
similarity index 95%
rename from src/core/hle/service/am/debug_functions.cpp
rename to src/core/hle/service/am/service/debug_functions.cpp
index f80b970f2..fcac4776d 100644
--- a/src/core/hle/service/am/debug_functions.cpp
+++ b/src/core/hle/service/am/service/debug_functions.cpp
@@ -1,8 +1,7 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/debug_functions.h"
-#include "core/hle/service/ipc_helpers.h"
+#include "core/hle/service/am/service/debug_functions.h"
 
 namespace Service::AM {
 
diff --git a/src/core/hle/service/am/debug_functions.h b/src/core/hle/service/am/service/debug_functions.h
similarity index 100%
rename from src/core/hle/service/am/debug_functions.h
rename to src/core/hle/service/am/service/debug_functions.h
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index 28886b0c3..d609871fb 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/debug_functions.h"
 #include "core/hle/service/am/display_controller.h"
 #include "core/hle/service/am/global_state_controller.h"
 #include "core/hle/service/am/home_menu_functions.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/common_state_getter.h"
+#include "core/hle/service/am/service/debug_functions.h"
 #include "core/hle/service/am/service/library_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index ea23bef94..d4ebe3ae0 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -2,7 +2,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/application_creator.h"
-#include "core/hle/service/am/debug_functions.h"
 #include "core/hle/service/am/display_controller.h"
 #include "core/hle/service/am/global_state_controller.h"
 #include "core/hle/service/am/home_menu_functions.h"
@@ -13,6 +12,7 @@
 #include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/common_state_getter.h"
+#include "core/hle/service/am/service/debug_functions.h"
 #include "core/hle/service/am/service/system_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"

From 77b7e1e68295221c05184d89bc46adb0129c5ec4 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 19:44:17 -0500
Subject: [PATCH 10/24] am: rewrite IDisplayController

---
 src/core/CMakeLists.txt                       |   4 +-
 .../hle/service/am/display_controller.cpp     | 135 ------------------
 src/core/hle/service/am/display_controller.h  |  30 ----
 .../service/am/service/application_proxy.cpp  |   2 +-
 .../service/am/service/display_controller.cpp | 105 ++++++++++++++
 .../service/am/service/display_controller.h   |  36 +++++
 .../am/service/library_applet_proxy.cpp       |   2 +-
 .../am/service/system_applet_proxy.cpp        |   2 +-
 8 files changed, 146 insertions(+), 170 deletions(-)
 delete mode 100644 src/core/hle/service/am/display_controller.cpp
 delete mode 100644 src/core/hle/service/am/display_controller.h
 create mode 100644 src/core/hle/service/am/service/display_controller.cpp
 create mode 100644 src/core/hle/service/am/service/display_controller.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index ad9831979..b5b1192b3 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -425,8 +425,6 @@ add_library(core STATIC
     hle/service/am/applet_message_queue.h
     hle/service/am/application_creator.cpp
     hle/service/am/application_creator.h
-    hle/service/am/display_controller.cpp
-    hle/service/am/display_controller.h
     hle/service/am/global_state_controller.cpp
     hle/service/am/global_state_controller.h
     hle/service/am/hid_registration.cpp
@@ -471,6 +469,8 @@ add_library(core STATIC
     hle/service/am/service/common_state_getter.h
     hle/service/am/service/debug_functions.cpp
     hle/service/am/service/debug_functions.h
+    hle/service/am/service/display_controller.cpp
+    hle/service/am/service/display_controller.h
     hle/service/am/service/library_applet_proxy.cpp
     hle/service/am/service/library_applet_proxy.h
     hle/service/am/service/system_applet_proxy.cpp
diff --git a/src/core/hle/service/am/display_controller.cpp b/src/core/hle/service/am/display_controller.cpp
deleted file mode 100644
index 4d6858348..000000000
--- a/src/core/hle/service/am/display_controller.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/am/applet.h"
-#include "core/hle/service/am/display_controller.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-namespace {
-struct OutputParameters {
-    bool was_written;
-    s32 fbshare_layer_index;
-};
-
-static_assert(sizeof(OutputParameters) == 8, "OutputParameters has wrong size");
-} // namespace
-
-IDisplayController::IDisplayController(Core::System& system_, std::shared_ptr<Applet> applet_)
-    : ServiceFramework{system_, "IDisplayController"}, applet(std::move(applet_)) {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {0, nullptr, "GetLastForegroundCaptureImage"},
-        {1, nullptr, "UpdateLastForegroundCaptureImage"},
-        {2, nullptr, "GetLastApplicationCaptureImage"},
-        {3, nullptr, "GetCallerAppletCaptureImage"},
-        {4, nullptr, "UpdateCallerAppletCaptureImage"},
-        {5, nullptr, "GetLastForegroundCaptureImageEx"},
-        {6, nullptr, "GetLastApplicationCaptureImageEx"},
-        {7, &IDisplayController::GetCallerAppletCaptureImageEx, "GetCallerAppletCaptureImageEx"},
-        {8, &IDisplayController::TakeScreenShotOfOwnLayer, "TakeScreenShotOfOwnLayer"},
-        {9, nullptr, "CopyBetweenCaptureBuffers"},
-        {10, nullptr, "AcquireLastApplicationCaptureBuffer"},
-        {11, nullptr, "ReleaseLastApplicationCaptureBuffer"},
-        {12, nullptr, "AcquireLastForegroundCaptureBuffer"},
-        {13, nullptr, "ReleaseLastForegroundCaptureBuffer"},
-        {14, nullptr, "AcquireCallerAppletCaptureBuffer"},
-        {15, nullptr, "ReleaseCallerAppletCaptureBuffer"},
-        {16, nullptr, "AcquireLastApplicationCaptureBufferEx"},
-        {17, nullptr, "AcquireLastForegroundCaptureBufferEx"},
-        {18, nullptr, "AcquireCallerAppletCaptureBufferEx"},
-        {20, nullptr, "ClearCaptureBuffer"},
-        {21, nullptr, "ClearAppletTransitionBuffer"},
-        {22, &IDisplayController::AcquireLastApplicationCaptureSharedBuffer, "AcquireLastApplicationCaptureSharedBuffer"},
-        {23, &IDisplayController::ReleaseLastApplicationCaptureSharedBuffer, "ReleaseLastApplicationCaptureSharedBuffer"},
-        {24, &IDisplayController::AcquireLastForegroundCaptureSharedBuffer, "AcquireLastForegroundCaptureSharedBuffer"},
-        {25, &IDisplayController::ReleaseLastForegroundCaptureSharedBuffer, "ReleaseLastForegroundCaptureSharedBuffer"},
-        {26, &IDisplayController::AcquireCallerAppletCaptureSharedBuffer, "AcquireCallerAppletCaptureSharedBuffer"},
-        {27, &IDisplayController::ReleaseCallerAppletCaptureSharedBuffer, "ReleaseCallerAppletCaptureSharedBuffer"},
-        {28, nullptr, "TakeScreenShotOfOwnLayerEx"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-IDisplayController::~IDisplayController() = default;
-
-void IDisplayController::GetCallerAppletCaptureImageEx(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    OutputParameters params{};
-    const auto res = applet->system_buffer_manager.WriteAppletCaptureBuffer(
-        &params.was_written, &params.fbshare_layer_index);
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(res);
-    rb.PushRaw(params);
-}
-
-void IDisplayController::TakeScreenShotOfOwnLayer(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IDisplayController::AcquireLastApplicationCaptureSharedBuffer(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    OutputParameters params{};
-    const auto res = applet->system_buffer_manager.WriteAppletCaptureBuffer(
-        &params.was_written, &params.fbshare_layer_index);
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(res);
-    rb.PushRaw(params);
-}
-
-void IDisplayController::ReleaseLastApplicationCaptureSharedBuffer(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IDisplayController::AcquireLastForegroundCaptureSharedBuffer(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    OutputParameters params{};
-    const auto res = applet->system_buffer_manager.WriteAppletCaptureBuffer(
-        &params.was_written, &params.fbshare_layer_index);
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(res);
-    rb.PushRaw(params);
-}
-
-void IDisplayController::ReleaseLastForegroundCaptureSharedBuffer(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IDisplayController::AcquireCallerAppletCaptureSharedBuffer(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    OutputParameters params{};
-    const auto res = applet->system_buffer_manager.WriteAppletCaptureBuffer(
-        &params.was_written, &params.fbshare_layer_index);
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(res);
-    rb.PushRaw(params);
-}
-
-void IDisplayController::ReleaseCallerAppletCaptureSharedBuffer(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/display_controller.h b/src/core/hle/service/am/display_controller.h
deleted file mode 100644
index 75172580c..000000000
--- a/src/core/hle/service/am/display_controller.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-struct Applet;
-
-class IDisplayController final : public ServiceFramework<IDisplayController> {
-public:
-    explicit IDisplayController(Core::System& system_, std::shared_ptr<Applet> applet_);
-    ~IDisplayController() override;
-
-private:
-    void GetCallerAppletCaptureImageEx(HLERequestContext& ctx);
-    void TakeScreenShotOfOwnLayer(HLERequestContext& ctx);
-    void AcquireLastForegroundCaptureSharedBuffer(HLERequestContext& ctx);
-    void ReleaseLastForegroundCaptureSharedBuffer(HLERequestContext& ctx);
-    void AcquireCallerAppletCaptureSharedBuffer(HLERequestContext& ctx);
-    void ReleaseCallerAppletCaptureSharedBuffer(HLERequestContext& ctx);
-    void AcquireLastApplicationCaptureSharedBuffer(HLERequestContext& ctx);
-    void ReleaseLastApplicationCaptureSharedBuffer(HLERequestContext& ctx);
-
-    const std::shared_ptr<Applet> applet;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index 6cd6df2d0..445f9b158 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/display_controller.h"
 #include "core/hle/service/am/library_applet_creator.h"
 #include "core/hle/service/am/library_applet_self_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/common_state_getter.h"
 #include "core/hle/service/am/service/debug_functions.h"
+#include "core/hle/service/am/service/display_controller.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
diff --git a/src/core/hle/service/am/service/display_controller.cpp b/src/core/hle/service/am/service/display_controller.cpp
new file mode 100644
index 000000000..249c73dfb
--- /dev/null
+++ b/src/core/hle/service/am/service/display_controller.cpp
@@ -0,0 +1,105 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/result.h"
+#include "core/hle/service/am/applet.h"
+#include "core/hle/service/am/service/display_controller.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+IDisplayController::IDisplayController(Core::System& system_, std::shared_ptr<Applet> applet_)
+    : ServiceFramework{system_, "IDisplayController"}, applet(std::move(applet_)) {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, nullptr, "GetLastForegroundCaptureImage"},
+        {1, nullptr, "UpdateLastForegroundCaptureImage"},
+        {2, nullptr, "GetLastApplicationCaptureImage"},
+        {3, nullptr, "GetCallerAppletCaptureImage"},
+        {4, nullptr, "UpdateCallerAppletCaptureImage"},
+        {5, nullptr, "GetLastForegroundCaptureImageEx"},
+        {6, nullptr, "GetLastApplicationCaptureImageEx"},
+        {7, D<&IDisplayController::GetCallerAppletCaptureImageEx>, "GetCallerAppletCaptureImageEx"},
+        {8, D<&IDisplayController::TakeScreenShotOfOwnLayer>, "TakeScreenShotOfOwnLayer"},
+        {9, nullptr, "CopyBetweenCaptureBuffers"},
+        {10, nullptr, "AcquireLastApplicationCaptureBuffer"},
+        {11, nullptr, "ReleaseLastApplicationCaptureBuffer"},
+        {12, nullptr, "AcquireLastForegroundCaptureBuffer"},
+        {13, nullptr, "ReleaseLastForegroundCaptureBuffer"},
+        {14, nullptr, "AcquireCallerAppletCaptureBuffer"},
+        {15, nullptr, "ReleaseCallerAppletCaptureBuffer"},
+        {16, nullptr, "AcquireLastApplicationCaptureBufferEx"},
+        {17, nullptr, "AcquireLastForegroundCaptureBufferEx"},
+        {18, nullptr, "AcquireCallerAppletCaptureBufferEx"},
+        {20, D<&IDisplayController::ClearCaptureBuffer>, "ClearCaptureBuffer"},
+        {21, nullptr, "ClearAppletTransitionBuffer"},
+        {22, D<&IDisplayController::AcquireLastApplicationCaptureSharedBuffer>, "AcquireLastApplicationCaptureSharedBuffer"},
+        {23, D<&IDisplayController::ReleaseLastApplicationCaptureSharedBuffer>, "ReleaseLastApplicationCaptureSharedBuffer"},
+        {24, D<&IDisplayController::AcquireLastForegroundCaptureSharedBuffer>, "AcquireLastForegroundCaptureSharedBuffer"},
+        {25, D<&IDisplayController::ReleaseLastForegroundCaptureSharedBuffer>, "ReleaseLastForegroundCaptureSharedBuffer"},
+        {26, D<&IDisplayController::AcquireCallerAppletCaptureSharedBuffer>, "AcquireCallerAppletCaptureSharedBuffer"},
+        {27, D<&IDisplayController::ReleaseCallerAppletCaptureSharedBuffer>, "ReleaseCallerAppletCaptureSharedBuffer"},
+        {28, nullptr, "TakeScreenShotOfOwnLayerEx"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IDisplayController::~IDisplayController() = default;
+
+Result IDisplayController::GetCallerAppletCaptureImageEx(
+    Out<bool> out_was_written, OutBuffer<BufferAttr_HipcMapAlias> out_image_data) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_was_written = true;
+    R_SUCCEED();
+}
+
+Result IDisplayController::TakeScreenShotOfOwnLayer(bool unknown0, s32 fbshare_layer_index) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result IDisplayController::ClearCaptureBuffer(bool unknown0, s32 fbshare_layer_index, u32 color) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, unknown0={} fbshare_layer_index={} color={:#x}",
+                unknown0, fbshare_layer_index, color);
+    R_SUCCEED();
+}
+
+Result IDisplayController::AcquireLastForegroundCaptureSharedBuffer(
+    Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written,
+                                                                    out_fbshare_layer_index));
+}
+
+Result IDisplayController::ReleaseLastForegroundCaptureSharedBuffer() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result IDisplayController::AcquireCallerAppletCaptureSharedBuffer(
+    Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written,
+                                                                    out_fbshare_layer_index));
+}
+
+Result IDisplayController::ReleaseCallerAppletCaptureSharedBuffer() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result IDisplayController::AcquireLastApplicationCaptureSharedBuffer(
+    Out<bool> out_was_written, Out<s32> out_fbshare_layer_index) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_RETURN(applet->system_buffer_manager.WriteAppletCaptureBuffer(out_was_written,
+                                                                    out_fbshare_layer_index));
+}
+
+Result IDisplayController::ReleaseLastApplicationCaptureSharedBuffer() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/display_controller.h b/src/core/hle/service/am/service/display_controller.h
new file mode 100644
index 000000000..406fae21a
--- /dev/null
+++ b/src/core/hle/service/am/service/display_controller.h
@@ -0,0 +1,36 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+struct Applet;
+
+class IDisplayController final : public ServiceFramework<IDisplayController> {
+public:
+    explicit IDisplayController(Core::System& system_, std::shared_ptr<Applet> applet_);
+    ~IDisplayController() override;
+
+private:
+    Result GetCallerAppletCaptureImageEx(Out<bool> out_was_written,
+                                         OutBuffer<BufferAttr_HipcMapAlias> out_image_data);
+    Result TakeScreenShotOfOwnLayer(bool unknown0, s32 fbshare_layer_index);
+    Result ClearCaptureBuffer(bool unknown0, s32 fbshare_layer_index, u32 color);
+    Result AcquireLastForegroundCaptureSharedBuffer(Out<bool> out_was_written,
+                                                    Out<s32> out_fbshare_layer_index);
+    Result ReleaseLastForegroundCaptureSharedBuffer();
+    Result AcquireCallerAppletCaptureSharedBuffer(Out<bool> out_was_written,
+                                                  Out<s32> out_fbshare_layer_index);
+    Result ReleaseCallerAppletCaptureSharedBuffer();
+    Result AcquireLastApplicationCaptureSharedBuffer(Out<bool> out_was_written,
+                                                     Out<s32> out_fbshare_layer_index);
+    Result ReleaseLastApplicationCaptureSharedBuffer();
+
+    const std::shared_ptr<Applet> applet;
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index d609871fb..589d53c20 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/display_controller.h"
 #include "core/hle/service/am/global_state_controller.h"
 #include "core/hle/service/am/home_menu_functions.h"
 #include "core/hle/service/am/library_applet_creator.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/common_state_getter.h"
 #include "core/hle/service/am/service/debug_functions.h"
+#include "core/hle/service/am/service/display_controller.h"
 #include "core/hle/service/am/service/library_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index d4ebe3ae0..4bfbd1067 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -2,7 +2,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/application_creator.h"
-#include "core/hle/service/am/display_controller.h"
 #include "core/hle/service/am/global_state_controller.h"
 #include "core/hle/service/am/home_menu_functions.h"
 #include "core/hle/service/am/library_applet_creator.h"
@@ -13,6 +12,7 @@
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/common_state_getter.h"
 #include "core/hle/service/am/service/debug_functions.h"
+#include "core/hle/service/am/service/display_controller.h"
 #include "core/hle/service/am/service/system_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"

From 17460def8eff8e5e70d2e298a31c591ba03593b6 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 19:48:13 -0500
Subject: [PATCH 11/24] am: rewrite IGlobalStateController, add
 ICradleFirmwareUpdater

---
 src/core/CMakeLists.txt                       |  6 +-
 .../service/am/global_state_controller.cpp    | 34 -----------
 .../hle/service/am/global_state_controller.h  | 16 -----
 .../am/service/cradle_firmware_updater.cpp    | 52 ++++++++++++++++
 .../am/service/cradle_firmware_updater.h      | 37 +++++++++++
 .../am/service/global_state_controller.cpp    | 61 +++++++++++++++++++
 .../am/service/global_state_controller.h      | 31 ++++++++++
 .../am/service/library_applet_proxy.cpp       |  2 +-
 .../am/service/system_applet_proxy.cpp        |  2 +-
 9 files changed, 187 insertions(+), 54 deletions(-)
 delete mode 100644 src/core/hle/service/am/global_state_controller.cpp
 delete mode 100644 src/core/hle/service/am/global_state_controller.h
 create mode 100644 src/core/hle/service/am/service/cradle_firmware_updater.cpp
 create mode 100644 src/core/hle/service/am/service/cradle_firmware_updater.h
 create mode 100644 src/core/hle/service/am/service/global_state_controller.cpp
 create mode 100644 src/core/hle/service/am/service/global_state_controller.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index b5b1192b3..724ed989d 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -425,8 +425,6 @@ add_library(core STATIC
     hle/service/am/applet_message_queue.h
     hle/service/am/application_creator.cpp
     hle/service/am/application_creator.h
-    hle/service/am/global_state_controller.cpp
-    hle/service/am/global_state_controller.h
     hle/service/am/hid_registration.cpp
     hle/service/am/hid_registration.h
     hle/service/am/home_menu_functions.cpp
@@ -467,10 +465,14 @@ add_library(core STATIC
     hle/service/am/service/audio_controller.h
     hle/service/am/service/common_state_getter.cpp
     hle/service/am/service/common_state_getter.h
+    hle/service/am/service/cradle_firmware_updater.cpp
+    hle/service/am/service/cradle_firmware_updater.h
     hle/service/am/service/debug_functions.cpp
     hle/service/am/service/debug_functions.h
     hle/service/am/service/display_controller.cpp
     hle/service/am/service/display_controller.h
+    hle/service/am/service/global_state_controller.cpp
+    hle/service/am/service/global_state_controller.h
     hle/service/am/service/library_applet_proxy.cpp
     hle/service/am/service/library_applet_proxy.h
     hle/service/am/service/system_applet_proxy.cpp
diff --git a/src/core/hle/service/am/global_state_controller.cpp b/src/core/hle/service/am/global_state_controller.cpp
deleted file mode 100644
index ed0eb7108..000000000
--- a/src/core/hle/service/am/global_state_controller.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/am/global_state_controller.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-IGlobalStateController::IGlobalStateController(Core::System& system_)
-    : ServiceFramework{system_, "IGlobalStateController"} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {0, nullptr, "RequestToEnterSleep"},
-        {1, nullptr, "EnterSleep"},
-        {2, nullptr, "StartSleepSequence"},
-        {3, nullptr, "StartShutdownSequence"},
-        {4, nullptr, "StartRebootSequence"},
-        {9, nullptr, "IsAutoPowerDownRequested"},
-        {10, nullptr, "LoadAndApplyIdlePolicySettings"},
-        {11, nullptr, "NotifyCecSettingsChanged"},
-        {12, nullptr, "SetDefaultHomeButtonLongPressTime"},
-        {13, nullptr, "UpdateDefaultDisplayResolution"},
-        {14, nullptr, "ShouldSleepOnBoot"},
-        {15, nullptr, "GetHdcpAuthenticationFailedEvent"},
-        {30, nullptr, "OpenCradleFirmwareUpdater"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-IGlobalStateController::~IGlobalStateController() = default;
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/global_state_controller.h b/src/core/hle/service/am/global_state_controller.h
deleted file mode 100644
index 7125464a1..000000000
--- a/src/core/hle/service/am/global_state_controller.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-class IGlobalStateController final : public ServiceFramework<IGlobalStateController> {
-public:
-    explicit IGlobalStateController(Core::System& system_);
-    ~IGlobalStateController() override;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/cradle_firmware_updater.cpp b/src/core/hle/service/am/service/cradle_firmware_updater.cpp
new file mode 100644
index 000000000..0a8af0858
--- /dev/null
+++ b/src/core/hle/service/am/service/cradle_firmware_updater.cpp
@@ -0,0 +1,52 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/am/service/cradle_firmware_updater.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+ICradleFirmwareUpdater::ICradleFirmwareUpdater(Core::System& system_)
+    : ServiceFramework{system_, "ICradleFirmwareUpdater"},
+      m_context{system, "ICradleFirmwareUpdater"}, m_cradle_device_info_event{m_context} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, D<&ICradleFirmwareUpdater::StartUpdate>, "StartUpdate"},
+        {1, D<&ICradleFirmwareUpdater::FinishUpdate>, "FinishUpdate"},
+        {2, D<&ICradleFirmwareUpdater::GetCradleDeviceInfo>, "GetCradleDeviceInfo"},
+        {3, D<&ICradleFirmwareUpdater::GetCradleDeviceInfoChangeEvent>, "GetCradleDeviceInfoChangeEvent"},
+        {4, nullptr, "GetUpdateProgressInfo"},
+        {5, nullptr, "GetLastInternalResult"},
+
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+ICradleFirmwareUpdater::~ICradleFirmwareUpdater() = default;
+
+Result ICradleFirmwareUpdater::StartUpdate() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result ICradleFirmwareUpdater::FinishUpdate() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result ICradleFirmwareUpdater::GetCradleDeviceInfo(Out<CradleDeviceInfo> out_cradle_device_info) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_cradle_device_info = {};
+    R_SUCCEED();
+}
+
+Result ICradleFirmwareUpdater::GetCradleDeviceInfoChangeEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_event = m_cradle_device_info_event.GetHandle();
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/cradle_firmware_updater.h b/src/core/hle/service/am/service/cradle_firmware_updater.h
new file mode 100644
index 000000000..3e803f0ae
--- /dev/null
+++ b/src/core/hle/service/am/service/cradle_firmware_updater.h
@@ -0,0 +1,37 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/kernel_helpers.h"
+#include "core/hle/service/os/event.h"
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+struct CradleDeviceInfo {
+    bool unknown0;
+    bool unknown1;
+    bool unknown2;
+    u64 unknown3;
+};
+static_assert(sizeof(CradleDeviceInfo) == 0x10, "CradleDeviceInfo has incorrect size");
+
+class ICradleFirmwareUpdater final : public ServiceFramework<ICradleFirmwareUpdater> {
+public:
+    explicit ICradleFirmwareUpdater(Core::System& system_);
+    ~ICradleFirmwareUpdater() override;
+
+private:
+    Result StartUpdate();
+    Result FinishUpdate();
+    Result GetCradleDeviceInfo(Out<CradleDeviceInfo> out_cradle_device_info);
+    Result GetCradleDeviceInfoChangeEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+
+private:
+    KernelHelpers::ServiceContext m_context;
+    Event m_cradle_device_info_event;
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/global_state_controller.cpp b/src/core/hle/service/am/service/global_state_controller.cpp
new file mode 100644
index 000000000..dba5d3613
--- /dev/null
+++ b/src/core/hle/service/am/service/global_state_controller.cpp
@@ -0,0 +1,61 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/am/service/cradle_firmware_updater.h"
+#include "core/hle/service/am/service/global_state_controller.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+IGlobalStateController::IGlobalStateController(Core::System& system_)
+    : ServiceFramework{system_, "IGlobalStateController"},
+      m_context{system_, "IGlobalStateController"}, m_hdcp_authentication_failed_event{m_context} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, nullptr, "RequestToEnterSleep"},
+        {1, nullptr, "EnterSleep"},
+        {2, nullptr, "StartSleepSequence"},
+        {3, nullptr, "StartShutdownSequence"},
+        {4, nullptr, "StartRebootSequence"},
+        {9, nullptr, "IsAutoPowerDownRequested"},
+        {10, D<&IGlobalStateController::LoadAndApplyIdlePolicySettings>, "LoadAndApplyIdlePolicySettings"},
+        {11, nullptr, "NotifyCecSettingsChanged"},
+        {12, nullptr, "SetDefaultHomeButtonLongPressTime"},
+        {13, nullptr, "UpdateDefaultDisplayResolution"},
+        {14, D<&IGlobalStateController::ShouldSleepOnBoot>, "ShouldSleepOnBoot"},
+        {15, D<&IGlobalStateController::GetHdcpAuthenticationFailedEvent>, "GetHdcpAuthenticationFailedEvent"},
+        {30, D<&IGlobalStateController::OpenCradleFirmwareUpdater>, "OpenCradleFirmwareUpdater"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IGlobalStateController::~IGlobalStateController() = default;
+
+Result IGlobalStateController::LoadAndApplyIdlePolicySettings() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result IGlobalStateController::ShouldSleepOnBoot(Out<bool> out_should_sleep_on_boot) {
+    LOG_INFO(Service_AM, "called");
+    *out_should_sleep_on_boot = false;
+    R_SUCCEED();
+}
+
+Result IGlobalStateController::GetHdcpAuthenticationFailedEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_INFO(Service_AM, "called");
+    *out_event = m_hdcp_authentication_failed_event.GetHandle();
+    R_SUCCEED();
+}
+
+Result IGlobalStateController::OpenCradleFirmwareUpdater(
+    Out<SharedPointer<ICradleFirmwareUpdater>> out_cradle_firmware_updater) {
+    LOG_INFO(Service_AM, "called");
+    *out_cradle_firmware_updater = std::make_shared<ICradleFirmwareUpdater>(system);
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/global_state_controller.h b/src/core/hle/service/am/service/global_state_controller.h
new file mode 100644
index 000000000..67c753513
--- /dev/null
+++ b/src/core/hle/service/am/service/global_state_controller.h
@@ -0,0 +1,31 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/kernel_helpers.h"
+#include "core/hle/service/os/event.h"
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+class ICradleFirmwareUpdater;
+
+class IGlobalStateController final : public ServiceFramework<IGlobalStateController> {
+public:
+    explicit IGlobalStateController(Core::System& system_);
+    ~IGlobalStateController() override;
+
+private:
+    Result LoadAndApplyIdlePolicySettings();
+    Result ShouldSleepOnBoot(Out<bool> out_should_sleep_on_boot);
+    Result GetHdcpAuthenticationFailedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result OpenCradleFirmwareUpdater(
+        Out<SharedPointer<ICradleFirmwareUpdater>> out_cradle_firmware_updater);
+
+    KernelHelpers::ServiceContext m_context;
+    Event m_hdcp_authentication_failed_event;
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index 589d53c20..7b5e9717d 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/global_state_controller.h"
 #include "core/hle/service/am/home_menu_functions.h"
 #include "core/hle/service/am/library_applet_creator.h"
 #include "core/hle/service/am/library_applet_self_accessor.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/service/common_state_getter.h"
 #include "core/hle/service/am/service/debug_functions.h"
 #include "core/hle/service/am/service/display_controller.h"
+#include "core/hle/service/am/service/global_state_controller.h"
 #include "core/hle/service/am/service/library_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index 4bfbd1067..077f6eea7 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -2,7 +2,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/application_creator.h"
-#include "core/hle/service/am/global_state_controller.h"
 #include "core/hle/service/am/home_menu_functions.h"
 #include "core/hle/service/am/library_applet_creator.h"
 #include "core/hle/service/am/library_applet_self_accessor.h"
@@ -13,6 +12,7 @@
 #include "core/hle/service/am/service/common_state_getter.h"
 #include "core/hle/service/am/service/debug_functions.h"
 #include "core/hle/service/am/service/display_controller.h"
+#include "core/hle/service/am/service/global_state_controller.h"
 #include "core/hle/service/am/service/system_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"

From 2c49ebbeead0d1269aefca832d284bd3a1be5a01 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 19:51:14 -0500
Subject: [PATCH 12/24] am: rewrite IHomeMenuFunctions

---
 src/core/CMakeLists.txt                       |  4 +-
 .../hle/service/am/home_menu_functions.cpp    | 57 --------------
 src/core/hle/service/am/home_menu_functions.h | 25 -------
 .../am/service/home_menu_functions.cpp        | 74 +++++++++++++++++++
 .../service/am/service/home_menu_functions.h  | 34 +++++++++
 .../am/service/library_applet_proxy.cpp       |  4 +-
 .../am/service/system_applet_proxy.cpp        |  4 +-
 7 files changed, 114 insertions(+), 88 deletions(-)
 delete mode 100644 src/core/hle/service/am/home_menu_functions.cpp
 delete mode 100644 src/core/hle/service/am/home_menu_functions.h
 create mode 100644 src/core/hle/service/am/service/home_menu_functions.cpp
 create mode 100644 src/core/hle/service/am/service/home_menu_functions.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 724ed989d..ae2fe0b68 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -427,8 +427,6 @@ add_library(core STATIC
     hle/service/am/application_creator.h
     hle/service/am/hid_registration.cpp
     hle/service/am/hid_registration.h
-    hle/service/am/home_menu_functions.cpp
-    hle/service/am/home_menu_functions.h
     hle/service/am/idle.cpp
     hle/service/am/idle.h
     hle/service/am/library_applet_accessor.cpp
@@ -473,6 +471,8 @@ add_library(core STATIC
     hle/service/am/service/display_controller.h
     hle/service/am/service/global_state_controller.cpp
     hle/service/am/service/global_state_controller.h
+    hle/service/am/service/home_menu_functions.cpp
+    hle/service/am/service/home_menu_functions.h
     hle/service/am/service/library_applet_proxy.cpp
     hle/service/am/service/library_applet_proxy.h
     hle/service/am/service/system_applet_proxy.cpp
diff --git a/src/core/hle/service/am/home_menu_functions.cpp b/src/core/hle/service/am/home_menu_functions.cpp
deleted file mode 100644
index 640e9fbb7..000000000
--- a/src/core/hle/service/am/home_menu_functions.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/am/home_menu_functions.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
-    : ServiceFramework{system_, "IHomeMenuFunctions"}, service_context{system,
-                                                                       "IHomeMenuFunctions"} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"},
-        {11, nullptr, "LockForeground"},
-        {12, nullptr, "UnlockForeground"},
-        {20, nullptr, "PopFromGeneralChannel"},
-        {21, &IHomeMenuFunctions::GetPopFromGeneralChannelEvent, "GetPopFromGeneralChannelEvent"},
-        {30, nullptr, "GetHomeButtonWriterLockAccessor"},
-        {31, nullptr, "GetWriterLockAccessorEx"},
-        {40, nullptr, "IsSleepEnabled"},
-        {41, nullptr, "IsRebootEnabled"},
-        {50, nullptr, "LaunchSystemApplet"},
-        {51, nullptr, "LaunchStarter"},
-        {100, nullptr, "PopRequestLaunchApplicationForDebug"},
-        {110, nullptr, "IsForceTerminateApplicationDisabledForDebug"},
-        {200, nullptr, "LaunchDevMenu"},
-        {1000, nullptr, "SetLastApplicationExitReason"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-
-    pop_from_general_channel_event =
-        service_context.CreateEvent("IHomeMenuFunctions:PopFromGeneralChannelEvent");
-}
-
-IHomeMenuFunctions::~IHomeMenuFunctions() {
-    service_context.CloseEvent(pop_from_general_channel_event);
-}
-
-void IHomeMenuFunctions::RequestToGetForeground(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(pop_from_general_channel_event->GetReadableEvent());
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/home_menu_functions.h b/src/core/hle/service/am/home_menu_functions.h
deleted file mode 100644
index e082d5d73..000000000
--- a/src/core/hle/service/am/home_menu_functions.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/kernel_helpers.h"
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
-public:
-    explicit IHomeMenuFunctions(Core::System& system_);
-    ~IHomeMenuFunctions() override;
-
-private:
-    void RequestToGetForeground(HLERequestContext& ctx);
-    void GetPopFromGeneralChannelEvent(HLERequestContext& ctx);
-
-    KernelHelpers::ServiceContext service_context;
-
-    Kernel::KEvent* pop_from_general_channel_event;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/home_menu_functions.cpp b/src/core/hle/service/am/service/home_menu_functions.cpp
new file mode 100644
index 000000000..0c4d24b58
--- /dev/null
+++ b/src/core/hle/service/am/service/home_menu_functions.cpp
@@ -0,0 +1,74 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/result.h"
+#include "core/hle/service/am/applet_manager.h"
+#include "core/hle/service/am/service/home_menu_functions.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet)
+    : ServiceFramework{system_, "IHomeMenuFunctions"}, m_applet{std::move(applet)},
+      m_context{system, "IHomeMenuFunctions"}, m_pop_from_general_channel_event{m_context} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {10, D<&IHomeMenuFunctions::RequestToGetForeground>, "RequestToGetForeground"},
+        {11, D<&IHomeMenuFunctions::LockForeground>, "LockForeground"},
+        {12, D<&IHomeMenuFunctions::UnlockForeground>, "UnlockForeground"},
+        {20, nullptr, "PopFromGeneralChannel"},
+        {21, D<&IHomeMenuFunctions::GetPopFromGeneralChannelEvent>, "GetPopFromGeneralChannelEvent"},
+        {30, nullptr, "GetHomeButtonWriterLockAccessor"},
+        {31, nullptr, "GetWriterLockAccessorEx"},
+        {40, nullptr, "IsSleepEnabled"},
+        {41, D<&IHomeMenuFunctions::IsRebootEnabled>, "IsRebootEnabled"},
+        {50, nullptr, "LaunchSystemApplet"},
+        {51, nullptr, "LaunchStarter"},
+        {100, nullptr, "PopRequestLaunchApplicationForDebug"},
+        {110, D<&IHomeMenuFunctions::IsForceTerminateApplicationDisabledForDebug>, "IsForceTerminateApplicationDisabledForDebug"},
+        {200, nullptr, "LaunchDevMenu"},
+        {1000, nullptr, "SetLastApplicationExitReason"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IHomeMenuFunctions::~IHomeMenuFunctions() = default;
+
+Result IHomeMenuFunctions::RequestToGetForeground() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result IHomeMenuFunctions::LockForeground() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result IHomeMenuFunctions::UnlockForeground() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result IHomeMenuFunctions::GetPopFromGeneralChannelEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_INFO(Service_AM, "called");
+    *out_event = m_pop_from_general_channel_event.GetHandle();
+    R_SUCCEED();
+}
+
+Result IHomeMenuFunctions::IsRebootEnabled(Out<bool> out_is_reboot_enbaled) {
+    LOG_INFO(Service_AM, "called");
+    *out_is_reboot_enbaled = true;
+    R_SUCCEED();
+}
+
+Result IHomeMenuFunctions::IsForceTerminateApplicationDisabledForDebug(
+    Out<bool> out_is_force_terminate_application_disabled_for_debug) {
+    LOG_INFO(Service_AM, "called");
+    *out_is_force_terminate_application_disabled_for_debug = false;
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/home_menu_functions.h b/src/core/hle/service/am/service/home_menu_functions.h
new file mode 100644
index 000000000..caf6fbaab
--- /dev/null
+++ b/src/core/hle/service/am/service/home_menu_functions.h
@@ -0,0 +1,34 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/kernel_helpers.h"
+#include "core/hle/service/os/event.h"
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+struct Applet;
+
+class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
+public:
+    explicit IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet);
+    ~IHomeMenuFunctions() override;
+
+private:
+    Result RequestToGetForeground();
+    Result LockForeground();
+    Result UnlockForeground();
+    Result GetPopFromGeneralChannelEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result IsRebootEnabled(Out<bool> out_is_reboot_enbaled);
+    Result IsForceTerminateApplicationDisabledForDebug(
+        Out<bool> out_is_force_terminate_application_disabled_for_debug);
+
+    const std::shared_ptr<Applet> m_applet;
+    KernelHelpers::ServiceContext m_context;
+    Event m_pop_from_general_channel_event;
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index 7b5e9717d..cf1a34db2 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/home_menu_functions.h"
 #include "core/hle/service/am/library_applet_creator.h"
 #include "core/hle/service/am/library_applet_self_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/service/debug_functions.h"
 #include "core/hle/service/am/service/display_controller.h"
 #include "core/hle/service/am/service/global_state_controller.h"
+#include "core/hle/service/am/service/home_menu_functions.h"
 #include "core/hle/service/am/service/library_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
@@ -119,7 +119,7 @@ Result ILibraryAppletProxy::GetAppletCommonFunctions(
 Result ILibraryAppletProxy::GetHomeMenuFunctions(
     Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) {
     LOG_DEBUG(Service_AM, "called");
-    *out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system);
+    *out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system, m_applet);
     R_SUCCEED();
 }
 
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index 077f6eea7..8fa852cfa 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -2,7 +2,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/application_creator.h"
-#include "core/hle/service/am/home_menu_functions.h"
 #include "core/hle/service/am/library_applet_creator.h"
 #include "core/hle/service/am/library_applet_self_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
@@ -13,6 +12,7 @@
 #include "core/hle/service/am/service/debug_functions.h"
 #include "core/hle/service/am/service/display_controller.h"
 #include "core/hle/service/am/service/global_state_controller.h"
+#include "core/hle/service/am/service/home_menu_functions.h"
 #include "core/hle/service/am/service/system_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
@@ -118,7 +118,7 @@ Result ISystemAppletProxy::GetAppletCommonFunctions(
 Result ISystemAppletProxy::GetHomeMenuFunctions(
     Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) {
     LOG_DEBUG(Service_AM, "called");
-    *out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system);
+    *out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system, m_applet);
     R_SUCCEED();
 }
 

From f9bba8007d3978ca9309ae82ec05299aacdfd24b Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 19:56:09 -0500
Subject: [PATCH 13/24] am: rewrite ILibraryAppletAccessor

---
 src/core/CMakeLists.txt                       |   4 +-
 .../service/am/library_applet_accessor.cpp    | 202 ------------------
 .../hle/service/am/library_applet_accessor.h  |  43 ----
 .../hle/service/am/library_applet_creator.cpp |   2 +-
 .../service/am/process_winding_controller.cpp |   2 +-
 .../am/service/library_applet_accessor.cpp    | 157 ++++++++++++++
 .../am/service/library_applet_accessor.h      |  45 ++++
 7 files changed, 206 insertions(+), 249 deletions(-)
 delete mode 100644 src/core/hle/service/am/library_applet_accessor.cpp
 delete mode 100644 src/core/hle/service/am/library_applet_accessor.h
 create mode 100644 src/core/hle/service/am/service/library_applet_accessor.cpp
 create mode 100644 src/core/hle/service/am/service/library_applet_accessor.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index ae2fe0b68..d763663e6 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -429,8 +429,6 @@ add_library(core STATIC
     hle/service/am/hid_registration.h
     hle/service/am/idle.cpp
     hle/service/am/idle.h
-    hle/service/am/library_applet_accessor.cpp
-    hle/service/am/library_applet_accessor.h
     hle/service/am/library_applet_creator.cpp
     hle/service/am/library_applet_creator.h
     hle/service/am/library_applet_self_accessor.cpp
@@ -473,6 +471,8 @@ add_library(core STATIC
     hle/service/am/service/global_state_controller.h
     hle/service/am/service/home_menu_functions.cpp
     hle/service/am/service/home_menu_functions.h
+    hle/service/am/service/library_applet_accessor.cpp
+    hle/service/am/service/library_applet_accessor.h
     hle/service/am/service/library_applet_proxy.cpp
     hle/service/am/service/library_applet_proxy.h
     hle/service/am/service/system_applet_proxy.cpp
diff --git a/src/core/hle/service/am/library_applet_accessor.cpp b/src/core/hle/service/am/library_applet_accessor.cpp
deleted file mode 100644
index 6b20814f8..000000000
--- a/src/core/hle/service/am/library_applet_accessor.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/scope_exit.h"
-#include "core/hle/service/am/am_results.h"
-#include "core/hle/service/am/applet_data_broker.h"
-#include "core/hle/service/am/frontend/applets.h"
-#include "core/hle/service/am/library_applet_accessor.h"
-#include "core/hle/service/am/storage.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_,
-                                               std::shared_ptr<AppletDataBroker> broker_,
-                                               std::shared_ptr<Applet> applet_)
-    : ServiceFramework{system_, "ILibraryAppletAccessor"}, broker{std::move(broker_)},
-      applet{std::move(applet_)} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"},
-        {1, &ILibraryAppletAccessor::IsCompleted, "IsCompleted"},
-        {10, &ILibraryAppletAccessor::Start, "Start"},
-        {20, &ILibraryAppletAccessor::RequestExit, "RequestExit"},
-        {25, nullptr, "Terminate"},
-        {30, &ILibraryAppletAccessor::GetResult, "GetResult"},
-        {50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"},
-        {60, &ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero, "PresetLibraryAppletGpuTimeSliceZero"},
-        {100, &ILibraryAppletAccessor::PushInData, "PushInData"},
-        {101, &ILibraryAppletAccessor::PopOutData, "PopOutData"},
-        {102, nullptr, "PushExtraStorage"},
-        {103, &ILibraryAppletAccessor::PushInteractiveInData, "PushInteractiveInData"},
-        {104, &ILibraryAppletAccessor::PopInteractiveOutData, "PopInteractiveOutData"},
-        {105, &ILibraryAppletAccessor::GetPopOutDataEvent, "GetPopOutDataEvent"},
-        {106, &ILibraryAppletAccessor::GetPopInteractiveOutDataEvent, "GetPopInteractiveOutDataEvent"},
-        {110, nullptr, "NeedsToExitProcess"},
-        {120, nullptr, "GetLibraryAppletInfo"},
-        {150, nullptr, "RequestForAppletToGetForeground"},
-        {160, &ILibraryAppletAccessor::GetIndirectLayerConsumerHandle, "GetIndirectLayerConsumerHandle"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-ILibraryAppletAccessor::~ILibraryAppletAccessor() = default;
-
-void ILibraryAppletAccessor::GetAppletStateChangedEvent(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(broker->GetStateChangedEvent().GetHandle());
-}
-
-void ILibraryAppletAccessor::IsCompleted(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    std::scoped_lock lk{applet->lock};
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push<u32>(broker->IsCompleted());
-}
-
-void ILibraryAppletAccessor::GetResult(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(applet->terminate_result);
-}
-
-void ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ILibraryAppletAccessor::Start(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    applet->process->Run();
-    FrontendExecute();
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ILibraryAppletAccessor::RequestExit(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    ASSERT(applet != nullptr);
-    applet->message_queue.RequestExit();
-    FrontendRequestExit();
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ILibraryAppletAccessor::PushInData(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::RequestParser rp{ctx};
-    broker->GetInData().Push(rp.PopIpcInterface<IStorage>().lock());
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ILibraryAppletAccessor::PopOutData(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    std::shared_ptr<IStorage> data;
-    const auto res = broker->GetOutData().Pop(&data);
-
-    if (res.IsSuccess()) {
-        IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-        rb.Push(res);
-        rb.PushIpcInterface(std::move(data));
-    } else {
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(res);
-    }
-}
-
-void ILibraryAppletAccessor::PushInteractiveInData(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::RequestParser rp{ctx};
-    broker->GetInteractiveInData().Push(rp.PopIpcInterface<IStorage>().lock());
-    FrontendExecuteInteractive();
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ILibraryAppletAccessor::PopInteractiveOutData(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    std::shared_ptr<IStorage> data;
-    const auto res = broker->GetInteractiveOutData().Pop(&data);
-
-    if (res.IsSuccess()) {
-        IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-        rb.Push(res);
-        rb.PushIpcInterface(std::move(data));
-    } else {
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(res);
-    }
-}
-
-void ILibraryAppletAccessor::GetPopOutDataEvent(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(broker->GetOutData().GetEvent());
-}
-
-void ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(broker->GetInteractiveOutData().GetEvent());
-}
-
-void ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    // We require a non-zero handle to be valid. Using 0xdeadbeef allows us to trace if this is
-    // actually used anywhere
-    constexpr u64 handle = 0xdeadbeef;
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.Push(handle);
-}
-
-void ILibraryAppletAccessor::FrontendExecute() {
-    if (applet->frontend) {
-        applet->frontend->Initialize();
-        applet->frontend->Execute();
-    }
-}
-
-void ILibraryAppletAccessor::FrontendExecuteInteractive() {
-    if (applet->frontend) {
-        applet->frontend->ExecuteInteractive();
-        applet->frontend->Execute();
-    }
-}
-
-void ILibraryAppletAccessor::FrontendRequestExit() {
-    if (applet->frontend) {
-        applet->frontend->RequestExit();
-    }
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/library_applet_accessor.h b/src/core/hle/service/am/library_applet_accessor.h
deleted file mode 100644
index 8be29e003..000000000
--- a/src/core/hle/service/am/library_applet_accessor.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-class AppletDataBroker;
-struct Applet;
-
-class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> {
-public:
-    explicit ILibraryAppletAccessor(Core::System& system_,
-                                    std::shared_ptr<AppletDataBroker> broker_,
-                                    std::shared_ptr<Applet> applet_);
-    ~ILibraryAppletAccessor();
-
-protected:
-    void GetAppletStateChangedEvent(HLERequestContext& ctx);
-    void IsCompleted(HLERequestContext& ctx);
-    void GetResult(HLERequestContext& ctx);
-    void PresetLibraryAppletGpuTimeSliceZero(HLERequestContext& ctx);
-    void Start(HLERequestContext& ctx);
-    void RequestExit(HLERequestContext& ctx);
-    void PushInData(HLERequestContext& ctx);
-    void PopOutData(HLERequestContext& ctx);
-    void PushInteractiveInData(HLERequestContext& ctx);
-    void PopInteractiveOutData(HLERequestContext& ctx);
-    void GetPopOutDataEvent(HLERequestContext& ctx);
-    void GetPopInteractiveOutDataEvent(HLERequestContext& ctx);
-    void GetIndirectLayerConsumerHandle(HLERequestContext& ctx);
-
-    void FrontendExecute();
-    void FrontendExecuteInteractive();
-    void FrontendRequestExit();
-
-    const std::shared_ptr<AppletDataBroker> broker;
-    const std::shared_ptr<Applet> applet;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/library_applet_creator.cpp b/src/core/hle/service/am/library_applet_creator.cpp
index f7fdcb5db..bc2e18e38 100644
--- a/src/core/hle/service/am/library_applet_creator.cpp
+++ b/src/core/hle/service/am/library_applet_creator.cpp
@@ -6,9 +6,9 @@
 #include "core/hle/service/am/applet_data_broker.h"
 #include "core/hle/service/am/applet_manager.h"
 #include "core/hle/service/am/frontend/applets.h"
-#include "core/hle/service/am/library_applet_accessor.h"
 #include "core/hle/service/am/library_applet_creator.h"
 #include "core/hle/service/am/library_applet_storage.h"
+#include "core/hle/service/am/service/library_applet_accessor.h"
 #include "core/hle/service/am/storage.h"
 #include "core/hle/service/ipc_helpers.h"
 #include "core/hle/service/sm/sm.h"
diff --git a/src/core/hle/service/am/process_winding_controller.cpp b/src/core/hle/service/am/process_winding_controller.cpp
index b48b52797..bc5a50a3d 100644
--- a/src/core/hle/service/am/process_winding_controller.cpp
+++ b/src/core/hle/service/am/process_winding_controller.cpp
@@ -2,8 +2,8 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/frontend/applets.h"
-#include "core/hle/service/am/library_applet_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
+#include "core/hle/service/am/service/library_applet_accessor.h"
 #include "core/hle/service/ipc_helpers.h"
 
 namespace Service::AM {
diff --git a/src/core/hle/service/am/service/library_applet_accessor.cpp b/src/core/hle/service/am/service/library_applet_accessor.cpp
new file mode 100644
index 000000000..aac875ef4
--- /dev/null
+++ b/src/core/hle/service/am/service/library_applet_accessor.cpp
@@ -0,0 +1,157 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/am/applet_data_broker.h"
+#include "core/hle/service/am/applet_manager.h"
+#include "core/hle/service/am/frontend/applets.h"
+#include "core/hle/service/am/service/library_applet_accessor.h"
+#include "core/hle/service/am/storage.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_,
+                                               std::shared_ptr<AppletDataBroker> broker,
+                                               std::shared_ptr<Applet> applet)
+    : ServiceFramework{system_, "ILibraryAppletAccessor"}, m_broker{std::move(broker)},
+      m_applet{std::move(applet)} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, D<&ILibraryAppletAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"},
+        {1, D<&ILibraryAppletAccessor::IsCompleted>, "IsCompleted"},
+        {10, D<&ILibraryAppletAccessor::Start>, "Start"},
+        {20, D<&ILibraryAppletAccessor::RequestExit>, "RequestExit"},
+        {25, D<&ILibraryAppletAccessor::Terminate>, "Terminate"},
+        {30, D<&ILibraryAppletAccessor::GetResult>, "GetResult"},
+        {50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"},
+        {60, D<&ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero>, "PresetLibraryAppletGpuTimeSliceZero"},
+        {100, D<&ILibraryAppletAccessor::PushInData>, "PushInData"},
+        {101, D<&ILibraryAppletAccessor::PopOutData>, "PopOutData"},
+        {102, nullptr, "PushExtraStorage"},
+        {103, D<&ILibraryAppletAccessor::PushInteractiveInData>, "PushInteractiveInData"},
+        {104, D<&ILibraryAppletAccessor::PopInteractiveOutData>, "PopInteractiveOutData"},
+        {105, D<&ILibraryAppletAccessor::GetPopOutDataEvent>, "GetPopOutDataEvent"},
+        {106, D<&ILibraryAppletAccessor::GetPopInteractiveOutDataEvent>, "GetPopInteractiveOutDataEvent"},
+        {110, nullptr, "NeedsToExitProcess"},
+        {120, nullptr, "GetLibraryAppletInfo"},
+        {150, nullptr, "RequestForAppletToGetForeground"},
+        {160, D<&ILibraryAppletAccessor::GetIndirectLayerConsumerHandle>, "GetIndirectLayerConsumerHandle"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+ILibraryAppletAccessor::~ILibraryAppletAccessor() = default;
+
+Result ILibraryAppletAccessor::GetAppletStateChangedEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_event = m_broker->GetStateChangedEvent().GetHandle();
+    R_SUCCEED();
+}
+
+Result ILibraryAppletAccessor::IsCompleted(Out<bool> out_is_completed) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_is_completed = m_broker->IsCompleted();
+    R_SUCCEED();
+}
+
+Result ILibraryAppletAccessor::GetResult(Out<Result> out_result) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_result = m_applet->terminate_result;
+    R_SUCCEED();
+}
+
+Result ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero() {
+    LOG_INFO(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result ILibraryAppletAccessor::Start() {
+    LOG_DEBUG(Service_AM, "called");
+    m_applet->process->Run();
+    FrontendExecute();
+    R_SUCCEED();
+}
+
+Result ILibraryAppletAccessor::RequestExit() {
+    LOG_DEBUG(Service_AM, "called");
+    m_applet->message_queue.RequestExit();
+    FrontendRequestExit();
+    R_SUCCEED();
+}
+
+Result ILibraryAppletAccessor::Terminate() {
+    LOG_DEBUG(Service_AM, "called");
+    m_applet->process->Terminate();
+    FrontendRequestExit();
+    R_SUCCEED();
+}
+
+Result ILibraryAppletAccessor::PushInData(SharedPointer<IStorage> storage) {
+    LOG_DEBUG(Service_AM, "called");
+    m_broker->GetInData().Push(storage);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletAccessor::PopOutData(Out<SharedPointer<IStorage>> out_storage) {
+    LOG_DEBUG(Service_AM, "called");
+    R_RETURN(m_broker->GetOutData().Pop(out_storage.Get()));
+}
+
+Result ILibraryAppletAccessor::PushInteractiveInData(SharedPointer<IStorage> storage) {
+    LOG_DEBUG(Service_AM, "called");
+    m_broker->GetInteractiveInData().Push(storage);
+    FrontendExecuteInteractive();
+    R_SUCCEED();
+}
+
+Result ILibraryAppletAccessor::PopInteractiveOutData(Out<SharedPointer<IStorage>> out_storage) {
+    LOG_DEBUG(Service_AM, "called");
+    R_RETURN(m_broker->GetInteractiveOutData().Pop(out_storage.Get()));
+}
+
+Result ILibraryAppletAccessor::GetPopOutDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_event = m_broker->GetOutData().GetEvent();
+    R_SUCCEED();
+}
+
+Result ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_event = m_broker->GetInteractiveOutData().GetEvent();
+    R_SUCCEED();
+}
+
+Result ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(Out<u64> out_handle) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    // We require a non-zero handle to be valid. Using 0xdeadbeef allows us to trace if this is
+    // actually used anywhere
+    *out_handle = 0xdeadbeef;
+    R_SUCCEED();
+}
+
+void ILibraryAppletAccessor::FrontendExecute() {
+    if (m_applet->frontend) {
+        m_applet->frontend->Initialize();
+        m_applet->frontend->Execute();
+    }
+}
+
+void ILibraryAppletAccessor::FrontendExecuteInteractive() {
+    if (m_applet->frontend) {
+        m_applet->frontend->ExecuteInteractive();
+        m_applet->frontend->Execute();
+    }
+}
+
+void ILibraryAppletAccessor::FrontendRequestExit() {
+    if (m_applet->frontend) {
+        m_applet->frontend->RequestExit();
+    }
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/library_applet_accessor.h b/src/core/hle/service/am/service/library_applet_accessor.h
new file mode 100644
index 000000000..97d3b6c8a
--- /dev/null
+++ b/src/core/hle/service/am/service/library_applet_accessor.h
@@ -0,0 +1,45 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+class AppletDataBroker;
+struct Applet;
+class IStorage;
+
+class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> {
+public:
+    explicit ILibraryAppletAccessor(Core::System& system_, std::shared_ptr<AppletDataBroker> broker,
+                                    std::shared_ptr<Applet> applet);
+    ~ILibraryAppletAccessor();
+
+private:
+    Result GetAppletStateChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result IsCompleted(Out<bool> out_is_completed);
+    Result GetResult(Out<Result> out_result);
+    Result PresetLibraryAppletGpuTimeSliceZero();
+    Result Start();
+    Result RequestExit();
+    Result Terminate();
+    Result PushInData(SharedPointer<IStorage> storage);
+    Result PopOutData(Out<SharedPointer<IStorage>> out_storage);
+    Result PushInteractiveInData(SharedPointer<IStorage> storage);
+    Result PopInteractiveOutData(Out<SharedPointer<IStorage>> out_storage);
+    Result GetPopOutDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result GetPopInteractiveOutDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result GetIndirectLayerConsumerHandle(Out<u64> out_handle);
+
+    void FrontendExecute();
+    void FrontendExecuteInteractive();
+    void FrontendRequestExit();
+
+    const std::shared_ptr<AppletDataBroker> m_broker;
+    const std::shared_ptr<Applet> m_applet;
+};
+
+} // namespace Service::AM

From 1c797a8048ccfab1322d61cad98fb4f2981721bf Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 20:02:41 -0500
Subject: [PATCH 14/24] am: rewrite ILibraryAppletCreator

---
 src/core/CMakeLists.txt                       |   4 +-
 .../hle/service/am/library_applet_creator.h   |  26 ---
 .../service/am/service/application_proxy.cpp  |   2 +-
 .../{ => service}/library_applet_creator.cpp  | 154 +++++++-----------
 .../am/service/library_applet_creator.h       |  35 ++++
 .../am/service/library_applet_proxy.cpp       |   2 +-
 .../am/service/system_applet_proxy.cpp        |   2 +-
 7 files changed, 96 insertions(+), 129 deletions(-)
 delete mode 100644 src/core/hle/service/am/library_applet_creator.h
 rename src/core/hle/service/am/{ => service}/library_applet_creator.cpp (66%)
 create mode 100644 src/core/hle/service/am/service/library_applet_creator.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index d763663e6..4f31e9c17 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -429,8 +429,6 @@ add_library(core STATIC
     hle/service/am/hid_registration.h
     hle/service/am/idle.cpp
     hle/service/am/idle.h
-    hle/service/am/library_applet_creator.cpp
-    hle/service/am/library_applet_creator.h
     hle/service/am/library_applet_self_accessor.cpp
     hle/service/am/library_applet_self_accessor.h
     hle/service/am/library_applet_storage.cpp
@@ -473,6 +471,8 @@ add_library(core STATIC
     hle/service/am/service/home_menu_functions.h
     hle/service/am/service/library_applet_accessor.cpp
     hle/service/am/service/library_applet_accessor.h
+    hle/service/am/service/library_applet_creator.cpp
+    hle/service/am/service/library_applet_creator.h
     hle/service/am/service/library_applet_proxy.cpp
     hle/service/am/service/library_applet_proxy.h
     hle/service/am/service/system_applet_proxy.cpp
diff --git a/src/core/hle/service/am/library_applet_creator.h b/src/core/hle/service/am/library_applet_creator.h
deleted file mode 100644
index 551f287bd..000000000
--- a/src/core/hle/service/am/library_applet_creator.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-struct Applet;
-
-class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
-public:
-    explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet_);
-    ~ILibraryAppletCreator() override;
-
-private:
-    void CreateLibraryApplet(HLERequestContext& ctx);
-    void CreateStorage(HLERequestContext& ctx);
-    void CreateTransferMemoryStorage(HLERequestContext& ctx);
-    void CreateHandleStorage(HLERequestContext& ctx);
-
-    const std::shared_ptr<Applet> applet;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index 445f9b158..26a818f14 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/library_applet_creator.h"
 #include "core/hle/service/am/library_applet_self_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/service/common_state_getter.h"
 #include "core/hle/service/am/service/debug_functions.h"
 #include "core/hle/service/am/service/display_controller.h"
+#include "core/hle/service/am/service/library_applet_creator.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
diff --git a/src/core/hle/service/am/library_applet_creator.cpp b/src/core/hle/service/am/service/library_applet_creator.cpp
similarity index 66%
rename from src/core/hle/service/am/library_applet_creator.cpp
rename to src/core/hle/service/am/service/library_applet_creator.cpp
index bc2e18e38..4d905549c 100644
--- a/src/core/hle/service/am/library_applet_creator.cpp
+++ b/src/core/hle/service/am/service/library_applet_creator.cpp
@@ -6,11 +6,11 @@
 #include "core/hle/service/am/applet_data_broker.h"
 #include "core/hle/service/am/applet_manager.h"
 #include "core/hle/service/am/frontend/applets.h"
-#include "core/hle/service/am/library_applet_creator.h"
 #include "core/hle/service/am/library_applet_storage.h"
 #include "core/hle/service/am/service/library_applet_accessor.h"
+#include "core/hle/service/am/service/library_applet_creator.h"
 #include "core/hle/service/am/storage.h"
-#include "core/hle/service/ipc_helpers.h"
+#include "core/hle/service/cmif_serialization.h"
 #include "core/hle/service/sm/sm.h"
 
 namespace Service::AM {
@@ -172,139 +172,97 @@ std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& syste
 
 } // namespace
 
-ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet_)
-    : ServiceFramework{system_, "ILibraryAppletCreator"}, applet{std::move(applet_)} {
+ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet)
+    : ServiceFramework{system_, "ILibraryAppletCreator"}, m_applet{std::move(applet)} {
     static const FunctionInfo functions[] = {
-        {0, &ILibraryAppletCreator::CreateLibraryApplet, "CreateLibraryApplet"},
+        {0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"},
         {1, nullptr, "TerminateAllLibraryApplets"},
         {2, nullptr, "AreAnyLibraryAppletsLeft"},
-        {10, &ILibraryAppletCreator::CreateStorage, "CreateStorage"},
-        {11, &ILibraryAppletCreator::CreateTransferMemoryStorage, "CreateTransferMemoryStorage"},
-        {12, &ILibraryAppletCreator::CreateHandleStorage, "CreateHandleStorage"},
+        {10, D<&ILibraryAppletCreator::CreateStorage>, "CreateStorage"},
+        {11, D<&ILibraryAppletCreator::CreateTransferMemoryStorage>, "CreateTransferMemoryStorage"},
+        {12, D<&ILibraryAppletCreator::CreateHandleStorage>, "CreateHandleStorage"},
     };
     RegisterHandlers(functions);
 }
 
 ILibraryAppletCreator::~ILibraryAppletCreator() = default;
 
-void ILibraryAppletCreator::CreateLibraryApplet(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const auto applet_id = rp.PopRaw<AppletId>();
-    const auto applet_mode = rp.PopRaw<LibraryAppletMode>();
-
-    LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id,
-              applet_mode);
+Result ILibraryAppletCreator::CreateLibraryApplet(
+    Out<SharedPointer<ILibraryAppletAccessor>> out_library_applet_accessor, AppletId applet_id,
+    LibraryAppletMode library_applet_mode) {
+    LOG_DEBUG(Service_AM, "called with applet_id={} applet_mode={}", applet_id,
+              library_applet_mode);
 
     std::shared_ptr<ILibraryAppletAccessor> library_applet;
     if (ShouldCreateGuestApplet(applet_id)) {
-        library_applet = CreateGuestApplet(system, applet, applet_id, applet_mode);
+        library_applet = CreateGuestApplet(system, m_applet, applet_id, library_applet_mode);
     }
     if (!library_applet) {
-        library_applet = CreateFrontendApplet(system, applet, applet_id, applet_mode);
+        library_applet = CreateFrontendApplet(system, m_applet, applet_id, library_applet_mode);
     }
     if (!library_applet) {
         LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
-
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(ResultUnknown);
-        return;
+        R_THROW(ResultUnknown);
     }
 
     // Applet is created, can now be launched.
-    applet->library_applet_launchable_event.Signal();
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ILibraryAppletAccessor>(library_applet);
+    m_applet->library_applet_launchable_event.Signal();
+    *out_library_applet_accessor = library_applet;
+    R_SUCCEED();
 }
 
-void ILibraryAppletCreator::CreateStorage(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const s64 size{rp.Pop<s64>()};
-
+Result ILibraryAppletCreator::CreateStorage(Out<SharedPointer<IStorage>> out_storage, s64 size) {
     LOG_DEBUG(Service_AM, "called, size={}", size);
 
     if (size <= 0) {
         LOG_ERROR(Service_AM, "size is less than or equal to 0");
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(ResultUnknown);
-        return;
+        R_THROW(ResultUnknown);
     }
 
-    std::vector<u8> data(size);
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IStorage>(system, AM::CreateStorage(std::move(data)));
+    *out_storage = std::make_shared<IStorage>(system, AM::CreateStorage(std::vector<u8>(size)));
+    R_SUCCEED();
 }
 
-void ILibraryAppletCreator::CreateTransferMemoryStorage(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    struct Parameters {
-        bool is_writable;
-        s64 size;
-    };
-
-    const auto params{rp.PopRaw<Parameters>()};
-    const auto handle{ctx.GetCopyHandle(0)};
-
-    LOG_DEBUG(Service_AM, "called, is_writable={}, size={}, handle={:08X}", params.is_writable,
-              params.size, handle);
-
-    if (params.size <= 0) {
-        LOG_ERROR(Service_AM, "size is less than or equal to 0");
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(ResultUnknown);
-        return;
-    }
-
-    auto transfer_mem = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(handle);
-
-    if (transfer_mem.IsNull()) {
-        LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(ResultUnknown);
-        return;
-    }
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IStorage>(
-        system, AM::CreateTransferMemoryStorage(ctx.GetMemory(), transfer_mem.GetPointerUnsafe(),
-                                                params.is_writable, params.size));
-}
-
-void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const s64 size{rp.Pop<s64>()};
-    const auto handle{ctx.GetCopyHandle(0)};
-
-    LOG_DEBUG(Service_AM, "called, size={}, handle={:08X}", size, handle);
+Result ILibraryAppletCreator::CreateTransferMemoryStorage(
+    Out<SharedPointer<IStorage>> out_storage, bool is_writable, s64 size,
+    InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle) {
+    LOG_DEBUG(Service_AM, "called, is_writable={} size={}", is_writable, size);
 
     if (size <= 0) {
         LOG_ERROR(Service_AM, "size is less than or equal to 0");
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(ResultUnknown);
-        return;
+        R_THROW(ResultUnknown);
     }
 
-    auto transfer_mem = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(handle);
-
-    if (transfer_mem.IsNull()) {
-        LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(ResultUnknown);
-        return;
+    if (!transfer_memory_handle) {
+        LOG_ERROR(Service_AM, "transfer_memory_handle is null");
+        R_THROW(ResultUnknown);
     }
 
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IStorage>(
-        system, AM::CreateHandleStorage(ctx.GetMemory(), transfer_mem.GetPointerUnsafe(), size));
+    *out_storage = std::make_shared<IStorage>(
+        system, AM::CreateTransferMemoryStorage(transfer_memory_handle->GetOwner()->GetMemory(),
+                                                transfer_memory_handle.Get(), is_writable, size));
+    R_SUCCEED();
+}
+
+Result ILibraryAppletCreator::CreateHandleStorage(
+    Out<SharedPointer<IStorage>> out_storage, s64 size,
+    InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle) {
+    LOG_DEBUG(Service_AM, "called, size={}", size);
+
+    if (size <= 0) {
+        LOG_ERROR(Service_AM, "size is less than or equal to 0");
+        R_THROW(ResultUnknown);
+    }
+
+    if (!transfer_memory_handle) {
+        LOG_ERROR(Service_AM, "transfer_memory_handle is null");
+        R_THROW(ResultUnknown);
+    }
+
+    *out_storage = std::make_shared<IStorage>(
+        system, AM::CreateHandleStorage(transfer_memory_handle->GetOwner()->GetMemory(),
+                                        transfer_memory_handle.Get(), size));
+    R_SUCCEED();
 }
 
 } // namespace Service::AM
diff --git a/src/core/hle/service/am/service/library_applet_creator.h b/src/core/hle/service/am/service/library_applet_creator.h
new file mode 100644
index 000000000..fe6d40eb3
--- /dev/null
+++ b/src/core/hle/service/am/service/library_applet_creator.h
@@ -0,0 +1,35 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/am/am_types.h"
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+struct Applet;
+class ILibraryAppletAccessor;
+class IStorage;
+
+class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
+public:
+    explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet);
+    ~ILibraryAppletCreator() override;
+
+private:
+    Result CreateLibraryApplet(
+        Out<SharedPointer<ILibraryAppletAccessor>> out_library_applet_accessor, AppletId applet_id,
+        LibraryAppletMode library_applet_mode);
+    Result CreateStorage(Out<SharedPointer<IStorage>> out_storage, s64 size);
+    Result CreateTransferMemoryStorage(
+        Out<SharedPointer<IStorage>> out_storage, bool is_writable, s64 size,
+        InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle);
+    Result CreateHandleStorage(Out<SharedPointer<IStorage>> out_storage, s64 size,
+                               InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle);
+
+    const std::shared_ptr<Applet> m_applet;
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index cf1a34db2..f1a13a331 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/library_applet_creator.h"
 #include "core/hle/service/am/library_applet_self_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/service/display_controller.h"
 #include "core/hle/service/am/service/global_state_controller.h"
 #include "core/hle/service/am/service/home_menu_functions.h"
+#include "core/hle/service/am/service/library_applet_creator.h"
 #include "core/hle/service/am/service/library_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index 8fa852cfa..59d5b2a23 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -2,7 +2,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/application_creator.h"
-#include "core/hle/service/am/library_applet_creator.h"
 #include "core/hle/service/am/library_applet_self_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
@@ -13,6 +12,7 @@
 #include "core/hle/service/am/service/display_controller.h"
 #include "core/hle/service/am/service/global_state_controller.h"
 #include "core/hle/service/am/service/home_menu_functions.h"
+#include "core/hle/service/am/service/library_applet_creator.h"
 #include "core/hle/service/am/service/system_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"

From c7e94e2175c02fe22846d89915b08d8b1802ef4f Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 20:12:09 -0500
Subject: [PATCH 15/24] am: rewrite ILibraryAppletSelfAccessor

---
 src/core/CMakeLists.txt                       |   4 +-
 .../am/library_applet_self_accessor.cpp       | 338 ------------------
 .../service/am/library_applet_self_accessor.h |  44 ---
 .../service/am/service/application_proxy.cpp  |   1 -
 .../am/service/library_applet_proxy.cpp       |   2 +-
 .../service/library_applet_self_accessor.cpp  | 322 +++++++++++++++++
 .../am/service/library_applet_self_accessor.h |  83 +++++
 .../am/service/system_applet_proxy.cpp        |   1 -
 8 files changed, 408 insertions(+), 387 deletions(-)
 delete mode 100644 src/core/hle/service/am/library_applet_self_accessor.cpp
 delete mode 100644 src/core/hle/service/am/library_applet_self_accessor.h
 create mode 100644 src/core/hle/service/am/service/library_applet_self_accessor.cpp
 create mode 100644 src/core/hle/service/am/service/library_applet_self_accessor.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 4f31e9c17..f7f6b216e 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -429,8 +429,6 @@ add_library(core STATIC
     hle/service/am/hid_registration.h
     hle/service/am/idle.cpp
     hle/service/am/idle.h
-    hle/service/am/library_applet_self_accessor.cpp
-    hle/service/am/library_applet_self_accessor.h
     hle/service/am/library_applet_storage.cpp
     hle/service/am/library_applet_storage.h
     hle/service/am/lock_accessor.cpp
@@ -475,6 +473,8 @@ add_library(core STATIC
     hle/service/am/service/library_applet_creator.h
     hle/service/am/service/library_applet_proxy.cpp
     hle/service/am/service/library_applet_proxy.h
+    hle/service/am/service/library_applet_self_accessor.cpp
+    hle/service/am/service/library_applet_self_accessor.h
     hle/service/am/service/system_applet_proxy.cpp
     hle/service/am/service/system_applet_proxy.h
     hle/service/am/system_buffer_manager.cpp
diff --git a/src/core/hle/service/am/library_applet_self_accessor.cpp b/src/core/hle/service/am/library_applet_self_accessor.cpp
deleted file mode 100644
index b560f580b..000000000
--- a/src/core/hle/service/am/library_applet_self_accessor.cpp
+++ /dev/null
@@ -1,338 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/scope_exit.h"
-#include "core/core_timing.h"
-#include "core/file_sys/control_metadata.h"
-#include "core/file_sys/patch_manager.h"
-#include "core/file_sys/registered_cache.h"
-#include "core/hle/service/acc/profile_manager.h"
-#include "core/hle/service/am/am_results.h"
-#include "core/hle/service/am/applet_data_broker.h"
-#include "core/hle/service/am/applet_manager.h"
-#include "core/hle/service/am/frontend/applet_cabinet.h"
-#include "core/hle/service/am/frontend/applet_controller.h"
-#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/frontend/applets.h"
-#include "core/hle/service/am/library_applet_self_accessor.h"
-#include "core/hle/service/am/storage.h"
-#include "core/hle/service/ipc_helpers.h"
-#include "core/hle/service/ns/ns.h"
-#include "core/hle/service/sm/sm.h"
-#include "hid_core/hid_types.h"
-
-namespace Service::AM {
-
-namespace {
-
-AppletIdentityInfo GetCallerIdentity(std::shared_ptr<Applet> applet) {
-    if (const auto caller_applet = applet->caller_applet.lock(); caller_applet) {
-        // TODO: is this actually the application ID?
-        return {
-            .applet_id = caller_applet->applet_id,
-            .application_id = caller_applet->program_id,
-        };
-    } else {
-        return {
-            .applet_id = AppletId::QLaunch,
-            .application_id = 0x0100000000001000ull,
-        };
-    }
-}
-
-} // namespace
-
-ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
-                                                       std::shared_ptr<Applet> applet_)
-    : ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, applet{std::move(applet_)},
-      broker{applet->caller_applet_broker} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {0, &ILibraryAppletSelfAccessor::PopInData, "PopInData"},
-        {1, &ILibraryAppletSelfAccessor::PushOutData, "PushOutData"},
-        {2, &ILibraryAppletSelfAccessor::PopInteractiveInData, "PopInteractiveInData"},
-        {3, &ILibraryAppletSelfAccessor::PushInteractiveOutData, "PushInteractiveOutData"},
-        {5, &ILibraryAppletSelfAccessor::GetPopInDataEvent, "GetPopInDataEvent"},
-        {6, &ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent, "GetPopInteractiveInDataEvent"},
-        {10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"},
-        {11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"},
-        {12, &ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo, "GetMainAppletIdentityInfo"},
-        {13, &ILibraryAppletSelfAccessor::CanUseApplicationCore, "CanUseApplicationCore"},
-        {14, &ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo, "GetCallerAppletIdentityInfo"},
-        {15, nullptr, "GetMainAppletApplicationControlProperty"},
-        {16, nullptr, "GetMainAppletStorageId"},
-        {17, nullptr, "GetCallerAppletIdentityInfoStack"},
-        {18, nullptr, "GetNextReturnDestinationAppletIdentityInfo"},
-        {19, &ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout, "GetDesirableKeyboardLayout"},
-        {20, nullptr, "PopExtraStorage"},
-        {25, nullptr, "GetPopExtraStorageEvent"},
-        {30, nullptr, "UnpopInData"},
-        {31, nullptr, "UnpopExtraStorage"},
-        {40, nullptr, "GetIndirectLayerProducerHandle"},
-        {50, nullptr, "ReportVisibleError"},
-        {51, nullptr, "ReportVisibleErrorWithErrorContext"},
-        {60, &ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage, "GetMainAppletApplicationDesiredLanguage"},
-        {70, &ILibraryAppletSelfAccessor::GetCurrentApplicationId, "GetCurrentApplicationId"},
-        {80, nullptr, "RequestExitToSelf"},
-        {90, nullptr, "CreateApplicationAndPushAndRequestToLaunch"},
-        {100, nullptr, "CreateGameMovieTrimmer"},
-        {101, nullptr, "ReserveResourceForMovieOperation"},
-        {102, nullptr, "UnreserveResourceForMovieOperation"},
-        {110, &ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers, "GetMainAppletAvailableUsers"},
-        {120, nullptr, "GetLaunchStorageInfoForDebug"},
-        {130, nullptr, "GetGpuErrorDetectedSystemEvent"},
-        {140, nullptr, "SetApplicationMemoryReservation"},
-        {150, &ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually, "ShouldSetGpuTimeSliceManually"},
-        {160, &ILibraryAppletSelfAccessor::Cmd160, "Cmd160"},
-    };
-    // clang-format on
-    RegisterHandlers(functions);
-}
-
-ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default;
-
-void ILibraryAppletSelfAccessor::PopInData(HLERequestContext& ctx) {
-    LOG_INFO(Service_AM, "called");
-
-    std::shared_ptr<IStorage> data;
-    const auto res = broker->GetInData().Pop(&data);
-
-    if (res.IsSuccess()) {
-        IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-        rb.Push(res);
-        rb.PushIpcInterface(std::move(data));
-    } else {
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(res);
-    }
-}
-
-void ILibraryAppletSelfAccessor::PushOutData(HLERequestContext& ctx) {
-    LOG_INFO(Service_AM, "called");
-
-    IPC::RequestParser rp{ctx};
-    broker->GetOutData().Push(rp.PopIpcInterface<IStorage>().lock());
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ILibraryAppletSelfAccessor::PopInteractiveInData(HLERequestContext& ctx) {
-    LOG_INFO(Service_AM, "called");
-
-    std::shared_ptr<IStorage> data;
-    const auto res = broker->GetInteractiveInData().Pop(&data);
-
-    if (res.IsSuccess()) {
-        IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-        rb.Push(res);
-        rb.PushIpcInterface(std::move(data));
-    } else {
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(res);
-    }
-}
-
-void ILibraryAppletSelfAccessor::PushInteractiveOutData(HLERequestContext& ctx) {
-    LOG_INFO(Service_AM, "called");
-
-    IPC::RequestParser rp{ctx};
-    broker->GetInteractiveOutData().Push(rp.PopIpcInterface<IStorage>().lock());
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ILibraryAppletSelfAccessor::GetPopInDataEvent(HLERequestContext& ctx) {
-    LOG_INFO(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(broker->GetInData().GetEvent());
-}
-
-void ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent(HLERequestContext& ctx) {
-    LOG_INFO(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(broker->GetInteractiveInData().GetEvent());
-}
-
-void ILibraryAppletSelfAccessor::ExitProcessAndReturn(HLERequestContext& ctx) {
-    LOG_INFO(Service_AM, "called");
-
-    system.GetAppletManager().TerminateAndRemoveApplet(applet->aruid);
-    broker->SignalCompletion();
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ILibraryAppletSelfAccessor::GetLibraryAppletInfo(HLERequestContext& ctx) {
-    struct LibraryAppletInfo {
-        AppletId applet_id;
-        LibraryAppletMode library_applet_mode;
-    };
-
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    const LibraryAppletInfo applet_info{
-        .applet_id = applet->applet_id,
-        .library_applet_mode = applet->library_applet_mode,
-    };
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.PushRaw(applet_info);
-}
-
-void ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    const AppletIdentityInfo applet_info{
-        .applet_id = AppletId::QLaunch,
-        .application_id = 0x0100000000001000ull,
-    };
-
-    IPC::ResponseBuilder rb{ctx, 6};
-    rb.Push(ResultSuccess);
-    rb.PushRaw(applet_info);
-}
-
-void ILibraryAppletSelfAccessor::CanUseApplicationCore(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    // TODO: This appears to read the NPDM from state and check the core mask of the applet.
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push<u8>(0);
-}
-
-void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 6};
-    rb.Push(ResultSuccess);
-    rb.PushRaw(GetCallerIdentity(applet));
-}
-
-void ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push<u32>(0);
-}
-
-void ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage(HLERequestContext& ctx) {
-    // FIXME: this is copied from IApplicationFunctions::GetDesiredLanguage
-    auto identity = GetCallerIdentity(applet);
-
-    // TODO(bunnei): This should be configurable
-    LOG_DEBUG(Service_AM, "called");
-
-    // Get supported languages from NACP, if possible
-    // Default to 0 (all languages supported)
-    u32 supported_languages = 0;
-
-    const auto res = [this, identity] {
-        const FileSys::PatchManager pm{identity.application_id, system.GetFileSystemController(),
-                                       system.GetContentProvider()};
-        auto metadata = pm.GetControlMetadata();
-        if (metadata.first != nullptr) {
-            return metadata;
-        }
-
-        const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(identity.application_id),
-                                              system.GetFileSystemController(),
-                                              system.GetContentProvider()};
-        return pm_update.GetControlMetadata();
-    }();
-
-    if (res.first != nullptr) {
-        supported_languages = res.first->GetSupportedLanguages();
-    }
-
-    // Call IApplicationManagerInterface implementation.
-    auto& service_manager = system.ServiceManager();
-    auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2");
-    auto app_man = ns_am2->GetApplicationManagerInterface();
-
-    // Get desired application language
-    u8 desired_language{};
-    const auto res_lang =
-        app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages);
-    if (res_lang != ResultSuccess) {
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(res_lang);
-        return;
-    }
-
-    // Convert to settings language code.
-    u64 language_code{};
-    const auto res_code =
-        app_man->ConvertApplicationLanguageToLanguageCode(&language_code, desired_language);
-    if (res_code != ResultSuccess) {
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(res_code);
-        return;
-    }
-
-    LOG_DEBUG(Service_AM, "got desired_language={:016X}", language_code);
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.Push(language_code);
-}
-
-void ILibraryAppletSelfAccessor::GetCurrentApplicationId(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    u64 application_id = 0;
-    if (auto caller_applet = applet->caller_applet.lock(); caller_applet) {
-        application_id = caller_applet->program_id;
-    }
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.Push(application_id);
-}
-
-void ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers(HLERequestContext& ctx) {
-    const Service::Account::ProfileManager manager{};
-    bool is_empty{true};
-    s32 user_count{-1};
-
-    LOG_INFO(Service_AM, "called");
-
-    if (manager.GetUserCount() > 0) {
-        is_empty = false;
-        user_count = static_cast<s32>(manager.GetUserCount());
-        ctx.WriteBuffer(manager.GetAllUsers());
-    }
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.Push<u8>(is_empty);
-    rb.Push(user_count);
-}
-
-void ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push<u8>(0);
-}
-
-void ILibraryAppletSelfAccessor::Cmd160(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.Push<u64>(0);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/library_applet_self_accessor.h b/src/core/hle/service/am/library_applet_self_accessor.h
deleted file mode 100644
index 8717a989a..000000000
--- a/src/core/hle/service/am/library_applet_self_accessor.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <deque>
-#include <vector>
-
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-class AppletDataBroker;
-struct Applet;
-
-class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> {
-public:
-    explicit ILibraryAppletSelfAccessor(Core::System& system_, std::shared_ptr<Applet> applet_);
-    ~ILibraryAppletSelfAccessor() override;
-
-private:
-    void PopInData(HLERequestContext& ctx);
-    void PushOutData(HLERequestContext& ctx);
-    void PopInteractiveInData(HLERequestContext& ctx);
-    void PushInteractiveOutData(HLERequestContext& ctx);
-    void GetPopInDataEvent(HLERequestContext& ctx);
-    void GetPopInteractiveInDataEvent(HLERequestContext& ctx);
-    void GetLibraryAppletInfo(HLERequestContext& ctx);
-    void GetMainAppletIdentityInfo(HLERequestContext& ctx);
-    void CanUseApplicationCore(HLERequestContext& ctx);
-    void ExitProcessAndReturn(HLERequestContext& ctx);
-    void GetCallerAppletIdentityInfo(HLERequestContext& ctx);
-    void GetDesirableKeyboardLayout(HLERequestContext& ctx);
-    void GetMainAppletApplicationDesiredLanguage(HLERequestContext& ctx);
-    void GetCurrentApplicationId(HLERequestContext& ctx);
-    void GetMainAppletAvailableUsers(HLERequestContext& ctx);
-    void ShouldSetGpuTimeSliceManually(HLERequestContext& ctx);
-    void Cmd160(HLERequestContext& ctx);
-
-    const std::shared_ptr<Applet> applet;
-    const std::shared_ptr<AppletDataBroker> broker;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index 26a818f14..c9b872887 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/library_applet_self_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index f1a13a331..9506739e9 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/library_applet_self_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
@@ -13,6 +12,7 @@
 #include "core/hle/service/am/service/home_menu_functions.h"
 #include "core/hle/service/am/service/library_applet_creator.h"
 #include "core/hle/service/am/service/library_applet_proxy.h"
+#include "core/hle/service/am/service/library_applet_self_accessor.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
diff --git a/src/core/hle/service/am/service/library_applet_self_accessor.cpp b/src/core/hle/service/am/service/library_applet_self_accessor.cpp
new file mode 100644
index 000000000..a432a79ba
--- /dev/null
+++ b/src/core/hle/service/am/service/library_applet_self_accessor.cpp
@@ -0,0 +1,322 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/core_timing.h"
+#include "core/file_sys/control_metadata.h"
+#include "core/file_sys/patch_manager.h"
+#include "core/file_sys/registered_cache.h"
+#include "core/hle/service/acc/profile_manager.h"
+#include "core/hle/service/am/applet_data_broker.h"
+#include "core/hle/service/am/applet_manager.h"
+#include "core/hle/service/am/frontend/applets.h"
+#include "core/hle/service/am/service/library_applet_self_accessor.h"
+#include "core/hle/service/am/storage.h"
+#include "core/hle/service/cmif_serialization.h"
+#include "core/hle/service/filesystem/filesystem.h"
+#include "core/hle/service/glue/glue_manager.h"
+#include "core/hle/service/ns/ns.h"
+#include "core/hle/service/sm/sm.h"
+
+namespace Service::AM {
+
+namespace {
+
+AppletIdentityInfo GetCallerIdentity(Applet& applet) {
+    if (const auto caller_applet = applet.caller_applet.lock(); caller_applet) {
+        // TODO: is this actually the application ID?
+        return {
+            .applet_id = caller_applet->applet_id,
+            .application_id = caller_applet->program_id,
+        };
+    } else {
+        return {
+            .applet_id = AppletId::QLaunch,
+            .application_id = 0x0100000000001000ull,
+        };
+    }
+}
+
+} // namespace
+
+ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
+                                                       std::shared_ptr<Applet> applet)
+    : ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, m_applet{std::move(applet)},
+      m_broker{m_applet->caller_applet_broker} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, D<&ILibraryAppletSelfAccessor::PopInData>, "PopInData"},
+        {1, D<&ILibraryAppletSelfAccessor::PushOutData>, "PushOutData"},
+        {2, D<&ILibraryAppletSelfAccessor::PopInteractiveInData>, "PopInteractiveInData"},
+        {3, D<&ILibraryAppletSelfAccessor::PushInteractiveOutData>, "PushInteractiveOutData"},
+        {5, D<&ILibraryAppletSelfAccessor::GetPopInDataEvent>, "GetPopInDataEvent"},
+        {6, D<&ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent>, "GetPopInteractiveInDataEvent"},
+        {10, D<&ILibraryAppletSelfAccessor::ExitProcessAndReturn>, "ExitProcessAndReturn"},
+        {11, D<&ILibraryAppletSelfAccessor::GetLibraryAppletInfo>, "GetLibraryAppletInfo"},
+        {12, D<&ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo>, "GetMainAppletIdentityInfo"},
+        {13, D<&ILibraryAppletSelfAccessor::CanUseApplicationCore>, "CanUseApplicationCore"},
+        {14, D<&ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo>, "GetCallerAppletIdentityInfo"},
+        {15, D<&ILibraryAppletSelfAccessor::GetMainAppletApplicationControlProperty>, "GetMainAppletApplicationControlProperty"},
+        {16, D<&ILibraryAppletSelfAccessor::GetMainAppletStorageId>, "GetMainAppletStorageId"},
+        {17, D<&ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfoStack>, "GetCallerAppletIdentityInfoStack"},
+        {18, nullptr, "GetNextReturnDestinationAppletIdentityInfo"},
+        {19, D<&ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout>, "GetDesirableKeyboardLayout"},
+        {20, nullptr, "PopExtraStorage"},
+        {25, nullptr, "GetPopExtraStorageEvent"},
+        {30, nullptr, "UnpopInData"},
+        {31, nullptr, "UnpopExtraStorage"},
+        {40, nullptr, "GetIndirectLayerProducerHandle"},
+        {50, D<&ILibraryAppletSelfAccessor::ReportVisibleError>, "ReportVisibleError"},
+        {51, D<&ILibraryAppletSelfAccessor::ReportVisibleErrorWithErrorContext>, "ReportVisibleErrorWithErrorContext"},
+        {60, D<&ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage>, "GetMainAppletApplicationDesiredLanguage"},
+        {70, D<&ILibraryAppletSelfAccessor::GetCurrentApplicationId>, "GetCurrentApplicationId"},
+        {80, nullptr, "RequestExitToSelf"},
+        {90, nullptr, "CreateApplicationAndPushAndRequestToLaunch"},
+        {100, nullptr, "CreateGameMovieTrimmer"},
+        {101, nullptr, "ReserveResourceForMovieOperation"},
+        {102, nullptr, "UnreserveResourceForMovieOperation"},
+        {110, D<&ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers>, "GetMainAppletAvailableUsers"},
+        {120, nullptr, "GetLaunchStorageInfoForDebug"},
+        {130, nullptr, "GetGpuErrorDetectedSystemEvent"},
+        {140, nullptr, "SetApplicationMemoryReservation"},
+        {150, D<&ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually>, "ShouldSetGpuTimeSliceManually"},
+        {160, D<&ILibraryAppletSelfAccessor::Cmd160>, "Cmd160"},
+    };
+    // clang-format on
+    RegisterHandlers(functions);
+}
+
+ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default;
+
+Result ILibraryAppletSelfAccessor::PopInData(Out<SharedPointer<IStorage>> out_storage) {
+    LOG_INFO(Service_AM, "called");
+    R_RETURN(m_broker->GetInData().Pop(out_storage));
+}
+
+Result ILibraryAppletSelfAccessor::PushOutData(SharedPointer<IStorage> storage) {
+    LOG_INFO(Service_AM, "called");
+    m_broker->GetOutData().Push(storage);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::PopInteractiveInData(Out<SharedPointer<IStorage>> out_storage) {
+    LOG_INFO(Service_AM, "called");
+    R_RETURN(m_broker->GetInteractiveInData().Pop(out_storage));
+}
+
+Result ILibraryAppletSelfAccessor::PushInteractiveOutData(SharedPointer<IStorage> storage) {
+    LOG_INFO(Service_AM, "called");
+    m_broker->GetInteractiveOutData().Push(storage);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::GetPopInDataEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_INFO(Service_AM, "called");
+    *out_event = m_broker->GetInData().GetEvent();
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_INFO(Service_AM, "called");
+    *out_event = m_broker->GetInteractiveInData().GetEvent();
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::GetLibraryAppletInfo(
+    Out<LibraryAppletInfo> out_library_applet_info) {
+    LOG_INFO(Service_AM, "called");
+    *out_library_applet_info = {
+        .applet_id = m_applet->applet_id,
+        .library_applet_mode = m_applet->library_applet_mode,
+    };
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(
+    Out<AppletIdentityInfo> out_identity_info) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_identity_info = {
+        .applet_id = AppletId::QLaunch,
+        .application_id = 0x0100000000001000ull,
+    };
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::CanUseApplicationCore(Out<bool> out_can_use_application_core) {
+    // TODO: This appears to read the NPDM from state and check the core mask of the applet.
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_can_use_application_core = false;
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::GetMainAppletApplicationControlProperty(
+    OutLargeData<std::array<u8, 0x4000>, BufferAttr_HipcMapAlias> out_nacp) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    // TODO: this should be the main applet, not the caller applet
+    const auto application = GetCallerIdentity(*m_applet);
+    std::vector<u8> nacp;
+    const auto result =
+        system.GetARPManager().GetControlProperty(&nacp, application.application_id);
+
+    if (R_SUCCEEDED(result)) {
+        std::memcpy(out_nacp->data(), nacp.data(), std::min(nacp.size(), out_nacp->size()));
+    }
+
+    R_RETURN(result);
+}
+
+Result ILibraryAppletSelfAccessor::GetMainAppletStorageId(Out<FileSys::StorageId> out_storage_id) {
+    LOG_INFO(Service_AM, "(STUBBED) called");
+    *out_storage_id = FileSys::StorageId::NandUser;
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::ExitProcessAndReturn() {
+    LOG_INFO(Service_AM, "called");
+    system.GetAppletManager().TerminateAndRemoveApplet(m_applet->aruid);
+    m_broker->SignalCompletion();
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(
+    Out<AppletIdentityInfo> out_identity_info) {
+    LOG_INFO(Service_AM, "called");
+    *out_identity_info = GetCallerIdentity(*m_applet);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfoStack(
+    Out<s32> out_count, OutArray<AppletIdentityInfo, BufferAttr_HipcMapAlias> out_identity_info) {
+    LOG_INFO(Service_AM, "called");
+
+    std::shared_ptr<Applet> applet = m_applet;
+    *out_count = 0;
+
+    do {
+        if (*out_count >= static_cast<s32>(out_identity_info.size())) {
+            break;
+        }
+        out_identity_info[(*out_count)++] = GetCallerIdentity(*applet);
+    } while ((applet = applet->caller_applet.lock()));
+
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout(Out<u32> out_desirable_layout) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_desirable_layout = 0;
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::ReportVisibleError(ErrorCode error_code) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, error {}-{}", error_code.category,
+                error_code.number);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::ReportVisibleErrorWithErrorContext(
+    ErrorCode error_code, InLargeData<ErrorContext, BufferAttr_HipcMapAlias> error_context) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, error {}-{}", error_code.category,
+                error_code.number);
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage(
+    Out<u64> out_desired_language) {
+    // FIXME: this is copied from IApplicationFunctions::GetDesiredLanguage
+    // FIXME: all of this stuff belongs to ns
+    auto identity = GetCallerIdentity(*m_applet);
+
+    // TODO(bunnei): This should be configurable
+    LOG_DEBUG(Service_AM, "called");
+
+    // Get supported languages from NACP, if possible
+    // Default to 0 (all languages supported)
+    u32 supported_languages = 0;
+
+    const auto res = [this, identity] {
+        const FileSys::PatchManager pm{identity.application_id, system.GetFileSystemController(),
+                                       system.GetContentProvider()};
+        auto metadata = pm.GetControlMetadata();
+        if (metadata.first != nullptr) {
+            return metadata;
+        }
+
+        const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(identity.application_id),
+                                              system.GetFileSystemController(),
+                                              system.GetContentProvider()};
+        return pm_update.GetControlMetadata();
+    }();
+
+    if (res.first != nullptr) {
+        supported_languages = res.first->GetSupportedLanguages();
+    }
+
+    // Call IApplicationManagerInterface implementation.
+    auto& service_manager = system.ServiceManager();
+    auto ns_am2 = service_manager.GetService<NS::NS>("ns:am2");
+    auto app_man = ns_am2->GetApplicationManagerInterface();
+
+    // Get desired application language
+    u8 desired_language{};
+    R_TRY(app_man->GetApplicationDesiredLanguage(&desired_language, supported_languages));
+
+    // Convert to settings language code.
+    u64 language_code{};
+    R_TRY(app_man->ConvertApplicationLanguageToLanguageCode(&language_code, desired_language));
+
+    LOG_DEBUG(Service_AM, "got desired_language={:016X}", language_code);
+
+    *out_desired_language = language_code;
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::GetCurrentApplicationId(Out<u64> out_application_id) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    // TODO: this should be the main applet, not the caller applet
+    const auto main_applet = GetCallerIdentity(*m_applet);
+    *out_application_id = main_applet.application_id;
+
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::GetMainAppletAvailableUsers(
+    Out<bool> out_no_users_available, Out<s32> out_users_count,
+    OutArray<Common::UUID, BufferAttr_HipcMapAlias> out_users) {
+    const Service::Account::ProfileManager manager{};
+
+    *out_no_users_available = true;
+    *out_users_count = -1;
+
+    LOG_INFO(Service_AM, "called");
+
+    if (manager.GetUserCount() > 0) {
+        *out_no_users_available = false;
+        *out_users_count = static_cast<s32>(manager.GetUserCount());
+
+        const auto users = manager.GetAllUsers();
+        for (size_t i = 0; i < users.size() && i < out_users.size(); i++) {
+            out_users[i] = users[i];
+        }
+    }
+
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually(
+    Out<bool> out_should_set_gpu_time_slice_manually) {
+    LOG_INFO(Service_AM, "(STUBBED) called");
+    *out_should_set_gpu_time_slice_manually = false;
+    R_SUCCEED();
+}
+
+Result ILibraryAppletSelfAccessor::Cmd160(Out<u64> out_unknown0) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_unknown0 = 0;
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/library_applet_self_accessor.h b/src/core/hle/service/am/service/library_applet_self_accessor.h
new file mode 100644
index 000000000..a9743569f
--- /dev/null
+++ b/src/core/hle/service/am/service/library_applet_self_accessor.h
@@ -0,0 +1,83 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "common/uuid.h"
+#include "core/hle/service/am/am_types.h"
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace FileSys {
+enum class StorageId : u8;
+}
+
+namespace Kernel {
+class KReadableEvent;
+}
+
+namespace Service::AM {
+
+class AppletDataBroker;
+struct Applet;
+class IStorage;
+
+struct LibraryAppletInfo {
+    AppletId applet_id;
+    LibraryAppletMode library_applet_mode;
+};
+static_assert(sizeof(LibraryAppletInfo) == 0x8, "LibraryAppletInfo has incorrect size.");
+
+struct ErrorCode {
+    u32 category;
+    u32 number;
+};
+static_assert(sizeof(ErrorCode) == 0x8, "ErrorCode has incorrect size.");
+
+struct ErrorContext {
+    u8 type;
+    INSERT_PADDING_BYTES_NOINIT(0x7);
+    std::array<u8, 0x1f4> data;
+    Result result;
+};
+static_assert(sizeof(ErrorContext) == 0x200, "ErrorContext has incorrect size.");
+
+class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> {
+public:
+    explicit ILibraryAppletSelfAccessor(Core::System& system_, std::shared_ptr<Applet> applet);
+    ~ILibraryAppletSelfAccessor() override;
+
+private:
+    Result PopInData(Out<SharedPointer<IStorage>> out_storage);
+    Result PushOutData(SharedPointer<IStorage> storage);
+    Result PopInteractiveInData(Out<SharedPointer<IStorage>> out_storage);
+    Result PushInteractiveOutData(SharedPointer<IStorage> storage);
+    Result GetPopInDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result GetPopInteractiveInDataEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result GetLibraryAppletInfo(Out<LibraryAppletInfo> out_library_applet_info);
+    Result GetMainAppletIdentityInfo(Out<AppletIdentityInfo> out_identity_info);
+    Result CanUseApplicationCore(Out<bool> out_can_use_application_core);
+    Result GetMainAppletApplicationControlProperty(
+        OutLargeData<std::array<u8, 0x4000>, BufferAttr_HipcMapAlias> out_nacp);
+    Result GetMainAppletStorageId(Out<FileSys::StorageId> out_storage_id);
+    Result ExitProcessAndReturn();
+    Result GetCallerAppletIdentityInfo(Out<AppletIdentityInfo> out_identity_info);
+    Result GetCallerAppletIdentityInfoStack(
+        Out<s32> out_count,
+        OutArray<AppletIdentityInfo, BufferAttr_HipcMapAlias> out_identity_info);
+    Result GetDesirableKeyboardLayout(Out<u32> out_desirable_layout);
+    Result ReportVisibleError(ErrorCode error_code);
+    Result ReportVisibleErrorWithErrorContext(
+        ErrorCode error_code, InLargeData<ErrorContext, BufferAttr_HipcMapAlias> error_context);
+    Result GetMainAppletApplicationDesiredLanguage(Out<u64> out_desired_language);
+    Result GetCurrentApplicationId(Out<u64> out_application_id);
+    Result GetMainAppletAvailableUsers(Out<bool> out_no_users_available, Out<s32> out_users_count,
+                                       OutArray<Common::UUID, BufferAttr_HipcMapAlias> out_users);
+    Result ShouldSetGpuTimeSliceManually(Out<bool> out_should_set_gpu_time_slice_manually);
+    Result Cmd160(Out<u64> out_unknown0);
+
+    const std::shared_ptr<Applet> m_applet;
+    const std::shared_ptr<AppletDataBroker> m_broker;
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index 59d5b2a23..1e931dec7 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -2,7 +2,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/application_creator.h"
-#include "core/hle/service/am/library_applet_self_accessor.h"
 #include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"

From 79f225bd5979f058b682845bcafa9a34af8fdc4e Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 20:16:38 -0500
Subject: [PATCH 16/24] am: rewrite IProcessWindingController

---
 src/core/CMakeLists.txt                       |  4 +-
 .../service/am/process_winding_controller.cpp | 56 -------------------
 .../service/am/service/application_proxy.cpp  |  2 +-
 .../am/service/library_applet_proxy.cpp       |  2 +-
 .../am/service/process_winding_controller.cpp | 54 ++++++++++++++++++
 .../process_winding_controller.h              | 10 +++-
 .../am/service/system_applet_proxy.cpp        |  2 +-
 7 files changed, 66 insertions(+), 64 deletions(-)
 delete mode 100644 src/core/hle/service/am/process_winding_controller.cpp
 create mode 100644 src/core/hle/service/am/service/process_winding_controller.cpp
 rename src/core/hle/service/am/{ => service}/process_winding_controller.h (57%)

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index f7f6b216e..935e3c57c 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -437,8 +437,6 @@ add_library(core STATIC
     hle/service/am/managed_layer_holder.h
     hle/service/am/omm.cpp
     hle/service/am/omm.h
-    hle/service/am/process_winding_controller.cpp
-    hle/service/am/process_winding_controller.h
     hle/service/am/process.cpp
     hle/service/am/process.h
     hle/service/am/self_controller.cpp
@@ -475,6 +473,8 @@ add_library(core STATIC
     hle/service/am/service/library_applet_proxy.h
     hle/service/am/service/library_applet_self_accessor.cpp
     hle/service/am/service/library_applet_self_accessor.h
+    hle/service/am/service/process_winding_controller.cpp
+    hle/service/am/service/process_winding_controller.h
     hle/service/am/service/system_applet_proxy.cpp
     hle/service/am/service/system_applet_proxy.h
     hle/service/am/system_buffer_manager.cpp
diff --git a/src/core/hle/service/am/process_winding_controller.cpp b/src/core/hle/service/am/process_winding_controller.cpp
deleted file mode 100644
index bc5a50a3d..000000000
--- a/src/core/hle/service/am/process_winding_controller.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/am/frontend/applets.h"
-#include "core/hle/service/am/process_winding_controller.h"
-#include "core/hle/service/am/service/library_applet_accessor.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-IProcessWindingController::IProcessWindingController(Core::System& system_,
-                                                     std::shared_ptr<Applet> applet_)
-    : ServiceFramework{system_, "IProcessWindingController"}, applet{std::move(applet_)} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {0, &IProcessWindingController::GetLaunchReason, "GetLaunchReason"},
-        {11, &IProcessWindingController::OpenCallingLibraryApplet, "OpenCallingLibraryApplet"},
-        {21, nullptr, "PushContext"},
-        {22, nullptr, "PopContext"},
-        {23, nullptr, "CancelWindingReservation"},
-        {30, nullptr, "WindAndDoReserved"},
-        {40, nullptr, "ReserveToStartAndWaitAndUnwindThis"},
-        {41, nullptr, "ReserveToStartAndWait"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-IProcessWindingController::~IProcessWindingController() = default;
-
-void IProcessWindingController::GetLaunchReason(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.PushRaw(applet->launch_reason);
-}
-
-void IProcessWindingController::OpenCallingLibraryApplet(HLERequestContext& ctx) {
-    const auto caller_applet = applet->caller_applet.lock();
-    if (caller_applet == nullptr) {
-        LOG_ERROR(Service_AM, "No calling applet available");
-
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(ResultUnknown);
-        return;
-    }
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet->caller_applet_broker,
-                                                caller_applet);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index c9b872887..5f5a8f06c 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/application_functions.h"
@@ -11,6 +10,7 @@
 #include "core/hle/service/am/service/debug_functions.h"
 #include "core/hle/service/am/service/display_controller.h"
 #include "core/hle/service/am/service/library_applet_creator.h"
+#include "core/hle/service/am/service/process_winding_controller.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index 9506739e9..91aa9f4db 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/audio_controller.h"
@@ -13,6 +12,7 @@
 #include "core/hle/service/am/service/library_applet_creator.h"
 #include "core/hle/service/am/service/library_applet_proxy.h"
 #include "core/hle/service/am/service/library_applet_self_accessor.h"
+#include "core/hle/service/am/service/process_winding_controller.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
diff --git a/src/core/hle/service/am/service/process_winding_controller.cpp b/src/core/hle/service/am/service/process_winding_controller.cpp
new file mode 100644
index 000000000..10df830d7
--- /dev/null
+++ b/src/core/hle/service/am/service/process_winding_controller.cpp
@@ -0,0 +1,54 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/am/frontend/applets.h"
+#include "core/hle/service/am/service/library_applet_accessor.h"
+#include "core/hle/service/am/service/process_winding_controller.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+IProcessWindingController::IProcessWindingController(Core::System& system_,
+                                                     std::shared_ptr<Applet> applet)
+    : ServiceFramework{system_, "IProcessWindingController"}, m_applet{std::move(applet)} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, D<&IProcessWindingController::GetLaunchReason>, "GetLaunchReason"},
+        {11, D<&IProcessWindingController::OpenCallingLibraryApplet>, "OpenCallingLibraryApplet"},
+        {21, nullptr, "PushContext"},
+        {22, nullptr, "PopContext"},
+        {23, nullptr, "CancelWindingReservation"},
+        {30, nullptr, "WindAndDoReserved"},
+        {40, nullptr, "ReserveToStartAndWaitAndUnwindThis"},
+        {41, nullptr, "ReserveToStartAndWait"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IProcessWindingController::~IProcessWindingController() = default;
+
+Result IProcessWindingController::GetLaunchReason(
+    Out<AppletProcessLaunchReason> out_launch_reason) {
+    LOG_INFO(Service_AM, "called");
+    *out_launch_reason = m_applet->launch_reason;
+    R_SUCCEED();
+}
+
+Result IProcessWindingController::OpenCallingLibraryApplet(
+    Out<SharedPointer<ILibraryAppletAccessor>> out_calling_library_applet) {
+    LOG_INFO(Service_AM, "called");
+
+    const auto caller_applet = m_applet->caller_applet.lock();
+    if (caller_applet == nullptr) {
+        LOG_ERROR(Service_AM, "No caller applet available");
+        R_THROW(ResultUnknown);
+    }
+
+    *out_calling_library_applet = std::make_shared<ILibraryAppletAccessor>(
+        system, m_applet->caller_applet_broker, caller_applet);
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/process_winding_controller.h b/src/core/hle/service/am/service/process_winding_controller.h
similarity index 57%
rename from src/core/hle/service/am/process_winding_controller.h
rename to src/core/hle/service/am/service/process_winding_controller.h
index 71ae4c4f5..4408af1f1 100644
--- a/src/core/hle/service/am/process_winding_controller.h
+++ b/src/core/hle/service/am/service/process_winding_controller.h
@@ -3,11 +3,14 @@
 
 #pragma once
 
+#include "core/hle/service/am/am_types.h"
+#include "core/hle/service/cmif_types.h"
 #include "core/hle/service/service.h"
 
 namespace Service::AM {
 
 struct Applet;
+class ILibraryAppletAccessor;
 
 class IProcessWindingController final : public ServiceFramework<IProcessWindingController> {
 public:
@@ -15,10 +18,11 @@ public:
     ~IProcessWindingController() override;
 
 private:
-    void GetLaunchReason(HLERequestContext& ctx);
-    void OpenCallingLibraryApplet(HLERequestContext& ctx);
+    Result GetLaunchReason(Out<AppletProcessLaunchReason> out_launch_reason);
+    Result OpenCallingLibraryApplet(
+        Out<SharedPointer<ILibraryAppletAccessor>> out_calling_library_applet);
 
-    const std::shared_ptr<Applet> applet;
+    const std::shared_ptr<Applet> m_applet;
 };
 
 } // namespace Service::AM
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index 1e931dec7..0f6175d32 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -2,7 +2,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/application_creator.h"
-#include "core/hle/service/am/process_winding_controller.h"
 #include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/audio_controller.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/service/global_state_controller.h"
 #include "core/hle/service/am/service/home_menu_functions.h"
 #include "core/hle/service/am/service/library_applet_creator.h"
+#include "core/hle/service/am/service/process_winding_controller.h"
 #include "core/hle/service/am/service/system_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"

From 9e271f20172b61e48241fa9044ab7ff3600ada61 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 20:22:48 -0500
Subject: [PATCH 17/24] am: rewrite ISelfController

---
 src/core/CMakeLists.txt                       |   4 +-
 src/core/hle/service/am/am_types.h            |   7 +-
 src/core/hle/service/am/self_controller.cpp   | 470 ------------------
 src/core/hle/service/am/self_controller.h     |  60 ---
 .../service/am/service/application_proxy.cpp  |   5 +-
 .../am/service/library_applet_proxy.cpp       |   5 +-
 .../service/am/service/self_controller.cpp    | 393 +++++++++++++++
 .../hle/service/am/service/self_controller.h  |  72 +++
 .../am/service/system_applet_proxy.cpp        |   5 +-
 9 files changed, 479 insertions(+), 542 deletions(-)
 delete mode 100644 src/core/hle/service/am/self_controller.cpp
 delete mode 100644 src/core/hle/service/am/self_controller.h
 create mode 100644 src/core/hle/service/am/service/self_controller.cpp
 create mode 100644 src/core/hle/service/am/service/self_controller.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 935e3c57c..956207fcf 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -439,8 +439,6 @@ add_library(core STATIC
     hle/service/am/omm.h
     hle/service/am/process.cpp
     hle/service/am/process.h
-    hle/service/am/self_controller.cpp
-    hle/service/am/self_controller.h
     hle/service/am/service/all_system_applet_proxies_service.cpp
     hle/service/am/service/all_system_applet_proxies_service.h
     hle/service/am/service/applet_common_functions.cpp
@@ -475,6 +473,8 @@ add_library(core STATIC
     hle/service/am/service/library_applet_self_accessor.h
     hle/service/am/service/process_winding_controller.cpp
     hle/service/am/service/process_winding_controller.h
+    hle/service/am/service/self_controller.cpp
+    hle/service/am/service/self_controller.h
     hle/service/am/service/system_applet_proxy.cpp
     hle/service/am/service/system_applet_proxy.h
     hle/service/am/system_buffer_manager.cpp
diff --git a/src/core/hle/service/am/am_types.h b/src/core/hle/service/am/am_types.h
index 093adcdea..46afb3996 100644
--- a/src/core/hle/service/am/am_types.h
+++ b/src/core/hle/service/am/am_types.h
@@ -67,10 +67,9 @@ enum class ScreenshotPermission : u32 {
 };
 
 struct FocusHandlingMode {
-    bool unknown0;
-    bool unknown1;
-    bool unknown2;
-    bool unknown3;
+    bool notify;
+    bool background;
+    bool suspend;
 };
 
 enum class IdleTimeDetectionExtension : u32 {
diff --git a/src/core/hle/service/am/self_controller.cpp b/src/core/hle/service/am/self_controller.cpp
deleted file mode 100644
index 65e249c0c..000000000
--- a/src/core/hle/service/am/self_controller.cpp
+++ /dev/null
@@ -1,470 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/logging/log.h"
-#include "core/hle/result.h"
-#include "core/hle/service/am/am_results.h"
-#include "core/hle/service/am/frontend/applets.h"
-#include "core/hle/service/am/self_controller.h"
-#include "core/hle/service/caps/caps_su.h"
-#include "core/hle/service/hle_ipc.h"
-#include "core/hle/service/ipc_helpers.h"
-#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
-#include "core/hle/service/nvnflinger/nvnflinger.h"
-#include "core/hle/service/sm/sm.h"
-#include "core/hle/service/vi/vi_results.h"
-
-namespace Service::AM {
-
-ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet_,
-                                 Nvnflinger::Nvnflinger& nvnflinger_)
-    : ServiceFramework{system_, "ISelfController"}, nvnflinger{nvnflinger_}, applet{std::move(
-                                                                                 applet_)} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {0, &ISelfController::Exit, "Exit"},
-        {1, &ISelfController::LockExit, "LockExit"},
-        {2, &ISelfController::UnlockExit, "UnlockExit"},
-        {3, &ISelfController::EnterFatalSection, "EnterFatalSection"},
-        {4, &ISelfController::LeaveFatalSection, "LeaveFatalSection"},
-        {9, &ISelfController::GetLibraryAppletLaunchableEvent, "GetLibraryAppletLaunchableEvent"},
-        {10, &ISelfController::SetScreenShotPermission, "SetScreenShotPermission"},
-        {11, &ISelfController::SetOperationModeChangedNotification, "SetOperationModeChangedNotification"},
-        {12, &ISelfController::SetPerformanceModeChangedNotification, "SetPerformanceModeChangedNotification"},
-        {13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"},
-        {14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"},
-        {15, &ISelfController::SetScreenShotAppletIdentityInfo, "SetScreenShotAppletIdentityInfo"},
-        {16, &ISelfController::SetOutOfFocusSuspendingEnabled, "SetOutOfFocusSuspendingEnabled"},
-        {17, nullptr, "SetControllerFirmwareUpdateSection"},
-        {18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"},
-        {19, &ISelfController::SetAlbumImageOrientation, "SetAlbumImageOrientation"},
-        {20, nullptr, "SetDesirableKeyboardLayout"},
-        {21, nullptr, "GetScreenShotProgramId"},
-        {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
-        {41, &ISelfController::IsSystemBufferSharingEnabled, "IsSystemBufferSharingEnabled"},
-        {42, &ISelfController::GetSystemSharedLayerHandle, "GetSystemSharedLayerHandle"},
-        {43, &ISelfController::GetSystemSharedBufferHandle, "GetSystemSharedBufferHandle"},
-        {44, &ISelfController::CreateManagedDisplaySeparableLayer, "CreateManagedDisplaySeparableLayer"},
-        {45, nullptr, "SetManagedDisplayLayerSeparationMode"},
-        {46, nullptr, "SetRecordingLayerCompositionEnabled"},
-        {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"},
-        {51, &ISelfController::ApproveToDisplay, "ApproveToDisplay"},
-        {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"},
-        {61, &ISelfController::SetMediaPlaybackState, "SetMediaPlaybackState"},
-        {62, &ISelfController::SetIdleTimeDetectionExtension, "SetIdleTimeDetectionExtension"},
-        {63, &ISelfController::GetIdleTimeDetectionExtension, "GetIdleTimeDetectionExtension"},
-        {64, nullptr, "SetInputDetectionSourceSet"},
-        {65, &ISelfController::ReportUserIsActive, "ReportUserIsActive"},
-        {66, nullptr, "GetCurrentIlluminance"},
-        {67, nullptr, "IsIlluminanceAvailable"},
-        {68, &ISelfController::SetAutoSleepDisabled, "SetAutoSleepDisabled"},
-        {69, &ISelfController::IsAutoSleepDisabled, "IsAutoSleepDisabled"},
-        {70, nullptr, "ReportMultimediaError"},
-        {71, nullptr, "GetCurrentIlluminanceEx"},
-        {72, nullptr, "SetInputDetectionPolicy"},
-        {80, nullptr, "SetWirelessPriorityMode"},
-        {90, &ISelfController::GetAccumulatedSuspendedTickValue, "GetAccumulatedSuspendedTickValue"},
-        {91, &ISelfController::GetAccumulatedSuspendedTickChangedEvent, "GetAccumulatedSuspendedTickChangedEvent"},
-        {100, &ISelfController::SetAlbumImageTakenNotificationEnabled, "SetAlbumImageTakenNotificationEnabled"},
-        {110, nullptr, "SetApplicationAlbumUserData"},
-        {120, &ISelfController::SaveCurrentScreenshot, "SaveCurrentScreenshot"},
-        {130, &ISelfController::SetRecordVolumeMuted, "SetRecordVolumeMuted"},
-        {1000, nullptr, "GetDebugStorageChannel"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-ISelfController::~ISelfController() = default;
-
-void ISelfController::Exit(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-
-    // TODO
-    system.Exit();
-}
-
-void ISelfController::LockExit(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    system.SetExitLocked(true);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::UnlockExit(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    system.SetExitLocked(false);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-
-    if (system.GetExitRequested()) {
-        system.Exit();
-    }
-}
-
-void ISelfController::EnterFatalSection(HLERequestContext& ctx) {
-
-    std::scoped_lock lk{applet->lock};
-    applet->fatal_section_count++;
-    LOG_DEBUG(Service_AM, "called. Num fatal sections entered: {}", applet->fatal_section_count);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::LeaveFatalSection(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called.");
-
-    // Entry and exit of fatal sections must be balanced.
-    std::scoped_lock lk{applet->lock};
-    if (applet->fatal_section_count == 0) {
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(AM::ResultFatalSectionCountImbalance);
-        return;
-    }
-
-    applet->fatal_section_count--;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::GetLibraryAppletLaunchableEvent(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    applet->library_applet_launchable_event.Signal();
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(applet->library_applet_launchable_event.GetHandle());
-}
-
-void ISelfController::SetScreenShotPermission(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto permission = rp.PopEnum<ScreenshotPermission>();
-    LOG_DEBUG(Service_AM, "called, permission={}", permission);
-
-    std::scoped_lock lk{applet->lock};
-    applet->screenshot_permission = permission;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetOperationModeChangedNotification(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const bool notification_enabled = rp.Pop<bool>();
-    LOG_WARNING(Service_AM, "(STUBBED) called notification_enabled={}", notification_enabled);
-
-    std::scoped_lock lk{applet->lock};
-    applet->operation_mode_changed_notification_enabled = notification_enabled;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetPerformanceModeChangedNotification(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const bool notification_enabled = rp.Pop<bool>();
-    LOG_WARNING(Service_AM, "(STUBBED) called notification_enabled={}", notification_enabled);
-
-    std::scoped_lock lk{applet->lock};
-    applet->performance_mode_changed_notification_enabled = notification_enabled;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetFocusHandlingMode(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const auto flags = rp.PopRaw<FocusHandlingMode>();
-
-    LOG_WARNING(Service_AM, "(STUBBED) called. unknown0={}, unknown1={}, unknown2={}",
-                flags.unknown0, flags.unknown1, flags.unknown2);
-
-    std::scoped_lock lk{applet->lock};
-    applet->focus_handling_mode = flags;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetRestartMessageEnabled(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-    applet->restart_message_enabled = true;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetScreenShotAppletIdentityInfo(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::RequestParser rp{ctx};
-    std::scoped_lock lk{applet->lock};
-    applet->screen_shot_identity = rp.PopRaw<AppletIdentityInfo>();
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const bool enabled = rp.Pop<bool>();
-    LOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled);
-
-    std::scoped_lock lk{applet->lock};
-    ASSERT(applet->type == AppletType::Application);
-    applet->out_of_focus_suspension_enabled = enabled;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetAlbumImageOrientation(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const auto orientation = rp.PopRaw<Capture::AlbumImageOrientation>();
-    LOG_WARNING(Service_AM, "(STUBBED) called, orientation={}", static_cast<s32>(orientation));
-
-    std::scoped_lock lk{applet->lock};
-    applet->album_image_orientation = orientation;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::CreateManagedDisplayLayer(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    u64 layer_id{};
-    applet->managed_layer_holder.Initialize(&nvnflinger);
-    applet->managed_layer_holder.CreateManagedDisplayLayer(&layer_id);
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.Push(layer_id);
-}
-
-void ISelfController::IsSystemBufferSharingEnabled(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess()));
-}
-
-void ISelfController::GetSystemSharedLayerHandle(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    u64 buffer_id, layer_id;
-    applet->system_buffer_manager.GetSystemSharedLayerHandle(&buffer_id, &layer_id);
-
-    IPC::ResponseBuilder rb{ctx, 6};
-    rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess()));
-    rb.Push<s64>(buffer_id);
-    rb.Push<s64>(layer_id);
-}
-
-void ISelfController::GetSystemSharedBufferHandle(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    u64 buffer_id, layer_id;
-    applet->system_buffer_manager.GetSystemSharedLayerHandle(&buffer_id, &layer_id);
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess()));
-    rb.Push<s64>(buffer_id);
-}
-
-Result ISelfController::EnsureBufferSharingEnabled(Kernel::KProcess* process) {
-    if (applet->system_buffer_manager.Initialize(&nvnflinger, process, applet->applet_id,
-                                                 applet->library_applet_mode)) {
-        return ResultSuccess;
-    }
-
-    return VI::ResultOperationFailed;
-}
-
-void ISelfController::CreateManagedDisplaySeparableLayer(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    u64 layer_id{};
-    u64 recording_layer_id{};
-    applet->managed_layer_holder.Initialize(&nvnflinger);
-    applet->managed_layer_holder.CreateManagedDisplaySeparableLayer(&layer_id, &recording_layer_id);
-
-    IPC::ResponseBuilder rb{ctx, 6};
-    rb.Push(ResultSuccess);
-    rb.Push(layer_id);
-    rb.Push(recording_layer_id);
-}
-
-void ISelfController::SetHandlesRequestToDisplay(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::ApproveToDisplay(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetMediaPlaybackState(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const u8 state = rp.Pop<u8>();
-
-    LOG_WARNING(Service_AM, "(STUBBED) called, state={}", state);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const auto extension = rp.PopRaw<IdleTimeDetectionExtension>();
-    LOG_DEBUG(Service_AM, "(STUBBED) called extension={}", extension);
-
-    std::scoped_lock lk{applet->lock};
-    applet->idle_time_detection_extension = extension;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::GetIdleTimeDetectionExtension(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.PushRaw<IdleTimeDetectionExtension>(applet->idle_time_detection_extension);
-}
-
-void ISelfController::ReportUserIsActive(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetAutoSleepDisabled(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    std::scoped_lock lk{applet->lock};
-    applet->auto_sleep_disabled = rp.Pop<bool>();
-
-    // On the system itself, if the previous state of is_auto_sleep_disabled
-    // differed from the current value passed in, it'd signify the internal
-    // window manager to update (and also increment some statistics like update counts)
-    //
-    // It'd also indicate this change to an idle handling context.
-    //
-    // However, given we're emulating this behavior, most of this can be ignored
-    // and it's sufficient to simply set the member variable for querying via
-    // IsAutoSleepDisabled().
-
-    LOG_DEBUG(Service_AM, "called. is_auto_sleep_disabled={}", applet->auto_sleep_disabled);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::IsAutoSleepDisabled(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called.");
-
-    std::scoped_lock lk{applet->lock};
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push(applet->auto_sleep_disabled);
-}
-
-void ISelfController::GetAccumulatedSuspendedTickValue(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called.");
-
-    std::scoped_lock lk{applet->lock};
-    // This command returns the total number of system ticks since ISelfController creation
-    // where the game was suspended. Since Yuzu doesn't implement game suspension, this command
-    // can just always return 0 ticks.
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.Push<u64>(applet->suspended_ticks);
-}
-
-void ISelfController::GetAccumulatedSuspendedTickChangedEvent(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called.");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(applet->accumulated_suspended_tick_changed_event.GetHandle());
-}
-
-void ISelfController::SetAlbumImageTakenNotificationEnabled(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    // This service call sets an internal flag whether a notification is shown when an image is
-    // captured. Currently we do not support capturing images via the capture button, so this can be
-    // stubbed for now.
-    const bool enabled = rp.Pop<bool>();
-    LOG_WARNING(Service_AM, "(STUBBED) called. enabled={}", enabled);
-
-    std::scoped_lock lk{applet->lock};
-    applet->album_image_taken_notification_enabled = enabled;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SaveCurrentScreenshot(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const auto report_option = rp.PopEnum<Capture::AlbumReportOption>();
-
-    LOG_INFO(Service_AM, "called, report_option={}", report_option);
-
-    const auto screenshot_service =
-        system.ServiceManager().GetService<Service::Capture::IScreenShotApplicationService>(
-            "caps:su");
-
-    if (screenshot_service) {
-        screenshot_service->CaptureAndSaveScreenshot(report_option);
-    }
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetRecordVolumeMuted(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const auto enabled = rp.Pop<bool>();
-    LOG_WARNING(Service_AM, "(STUBBED) called. enabled={}", enabled);
-
-    std::scoped_lock lk{applet->lock};
-    applet->record_volume_muted = enabled;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/self_controller.h b/src/core/hle/service/am/self_controller.h
deleted file mode 100644
index ab21a1881..000000000
--- a/src/core/hle/service/am/self_controller.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/hle_ipc.h"
-#include "core/hle/service/kernel_helpers.h"
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-struct Applet;
-
-class ISelfController final : public ServiceFramework<ISelfController> {
-public:
-    explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet_,
-                             Nvnflinger::Nvnflinger& nvnflinger_);
-    ~ISelfController() override;
-
-private:
-    void Exit(HLERequestContext& ctx);
-    void LockExit(HLERequestContext& ctx);
-    void UnlockExit(HLERequestContext& ctx);
-    void EnterFatalSection(HLERequestContext& ctx);
-    void LeaveFatalSection(HLERequestContext& ctx);
-    void GetLibraryAppletLaunchableEvent(HLERequestContext& ctx);
-    void SetScreenShotPermission(HLERequestContext& ctx);
-    void SetOperationModeChangedNotification(HLERequestContext& ctx);
-    void SetPerformanceModeChangedNotification(HLERequestContext& ctx);
-    void SetFocusHandlingMode(HLERequestContext& ctx);
-    void SetRestartMessageEnabled(HLERequestContext& ctx);
-    void SetScreenShotAppletIdentityInfo(HLERequestContext& ctx);
-    void SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx);
-    void SetAlbumImageOrientation(HLERequestContext& ctx);
-    void IsSystemBufferSharingEnabled(HLERequestContext& ctx);
-    void GetSystemSharedBufferHandle(HLERequestContext& ctx);
-    void GetSystemSharedLayerHandle(HLERequestContext& ctx);
-    void CreateManagedDisplayLayer(HLERequestContext& ctx);
-    void CreateManagedDisplaySeparableLayer(HLERequestContext& ctx);
-    void SetHandlesRequestToDisplay(HLERequestContext& ctx);
-    void ApproveToDisplay(HLERequestContext& ctx);
-    void SetMediaPlaybackState(HLERequestContext& ctx);
-    void SetIdleTimeDetectionExtension(HLERequestContext& ctx);
-    void GetIdleTimeDetectionExtension(HLERequestContext& ctx);
-    void ReportUserIsActive(HLERequestContext& ctx);
-    void SetAutoSleepDisabled(HLERequestContext& ctx);
-    void IsAutoSleepDisabled(HLERequestContext& ctx);
-    void GetAccumulatedSuspendedTickValue(HLERequestContext& ctx);
-    void GetAccumulatedSuspendedTickChangedEvent(HLERequestContext& ctx);
-    void SetAlbumImageTakenNotificationEnabled(HLERequestContext& ctx);
-    void SaveCurrentScreenshot(HLERequestContext& ctx);
-    void SetRecordVolumeMuted(HLERequestContext& ctx);
-
-    Result EnsureBufferSharingEnabled(Kernel::KProcess* process);
-
-    Nvnflinger::Nvnflinger& nvnflinger;
-    const std::shared_ptr<Applet> applet;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index 5f5a8f06c..9bba985be 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/application_functions.h"
 #include "core/hle/service/am/service/application_proxy.h"
@@ -11,6 +10,7 @@
 #include "core/hle/service/am/service/display_controller.h"
 #include "core/hle/service/am/service/library_applet_creator.h"
 #include "core/hle/service/am/service/process_winding_controller.h"
+#include "core/hle/service/am/service/self_controller.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
@@ -77,7 +77,8 @@ Result IApplicationProxy::GetWindowController(
 Result IApplicationProxy::GetSelfController(
     Out<SharedPointer<ISelfController>> out_self_controller) {
     LOG_DEBUG(Service_AM, "called");
-    *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_nvnflinger);
+    *out_self_controller =
+        std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
     R_SUCCEED();
 }
 
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index 91aa9f4db..bac3e0168 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/common_state_getter.h"
@@ -13,6 +12,7 @@
 #include "core/hle/service/am/service/library_applet_proxy.h"
 #include "core/hle/service/am/service/library_applet_self_accessor.h"
 #include "core/hle/service/am/service/process_winding_controller.h"
+#include "core/hle/service/am/service/self_controller.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
@@ -83,7 +83,8 @@ Result ILibraryAppletProxy::GetWindowController(
 Result ILibraryAppletProxy::GetSelfController(
     Out<SharedPointer<ISelfController>> out_self_controller) {
     LOG_DEBUG(Service_AM, "called");
-    *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_nvnflinger);
+    *out_self_controller =
+        std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
     R_SUCCEED();
 }
 
diff --git a/src/core/hle/service/am/service/self_controller.cpp b/src/core/hle/service/am/service/self_controller.cpp
new file mode 100644
index 000000000..5c4c13de1
--- /dev/null
+++ b/src/core/hle/service/am/service/self_controller.cpp
@@ -0,0 +1,393 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/logging/log.h"
+#include "core/hle/result.h"
+#include "core/hle/service/am/am_results.h"
+#include "core/hle/service/am/frontend/applets.h"
+#include "core/hle/service/am/service/self_controller.h"
+#include "core/hle/service/caps/caps_su.h"
+#include "core/hle/service/cmif_serialization.h"
+#include "core/hle/service/nvnflinger/nvnflinger.h"
+#include "core/hle/service/sm/sm.h"
+#include "core/hle/service/vi/vi_results.h"
+
+namespace Service::AM {
+
+ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet,
+                                 Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger)
+    : ServiceFramework{system_, "ISelfController"},
+      m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, D<&ISelfController::Exit>, "Exit"},
+        {1, D<&ISelfController::LockExit>, "LockExit"},
+        {2, D<&ISelfController::UnlockExit>, "UnlockExit"},
+        {3, D<&ISelfController::EnterFatalSection>, "EnterFatalSection"},
+        {4, D<&ISelfController::LeaveFatalSection>, "LeaveFatalSection"},
+        {9, D<&ISelfController::GetLibraryAppletLaunchableEvent>, "GetLibraryAppletLaunchableEvent"},
+        {10, D<&ISelfController::SetScreenShotPermission>, "SetScreenShotPermission"},
+        {11, D<&ISelfController::SetOperationModeChangedNotification>, "SetOperationModeChangedNotification"},
+        {12, D<&ISelfController::SetPerformanceModeChangedNotification>, "SetPerformanceModeChangedNotification"},
+        {13, D<&ISelfController::SetFocusHandlingMode>, "SetFocusHandlingMode"},
+        {14, D<&ISelfController::SetRestartMessageEnabled>, "SetRestartMessageEnabled"},
+        {15, D<&ISelfController::SetScreenShotAppletIdentityInfo>, "SetScreenShotAppletIdentityInfo"},
+        {16, D<&ISelfController::SetOutOfFocusSuspendingEnabled>, "SetOutOfFocusSuspendingEnabled"},
+        {17, nullptr, "SetControllerFirmwareUpdateSection"},
+        {18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"},
+        {19, D<&ISelfController::SetAlbumImageOrientation>, "SetAlbumImageOrientation"},
+        {20, nullptr, "SetDesirableKeyboardLayout"},
+        {21, nullptr, "GetScreenShotProgramId"},
+        {40, D<&ISelfController::CreateManagedDisplayLayer>, "CreateManagedDisplayLayer"},
+        {41, D<&ISelfController::IsSystemBufferSharingEnabled>, "IsSystemBufferSharingEnabled"},
+        {42, D<&ISelfController::GetSystemSharedLayerHandle>, "GetSystemSharedLayerHandle"},
+        {43, D<&ISelfController::GetSystemSharedBufferHandle>, "GetSystemSharedBufferHandle"},
+        {44, D<&ISelfController::CreateManagedDisplaySeparableLayer>, "CreateManagedDisplaySeparableLayer"},
+        {45, nullptr, "SetManagedDisplayLayerSeparationMode"},
+        {46, nullptr, "SetRecordingLayerCompositionEnabled"},
+        {50, D<&ISelfController::SetHandlesRequestToDisplay>, "SetHandlesRequestToDisplay"},
+        {51, D<&ISelfController::ApproveToDisplay>, "ApproveToDisplay"},
+        {60, D<&ISelfController::OverrideAutoSleepTimeAndDimmingTime>, "OverrideAutoSleepTimeAndDimmingTime"},
+        {61, D<&ISelfController::SetMediaPlaybackState>, "SetMediaPlaybackState"},
+        {62, D<&ISelfController::SetIdleTimeDetectionExtension>, "SetIdleTimeDetectionExtension"},
+        {63, D<&ISelfController::GetIdleTimeDetectionExtension>, "GetIdleTimeDetectionExtension"},
+        {64, nullptr, "SetInputDetectionSourceSet"},
+        {65, D<&ISelfController::ReportUserIsActive>, "ReportUserIsActive"},
+        {66, nullptr, "GetCurrentIlluminance"},
+        {67, nullptr, "IsIlluminanceAvailable"},
+        {68, D<&ISelfController::SetAutoSleepDisabled>, "SetAutoSleepDisabled"},
+        {69, D<&ISelfController::IsAutoSleepDisabled>, "IsAutoSleepDisabled"},
+        {70, nullptr, "ReportMultimediaError"},
+        {71, nullptr, "GetCurrentIlluminanceEx"},
+        {72, D<&ISelfController::SetInputDetectionPolicy>, "SetInputDetectionPolicy"},
+        {80, nullptr, "SetWirelessPriorityMode"},
+        {90, D<&ISelfController::GetAccumulatedSuspendedTickValue>, "GetAccumulatedSuspendedTickValue"},
+        {91, D<&ISelfController::GetAccumulatedSuspendedTickChangedEvent>, "GetAccumulatedSuspendedTickChangedEvent"},
+        {100, D<&ISelfController::SetAlbumImageTakenNotificationEnabled>, "SetAlbumImageTakenNotificationEnabled"},
+        {110, nullptr, "SetApplicationAlbumUserData"},
+        {120, D<&ISelfController::SaveCurrentScreenshot>, "SaveCurrentScreenshot"},
+        {130, D<&ISelfController::SetRecordVolumeMuted>, "SetRecordVolumeMuted"},
+        {1000, nullptr, "GetDebugStorageChannel"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+ISelfController::~ISelfController() = default;
+
+Result ISelfController::Exit() {
+    LOG_DEBUG(Service_AM, "called");
+
+    // TODO
+    system.Exit();
+
+    R_SUCCEED();
+}
+
+Result ISelfController::LockExit() {
+    LOG_DEBUG(Service_AM, "called");
+
+    system.SetExitLocked(true);
+
+    R_SUCCEED();
+}
+
+Result ISelfController::UnlockExit() {
+    LOG_DEBUG(Service_AM, "called");
+
+    system.SetExitLocked(false);
+
+    if (system.GetExitRequested()) {
+        system.Exit();
+    }
+
+    R_SUCCEED();
+}
+
+Result ISelfController::EnterFatalSection() {
+    std::scoped_lock lk{m_applet->lock};
+
+    m_applet->fatal_section_count++;
+    LOG_DEBUG(Service_AM, "called. Num fatal sections entered: {}", m_applet->fatal_section_count);
+
+    R_SUCCEED();
+}
+
+Result ISelfController::LeaveFatalSection() {
+    LOG_DEBUG(Service_AM, "called");
+
+    // Entry and exit of fatal sections must be balanced.
+    std::scoped_lock lk{m_applet->lock};
+    R_UNLESS(m_applet->fatal_section_count > 0, AM::ResultFatalSectionCountImbalance);
+    m_applet->fatal_section_count--;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::GetLibraryAppletLaunchableEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    m_applet->library_applet_launchable_event.Signal();
+    *out_event = m_applet->library_applet_launchable_event.GetHandle();
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetScreenShotPermission(ScreenshotPermission screen_shot_permission) {
+    LOG_DEBUG(Service_AM, "called, permission={}", screen_shot_permission);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->screenshot_permission = screen_shot_permission;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetOperationModeChangedNotification(bool enabled) {
+    LOG_INFO(Service_AM, "called, enabled={}", enabled);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->operation_mode_changed_notification_enabled = enabled;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetPerformanceModeChangedNotification(bool enabled) {
+    LOG_INFO(Service_AM, "called, enabled={}", enabled);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->performance_mode_changed_notification_enabled = enabled;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetFocusHandlingMode(bool notify, bool background, bool suspend) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, notify={} background={} suspend={}", notify,
+                background, suspend);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->focus_handling_mode = {notify, background, suspend};
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetRestartMessageEnabled(bool enabled) {
+    LOG_INFO(Service_AM, "called, enabled={}", enabled);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->restart_message_enabled = enabled;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetScreenShotAppletIdentityInfo(
+    AppletIdentityInfo screen_shot_applet_identity_info) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->screen_shot_identity = screen_shot_applet_identity_info;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetOutOfFocusSuspendingEnabled(bool enabled) {
+    LOG_INFO(Service_AM, "called, enabled={}", enabled);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->out_of_focus_suspension_enabled = enabled;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetAlbumImageOrientation(
+    Capture::AlbumImageOrientation album_image_orientation) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, orientation={}", album_image_orientation);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->album_image_orientation = album_image_orientation;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::IsSystemBufferSharingEnabled() {
+    LOG_INFO(Service_AM, "called");
+    R_SUCCEED_IF(m_applet->system_buffer_manager.Initialize(
+        &m_nvnflinger, m_process, m_applet->applet_id, m_applet->library_applet_mode));
+    R_THROW(VI::ResultOperationFailed);
+}
+
+Result ISelfController::GetSystemSharedBufferHandle(Out<u64> out_buffer_id) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    R_TRY(this->IsSystemBufferSharingEnabled());
+
+    u64 layer_id;
+    m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, &layer_id);
+    R_SUCCEED();
+}
+
+Result ISelfController::GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id) {
+    LOG_INFO(Service_AM, "(STUBBED) called");
+
+    R_TRY(this->IsSystemBufferSharingEnabled());
+
+    m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, out_layer_id);
+    R_SUCCEED();
+}
+
+Result ISelfController::CreateManagedDisplayLayer(Out<u64> out_layer_id) {
+    LOG_INFO(Service_AM, "called");
+
+    m_applet->managed_layer_holder.Initialize(&m_nvnflinger);
+    m_applet->managed_layer_holder.CreateManagedDisplayLayer(out_layer_id);
+
+    R_SUCCEED();
+}
+
+Result ISelfController::CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id,
+                                                           Out<u64> out_recording_layer_id) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    m_applet->managed_layer_holder.Initialize(&m_nvnflinger);
+    m_applet->managed_layer_holder.CreateManagedDisplaySeparableLayer(out_layer_id,
+                                                                      out_recording_layer_id);
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetHandlesRequestToDisplay(bool enable) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, enable={}", enable);
+    R_SUCCEED();
+}
+
+Result ISelfController::ApproveToDisplay() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result ISelfController::SetMediaPlaybackState(bool state) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, state={}", state);
+    R_SUCCEED();
+}
+
+Result ISelfController::OverrideAutoSleepTimeAndDimmingTime(s32 a, s32 b, s32 c, s32 d) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, a={}, b={}, c={}, d={}", a, b, c, d);
+    R_SUCCEED();
+}
+
+Result ISelfController::SetIdleTimeDetectionExtension(
+    IdleTimeDetectionExtension idle_time_detection_extension) {
+    LOG_DEBUG(Service_AM, "(STUBBED) called extension={}", idle_time_detection_extension);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->idle_time_detection_extension = idle_time_detection_extension;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::GetIdleTimeDetectionExtension(
+    Out<IdleTimeDetectionExtension> out_idle_time_detection_extension) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    std::scoped_lock lk{m_applet->lock};
+    *out_idle_time_detection_extension = m_applet->idle_time_detection_extension;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::ReportUserIsActive() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result ISelfController::SetAutoSleepDisabled(bool is_auto_sleep_disabled) {
+    LOG_DEBUG(Service_AM, "called. is_auto_sleep_disabled={}", is_auto_sleep_disabled);
+
+    // On the system itself, if the previous state of is_auto_sleep_disabled
+    // differed from the current value passed in, it'd signify the internal
+    // window manager to update (and also increment some statistics like update counts)
+    //
+    // It'd also indicate this change to an idle handling context.
+    //
+    // However, given we're emulating this behavior, most of this can be ignored
+    // and it's sufficient to simply set the member variable for querying via
+    // IsAutoSleepDisabled().
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->auto_sleep_disabled = is_auto_sleep_disabled;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::IsAutoSleepDisabled(Out<bool> out_is_auto_sleep_disabled) {
+    LOG_DEBUG(Service_AM, "called.");
+
+    std::scoped_lock lk{m_applet->lock};
+    *out_is_auto_sleep_disabled = m_applet->auto_sleep_disabled;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetInputDetectionPolicy(InputDetectionPolicy input_detection_policy) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result ISelfController::GetAccumulatedSuspendedTickValue(
+    Out<u64> out_accumulated_suspended_tick_value) {
+    LOG_DEBUG(Service_AM, "called.");
+
+    // This command returns the total number of system ticks since ISelfController creation
+    // where the game was suspended. Since Yuzu doesn't implement game suspension, this command
+    // can just always return 0 ticks.
+    std::scoped_lock lk{m_applet->lock};
+    *out_accumulated_suspended_tick_value = m_applet->suspended_ticks;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::GetAccumulatedSuspendedTickChangedEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_DEBUG(Service_AM, "called.");
+
+    *out_event = m_applet->accumulated_suspended_tick_changed_event.GetHandle();
+    R_SUCCEED();
+}
+
+Result ISelfController::SetAlbumImageTakenNotificationEnabled(bool enabled) {
+    LOG_WARNING(Service_AM, "(STUBBED) called. enabled={}", enabled);
+
+    // This service call sets an internal flag whether a notification is shown when an image is
+    // captured. Currently we do not support capturing images via the capture button, so this can be
+    // stubbed for now.
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->album_image_taken_notification_enabled = enabled;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option) {
+    LOG_INFO(Service_AM, "called, report_option={}", album_report_option);
+
+    const auto screenshot_service =
+        system.ServiceManager().GetService<Service::Capture::IScreenShotApplicationService>(
+            "caps:su");
+
+    if (screenshot_service) {
+        screenshot_service->CaptureAndSaveScreenshot(album_report_option);
+    }
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetRecordVolumeMuted(bool muted) {
+    LOG_WARNING(Service_AM, "(STUBBED) called. muted={}", muted);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->record_volume_muted = muted;
+
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/self_controller.h b/src/core/hle/service/am/service/self_controller.h
new file mode 100644
index 000000000..01fa381a3
--- /dev/null
+++ b/src/core/hle/service/am/service/self_controller.h
@@ -0,0 +1,72 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/am/am_types.h"
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace Kernel {
+class KReadableEvent;
+}
+
+namespace Service::Capture {
+enum class AlbumImageOrientation;
+enum class AlbumReportOption;
+} // namespace Service::Capture
+
+namespace Service::AM {
+
+struct Applet;
+
+class ISelfController final : public ServiceFramework<ISelfController> {
+public:
+    explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet,
+                             Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger);
+    ~ISelfController() override;
+
+private:
+    Result Exit();
+    Result LockExit();
+    Result UnlockExit();
+    Result EnterFatalSection();
+    Result LeaveFatalSection();
+    Result GetLibraryAppletLaunchableEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result SetScreenShotPermission(ScreenshotPermission screen_shot_permission);
+    Result SetOperationModeChangedNotification(bool enabled);
+    Result SetPerformanceModeChangedNotification(bool enabled);
+    Result SetFocusHandlingMode(bool notify, bool background, bool suspend);
+    Result SetRestartMessageEnabled(bool enabled);
+    Result SetScreenShotAppletIdentityInfo(AppletIdentityInfo screen_shot_applet_identity_info);
+    Result SetOutOfFocusSuspendingEnabled(bool enabled);
+    Result SetAlbumImageOrientation(Capture::AlbumImageOrientation album_image_orientation);
+    Result IsSystemBufferSharingEnabled();
+    Result GetSystemSharedBufferHandle(Out<u64> out_buffer_id);
+    Result GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id);
+    Result CreateManagedDisplayLayer(Out<u64> out_layer_id);
+    Result CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id,
+                                              Out<u64> out_recording_layer_id);
+    Result SetHandlesRequestToDisplay(bool enable);
+    Result ApproveToDisplay();
+    Result SetMediaPlaybackState(bool state);
+    Result OverrideAutoSleepTimeAndDimmingTime(s32 a, s32 b, s32 c, s32 d);
+    Result SetIdleTimeDetectionExtension(IdleTimeDetectionExtension idle_time_detection_extension);
+    Result GetIdleTimeDetectionExtension(
+        Out<IdleTimeDetectionExtension> out_idle_time_detection_extension);
+    Result ReportUserIsActive();
+    Result SetAutoSleepDisabled(bool is_auto_sleep_disabled);
+    Result IsAutoSleepDisabled(Out<bool> out_is_auto_sleep_disabled);
+    Result SetInputDetectionPolicy(InputDetectionPolicy input_detection_policy);
+    Result GetAccumulatedSuspendedTickValue(Out<u64> out_accumulated_suspended_tick_value);
+    Result GetAccumulatedSuspendedTickChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result SetAlbumImageTakenNotificationEnabled(bool enabled);
+    Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option);
+    Result SetRecordVolumeMuted(bool muted);
+
+    Nvnflinger::Nvnflinger& m_nvnflinger;
+    Kernel::KProcess* const m_process;
+    const std::shared_ptr<Applet> m_applet;
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index 0f6175d32..da6e8dadd 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -2,7 +2,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/application_creator.h"
-#include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/common_state_getter.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/service/home_menu_functions.h"
 #include "core/hle/service/am/service/library_applet_creator.h"
 #include "core/hle/service/am/service/process_winding_controller.h"
+#include "core/hle/service/am/service/self_controller.h"
 #include "core/hle/service/am/service/system_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
@@ -83,7 +83,8 @@ Result ISystemAppletProxy::GetWindowController(
 Result ISystemAppletProxy::GetSelfController(
     Out<SharedPointer<ISelfController>> out_self_controller) {
     LOG_DEBUG(Service_AM, "called");
-    *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_nvnflinger);
+    *out_self_controller =
+        std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
     R_SUCCEED();
 }
 

From 2e614ce08f56f4c49d8070e69ecdb44e2cb9f1c1 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 20:28:51 -0500
Subject: [PATCH 18/24] am: rewrite IStorageAccessor, ITransferStorageAccessor

---
 src/core/CMakeLists.txt                       |  4 +-
 .../service/am/service/storage_accessor.cpp   | 68 ++++++++++++++
 .../am/{ => service}/storage_accessor.h       | 21 ++---
 src/core/hle/service/am/storage.cpp           |  2 +-
 src/core/hle/service/am/storage_accessor.cpp  | 90 -------------------
 5 files changed, 82 insertions(+), 103 deletions(-)
 create mode 100644 src/core/hle/service/am/service/storage_accessor.cpp
 rename src/core/hle/service/am/{ => service}/storage_accessor.h (54%)
 delete mode 100644 src/core/hle/service/am/storage_accessor.cpp

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 956207fcf..c2c08c2e9 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -475,14 +475,14 @@ add_library(core STATIC
     hle/service/am/service/process_winding_controller.h
     hle/service/am/service/self_controller.cpp
     hle/service/am/service/self_controller.h
+    hle/service/am/service/storage_accessor.cpp
+    hle/service/am/service/storage_accessor.h
     hle/service/am/service/system_applet_proxy.cpp
     hle/service/am/service/system_applet_proxy.h
     hle/service/am/system_buffer_manager.cpp
     hle/service/am/system_buffer_manager.h
     hle/service/am/spsm.cpp
     hle/service/am/spsm.h
-    hle/service/am/storage_accessor.cpp
-    hle/service/am/storage_accessor.h
     hle/service/am/storage.cpp
     hle/service/am/storage.h
     hle/service/am/window_controller.cpp
diff --git a/src/core/hle/service/am/service/storage_accessor.cpp b/src/core/hle/service/am/service/storage_accessor.cpp
new file mode 100644
index 000000000..84577fee4
--- /dev/null
+++ b/src/core/hle/service/am/service/storage_accessor.cpp
@@ -0,0 +1,68 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/kernel/k_transfer_memory.h"
+#include "core/hle/service/am/library_applet_storage.h"
+#include "core/hle/service/am/service/storage_accessor.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+IStorageAccessor::IStorageAccessor(Core::System& system_,
+                                   std::shared_ptr<LibraryAppletStorage> impl)
+    : ServiceFramework{system_, "IStorageAccessor"}, m_impl{std::move(impl)} {
+    static const FunctionInfo functions[] = {
+        {0, D<&IStorageAccessor::GetSize>, "GetSize"},
+        {10, D<&IStorageAccessor::Write>, "Write"},
+        {11, D<&IStorageAccessor::Read>, "Read"},
+    };
+
+    RegisterHandlers(functions);
+}
+
+IStorageAccessor::~IStorageAccessor() = default;
+
+Result IStorageAccessor::GetSize(Out<s64> out_size) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_size = m_impl->GetSize();
+    R_SUCCEED();
+}
+
+Result IStorageAccessor::Write(InBuffer<BufferAttr_HipcAutoSelect> buffer, s64 offset) {
+    LOG_DEBUG(Service_AM, "called, offset={} size={}", offset, buffer.size());
+    R_RETURN(m_impl->Write(offset, buffer.data(), buffer.size()));
+}
+
+Result IStorageAccessor::Read(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer, s64 offset) {
+    LOG_DEBUG(Service_AM, "called, offset={} size={}", offset, out_buffer.size());
+    R_RETURN(m_impl->Read(offset, out_buffer.data(), out_buffer.size()));
+}
+
+ITransferStorageAccessor::ITransferStorageAccessor(Core::System& system_,
+                                                   std::shared_ptr<LibraryAppletStorage> impl)
+    : ServiceFramework{system_, "ITransferStorageAccessor"}, m_impl{std::move(impl)} {
+    static const FunctionInfo functions[] = {
+        {0, D<&ITransferStorageAccessor::GetSize>, "GetSize"},
+        {1, D<&ITransferStorageAccessor::GetHandle>, "GetHandle"},
+    };
+
+    RegisterHandlers(functions);
+}
+
+ITransferStorageAccessor::~ITransferStorageAccessor() = default;
+
+Result ITransferStorageAccessor::GetSize(Out<s64> out_size) {
+    LOG_DEBUG(Service_AM, "called");
+    *out_size = m_impl->GetSize();
+    R_SUCCEED();
+}
+
+Result ITransferStorageAccessor::GetHandle(Out<s64> out_size,
+                                           OutCopyHandle<Kernel::KTransferMemory> out_handle) {
+    LOG_INFO(Service_AM, "called");
+    *out_size = m_impl->GetSize();
+    *out_handle = m_impl->GetHandle();
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/storage_accessor.h b/src/core/hle/service/am/service/storage_accessor.h
similarity index 54%
rename from src/core/hle/service/am/storage_accessor.h
rename to src/core/hle/service/am/service/storage_accessor.h
index b9aa85a66..1a01730e0 100644
--- a/src/core/hle/service/am/storage_accessor.h
+++ b/src/core/hle/service/am/service/storage_accessor.h
@@ -3,35 +3,36 @@
 
 #pragma once
 
-#include "core/hle/service/am/storage.h"
+#include "core/hle/service/am/library_applet_storage.h"
+#include "core/hle/service/cmif_types.h"
 #include "core/hle/service/service.h"
 
 namespace Service::AM {
 
 class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
 public:
-    explicit IStorageAccessor(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl_);
+    explicit IStorageAccessor(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl);
     ~IStorageAccessor() override;
 
 private:
-    void GetSize(HLERequestContext& ctx);
-    void Write(HLERequestContext& ctx);
-    void Read(HLERequestContext& ctx);
+    Result GetSize(Out<s64> out_size);
+    Result Write(InBuffer<BufferAttr_HipcAutoSelect> buffer, s64 offset);
+    Result Read(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer, s64 offset);
 
-    const std::shared_ptr<LibraryAppletStorage> impl;
+    const std::shared_ptr<LibraryAppletStorage> m_impl;
 };
 
 class ITransferStorageAccessor final : public ServiceFramework<ITransferStorageAccessor> {
 public:
     explicit ITransferStorageAccessor(Core::System& system_,
-                                      std::shared_ptr<LibraryAppletStorage> impl_);
+                                      std::shared_ptr<LibraryAppletStorage> impl);
     ~ITransferStorageAccessor() override;
 
 private:
-    void GetSize(HLERequestContext& ctx);
-    void GetHandle(HLERequestContext& ctx);
+    Result GetSize(Out<s64> out_size);
+    Result GetHandle(Out<s64> out_size, OutCopyHandle<Kernel::KTransferMemory> out_handle);
 
-    const std::shared_ptr<LibraryAppletStorage> impl;
+    const std::shared_ptr<LibraryAppletStorage> m_impl;
 };
 
 } // namespace Service::AM
diff --git a/src/core/hle/service/am/storage.cpp b/src/core/hle/service/am/storage.cpp
index 4e82afd1c..12d95eebd 100644
--- a/src/core/hle/service/am/storage.cpp
+++ b/src/core/hle/service/am/storage.cpp
@@ -3,8 +3,8 @@
 
 #include "core/hle/service/am/am_results.h"
 #include "core/hle/service/am/library_applet_storage.h"
+#include "core/hle/service/am/service/storage_accessor.h"
 #include "core/hle/service/am/storage.h"
-#include "core/hle/service/am/storage_accessor.h"
 #include "core/hle/service/ipc_helpers.h"
 
 namespace Service::AM {
diff --git a/src/core/hle/service/am/storage_accessor.cpp b/src/core/hle/service/am/storage_accessor.cpp
deleted file mode 100644
index a1184b065..000000000
--- a/src/core/hle/service/am/storage_accessor.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/kernel/k_transfer_memory.h"
-#include "core/hle/service/am/am_results.h"
-#include "core/hle/service/am/library_applet_storage.h"
-#include "core/hle/service/am/storage_accessor.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-IStorageAccessor::IStorageAccessor(Core::System& system_,
-                                   std::shared_ptr<LibraryAppletStorage> impl_)
-    : ServiceFramework{system_, "IStorageAccessor"}, impl{std::move(impl_)} {
-    static const FunctionInfo functions[] = {
-        {0, &IStorageAccessor::GetSize, "GetSize"},
-        {10, &IStorageAccessor::Write, "Write"},
-        {11, &IStorageAccessor::Read, "Read"},
-    };
-
-    RegisterHandlers(functions);
-}
-
-IStorageAccessor::~IStorageAccessor() = default;
-
-void IStorageAccessor::GetSize(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 4};
-
-    rb.Push(ResultSuccess);
-    rb.Push(impl->GetSize());
-}
-
-void IStorageAccessor::Write(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const s64 offset{rp.Pop<s64>()};
-    const auto data{ctx.ReadBuffer()};
-    LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, data.size());
-
-    const auto res{impl->Write(offset, data.data(), data.size())};
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(res);
-}
-
-void IStorageAccessor::Read(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const s64 offset{rp.Pop<s64>()};
-    std::vector<u8> data(ctx.GetWriteBufferSize());
-
-    LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, data.size());
-
-    const auto res{impl->Read(offset, data.data(), data.size())};
-
-    ctx.WriteBuffer(data);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(res);
-}
-
-ITransferStorageAccessor::ITransferStorageAccessor(Core::System& system_,
-                                                   std::shared_ptr<LibraryAppletStorage> impl_)
-    : ServiceFramework{system_, "ITransferStorageAccessor"}, impl{std::move(impl_)} {
-    static const FunctionInfo functions[] = {
-        {0, &ITransferStorageAccessor::GetSize, "GetSize"},
-        {1, &ITransferStorageAccessor::GetHandle, "GetHandle"},
-    };
-
-    RegisterHandlers(functions);
-}
-
-ITransferStorageAccessor::~ITransferStorageAccessor() = default;
-
-void ITransferStorageAccessor::GetSize(HLERequestContext& ctx) {
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.Push(impl->GetSize());
-}
-
-void ITransferStorageAccessor::GetHandle(HLERequestContext& ctx) {
-    IPC::ResponseBuilder rb{ctx, 4, 1};
-    rb.Push(ResultSuccess);
-    rb.Push(impl->GetSize());
-    rb.PushCopyObjects(impl->GetHandle());
-}
-
-} // namespace Service::AM

From 203d2135293ccc6addd8f93c885e1ea54f3239b6 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 20:34:27 -0500
Subject: [PATCH 19/24] am: rewrite IStorage

---
 src/core/CMakeLists.txt                       |  4 +-
 src/core/hle/service/am/applet.h              |  2 -
 src/core/hle/service/am/applet_manager.cpp    |  1 +
 .../service/am/frontend/applet_cabinet.cpp    |  2 +-
 .../service/am/frontend/applet_controller.cpp |  2 +-
 .../hle/service/am/frontend/applet_error.cpp  |  2 +-
 .../service/am/frontend/applet_general.cpp    |  2 +-
 .../service/am/frontend/applet_mii_edit.cpp   |  2 +-
 .../am/frontend/applet_profile_select.cpp     |  2 +-
 .../am/frontend/applet_software_keyboard.cpp  |  2 +-
 .../am/frontend/applet_web_browser.cpp        |  2 +-
 src/core/hle/service/am/frontend/applets.cpp  |  2 +-
 .../am/service/application_functions.cpp      |  2 +-
 .../am/service/library_applet_accessor.cpp    |  2 +-
 .../am/service/library_applet_creator.cpp     |  2 +-
 .../service/library_applet_self_accessor.cpp  |  2 +-
 src/core/hle/service/am/service/storage.cpp   | 48 +++++++++++++++
 .../hle/service/am/{ => service}/storage.h    | 14 +++--
 src/core/hle/service/am/storage.cpp           | 59 -------------------
 19 files changed, 73 insertions(+), 81 deletions(-)
 create mode 100644 src/core/hle/service/am/service/storage.cpp
 rename src/core/hle/service/am/{ => service}/storage.h (60%)
 delete mode 100644 src/core/hle/service/am/storage.cpp

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index c2c08c2e9..bd483816b 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -477,14 +477,14 @@ add_library(core STATIC
     hle/service/am/service/self_controller.h
     hle/service/am/service/storage_accessor.cpp
     hle/service/am/service/storage_accessor.h
+    hle/service/am/service/storage.cpp
+    hle/service/am/service/storage.h
     hle/service/am/service/system_applet_proxy.cpp
     hle/service/am/service/system_applet_proxy.h
     hle/service/am/system_buffer_manager.cpp
     hle/service/am/system_buffer_manager.h
     hle/service/am/spsm.cpp
     hle/service/am/spsm.h
-    hle/service/am/storage.cpp
-    hle/service/am/storage.h
     hle/service/am/window_controller.cpp
     hle/service/am/window_controller.h
     hle/service/aoc/aoc_u.cpp
diff --git a/src/core/hle/service/am/applet.h b/src/core/hle/service/am/applet.h
index 6c593ab1a..4f34d4811 100644
--- a/src/core/hle/service/am/applet.h
+++ b/src/core/hle/service/am/applet.h
@@ -3,7 +3,6 @@
 
 #pragma once
 
-#include <list>
 #include <mutex>
 
 #include "common/math_util.h"
@@ -18,7 +17,6 @@
 #include "core/hle/service/am/hid_registration.h"
 #include "core/hle/service/am/managed_layer_holder.h"
 #include "core/hle/service/am/process.h"
-#include "core/hle/service/am/storage.h"
 #include "core/hle/service/am/system_buffer_manager.h"
 
 namespace Service::AM {
diff --git a/src/core/hle/service/am/applet_manager.cpp b/src/core/hle/service/am/applet_manager.cpp
index b35d97bc7..4c7266f89 100644
--- a/src/core/hle/service/am/applet_manager.cpp
+++ b/src/core/hle/service/am/applet_manager.cpp
@@ -12,6 +12,7 @@
 #include "core/hle/service/am/frontend/applet_controller.h"
 #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 "hid_core/hid_types.h"
 
 namespace Service::AM {
diff --git a/src/core/hle/service/am/frontend/applet_cabinet.cpp b/src/core/hle/service/am/frontend/applet_cabinet.cpp
index 0862c81b6..4cbc80d63 100644
--- a/src/core/hle/service/am/frontend/applet_cabinet.cpp
+++ b/src/core/hle/service/am/frontend/applet_cabinet.cpp
@@ -9,7 +9,7 @@
 #include "core/hle/kernel/k_readable_event.h"
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/frontend/applet_cabinet.h"
-#include "core/hle/service/am/storage.h"
+#include "core/hle/service/am/service/storage.h"
 #include "core/hle/service/mii/mii_manager.h"
 #include "core/hle/service/nfc/common/device.h"
 #include "hid_core/hid_core.h"
diff --git a/src/core/hle/service/am/frontend/applet_controller.cpp b/src/core/hle/service/am/frontend/applet_controller.cpp
index bd3e49fc4..66f52686d 100644
--- a/src/core/hle/service/am/frontend/applet_controller.cpp
+++ b/src/core/hle/service/am/frontend/applet_controller.cpp
@@ -12,7 +12,7 @@
 #include "core/hle/result.h"
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/frontend/applet_controller.h"
-#include "core/hle/service/am/storage.h"
+#include "core/hle/service/am/service/storage.h"
 #include "hid_core/frontend/emulated_controller.h"
 #include "hid_core/hid_core.h"
 #include "hid_core/hid_types.h"
diff --git a/src/core/hle/service/am/frontend/applet_error.cpp b/src/core/hle/service/am/frontend/applet_error.cpp
index b97a5f3ea..34ec7013b 100644
--- a/src/core/hle/service/am/frontend/applet_error.cpp
+++ b/src/core/hle/service/am/frontend/applet_error.cpp
@@ -10,7 +10,7 @@
 #include "core/frontend/applets/error.h"
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/frontend/applet_error.h"
-#include "core/hle/service/am/storage.h"
+#include "core/hle/service/am/service/storage.h"
 #include "core/reporter.h"
 
 namespace Service::AM::Frontend {
diff --git a/src/core/hle/service/am/frontend/applet_general.cpp b/src/core/hle/service/am/frontend/applet_general.cpp
index 3c091a602..d2cabb7b5 100644
--- a/src/core/hle/service/am/frontend/applet_general.cpp
+++ b/src/core/hle/service/am/frontend/applet_general.cpp
@@ -10,7 +10,7 @@
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/applet_data_broker.h"
 #include "core/hle/service/am/frontend/applet_general.h"
-#include "core/hle/service/am/storage.h"
+#include "core/hle/service/am/service/storage.h"
 #include "core/reporter.h"
 
 namespace Service::AM::Frontend {
diff --git a/src/core/hle/service/am/frontend/applet_mii_edit.cpp b/src/core/hle/service/am/frontend/applet_mii_edit.cpp
index e3d19fb3d..0180ab761 100644
--- a/src/core/hle/service/am/frontend/applet_mii_edit.cpp
+++ b/src/core/hle/service/am/frontend/applet_mii_edit.cpp
@@ -7,7 +7,7 @@
 #include "core/frontend/applets/mii_edit.h"
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/frontend/applet_mii_edit.h"
-#include "core/hle/service/am/storage.h"
+#include "core/hle/service/am/service/storage.h"
 #include "core/hle/service/mii/mii.h"
 #include "core/hle/service/mii/mii_manager.h"
 #include "core/hle/service/sm/sm.h"
diff --git a/src/core/hle/service/am/frontend/applet_profile_select.cpp b/src/core/hle/service/am/frontend/applet_profile_select.cpp
index efb4053b8..89b5a1eab 100644
--- a/src/core/hle/service/am/frontend/applet_profile_select.cpp
+++ b/src/core/hle/service/am/frontend/applet_profile_select.cpp
@@ -10,7 +10,7 @@
 #include "core/hle/service/acc/errors.h"
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/frontend/applet_profile_select.h"
-#include "core/hle/service/am/storage.h"
+#include "core/hle/service/am/service/storage.h"
 
 namespace Service::AM::Frontend {
 
diff --git a/src/core/hle/service/am/frontend/applet_software_keyboard.cpp b/src/core/hle/service/am/frontend/applet_software_keyboard.cpp
index 034c62f32..d1bc03018 100644
--- a/src/core/hle/service/am/frontend/applet_software_keyboard.cpp
+++ b/src/core/hle/service/am/frontend/applet_software_keyboard.cpp
@@ -6,7 +6,7 @@
 #include "core/frontend/applets/software_keyboard.h"
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/frontend/applet_software_keyboard.h"
-#include "core/hle/service/am/storage.h"
+#include "core/hle/service/am/service/storage.h"
 
 namespace Service::AM::Frontend {
 
diff --git a/src/core/hle/service/am/frontend/applet_web_browser.cpp b/src/core/hle/service/am/frontend/applet_web_browser.cpp
index 6ee4caf34..bb60260b4 100644
--- a/src/core/hle/service/am/frontend/applet_web_browser.cpp
+++ b/src/core/hle/service/am/frontend/applet_web_browser.cpp
@@ -20,7 +20,7 @@
 #include "core/hle/result.h"
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/frontend/applet_web_browser.h"
-#include "core/hle/service/am/storage.h"
+#include "core/hle/service/am/service/storage.h"
 #include "core/hle/service/filesystem/filesystem.h"
 #include "core/hle/service/ns/iplatform_service_manager.h"
 #include "core/loader/loader.h"
diff --git a/src/core/hle/service/am/frontend/applets.cpp b/src/core/hle/service/am/frontend/applets.cpp
index 944d8b105..e662c6cd6 100644
--- a/src/core/hle/service/am/frontend/applets.cpp
+++ b/src/core/hle/service/am/frontend/applets.cpp
@@ -26,7 +26,7 @@
 #include "core/hle/service/am/frontend/applet_software_keyboard.h"
 #include "core/hle/service/am/frontend/applet_web_browser.h"
 #include "core/hle/service/am/frontend/applets.h"
-#include "core/hle/service/am/storage.h"
+#include "core/hle/service/am/service/storage.h"
 #include "core/hle/service/sm/sm.h"
 
 namespace Service::AM::Frontend {
diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp
index 346ab42ab..b788fddd4 100644
--- a/src/core/hle/service/am/service/application_functions.cpp
+++ b/src/core/hle/service/am/service/application_functions.cpp
@@ -11,7 +11,7 @@
 #include "core/hle/service/am/am_results.h"
 #include "core/hle/service/am/applet.h"
 #include "core/hle/service/am/service/application_functions.h"
-#include "core/hle/service/am/storage.h"
+#include "core/hle/service/am/service/storage.h"
 #include "core/hle/service/cmif_serialization.h"
 #include "core/hle/service/filesystem/filesystem.h"
 #include "core/hle/service/filesystem/save_data_controller.h"
diff --git a/src/core/hle/service/am/service/library_applet_accessor.cpp b/src/core/hle/service/am/service/library_applet_accessor.cpp
index aac875ef4..0c2426d4b 100644
--- a/src/core/hle/service/am/service/library_applet_accessor.cpp
+++ b/src/core/hle/service/am/service/library_applet_accessor.cpp
@@ -5,7 +5,7 @@
 #include "core/hle/service/am/applet_manager.h"
 #include "core/hle/service/am/frontend/applets.h"
 #include "core/hle/service/am/service/library_applet_accessor.h"
-#include "core/hle/service/am/storage.h"
+#include "core/hle/service/am/service/storage.h"
 #include "core/hle/service/cmif_serialization.h"
 
 namespace Service::AM {
diff --git a/src/core/hle/service/am/service/library_applet_creator.cpp b/src/core/hle/service/am/service/library_applet_creator.cpp
index 4d905549c..166637d60 100644
--- a/src/core/hle/service/am/service/library_applet_creator.cpp
+++ b/src/core/hle/service/am/service/library_applet_creator.cpp
@@ -9,7 +9,7 @@
 #include "core/hle/service/am/library_applet_storage.h"
 #include "core/hle/service/am/service/library_applet_accessor.h"
 #include "core/hle/service/am/service/library_applet_creator.h"
-#include "core/hle/service/am/storage.h"
+#include "core/hle/service/am/service/storage.h"
 #include "core/hle/service/cmif_serialization.h"
 #include "core/hle/service/sm/sm.h"
 
diff --git a/src/core/hle/service/am/service/library_applet_self_accessor.cpp b/src/core/hle/service/am/service/library_applet_self_accessor.cpp
index a432a79ba..7a3a86e88 100644
--- a/src/core/hle/service/am/service/library_applet_self_accessor.cpp
+++ b/src/core/hle/service/am/service/library_applet_self_accessor.cpp
@@ -10,7 +10,7 @@
 #include "core/hle/service/am/applet_manager.h"
 #include "core/hle/service/am/frontend/applets.h"
 #include "core/hle/service/am/service/library_applet_self_accessor.h"
-#include "core/hle/service/am/storage.h"
+#include "core/hle/service/am/service/storage.h"
 #include "core/hle/service/cmif_serialization.h"
 #include "core/hle/service/filesystem/filesystem.h"
 #include "core/hle/service/glue/glue_manager.h"
diff --git a/src/core/hle/service/am/service/storage.cpp b/src/core/hle/service/am/service/storage.cpp
new file mode 100644
index 000000000..25ee0afbd
--- /dev/null
+++ b/src/core/hle/service/am/service/storage.cpp
@@ -0,0 +1,48 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/am/am_results.h"
+#include "core/hle/service/am/library_applet_storage.h"
+#include "core/hle/service/am/service/storage.h"
+#include "core/hle/service/am/service/storage_accessor.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+IStorage::IStorage(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl)
+    : ServiceFramework{system_, "IStorage"}, m_impl{std::move(impl)} {
+    static const FunctionInfo functions[] = {
+        {0, D<&IStorage::Open>, "Open"},
+        {1, D<&IStorage::OpenTransferStorage>, "OpenTransferStorage"},
+    };
+
+    RegisterHandlers(functions);
+}
+
+IStorage::IStorage(Core::System& system_, std::vector<u8>&& data)
+    : IStorage(system_, CreateStorage(std::move(data))) {}
+
+IStorage::~IStorage() = default;
+
+Result IStorage::Open(Out<SharedPointer<IStorageAccessor>> out_storage_accessor) {
+    LOG_DEBUG(Service_AM, "called");
+
+    R_UNLESS(m_impl->GetHandle() == nullptr, AM::ResultInvalidStorageType);
+
+    *out_storage_accessor = std::make_shared<IStorageAccessor>(system, m_impl);
+    R_SUCCEED();
+}
+
+Result IStorage::OpenTransferStorage(
+    Out<SharedPointer<ITransferStorageAccessor>> out_transfer_storage_accessor) {
+    R_UNLESS(m_impl->GetHandle() != nullptr, AM::ResultInvalidStorageType);
+
+    *out_transfer_storage_accessor = std::make_shared<ITransferStorageAccessor>(system, m_impl);
+    R_SUCCEED();
+}
+
+std::vector<u8> IStorage::GetData() const {
+    return m_impl->GetData();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/storage.h b/src/core/hle/service/am/service/storage.h
similarity index 60%
rename from src/core/hle/service/am/storage.h
rename to src/core/hle/service/am/service/storage.h
index 10d00b141..cde2ed0ea 100644
--- a/src/core/hle/service/am/storage.h
+++ b/src/core/hle/service/am/service/storage.h
@@ -3,29 +3,33 @@
 
 #pragma once
 
+#include "core/hle/service/cmif_types.h"
 #include "core/hle/service/service.h"
 
 namespace Service::AM {
 
 class LibraryAppletStorage;
+class IStorageAccessor;
+class ITransferStorageAccessor;
 
 class IStorage final : public ServiceFramework<IStorage> {
 public:
-    explicit IStorage(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl_);
+    explicit IStorage(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl);
     explicit IStorage(Core::System& system_, std::vector<u8>&& buffer);
     ~IStorage() override;
 
     std::shared_ptr<LibraryAppletStorage> GetImpl() const {
-        return impl;
+        return m_impl;
     }
 
     std::vector<u8> GetData() const;
 
 private:
-    void Open(HLERequestContext& ctx);
-    void OpenTransferStorage(HLERequestContext& ctx);
+    Result Open(Out<SharedPointer<IStorageAccessor>> out_storage_accessor);
+    Result OpenTransferStorage(
+        Out<SharedPointer<ITransferStorageAccessor>> out_transfer_storage_accessor);
 
-    const std::shared_ptr<LibraryAppletStorage> impl;
+    const std::shared_ptr<LibraryAppletStorage> m_impl;
 };
 
 } // namespace Service::AM
diff --git a/src/core/hle/service/am/storage.cpp b/src/core/hle/service/am/storage.cpp
deleted file mode 100644
index 12d95eebd..000000000
--- a/src/core/hle/service/am/storage.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/am/am_results.h"
-#include "core/hle/service/am/library_applet_storage.h"
-#include "core/hle/service/am/service/storage_accessor.h"
-#include "core/hle/service/am/storage.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-IStorage::IStorage(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl_)
-    : ServiceFramework{system_, "IStorage"}, impl{std::move(impl_)} {
-    static const FunctionInfo functions[] = {
-        {0, &IStorage::Open, "Open"},
-        {1, &IStorage::OpenTransferStorage, "OpenTransferStorage"},
-    };
-
-    RegisterHandlers(functions);
-}
-
-IStorage::IStorage(Core::System& system_, std::vector<u8>&& data)
-    : IStorage(system_, CreateStorage(std::move(data))) {}
-
-IStorage::~IStorage() = default;
-
-void IStorage::Open(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    if (impl->GetHandle() != nullptr) {
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(AM::ResultInvalidStorageType);
-        return;
-    }
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IStorageAccessor>(system, impl);
-}
-
-void IStorage::OpenTransferStorage(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    if (impl->GetHandle() == nullptr) {
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(AM::ResultInvalidStorageType);
-        return;
-    }
-
-    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
-    rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ITransferStorageAccessor>(system, impl);
-}
-
-std::vector<u8> IStorage::GetData() const {
-    return impl->GetData();
-}
-
-} // namespace Service::AM

From 87b740df46935a672a6bf5d43c944a2516cc72f9 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 20:38:42 -0500
Subject: [PATCH 20/24] am: rewrite IWindowController

---
 src/core/CMakeLists.txt                       |  4 +-
 .../service/am/service/application_proxy.cpp  |  2 +-
 .../am/service/library_applet_proxy.cpp       |  2 +-
 .../am/service/system_applet_proxy.cpp        |  2 +-
 .../service/am/service/window_controller.cpp  | 86 +++++++++++++++++++
 .../service/am/service/window_controller.h    | 30 +++++++
 src/core/hle/service/am/window_controller.cpp | 86 -------------------
 src/core/hle/service/am/window_controller.h   | 27 ------
 8 files changed, 121 insertions(+), 118 deletions(-)
 create mode 100644 src/core/hle/service/am/service/window_controller.cpp
 create mode 100644 src/core/hle/service/am/service/window_controller.h
 delete mode 100644 src/core/hle/service/am/window_controller.cpp
 delete mode 100644 src/core/hle/service/am/window_controller.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index bd483816b..f8e093be7 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -481,12 +481,12 @@ add_library(core STATIC
     hle/service/am/service/storage.h
     hle/service/am/service/system_applet_proxy.cpp
     hle/service/am/service/system_applet_proxy.h
+    hle/service/am/service/window_controller.cpp
+    hle/service/am/service/window_controller.h
     hle/service/am/system_buffer_manager.cpp
     hle/service/am/system_buffer_manager.h
     hle/service/am/spsm.cpp
     hle/service/am/spsm.h
-    hle/service/am/window_controller.cpp
-    hle/service/am/window_controller.h
     hle/service/aoc/aoc_u.cpp
     hle/service/aoc/aoc_u.h
     hle/service/apm/apm.cpp
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index 9bba985be..776f4552b 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -11,7 +11,7 @@
 #include "core/hle/service/am/service/library_applet_creator.h"
 #include "core/hle/service/am/service/process_winding_controller.h"
 #include "core/hle/service/am/service/self_controller.h"
-#include "core/hle/service/am/window_controller.h"
+#include "core/hle/service/am/service/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
 namespace Service::AM {
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index bac3e0168..bcb44a71c 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -13,7 +13,7 @@
 #include "core/hle/service/am/service/library_applet_self_accessor.h"
 #include "core/hle/service/am/service/process_winding_controller.h"
 #include "core/hle/service/am/service/self_controller.h"
-#include "core/hle/service/am/window_controller.h"
+#include "core/hle/service/am/service/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
 namespace Service::AM {
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index da6e8dadd..a3e801799 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -13,7 +13,7 @@
 #include "core/hle/service/am/service/process_winding_controller.h"
 #include "core/hle/service/am/service/self_controller.h"
 #include "core/hle/service/am/service/system_applet_proxy.h"
-#include "core/hle/service/am/window_controller.h"
+#include "core/hle/service/am/service/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
 namespace Service::AM {
diff --git a/src/core/hle/service/am/service/window_controller.cpp b/src/core/hle/service/am/service/window_controller.cpp
new file mode 100644
index 000000000..b874ecb91
--- /dev/null
+++ b/src/core/hle/service/am/service/window_controller.cpp
@@ -0,0 +1,86 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/am/applet.h"
+#include "core/hle/service/am/applet_manager.h"
+#include "core/hle/service/am/service/window_controller.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+IWindowController::IWindowController(Core::System& system_, std::shared_ptr<Applet> applet)
+    : ServiceFramework{system_, "IWindowController"}, m_applet{std::move(applet)} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, nullptr, "CreateWindow"},
+        {1,  D<&IWindowController::GetAppletResourceUserId>, "GetAppletResourceUserId"},
+        {2,  D<&IWindowController::GetAppletResourceUserIdOfCallerApplet>, "GetAppletResourceUserIdOfCallerApplet"},
+        {10, D<&IWindowController::AcquireForegroundRights>, "AcquireForegroundRights"},
+        {11, D<&IWindowController::ReleaseForegroundRights>, "ReleaseForegroundRights"},
+        {12, D<&IWindowController::RejectToChangeIntoBackground>, "RejectToChangeIntoBackground"},
+        {20, D<&IWindowController::SetAppletWindowVisibility>, "SetAppletWindowVisibility"},
+        {21, D<&IWindowController::SetAppletGpuTimeSlice>, "SetAppletGpuTimeSlice"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IWindowController::~IWindowController() = default;
+
+Result IWindowController::GetAppletResourceUserId(Out<AppletResourceUserId> out_aruid) {
+    LOG_INFO(Service_AM, "called");
+    *out_aruid = m_applet->aruid;
+    R_SUCCEED();
+}
+
+Result IWindowController::GetAppletResourceUserIdOfCallerApplet(
+    Out<AppletResourceUserId> out_aruid) {
+    LOG_INFO(Service_AM, "called");
+
+    if (auto caller_applet = m_applet->caller_applet.lock(); caller_applet != nullptr) {
+        *out_aruid = caller_applet->aruid;
+    } else {
+        *out_aruid = AppletResourceUserId{};
+    }
+
+    R_SUCCEED();
+}
+
+Result IWindowController::AcquireForegroundRights() {
+    LOG_INFO(Service_AM, "called");
+    R_SUCCEED();
+}
+
+Result IWindowController::ReleaseForegroundRights() {
+    LOG_INFO(Service_AM, "called");
+    R_SUCCEED();
+}
+
+Result IWindowController::RejectToChangeIntoBackground() {
+    LOG_INFO(Service_AM, "called");
+    R_SUCCEED();
+}
+
+Result IWindowController::SetAppletWindowVisibility(bool visible) {
+    m_applet->system_buffer_manager.SetWindowVisibility(visible);
+    m_applet->hid_registration.EnableAppletToGetInput(visible);
+
+    if (visible) {
+        m_applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground);
+        m_applet->focus_state = FocusState::InFocus;
+    } else {
+        m_applet->focus_state = FocusState::NotInFocus;
+    }
+
+    m_applet->message_queue.PushMessage(AppletMessage::FocusStateChanged);
+
+    R_SUCCEED();
+}
+
+Result IWindowController::SetAppletGpuTimeSlice(s64 time_slice) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, time_slice={}", time_slice);
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/window_controller.h b/src/core/hle/service/am/service/window_controller.h
new file mode 100644
index 000000000..bfbad9bcc
--- /dev/null
+++ b/src/core/hle/service/am/service/window_controller.h
@@ -0,0 +1,30 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+struct Applet;
+
+class IWindowController final : public ServiceFramework<IWindowController> {
+public:
+    explicit IWindowController(Core::System& system_, std::shared_ptr<Applet> applet);
+    ~IWindowController() override;
+
+private:
+    Result GetAppletResourceUserId(Out<AppletResourceUserId> out_aruid);
+    Result GetAppletResourceUserIdOfCallerApplet(Out<AppletResourceUserId> out_aruid);
+    Result AcquireForegroundRights();
+    Result ReleaseForegroundRights();
+    Result RejectToChangeIntoBackground();
+    Result SetAppletWindowVisibility(bool visible);
+    Result SetAppletGpuTimeSlice(s64 time_slice);
+
+    const std::shared_ptr<Applet> m_applet;
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/window_controller.cpp b/src/core/hle/service/am/window_controller.cpp
deleted file mode 100644
index 7347fe9d9..000000000
--- a/src/core/hle/service/am/window_controller.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/am/applet.h"
-#include "core/hle/service/am/window_controller.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-IWindowController::IWindowController(Core::System& system_, std::shared_ptr<Applet> applet_)
-    : ServiceFramework{system_, "IWindowController"}, applet{std::move(applet_)} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {0, nullptr, "CreateWindow"},
-        {1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
-        {2, &IWindowController::GetAppletResourceUserIdOfCallerApplet, "GetAppletResourceUserIdOfCallerApplet"},
-        {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
-        {11, nullptr, "ReleaseForegroundRights"},
-        {12, nullptr, "RejectToChangeIntoBackground"},
-        {20, &IWindowController::SetAppletWindowVisibility, "SetAppletWindowVisibility"},
-        {21, &IWindowController::SetAppletGpuTimeSlice, "SetAppletGpuTimeSlice"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-IWindowController::~IWindowController() = default;
-
-void IWindowController::GetAppletResourceUserId(HLERequestContext& ctx) {
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.Push<u64>(applet->aruid);
-}
-
-void IWindowController::GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx) {
-    u64 aruid = 0;
-    if (auto caller = applet->caller_applet.lock(); caller) {
-        aruid = caller->aruid;
-    }
-
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.Push<u64>(aruid);
-}
-
-void IWindowController::AcquireForegroundRights(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IWindowController::SetAppletWindowVisibility(HLERequestContext& ctx) {
-    LOG_INFO(Service_AM, "called");
-
-    IPC::RequestParser rp{ctx};
-    const bool visible = rp.Pop<bool>();
-
-    applet->system_buffer_manager.SetWindowVisibility(visible);
-    applet->hid_registration.EnableAppletToGetInput(visible);
-
-    if (visible) {
-        applet->focus_state = FocusState::InFocus;
-        applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground);
-    } else {
-        applet->focus_state = FocusState::NotInFocus;
-        applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground);
-    }
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void IWindowController::SetAppletGpuTimeSlice(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto time_slice = rp.Pop<s64>();
-
-    LOG_WARNING(Service_AM, "(STUBBED) called, time_slice={}", time_slice);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/window_controller.h b/src/core/hle/service/am/window_controller.h
deleted file mode 100644
index a28219abe..000000000
--- a/src/core/hle/service/am/window_controller.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-struct Applet;
-
-class IWindowController final : public ServiceFramework<IWindowController> {
-public:
-    explicit IWindowController(Core::System& system_, std::shared_ptr<Applet> applet_);
-    ~IWindowController() override;
-
-private:
-    void GetAppletResourceUserId(HLERequestContext& ctx);
-    void GetAppletResourceUserIdOfCallerApplet(HLERequestContext& ctx);
-    void AcquireForegroundRights(HLERequestContext& ctx);
-    void SetAppletWindowVisibility(HLERequestContext& ctx);
-    void SetAppletGpuTimeSlice(HLERequestContext& ctx);
-
-    const std::shared_ptr<Applet> applet;
-};
-
-} // namespace Service::AM

From 927fa532e5459502a10767f58a7d2f48338e7963 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 20:41:48 -0500
Subject: [PATCH 21/24] am: rewrite ILockAccessor

---
 src/core/CMakeLists.txt                       |  4 +-
 src/core/hle/service/am/lock_accessor.cpp     | 71 ------------------
 src/core/hle/service/am/lock_accessor.h       | 28 -------
 .../am/service/common_state_getter.cpp        |  2 +-
 .../hle/service/am/service/lock_accessor.cpp  | 75 +++++++++++++++++++
 .../hle/service/am/service/lock_accessor.h    | 32 ++++++++
 6 files changed, 110 insertions(+), 102 deletions(-)
 delete mode 100644 src/core/hle/service/am/lock_accessor.cpp
 delete mode 100644 src/core/hle/service/am/lock_accessor.h
 create mode 100644 src/core/hle/service/am/service/lock_accessor.cpp
 create mode 100644 src/core/hle/service/am/service/lock_accessor.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index f8e093be7..073e42e00 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -431,8 +431,6 @@ add_library(core STATIC
     hle/service/am/idle.h
     hle/service/am/library_applet_storage.cpp
     hle/service/am/library_applet_storage.h
-    hle/service/am/lock_accessor.cpp
-    hle/service/am/lock_accessor.h
     hle/service/am/managed_layer_holder.cpp
     hle/service/am/managed_layer_holder.h
     hle/service/am/omm.cpp
@@ -471,6 +469,8 @@ add_library(core STATIC
     hle/service/am/service/library_applet_proxy.h
     hle/service/am/service/library_applet_self_accessor.cpp
     hle/service/am/service/library_applet_self_accessor.h
+    hle/service/am/service/lock_accessor.cpp
+    hle/service/am/service/lock_accessor.h
     hle/service/am/service/process_winding_controller.cpp
     hle/service/am/service/process_winding_controller.h
     hle/service/am/service/self_controller.cpp
diff --git a/src/core/hle/service/am/lock_accessor.cpp b/src/core/hle/service/am/lock_accessor.cpp
deleted file mode 100644
index d0bd8d95e..000000000
--- a/src/core/hle/service/am/lock_accessor.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/am/lock_accessor.h"
-#include "core/hle/service/ipc_helpers.h"
-
-namespace Service::AM {
-
-ILockAccessor::ILockAccessor(Core::System& system_)
-    : ServiceFramework{system_, "ILockAccessor"}, service_context{system_, "ILockAccessor"} {
-    // clang-format off
-        static const FunctionInfo functions[] = {
-            {1, &ILockAccessor::TryLock, "TryLock"},
-            {2, &ILockAccessor::Unlock, "Unlock"},
-            {3, &ILockAccessor::GetEvent, "GetEvent"},
-            {4,&ILockAccessor::IsLocked, "IsLocked"},
-        };
-    // clang-format on
-
-    RegisterHandlers(functions);
-
-    lock_event = service_context.CreateEvent("ILockAccessor::LockEvent");
-}
-
-ILockAccessor::~ILockAccessor() {
-    service_context.CloseEvent(lock_event);
-};
-
-void ILockAccessor::TryLock(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto return_handle = rp.Pop<bool>();
-
-    LOG_WARNING(Service_AM, "(STUBBED) called, return_handle={}", return_handle);
-
-    // TODO: When return_handle is true this function should return the lock handle
-
-    is_locked = true;
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push<u8>(is_locked);
-}
-
-void ILockAccessor::Unlock(HLERequestContext& ctx) {
-    LOG_INFO(Service_AM, "called");
-
-    is_locked = false;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ILockAccessor::GetEvent(HLERequestContext& ctx) {
-    LOG_INFO(Service_AM, "called");
-
-    lock_event->Signal();
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(lock_event->GetReadableEvent());
-}
-
-void ILockAccessor::IsLocked(HLERequestContext& ctx) {
-    LOG_INFO(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-    rb.Push<u8>(is_locked);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/lock_accessor.h b/src/core/hle/service/am/lock_accessor.h
deleted file mode 100644
index 626f60e07..000000000
--- a/src/core/hle/service/am/lock_accessor.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/kernel_helpers.h"
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-class ILockAccessor final : public ServiceFramework<ILockAccessor> {
-public:
-    explicit ILockAccessor(Core::System& system_);
-    ~ILockAccessor() override;
-
-private:
-    void TryLock(HLERequestContext& ctx);
-    void Unlock(HLERequestContext& ctx);
-    void GetEvent(HLERequestContext& ctx);
-    void IsLocked(HLERequestContext& ctx);
-
-    bool is_locked{};
-
-    Kernel::KEvent* lock_event;
-    KernelHelpers::ServiceContext service_context;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/common_state_getter.cpp b/src/core/hle/service/am/service/common_state_getter.cpp
index ac05b457b..12d7e8cb1 100644
--- a/src/core/hle/service/am/service/common_state_getter.cpp
+++ b/src/core/hle/service/am/service/common_state_getter.cpp
@@ -4,8 +4,8 @@
 #include "common/settings.h"
 #include "core/hle/service/am/am_results.h"
 #include "core/hle/service/am/applet.h"
-#include "core/hle/service/am/lock_accessor.h"
 #include "core/hle/service/am/service/common_state_getter.h"
+#include "core/hle/service/am/service/lock_accessor.h"
 #include "core/hle/service/apm/apm_interface.h"
 #include "core/hle/service/cmif_serialization.h"
 #include "core/hle/service/pm/pm.h"
diff --git a/src/core/hle/service/am/service/lock_accessor.cpp b/src/core/hle/service/am/service/lock_accessor.cpp
new file mode 100644
index 000000000..8e556fdd6
--- /dev/null
+++ b/src/core/hle/service/am/service/lock_accessor.cpp
@@ -0,0 +1,75 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/am/service/lock_accessor.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+ILockAccessor::ILockAccessor(Core::System& system_)
+    : ServiceFramework{system_, "ILockAccessor"}, m_context{system_, "ILockAccessor"},
+      m_event{m_context} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {1, D<&ILockAccessor::TryLock>, "TryLock"},
+        {2, D<&ILockAccessor::Unlock>, "Unlock"},
+        {3, D<&ILockAccessor::GetEvent>, "GetEvent"},
+        {4, D<&ILockAccessor::IsLocked>, "IsLocked"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+
+    m_event.Signal();
+}
+
+ILockAccessor::~ILockAccessor() = default;
+
+Result ILockAccessor::TryLock(Out<bool> out_is_locked,
+                              OutCopyHandle<Kernel::KReadableEvent> out_handle,
+                              bool return_handle) {
+    LOG_INFO(Service_AM, "called, return_handle={}", return_handle);
+
+    {
+        std::scoped_lock lk{m_mutex};
+        if (m_is_locked) {
+            *out_is_locked = false;
+        } else {
+            m_is_locked = true;
+            *out_is_locked = true;
+        }
+    }
+
+    if (return_handle) {
+        *out_handle = m_event.GetHandle();
+    }
+
+    R_SUCCEED();
+}
+
+Result ILockAccessor::Unlock() {
+    LOG_INFO(Service_AM, "called");
+
+    {
+        std::scoped_lock lk{m_mutex};
+        m_is_locked = false;
+    }
+
+    m_event.Signal();
+    R_SUCCEED();
+}
+
+Result ILockAccessor::GetEvent(OutCopyHandle<Kernel::KReadableEvent> out_handle) {
+    LOG_INFO(Service_AM, "called");
+    *out_handle = m_event.GetHandle();
+    R_SUCCEED();
+}
+
+Result ILockAccessor::IsLocked(Out<bool> out_is_locked) {
+    LOG_INFO(Service_AM, "called");
+    std::scoped_lock lk{m_mutex};
+    *out_is_locked = m_is_locked;
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/lock_accessor.h b/src/core/hle/service/am/service/lock_accessor.h
new file mode 100644
index 000000000..9bfb5c050
--- /dev/null
+++ b/src/core/hle/service/am/service/lock_accessor.h
@@ -0,0 +1,32 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/kernel_helpers.h"
+#include "core/hle/service/os/event.h"
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+class ILockAccessor final : public ServiceFramework<ILockAccessor> {
+public:
+    explicit ILockAccessor(Core::System& system_);
+    ~ILockAccessor() override;
+
+private:
+    Result TryLock(Out<bool> out_is_locked, OutCopyHandle<Kernel::KReadableEvent> out_handle,
+                   bool return_handle);
+    Result Unlock();
+    Result GetEvent(OutCopyHandle<Kernel::KReadableEvent> out_handle);
+    Result IsLocked(Out<bool> out_is_locked);
+
+private:
+    KernelHelpers::ServiceContext m_context;
+    Event m_event;
+    std::mutex m_mutex{};
+    bool m_is_locked{};
+};
+
+} // namespace Service::AM

From bbb1ff6574b2e4e13b3aec68c20e62c622845859 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 20:45:40 -0500
Subject: [PATCH 22/24] am: add IApplicationAccessor

---
 src/core/CMakeLists.txt                       |   2 +
 .../am/service/application_accessor.cpp       | 138 ++++++++++++++++++
 .../service/am/service/application_accessor.h |  40 +++++
 3 files changed, 180 insertions(+)
 create mode 100644 src/core/hle/service/am/service/application_accessor.cpp
 create mode 100644 src/core/hle/service/am/service/application_accessor.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 073e42e00..db27e0f3e 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -441,6 +441,8 @@ add_library(core STATIC
     hle/service/am/service/all_system_applet_proxies_service.h
     hle/service/am/service/applet_common_functions.cpp
     hle/service/am/service/applet_common_functions.h
+    hle/service/am/service/application_accessor.cpp
+    hle/service/am/service/application_accessor.h
     hle/service/am/service/application_functions.cpp
     hle/service/am/service/application_functions.h
     hle/service/am/service/application_proxy_service.cpp
diff --git a/src/core/hle/service/am/service/application_accessor.cpp b/src/core/hle/service/am/service/application_accessor.cpp
new file mode 100644
index 000000000..6e7d110e8
--- /dev/null
+++ b/src/core/hle/service/am/service/application_accessor.cpp
@@ -0,0 +1,138 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/result.h"
+#include "core/hle/service/am/am_types.h"
+#include "core/hle/service/am/applet.h"
+#include "core/hle/service/am/applet_data_broker.h"
+#include "core/hle/service/am/applet_manager.h"
+#include "core/hle/service/am/service/application_accessor.h"
+#include "core/hle/service/am/service/library_applet_accessor.h"
+#include "core/hle/service/am/service/storage.h"
+#include "core/hle/service/cmif_serialization.h"
+
+namespace Service::AM {
+
+IApplicationAccessor::IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet)
+    : ServiceFramework{system_, "IApplicationAccessor"}, m_applet(std::move(applet)) {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, D<&IApplicationAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"},
+        {1, nullptr, "IsCompleted"},
+        {10, D<&IApplicationAccessor::Start>, "Start"},
+        {20, D<&IApplicationAccessor::RequestExit>, "RequestExit"},
+        {25, D<&IApplicationAccessor::Terminate>, "Terminate"},
+        {30, D<&IApplicationAccessor::GetResult>, "GetResult"},
+        {101, D<&IApplicationAccessor::RequestForApplicationToGetForeground>, "RequestForApplicationToGetForeground"},
+        {110, nullptr, "TerminateAllLibraryApplets"},
+        {111, nullptr, "AreAnyLibraryAppletsLeft"},
+        {112, D<&IApplicationAccessor::GetCurrentLibraryApplet>, "GetCurrentLibraryApplet"},
+        {120, nullptr, "GetApplicationId"},
+        {121, D<&IApplicationAccessor::PushLaunchParameter>, "PushLaunchParameter"},
+        {122, D<&IApplicationAccessor::GetApplicationControlProperty>, "GetApplicationControlProperty"},
+        {123, nullptr, "GetApplicationLaunchProperty"},
+        {124, nullptr, "GetApplicationLaunchRequestInfo"},
+        {130, D<&IApplicationAccessor::SetUsers>, "SetUsers"},
+        {131, D<&IApplicationAccessor::CheckRightsEnvironmentAvailable>, "CheckRightsEnvironmentAvailable"},
+        {132, D<&IApplicationAccessor::GetNsRightsEnvironmentHandle>, "GetNsRightsEnvironmentHandle"},
+        {140, nullptr, "GetDesirableUids"},
+        {150, D<&IApplicationAccessor::ReportApplicationExitTimeout>, "ReportApplicationExitTimeout"},
+        {160, nullptr, "SetApplicationAttribute"},
+        {170, nullptr, "HasSaveDataAccessPermission"},
+        {180, nullptr, "PushToFriendInvitationStorageChannel"},
+        {190, nullptr, "PushToNotificationStorageChannel"},
+        {200, nullptr, "RequestApplicationSoftReset"},
+        {201, nullptr, "RestartApplicationTimer"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IApplicationAccessor::~IApplicationAccessor() = default;
+
+Result IApplicationAccessor::Start() {
+    LOG_INFO(Service_AM, "called");
+    m_applet->process->Run();
+    R_SUCCEED();
+}
+
+Result IApplicationAccessor::RequestExit() {
+    LOG_INFO(Service_AM, "called");
+    m_applet->message_queue.RequestExit();
+    R_SUCCEED();
+}
+
+Result IApplicationAccessor::Terminate() {
+    LOG_INFO(Service_AM, "called");
+    m_applet->process->Terminate();
+    R_SUCCEED();
+}
+
+Result IApplicationAccessor::GetResult() {
+    LOG_INFO(Service_AM, "called");
+    R_SUCCEED();
+}
+
+Result IApplicationAccessor::GetAppletStateChangedEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_INFO(Service_AM, "called");
+    *out_event = m_applet->caller_applet_broker->GetStateChangedEvent().GetHandle();
+    R_SUCCEED();
+}
+
+Result IApplicationAccessor::PushLaunchParameter(LaunchParameterKind kind,
+                                                 SharedPointer<IStorage> storage) {
+    LOG_INFO(Service_AM, "called, kind={}", kind);
+
+    switch (kind) {
+    case LaunchParameterKind::AccountPreselectedUser:
+        m_applet->preselected_user_launch_parameter.push_back(storage->GetData());
+        R_SUCCEED();
+    default:
+        R_THROW(ResultUnknown);
+    }
+}
+
+Result IApplicationAccessor::GetApplicationControlProperty(
+    OutBuffer<BufferAttr_HipcMapAlias> out_control_property) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_THROW(ResultUnknown);
+}
+
+Result IApplicationAccessor::SetUsers(bool enable,
+                                      InArray<Common::UUID, BufferAttr_HipcMapAlias> user_ids) {
+    LOG_INFO(Service_AM, "called, enable={} user_id_count={}", enable, user_ids.size());
+    R_SUCCEED();
+}
+
+Result IApplicationAccessor::GetCurrentLibraryApplet(
+    Out<SharedPointer<ILibraryAppletAccessor>> out_accessor) {
+    LOG_INFO(Service_AM, "(STUBBED) called");
+    *out_accessor = nullptr;
+    R_SUCCEED();
+}
+
+Result IApplicationAccessor::RequestForApplicationToGetForeground() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_THROW(ResultUnknown);
+}
+
+Result IApplicationAccessor::CheckRightsEnvironmentAvailable(Out<bool> out_is_available) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_is_available = true;
+    R_SUCCEED();
+}
+
+Result IApplicationAccessor::GetNsRightsEnvironmentHandle(Out<u64> out_handle) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    *out_handle = 0xdeadbeef;
+    R_SUCCEED();
+}
+
+Result IApplicationAccessor::ReportApplicationExitTimeout() {
+    LOG_ERROR(Service_AM, "called");
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_accessor.h b/src/core/hle/service/am/service/application_accessor.h
new file mode 100644
index 000000000..39a9b2153
--- /dev/null
+++ b/src/core/hle/service/am/service/application_accessor.h
@@ -0,0 +1,40 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "common/uuid.h"
+#include "core/hle/service/am/am_types.h"
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace Service::AM {
+
+struct Applet;
+class ILibraryAppletAccessor;
+class IStorage;
+
+class IApplicationAccessor final : public ServiceFramework<IApplicationAccessor> {
+public:
+    explicit IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet);
+    ~IApplicationAccessor() override;
+
+private:
+    Result Start();
+    Result RequestExit();
+    Result Terminate();
+    Result GetResult();
+    Result GetAppletStateChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result PushLaunchParameter(LaunchParameterKind kind, SharedPointer<IStorage> storage);
+    Result GetApplicationControlProperty(OutBuffer<BufferAttr_HipcMapAlias> out_control_property);
+    Result SetUsers(bool enable, InArray<Common::UUID, BufferAttr_HipcMapAlias> user_ids);
+    Result GetCurrentLibraryApplet(Out<SharedPointer<ILibraryAppletAccessor>> out_accessor);
+    Result RequestForApplicationToGetForeground();
+    Result CheckRightsEnvironmentAvailable(Out<bool> out_is_available);
+    Result GetNsRightsEnvironmentHandle(Out<u64> out_handle);
+    Result ReportApplicationExitTimeout();
+
+    const std::shared_ptr<Applet> m_applet;
+};
+
+} // namespace Service::AM

From a65fb85b6d3f249d2179ad88de29869ec0d38c76 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 20:49:45 -0500
Subject: [PATCH 23/24] am: rewrite IApplicationCreator

---
 src/core/CMakeLists.txt                          |  4 ++--
 .../am/{ => service}/application_creator.cpp     | 16 +++++++++++++---
 .../am/{ => service}/application_creator.h       |  7 +++++++
 .../service/am/service/system_applet_proxy.cpp   |  7 ++++---
 4 files changed, 26 insertions(+), 8 deletions(-)
 rename src/core/hle/service/am/{ => service}/application_creator.cpp (50%)
 rename src/core/hle/service/am/{ => service}/application_creator.h (68%)

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index db27e0f3e..8fd99a5e9 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -423,8 +423,6 @@ add_library(core STATIC
     hle/service/am/applet_manager.h
     hle/service/am/applet_message_queue.cpp
     hle/service/am/applet_message_queue.h
-    hle/service/am/application_creator.cpp
-    hle/service/am/application_creator.h
     hle/service/am/hid_registration.cpp
     hle/service/am/hid_registration.h
     hle/service/am/idle.cpp
@@ -443,6 +441,8 @@ add_library(core STATIC
     hle/service/am/service/applet_common_functions.h
     hle/service/am/service/application_accessor.cpp
     hle/service/am/service/application_accessor.h
+    hle/service/am/service/application_creator.cpp
+    hle/service/am/service/application_creator.h
     hle/service/am/service/application_functions.cpp
     hle/service/am/service/application_functions.h
     hle/service/am/service/application_proxy_service.cpp
diff --git a/src/core/hle/service/am/application_creator.cpp b/src/core/hle/service/am/service/application_creator.cpp
similarity index 50%
rename from src/core/hle/service/am/application_creator.cpp
rename to src/core/hle/service/am/service/application_creator.cpp
index 79ea045a3..568bb0122 100644
--- a/src/core/hle/service/am/application_creator.cpp
+++ b/src/core/hle/service/am/service/application_creator.cpp
@@ -1,8 +1,12 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/application_creator.h"
-#include "core/hle/service/ipc_helpers.h"
+#include "core/hle/service/am/am_types.h"
+#include "core/hle/service/am/applet.h"
+#include "core/hle/service/am/applet_manager.h"
+#include "core/hle/service/am/service/application_accessor.h"
+#include "core/hle/service/am/service/application_creator.h"
+#include "core/hle/service/cmif_serialization.h"
 
 namespace Service::AM {
 
@@ -10,7 +14,7 @@ IApplicationCreator::IApplicationCreator(Core::System& system_)
     : ServiceFramework{system_, "IApplicationCreator"} {
     // clang-format off
     static const FunctionInfo functions[] = {
-        {0, nullptr, "CreateApplication"},
+        {0, D<&IApplicationCreator::CreateApplication>, "CreateApplication"},
         {1, nullptr, "PopLaunchRequestedApplication"},
         {10, nullptr, "CreateSystemApplication"},
         {100, nullptr, "PopFloatingApplicationForDevelopment"},
@@ -22,4 +26,10 @@ IApplicationCreator::IApplicationCreator(Core::System& system_)
 
 IApplicationCreator::~IApplicationCreator() = default;
 
+Result IApplicationCreator::CreateApplication(
+    Out<SharedPointer<IApplicationAccessor>> out_application_accessor, u64 application_id) {
+    LOG_ERROR(Service_NS, "called, application_id={:x}", application_id);
+    R_THROW(ResultUnknown);
+}
+
 } // namespace Service::AM
diff --git a/src/core/hle/service/am/application_creator.h b/src/core/hle/service/am/service/application_creator.h
similarity index 68%
rename from src/core/hle/service/am/application_creator.h
rename to src/core/hle/service/am/service/application_creator.h
index 375a3c476..9f939ebf6 100644
--- a/src/core/hle/service/am/application_creator.h
+++ b/src/core/hle/service/am/service/application_creator.h
@@ -3,14 +3,21 @@
 
 #pragma once
 
+#include "core/hle/service/cmif_types.h"
 #include "core/hle/service/service.h"
 
 namespace Service::AM {
 
+class IApplicationAccessor;
+struct Applet;
+
 class IApplicationCreator final : public ServiceFramework<IApplicationCreator> {
 public:
     explicit IApplicationCreator(Core::System& system_);
     ~IApplicationCreator() override;
+
+private:
+    Result CreateApplication(Out<SharedPointer<IApplicationAccessor>>, u64 application_id);
 };
 
 } // namespace Service::AM
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index a3e801799..5ec509d2e 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -1,8 +1,8 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/application_creator.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
+#include "core/hle/service/am/service/application_creator.h"
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/common_state_getter.h"
 #include "core/hle/service/am/service/debug_functions.h"
@@ -104,8 +104,9 @@ Result ISystemAppletProxy::GetLibraryAppletCreator(
 
 Result ISystemAppletProxy::GetApplicationCreator(
     Out<SharedPointer<IApplicationCreator>> out_application_creator) {
-    LOG_ERROR(Service_AM, "called");
-    R_THROW(ResultUnknown);
+    LOG_DEBUG(Service_AM, "called");
+    *out_application_creator = std::make_shared<IApplicationCreator>(system);
+    R_SUCCEED();
 }
 
 Result ISystemAppletProxy::GetAppletCommonFunctions(

From bca698a17ae4b39106cd7f8c7eef06ccc7c8d6dd Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 11 Feb 2024 21:01:19 -0500
Subject: [PATCH 24/24] am: move out omm interfaces to new module

---
 src/core/CMakeLists.txt                       | 14 +++++++-----
 src/core/hle/service/am/am.cpp                |  6 -----
 src/core/hle/service/am/idle.h                | 20 -----------------
 src/core/hle/service/am/omm.h                 | 20 -----------------
 src/core/hle/service/am/spsm.h                | 20 -----------------
 src/core/hle/service/omm/omm.cpp              | 22 +++++++++++++++++++
 src/core/hle/service/omm/omm.h                | 14 ++++++++++++
 .../operation_mode_manager.cpp}               | 11 +++++-----
 .../hle/service/omm/operation_mode_manager.h  | 20 +++++++++++++++++
 .../policy_manager_system.cpp}                | 11 +++++-----
 .../hle/service/omm/policy_manager_system.h   | 20 +++++++++++++++++
 .../power_state_interface.cpp}                | 11 +++++-----
 .../hle/service/omm/power_state_interface.h   | 20 +++++++++++++++++
 src/core/hle/service/service.cpp              |  2 ++
 14 files changed, 124 insertions(+), 87 deletions(-)
 delete mode 100644 src/core/hle/service/am/idle.h
 delete mode 100644 src/core/hle/service/am/omm.h
 delete mode 100644 src/core/hle/service/am/spsm.h
 create mode 100644 src/core/hle/service/omm/omm.cpp
 create mode 100644 src/core/hle/service/omm/omm.h
 rename src/core/hle/service/{am/omm.cpp => omm/operation_mode_manager.cpp} (86%)
 create mode 100644 src/core/hle/service/omm/operation_mode_manager.h
 rename src/core/hle/service/{am/idle.cpp => omm/policy_manager_system.cpp} (64%)
 create mode 100644 src/core/hle/service/omm/policy_manager_system.h
 rename src/core/hle/service/{am/spsm.cpp => omm/power_state_interface.cpp} (75%)
 create mode 100644 src/core/hle/service/omm/power_state_interface.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 8fd99a5e9..5e2f4869e 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -425,14 +425,10 @@ add_library(core STATIC
     hle/service/am/applet_message_queue.h
     hle/service/am/hid_registration.cpp
     hle/service/am/hid_registration.h
-    hle/service/am/idle.cpp
-    hle/service/am/idle.h
     hle/service/am/library_applet_storage.cpp
     hle/service/am/library_applet_storage.h
     hle/service/am/managed_layer_holder.cpp
     hle/service/am/managed_layer_holder.h
-    hle/service/am/omm.cpp
-    hle/service/am/omm.h
     hle/service/am/process.cpp
     hle/service/am/process.h
     hle/service/am/service/all_system_applet_proxies_service.cpp
@@ -487,8 +483,6 @@ add_library(core STATIC
     hle/service/am/service/window_controller.h
     hle/service/am/system_buffer_manager.cpp
     hle/service/am/system_buffer_manager.h
-    hle/service/am/spsm.cpp
-    hle/service/am/spsm.h
     hle/service/aoc/aoc_u.cpp
     hle/service/aoc/aoc_u.h
     hle/service/apm/apm.cpp
@@ -815,6 +809,14 @@ add_library(core STATIC
     hle/service/nvnflinger/window.h
     hle/service/olsc/olsc.cpp
     hle/service/olsc/olsc.h
+    hle/service/omm/omm.cpp
+    hle/service/omm/omm.h
+    hle/service/omm/operation_mode_manager.cpp
+    hle/service/omm/operation_mode_manager.h
+    hle/service/omm/policy_manager_system.cpp
+    hle/service/omm/policy_manager_system.h
+    hle/service/omm/power_state_interface.cpp
+    hle/service/omm/power_state_interface.h
     hle/service/os/event.cpp
     hle/service/os/event.h
     hle/service/os/multi_wait_holder.cpp
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index da0f9e3df..9dc710ba9 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -2,11 +2,8 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/am.h"
-#include "core/hle/service/am/idle.h"
-#include "core/hle/service/am/omm.h"
 #include "core/hle/service/am/service/all_system_applet_proxies_service.h"
 #include "core/hle/service/am/service/application_proxy_service.h"
-#include "core/hle/service/am/spsm.h"
 #include "core/hle/service/server_manager.h"
 
 namespace Service::AM {
@@ -18,9 +15,6 @@ void LoopProcess(Nvnflinger::Nvnflinger& nvnflinger, Core::System& system) {
         "appletAE", std::make_shared<IAllSystemAppletProxiesService>(system, nvnflinger));
     server_manager->RegisterNamedService(
         "appletOE", std::make_shared<IApplicationProxyService>(system, nvnflinger));
-    server_manager->RegisterNamedService("idle:sys", std::make_shared<IdleSys>(system));
-    server_manager->RegisterNamedService("omm", std::make_shared<OMM>(system));
-    server_manager->RegisterNamedService("spsm", std::make_shared<SPSM>(system));
     ServerManager::RunServer(std::move(server_manager));
 }
 
diff --git a/src/core/hle/service/am/idle.h b/src/core/hle/service/am/idle.h
deleted file mode 100644
index 15b31f67e..000000000
--- a/src/core/hle/service/am/idle.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/service.h"
-
-namespace Core {
-class System;
-}
-
-namespace Service::AM {
-
-class IdleSys final : public ServiceFramework<IdleSys> {
-public:
-    explicit IdleSys(Core::System& system_);
-    ~IdleSys() override;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/omm.h b/src/core/hle/service/am/omm.h
deleted file mode 100644
index 73d0c82d5..000000000
--- a/src/core/hle/service/am/omm.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/service.h"
-
-namespace Core {
-class System;
-}
-
-namespace Service::AM {
-
-class OMM final : public ServiceFramework<OMM> {
-public:
-    explicit OMM(Core::System& system_);
-    ~OMM() override;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/spsm.h b/src/core/hle/service/am/spsm.h
deleted file mode 100644
index 922f8863e..000000000
--- a/src/core/hle/service/am/spsm.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/service.h"
-
-namespace Core {
-class System;
-}
-
-namespace Service::AM {
-
-class SPSM final : public ServiceFramework<SPSM> {
-public:
-    explicit SPSM(Core::System& system_);
-    ~SPSM() override;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/omm/omm.cpp b/src/core/hle/service/omm/omm.cpp
new file mode 100644
index 000000000..b95319e26
--- /dev/null
+++ b/src/core/hle/service/omm/omm.cpp
@@ -0,0 +1,22 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/omm/omm.h"
+#include "core/hle/service/omm/operation_mode_manager.h"
+#include "core/hle/service/omm/policy_manager_system.h"
+#include "core/hle/service/omm/power_state_interface.h"
+#include "core/hle/service/server_manager.h"
+
+namespace Service::OMM {
+
+void LoopProcess(Core::System& system) {
+    auto server_manager = std::make_unique<ServerManager>(system);
+
+    server_manager->RegisterNamedService("idle:sys",
+                                         std::make_shared<IPolicyManagerSystem>(system));
+    server_manager->RegisterNamedService("omm", std::make_shared<IOperationModeManager>(system));
+    server_manager->RegisterNamedService("spsm", std::make_shared<IPowerStateInterface>(system));
+    ServerManager::RunServer(std::move(server_manager));
+}
+
+} // namespace Service::OMM
diff --git a/src/core/hle/service/omm/omm.h b/src/core/hle/service/omm/omm.h
new file mode 100644
index 000000000..7bf04688a
--- /dev/null
+++ b/src/core/hle/service/omm/omm.h
@@ -0,0 +1,14 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+namespace Core {
+class System;
+}
+
+namespace Service::OMM {
+
+void LoopProcess(Core::System& system);
+
+} // namespace Service::OMM
diff --git a/src/core/hle/service/am/omm.cpp b/src/core/hle/service/omm/operation_mode_manager.cpp
similarity index 86%
rename from src/core/hle/service/am/omm.cpp
rename to src/core/hle/service/omm/operation_mode_manager.cpp
index 66824e495..fe7ed84a7 100644
--- a/src/core/hle/service/am/omm.cpp
+++ b/src/core/hle/service/omm/operation_mode_manager.cpp
@@ -1,11 +1,12 @@
 // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/omm.h"
+#include "core/hle/service/omm/operation_mode_manager.h"
 
-namespace Service::AM {
+namespace Service::OMM {
 
-OMM::OMM(Core::System& system_) : ServiceFramework{system_, "omm"} {
+IOperationModeManager::IOperationModeManager(Core::System& system_)
+    : ServiceFramework{system_, "omm"} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {0, nullptr, "GetOperationMode"},
@@ -43,6 +44,6 @@ OMM::OMM(Core::System& system_) : ServiceFramework{system_, "omm"} {
     RegisterHandlers(functions);
 }
 
-OMM::~OMM() = default;
+IOperationModeManager::~IOperationModeManager() = default;
 
-} // namespace Service::AM
+} // namespace Service::OMM
diff --git a/src/core/hle/service/omm/operation_mode_manager.h b/src/core/hle/service/omm/operation_mode_manager.h
new file mode 100644
index 000000000..32bc7b2f9
--- /dev/null
+++ b/src/core/hle/service/omm/operation_mode_manager.h
@@ -0,0 +1,20 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Core {
+class System;
+}
+
+namespace Service::OMM {
+
+class IOperationModeManager final : public ServiceFramework<IOperationModeManager> {
+public:
+    explicit IOperationModeManager(Core::System& system_);
+    ~IOperationModeManager() override;
+};
+
+} // namespace Service::OMM
diff --git a/src/core/hle/service/am/idle.cpp b/src/core/hle/service/omm/policy_manager_system.cpp
similarity index 64%
rename from src/core/hle/service/am/idle.cpp
rename to src/core/hle/service/omm/policy_manager_system.cpp
index 603515284..1cd6fd807 100644
--- a/src/core/hle/service/am/idle.cpp
+++ b/src/core/hle/service/omm/policy_manager_system.cpp
@@ -1,11 +1,12 @@
 // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/idle.h"
+#include "core/hle/service/omm/policy_manager_system.h"
 
-namespace Service::AM {
+namespace Service::OMM {
 
-IdleSys::IdleSys(Core::System& system_) : ServiceFramework{system_, "idle:sys"} {
+IPolicyManagerSystem::IPolicyManagerSystem(Core::System& system_)
+    : ServiceFramework{system_, "idle:sys"} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {0, nullptr, "GetAutoPowerDownEvent"},
@@ -20,6 +21,6 @@ IdleSys::IdleSys(Core::System& system_) : ServiceFramework{system_, "idle:sys"}
     RegisterHandlers(functions);
 }
 
-IdleSys::~IdleSys() = default;
+IPolicyManagerSystem::~IPolicyManagerSystem() = default;
 
-} // namespace Service::AM
+} // namespace Service::OMM
diff --git a/src/core/hle/service/omm/policy_manager_system.h b/src/core/hle/service/omm/policy_manager_system.h
new file mode 100644
index 000000000..151ca0d2e
--- /dev/null
+++ b/src/core/hle/service/omm/policy_manager_system.h
@@ -0,0 +1,20 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Core {
+class System;
+}
+
+namespace Service::OMM {
+
+class IPolicyManagerSystem final : public ServiceFramework<IPolicyManagerSystem> {
+public:
+    explicit IPolicyManagerSystem(Core::System& system_);
+    ~IPolicyManagerSystem() override;
+};
+
+} // namespace Service::OMM
diff --git a/src/core/hle/service/am/spsm.cpp b/src/core/hle/service/omm/power_state_interface.cpp
similarity index 75%
rename from src/core/hle/service/am/spsm.cpp
rename to src/core/hle/service/omm/power_state_interface.cpp
index ec581e32b..22cac8259 100644
--- a/src/core/hle/service/am/spsm.cpp
+++ b/src/core/hle/service/omm/power_state_interface.cpp
@@ -1,11 +1,12 @@
 // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/spsm.h"
+#include "core/hle/service/omm/power_state_interface.h"
 
-namespace Service::AM {
+namespace Service::OMM {
 
-SPSM::SPSM(Core::System& system_) : ServiceFramework{system_, "spsm"} {
+IPowerStateInterface::IPowerStateInterface(Core::System& system_)
+    : ServiceFramework{system_, "spsm"} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {0, nullptr, "GetState"},
@@ -26,6 +27,6 @@ SPSM::SPSM(Core::System& system_) : ServiceFramework{system_, "spsm"} {
     RegisterHandlers(functions);
 }
 
-SPSM::~SPSM() = default;
+IPowerStateInterface::~IPowerStateInterface() = default;
 
-} // namespace Service::AM
+} // namespace Service::OMM
diff --git a/src/core/hle/service/omm/power_state_interface.h b/src/core/hle/service/omm/power_state_interface.h
new file mode 100644
index 000000000..825a6512d
--- /dev/null
+++ b/src/core/hle/service/omm/power_state_interface.h
@@ -0,0 +1,20 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Core {
+class System;
+}
+
+namespace Service::OMM {
+
+class IPowerStateInterface final : public ServiceFramework<IPowerStateInterface> {
+public:
+    explicit IPowerStateInterface(Core::System& system_);
+    ~IPowerStateInterface() override;
+};
+
+} // namespace Service::OMM
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index f68c3c686..fbdf217ba 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -52,6 +52,7 @@
 #include "core/hle/service/nvnflinger/hos_binder_driver_server.h"
 #include "core/hle/service/nvnflinger/nvnflinger.h"
 #include "core/hle/service/olsc/olsc.h"
+#include "core/hle/service/omm/omm.h"
 #include "core/hle/service/pcie/pcie.h"
 #include "core/hle/service/pctl/pctl_module.h"
 #include "core/hle/service/pcv/pcv.h"
@@ -266,6 +267,7 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
     kernel.RunOnGuestCoreProcess("npns",       [&] { NPNS::LoopProcess(system); });
     kernel.RunOnGuestCoreProcess("ns",         [&] { NS::LoopProcess(system); });
     kernel.RunOnGuestCoreProcess("olsc",       [&] { OLSC::LoopProcess(system); });
+    kernel.RunOnGuestCoreProcess("omm",        [&] { OMM::LoopProcess(system); });
     kernel.RunOnGuestCoreProcess("pcie",       [&] { PCIe::LoopProcess(system); });
     kernel.RunOnGuestCoreProcess("pctl",       [&] { PCTL::LoopProcess(system); });
     kernel.RunOnGuestCoreProcess("pcv",        [&] { PCV::LoopProcess(system); });