Просмотр исходного кода

am: rewrite ILibraryAppletSelfAccessor

Liam 2 лет назад
Родитель
Сommit
c7e94e2175

+ 2 - 2
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

+ 0 - 338
src/core/hle/service/am/library_applet_self_accessor.cpp

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

+ 0 - 44
src/core/hle/service/am/library_applet_self_accessor.h

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

+ 0 - 1
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"

+ 1 - 1
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"
 

+ 322 - 0
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

+ 83 - 0
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

+ 0 - 1
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"