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
This commit is contained in:
Zephyron
2026-01-28 16:41:03 +10:00
parent af5eb92450
commit ab93279542
6 changed files with 134 additions and 2 deletions

View File

@@ -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<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>(
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<SharedPointer<ILibraryAppletProxy>> out_library_applet_proxy, ClientProcessId pid,
InCopyHandle<Kernel::KProcess> process_handle,
@@ -130,6 +149,18 @@ Result IAllSystemAppletProxiesService::GetSystemAppletControllerForDebug() {
R_THROW(ResultUnknown);
}
Result IAllSystemAppletProxiesService::GetSystemProcessCommonFunctions(
Out<SharedPointer<ISystemProcessCommonFunctions>> out_system_process_common_functions) {
LOG_DEBUG(Service_AM, "called");
*out_system_process_common_functions = std::make_shared<ISystemProcessCommonFunctions>(system);
R_SUCCEED();
}
Result IAllSystemAppletProxiesService::Cmd460() {
LOG_WARNING(Service_AM, "(STUBBED) called");
R_SUCCEED();
}
Result IAllSystemAppletProxiesService::GetDebugFunctions(
Out<SharedPointer<IDebugFunctions>> out_debug_functions) {
LOG_DEBUG(Service_AM, "called");

View File

@@ -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<SharedPointer<ISystemAppletProxy>> out_system_applet_proxy,
ClientProcessId pid,
InCopyHandle<Kernel::KProcess> process_handle);
Result OpenHomeMenuProxy(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,
@@ -49,6 +53,9 @@ private:
ClientProcessId pid,
InCopyHandle<Kernel::KProcess> process_handle);
Result GetSystemAppletControllerForDebug();
Result GetSystemProcessCommonFunctions(
Out<SharedPointer<ISystemProcessCommonFunctions>> out_system_process_common_functions);
Result Cmd460();
Result GetDebugFunctions(Out<SharedPointer<IDebugFunctions>> out_debug_functions);
private:

View File

@@ -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

View File

@@ -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<IApplicationObserver> {
public:
explicit IApplicationObserver(Core::System& system_);
~IApplicationObserver() override;
};
} // namespace Service::AM

View File

@@ -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<SharedPointer<IApplicationObserver>> out_observer) {
LOG_DEBUG(Service_AM, "called");
*out_observer = std::make_shared<IApplicationObserver>(system);
R_SUCCEED();
}
} // namespace Service::AM

View File

@@ -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<ISystemProcessCommonFunctions> {
public:
explicit ISystemProcessCommonFunctions(Core::System& system_);
~ISystemProcessCommonFunctions() override;
private:
Result GetApplicationObserver(Out<SharedPointer<IApplicationObserver>> out_observer);
};
} // namespace Service::AM