From ab93279542c005eb3cdc7327f62c39d7f6c37749 Mon Sep 17 00:00:00 2001 From: Zephyron Date: Wed, 28 Jan 2026 16:41:03 +1000 Subject: [PATCH] feat(hle/am): implement system applet proxies and observer services - Add OpenHomeMenuProxy (cmd 110) for QLaunch support - Add GetSystemProcessCommonFunctions (cmd 450) - Add Cmd460 stub for system process initialization - Implement IApplicationObserver and ISystemProcessCommonFunctions services --- .../all_system_applet_proxies_service.cpp | 33 ++++++++++++++++++- .../all_system_applet_proxies_service.h | 9 ++++- .../am/service/application_observer.cpp | 25 ++++++++++++++ .../service/am/service/application_observer.h | 16 +++++++++ .../system_process_common_functions.cpp | 30 +++++++++++++++++ .../service/system_process_common_functions.h | 23 +++++++++++++ 6 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 src/core/hle/service/am/service/application_observer.cpp create mode 100644 src/core/hle/service/am/service/application_observer.h create mode 100644 src/core/hle/service/am/service/system_process_common_functions.cpp create mode 100644 src/core/hle/service/am/service/system_process_common_functions.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 index ca27c72d2..475959c18 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 @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "core/core.h" @@ -11,6 +11,7 @@ #include "core/hle/service/am/service/overlay_applet_proxy.h" #include "core/hle/service/am/service/system_applet_proxy.h" #include "core/hle/service/am/service/system_application_proxy.h" +#include "core/hle/service/am/service/system_process_common_functions.h" #include "core/hle/service/am/window_system.h" #include "core/hle/service/cmif_serialization.h" @@ -22,12 +23,15 @@ IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& sys // clang-format off static const FunctionInfo functions[] = { {100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"}, + {110, D<&IAllSystemAppletProxiesService::OpenHomeMenuProxy>, "OpenHomeMenuProxy"}, {200, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld>, "OpenLibraryAppletProxyOld"}, {201, D<&IAllSystemAppletProxiesService::OpenLibraryAppletProxy>, "OpenLibraryAppletProxy"}, {300, D<&IAllSystemAppletProxiesService::OpenOverlayAppletProxy>, "OpenOverlayAppletProxy"}, {350, D<&IAllSystemAppletProxiesService::OpenSystemApplicationProxy>, "OpenSystemApplicationProxy"}, {400, D<&IAllSystemAppletProxiesService::CreateSelfLibraryAppletCreatorForDevelop>, "CreateSelfLibraryAppletCreatorForDevelop"}, {410, D<&IAllSystemAppletProxiesService::GetSystemAppletControllerForDebug>, "GetSystemAppletControllerForDebug"}, + {450, D<&IAllSystemAppletProxiesService::GetSystemProcessCommonFunctions>, "GetSystemProcessCommonFunctions"}, + {460, D<&IAllSystemAppletProxiesService::Cmd460>, "Cmd460"}, {1000, D<&IAllSystemAppletProxiesService::GetDebugFunctions>, "GetDebugFunctions"}, }; // clang-format on @@ -52,6 +56,21 @@ Result IAllSystemAppletProxiesService::OpenSystemAppletProxy( } } +Result IAllSystemAppletProxiesService::OpenHomeMenuProxy( + Out> out_system_applet_proxy, ClientProcessId pid, + InCopyHandle process_handle) { + LOG_DEBUG(Service_AM, "called"); + + if (const auto applet = this->GetAppletFromProcessId(pid); applet) { + *out_system_applet_proxy = std::make_shared( + system, applet, process_handle.Get(), m_window_system); + R_SUCCEED(); + } else { + LOG_ERROR(Service_AM, "Home menu applet doesn't exist for process_id={}", pid.pid); + R_THROW(ResultUnknown); + } +} + Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy( Out> out_library_applet_proxy, ClientProcessId pid, InCopyHandle process_handle, @@ -130,6 +149,18 @@ Result IAllSystemAppletProxiesService::GetSystemAppletControllerForDebug() { R_THROW(ResultUnknown); } +Result IAllSystemAppletProxiesService::GetSystemProcessCommonFunctions( + Out> out_system_process_common_functions) { + LOG_DEBUG(Service_AM, "called"); + *out_system_process_common_functions = std::make_shared(system); + R_SUCCEED(); +} + +Result IAllSystemAppletProxiesService::Cmd460() { + LOG_WARNING(Service_AM, "(STUBBED) called"); + R_SUCCEED(); +} + Result IAllSystemAppletProxiesService::GetDebugFunctions( Out> out_debug_functions) { LOG_DEBUG(Service_AM, "called"); 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 index f13a7ea12..72c9252ba 100644 --- 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 @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -19,6 +19,7 @@ class ILibraryAppletProxy; class IOverlayAppletProxy; class ISystemAppletProxy; class ISystemApplicationProxy; +class ISystemProcessCommonFunctions; class WindowSystem; class IAllSystemAppletProxiesService final @@ -31,6 +32,9 @@ private: Result OpenSystemAppletProxy(Out> out_system_applet_proxy, ClientProcessId pid, InCopyHandle process_handle); + Result OpenHomeMenuProxy(Out> out_system_applet_proxy, + ClientProcessId pid, + InCopyHandle process_handle); Result OpenLibraryAppletProxy(Out> out_library_applet_proxy, ClientProcessId pid, InCopyHandle process_handle, @@ -49,6 +53,9 @@ private: ClientProcessId pid, InCopyHandle process_handle); Result GetSystemAppletControllerForDebug(); + Result GetSystemProcessCommonFunctions( + Out> out_system_process_common_functions); + Result Cmd460(); Result GetDebugFunctions(Out> out_debug_functions); private: diff --git a/src/core/hle/service/am/service/application_observer.cpp b/src/core/hle/service/am/service/application_observer.cpp new file mode 100644 index 000000000..f3d5b0cb8 --- /dev/null +++ b/src/core/hle/service/am/service/application_observer.cpp @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/am/service/application_observer.h" + +namespace Service::AM { + +IApplicationObserver::IApplicationObserver(Core::System& system_) + : ServiceFramework{system_, "IApplicationObserver"} { + // clang-format off + static const FunctionInfo functions[] = { + {1, nullptr, "Unknown1"}, + {2, nullptr, "Unknown2"}, + {10, nullptr, "Unknown10"}, + {20, nullptr, "Unknown20"}, + {30, nullptr, "Unknown30"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +IApplicationObserver::~IApplicationObserver() = default; + +} // namespace Service::AM diff --git a/src/core/hle/service/am/service/application_observer.h b/src/core/hle/service/am/service/application_observer.h new file mode 100644 index 000000000..4ac5c4619 --- /dev/null +++ b/src/core/hle/service/am/service/application_observer.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::AM { + +class IApplicationObserver final : public ServiceFramework { +public: + explicit IApplicationObserver(Core::System& system_); + ~IApplicationObserver() override; +}; + +} // namespace Service::AM diff --git a/src/core/hle/service/am/service/system_process_common_functions.cpp b/src/core/hle/service/am/service/system_process_common_functions.cpp new file mode 100644 index 000000000..6c0a8c7ea --- /dev/null +++ b/src/core/hle/service/am/service/system_process_common_functions.cpp @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/am/service/application_observer.h" +#include "core/hle/service/am/service/system_process_common_functions.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::AM { + +ISystemProcessCommonFunctions::ISystemProcessCommonFunctions(Core::System& system_) + : ServiceFramework{system_, "ISystemProcessCommonFunctions"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, D<&ISystemProcessCommonFunctions::GetApplicationObserver>, "GetApplicationObserver"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ISystemProcessCommonFunctions::~ISystemProcessCommonFunctions() = default; + +Result ISystemProcessCommonFunctions::GetApplicationObserver( + Out> out_observer) { + LOG_DEBUG(Service_AM, "called"); + *out_observer = std::make_shared(system); + R_SUCCEED(); +} + +} // namespace Service::AM diff --git a/src/core/hle/service/am/service/system_process_common_functions.h b/src/core/hle/service/am/service/system_process_common_functions.h new file mode 100644 index 000000000..dd5865a6e --- /dev/null +++ b/src/core/hle/service/am/service/system_process_common_functions.h @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: Copyright 2026 citron 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 IApplicationObserver; + +class ISystemProcessCommonFunctions final + : public ServiceFramework { +public: + explicit ISystemProcessCommonFunctions(Core::System& system_); + ~ISystemProcessCommonFunctions() override; + +private: + Result GetApplicationObserver(Out> out_observer); +}; + +} // namespace Service::AM