Bladeren bron

core: support offline web applet

Liam 2 jaren geleden
bovenliggende
commit
68303ed601
32 gewijzigde bestanden met toevoegingen van 470 en 58 verwijderingen
  1. 7 0
      src/core/hle/service/am/am_types.h
  2. 3 0
      src/core/hle/service/am/applet.h
  3. 9 0
      src/core/hle/service/am/applet_common_functions.cpp
  4. 1 0
      src/core/hle/service/am/applet_common_functions.h
  5. 1 1
      src/core/hle/service/am/application_proxy.cpp
  6. 22 1
      src/core/hle/service/am/common_state_getter.cpp
  7. 1 0
      src/core/hle/service/am/common_state_getter.h
  8. 51 13
      src/core/hle/service/am/display_controller.cpp
  9. 7 1
      src/core/hle/service/am/display_controller.h
  10. 6 0
      src/core/hle/service/am/hid_registration.cpp
  11. 2 0
      src/core/hle/service/am/hid_registration.h
  12. 23 4
      src/core/hle/service/am/library_applet_creator.cpp
  13. 1 1
      src/core/hle/service/am/library_applet_proxy.cpp
  14. 102 12
      src/core/hle/service/am/library_applet_self_accessor.cpp
  15. 4 0
      src/core/hle/service/am/library_applet_self_accessor.h
  16. 12 1
      src/core/hle/service/am/self_controller.cpp
  17. 1 0
      src/core/hle/service/am/self_controller.h
  18. 1 1
      src/core/hle/service/am/system_applet_proxy.cpp
  19. 20 0
      src/core/hle/service/am/system_buffer_manager.cpp
  20. 7 0
      src/core/hle/service/am/system_buffer_manager.h
  21. 33 2
      src/core/hle/service/am/window_controller.cpp
  22. 2 0
      src/core/hle/service/am/window_controller.h
  23. 35 13
      src/core/hle/service/filesystem/fsp/fsp_srv.cpp
  24. 11 1
      src/core/hle/service/nifm/nifm.cpp
  25. 64 3
      src/core/hle/service/ns/ns.cpp
  26. 15 0
      src/core/hle/service/ns/ns.h
  27. 10 0
      src/core/hle/service/nvnflinger/nvnflinger.cpp
  28. 3 0
      src/core/hle/service/nvnflinger/nvnflinger.h
  29. 2 2
      src/core/hle/service/vi/display/vi_display.cpp
  30. 1 1
      src/core/hle/service/vi/layer/vi_layer.cpp
  31. 9 0
      src/core/hle/service/vi/layer/vi_layer.h
  32. 4 1
      src/yuzu/main.cpp

+ 7 - 0
src/core/hle/service/am/am_types.h

@@ -162,6 +162,13 @@ struct CommonArguments {
 };
 static_assert(sizeof(CommonArguments) == 0x20, "CommonArguments has incorrect size.");
 
+struct AppletIdentityInfo {
+    AppletId applet_id;
+    INSERT_PADDING_BYTES(0x4);
+    u64 application_id;
+};
+static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size.");
+
 using AppletResourceUserId = u64;
 using ProgramId = u64;
 

+ 3 - 0
src/core/hle/service/am/applet.h

@@ -49,6 +49,9 @@ struct Applet {
     s32 previous_program_index{-1};
     ScreenshotPermission previous_screenshot_permission{ScreenshotPermission::Enable};
 
+    // TODO: some fields above can be AppletIdentityInfo
+    AppletIdentityInfo screen_shot_identity;
+
     // hid state
     HidRegistration hid_registration;
 

+ 9 - 0
src/core/hle/service/am/applet_common_functions.cpp

@@ -31,6 +31,7 @@ IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_,
         {90, nullptr, "OpenNamedChannelAsParent"},
         {91, nullptr, "OpenNamedChannelAsChild"},
         {100, nullptr, "SetApplicationCoreUsageMode"},
+        {300, &IAppletCommonFunctions::GetCurrentApplicationId, "GetCurrentApplicationId"},
     };
     // clang-format on
 
@@ -51,4 +52,12 @@ void IAppletCommonFunctions::SetCpuBoostRequestPriority(HLERequestContext& ctx)
     rb.Push(ResultSuccess);
 }
 
+void IAppletCommonFunctions::GetCurrentApplicationId(HLERequestContext& ctx) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    IPC::ResponseBuilder rb{ctx, 4};
+    rb.Push(ResultSuccess);
+    rb.Push<u64>(system.GetApplicationProcessProgramID() & ~0xFFFULL);
+}
+
 } // namespace Service::AM

+ 1 - 0
src/core/hle/service/am/applet_common_functions.h

@@ -16,6 +16,7 @@ public:
 
 private:
     void SetCpuBoostRequestPriority(HLERequestContext& ctx);
+    void GetCurrentApplicationId(HLERequestContext& ctx);
 
     const std::shared_ptr<Applet> applet;
 };

+ 1 - 1
src/core/hle/service/am/application_proxy.cpp

@@ -53,7 +53,7 @@ void IApplicationProxy::GetDisplayController(HLERequestContext& ctx) {
 
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
     rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IDisplayController>(system);
+    rb.PushIpcInterface<IDisplayController>(system, applet);
 }
 
 void IApplicationProxy::GetProcessWindingController(HLERequestContext& ctx) {

+ 22 - 1
src/core/hle/service/am/common_state_getter.cpp

@@ -60,7 +60,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr<Ap
         {91, nullptr, "GetCurrentPerformanceConfiguration"},
         {100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"},
         {110, nullptr, "OpenMyGpuErrorHandler"},
-        {120, nullptr, "GetAppletLaunchedHistory"},
+        {120, &ICommonStateGetter::GetAppletLaunchedHistory, "GetAppletLaunchedHistory"},
         {200, nullptr, "GetOperationModeSystemInfo"},
         {300, &ICommonStateGetter::GetSettingsPlatformRegion, "GetSettingsPlatformRegion"},
         {400, nullptr, "ActivateMigrationService"},
@@ -271,6 +271,27 @@ void ICommonStateGetter::PerformSystemButtonPressingIfInFocus(HLERequestContext&
     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");
 

+ 1 - 0
src/core/hle/service/am/common_state_getter.h

@@ -67,6 +67,7 @@ private:
     void SetCpuBoostMode(HLERequestContext& ctx);
     void GetBuiltInDisplayType(HLERequestContext& ctx);
     void PerformSystemButtonPressingIfInFocus(HLERequestContext& ctx);
+    void GetAppletLaunchedHistory(HLERequestContext& ctx);
     void GetSettingsPlatformRegion(HLERequestContext& ctx);
     void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(HLERequestContext& ctx);
 

+ 51 - 13
src/core/hle/service/am/display_controller.cpp

@@ -1,13 +1,23 @@
 // 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 {
 
-IDisplayController::IDisplayController(Core::System& system_)
-    : ServiceFramework{system_, "IDisplayController"} {
+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"},
@@ -31,8 +41,8 @@ IDisplayController::IDisplayController(Core::System& system_)
         {18, nullptr, "AcquireCallerAppletCaptureBufferEx"},
         {20, nullptr, "ClearCaptureBuffer"},
         {21, nullptr, "ClearAppletTransitionBuffer"},
-        {22, nullptr, "AcquireLastApplicationCaptureSharedBuffer"},
-        {23, nullptr, "ReleaseLastApplicationCaptureSharedBuffer"},
+        {22, &IDisplayController::AcquireLastApplicationCaptureSharedBuffer, "AcquireLastApplicationCaptureSharedBuffer"},
+        {23, &IDisplayController::ReleaseLastApplicationCaptureSharedBuffer, "ReleaseLastApplicationCaptureSharedBuffer"},
         {24, &IDisplayController::AcquireLastForegroundCaptureSharedBuffer, "AcquireLastForegroundCaptureSharedBuffer"},
         {25, &IDisplayController::ReleaseLastForegroundCaptureSharedBuffer, "ReleaseLastForegroundCaptureSharedBuffer"},
         {26, &IDisplayController::AcquireCallerAppletCaptureSharedBuffer, "AcquireCallerAppletCaptureSharedBuffer"},
@@ -49,10 +59,13 @@ 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(ResultSuccess);
-    rb.Push(1u);
-    rb.Push(1);
+    rb.Push(res);
+    rb.PushRaw(params);
 }
 
 void IDisplayController::TakeScreenShotOfOwnLayer(HLERequestContext& ctx) {
@@ -62,13 +75,35 @@ void IDisplayController::TakeScreenShotOfOwnLayer(HLERequestContext& ctx) {
     rb.Push(ResultSuccess);
 }
 
-void IDisplayController::AcquireLastForegroundCaptureSharedBuffer(HLERequestContext& ctx) {
+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);
-    rb.Push(1U);
-    rb.Push(1);
+}
+
+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) {
@@ -81,10 +116,13 @@ void IDisplayController::ReleaseLastForegroundCaptureSharedBuffer(HLERequestCont
 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(ResultSuccess);
-    rb.Push(1U);
-    rb.Push(1);
+    rb.Push(res);
+    rb.PushRaw(params);
 }
 
 void IDisplayController::ReleaseCallerAppletCaptureSharedBuffer(HLERequestContext& ctx) {

+ 7 - 1
src/core/hle/service/am/display_controller.h

@@ -7,9 +7,11 @@
 
 namespace Service::AM {
 
+struct Applet;
+
 class IDisplayController final : public ServiceFramework<IDisplayController> {
 public:
-    explicit IDisplayController(Core::System& system_);
+    explicit IDisplayController(Core::System& system_, std::shared_ptr<Applet> applet_);
     ~IDisplayController() override;
 
 private:
@@ -19,6 +21,10 @@ private:
     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

+ 6 - 0
src/core/hle/service/am/hid_registration.cpp

@@ -26,4 +26,10 @@ HidRegistration::~HidRegistration() {
     }
 }
 
+void HidRegistration::EnableAppletToGetInput(bool enable) {
+    if (m_process.IsInitialized()) {
+        m_hid_server->GetResourceManager()->EnableInput(m_process.GetProcessId(), enable);
+    }
+}
+
 } // namespace Service::AM

+ 2 - 0
src/core/hle/service/am/hid_registration.h

@@ -22,6 +22,8 @@ public:
     explicit HidRegistration(Core::System& system, Process& process);
     ~HidRegistration();
 
+    void EnableAppletToGetInput(bool enable);
+
 private:
     Process& m_process;
     std::shared_ptr<Service::HID::IHidServer> m_hid_server;

+ 23 - 4
src/core/hle/service/am/library_applet_creator.cpp

@@ -84,10 +84,29 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) {
     applet->type = AppletType::LibraryApplet;
     applet->library_applet_mode = mode;
 
-    // Library applet should be foreground
-    applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
-    applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
-    applet->focus_state = FocusState::InFocus;
+    // Set focus state
+    switch (mode) {
+    case LibraryAppletMode::AllForeground:
+    case LibraryAppletMode::NoUI:
+        applet->focus_state = FocusState::InFocus;
+        applet->hid_registration.EnableAppletToGetInput(true);
+        applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
+        applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
+        break;
+    case LibraryAppletMode::AllForegroundInitiallyHidden:
+        applet->system_buffer_manager.SetWindowVisibility(false);
+        applet->focus_state = FocusState::NotInFocus;
+        applet->hid_registration.EnableAppletToGetInput(false);
+        applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
+        break;
+    case LibraryAppletMode::Background:
+    case LibraryAppletMode::BackgroundIndirectDisplay:
+    default:
+        applet->focus_state = FocusState::Background;
+        applet->hid_registration.EnableAppletToGetInput(true);
+        applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
+        break;
+    }
 
     auto broker = std::make_shared<AppletDataBroker>(system);
     applet->caller_applet = caller_applet;

+ 1 - 1
src/core/hle/service/am/library_applet_proxy.cpp

@@ -81,7 +81,7 @@ void ILibraryAppletProxy::GetDisplayController(HLERequestContext& ctx) {
 
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
     rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IDisplayController>(system);
+    rb.PushIpcInterface<IDisplayController>(system, applet);
 }
 
 void ILibraryAppletProxy::GetProcessWindingController(HLERequestContext& ctx) {

+ 102 - 12
src/core/hle/service/am/library_applet_self_accessor.cpp

@@ -3,6 +3,9 @@
 
 #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"
@@ -15,25 +18,20 @@
 #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 {
 
-struct AppletIdentityInfo {
-    AppletId applet_id;
-    INSERT_PADDING_BYTES(0x4);
-    u64 application_id;
-};
-static_assert(sizeof(AppletIdentityInfo) == 0x10, "AppletIdentityInfo has incorrect size.");
-
 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 = applet->applet_id,
-            .application_id = applet->program_id,
+            .applet_id = caller_applet->applet_id,
+            .application_id = caller_applet->program_id,
         };
     } else {
         return {
@@ -60,7 +58,7 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
         {10, &ILibraryAppletSelfAccessor::ExitProcessAndReturn, "ExitProcessAndReturn"},
         {11, &ILibraryAppletSelfAccessor::GetLibraryAppletInfo, "GetLibraryAppletInfo"},
         {12, &ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo, "GetMainAppletIdentityInfo"},
-        {13, nullptr, "CanUseApplicationCore"},
+        {13, &ILibraryAppletSelfAccessor::CanUseApplicationCore, "CanUseApplicationCore"},
         {14, &ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo, "GetCallerAppletIdentityInfo"},
         {15, nullptr, "GetMainAppletApplicationControlProperty"},
         {16, nullptr, "GetMainAppletStorageId"},
@@ -74,8 +72,8 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
         {40, nullptr, "GetIndirectLayerProducerHandle"},
         {50, nullptr, "ReportVisibleError"},
         {51, nullptr, "ReportVisibleErrorWithErrorContext"},
-        {60, nullptr, "GetMainAppletApplicationDesiredLanguage"},
-        {70, nullptr, "GetCurrentApplicationId"},
+        {60, &ILibraryAppletSelfAccessor::GetMainAppletApplicationDesiredLanguage, "GetMainAppletApplicationDesiredLanguage"},
+        {70, &ILibraryAppletSelfAccessor::GetCurrentApplicationId, "GetCurrentApplicationId"},
         {80, nullptr, "RequestExitToSelf"},
         {90, nullptr, "CreateApplicationAndPushAndRequestToLaunch"},
         {100, nullptr, "CreateGameMovieTrimmer"},
@@ -86,6 +84,7 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
         {130, nullptr, "GetGpuErrorDetectedSystemEvent"},
         {140, nullptr, "SetApplicationMemoryReservation"},
         {150, &ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually, "ShouldSetGpuTimeSliceManually"},
+        {160, &ILibraryAppletSelfAccessor::Cmd160, "Cmd160"},
     };
     // clang-format on
     RegisterHandlers(functions);
@@ -202,6 +201,15 @@ void ILibraryAppletSelfAccessor::GetMainAppletIdentityInfo(HLERequestContext& ct
     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");
 
@@ -218,6 +226,80 @@ void ILibraryAppletSelfAccessor::GetDesirableKeyboardLayout(HLERequestContext& c
     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};
@@ -245,4 +327,12 @@ void ILibraryAppletSelfAccessor::ShouldSetGpuTimeSliceManually(HLERequestContext
     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

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

@@ -27,11 +27,15 @@ private:
     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;

+ 12 - 1
src/core/hle/service/am/self_controller.cpp

@@ -30,7 +30,7 @@ ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet>
         {12, &ISelfController::SetPerformanceModeChangedNotification, "SetPerformanceModeChangedNotification"},
         {13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"},
         {14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"},
-        {15, nullptr, "SetScreenShotAppletIdentityInfo"},
+        {15, &ISelfController::SetScreenShotAppletIdentityInfo, "SetScreenShotAppletIdentityInfo"},
         {16, &ISelfController::SetOutOfFocusSuspendingEnabled, "SetOutOfFocusSuspendingEnabled"},
         {17, nullptr, "SetControllerFirmwareUpdateSection"},
         {18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"},
@@ -207,6 +207,17 @@ void ISelfController::SetRestartMessageEnabled(HLERequestContext& ctx) {
     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};
 

+ 1 - 0
src/core/hle/service/am/self_controller.h

@@ -28,6 +28,7 @@ private:
     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);

+ 1 - 1
src/core/hle/service/am/system_applet_proxy.cpp

@@ -82,7 +82,7 @@ void ISystemAppletProxy::GetDisplayController(HLERequestContext& ctx) {
 
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
     rb.Push(ResultSuccess);
-    rb.PushIpcInterface<IDisplayController>(system);
+    rb.PushIpcInterface<IDisplayController>(system, applet);
 }
 
 void ISystemAppletProxy::GetLibraryAppletCreator(HLERequestContext& ctx) {

+ 20 - 0
src/core/hle/service/am/system_buffer_manager.cpp

@@ -4,6 +4,7 @@
 #include "core/hle/service/am/system_buffer_manager.h"
 #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
 #include "core/hle/service/nvnflinger/nvnflinger.h"
+#include "core/hle/service/vi/vi_results.h"
 
 namespace Service::AM {
 
@@ -41,9 +42,28 @@ bool SystemBufferManager::Initialize(Nvnflinger::Nvnflinger* nvnflinger, Kernel:
 
     if (res.IsSuccess()) {
         m_buffer_sharing_enabled = true;
+        m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible);
     }
 
     return m_buffer_sharing_enabled;
 }
 
+void SystemBufferManager::SetWindowVisibility(bool visible) {
+    if (m_visible == visible) {
+        return;
+    }
+
+    m_visible = visible;
+
+    if (m_nvnflinger) {
+        m_nvnflinger->SetLayerVisibility(m_system_shared_layer_id, m_visible);
+    }
+}
+
+Result SystemBufferManager::WriteAppletCaptureBuffer(bool* out_was_written,
+                                                     s32* out_fbshare_layer_index) {
+    // TODO
+    R_SUCCEED();
+}
+
 } // namespace Service::AM

+ 7 - 0
src/core/hle/service/am/system_buffer_manager.h

@@ -18,6 +18,8 @@ namespace Service::Nvnflinger {
 class Nvnflinger;
 }
 
+union Result;
+
 namespace Service::AM {
 
 class SystemBufferManager {
@@ -33,10 +35,15 @@ public:
         *out_system_shared_layer_id = m_system_shared_layer_id;
     }
 
+    void SetWindowVisibility(bool visible);
+
+    Result WriteAppletCaptureBuffer(bool* out_was_written, s32* out_fbshare_layer_index);
+
 private:
     Kernel::KProcess* m_process{};
     Nvnflinger::Nvnflinger* m_nvnflinger{};
     bool m_buffer_sharing_enabled{};
+    bool m_visible{true};
     u64 m_system_shared_buffer_id{};
     u64 m_system_shared_layer_id{};
 };

+ 33 - 2
src/core/hle/service/am/window_controller.cpp

@@ -17,8 +17,8 @@ IWindowController::IWindowController(Core::System& system_, std::shared_ptr<Appl
         {10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
         {11, nullptr, "ReleaseForegroundRights"},
         {12, nullptr, "RejectToChangeIntoBackground"},
-        {20, nullptr, "SetAppletWindowVisibility"},
-        {21, nullptr, "SetAppletGpuTimeSlice"},
+        {20, &IWindowController::SetAppletWindowVisibility, "SetAppletWindowVisibility"},
+        {21, &IWindowController::SetAppletGpuTimeSlice, "SetAppletGpuTimeSlice"},
     };
     // clang-format on
 
@@ -52,4 +52,35 @@ void IWindowController::AcquireForegroundRights(HLERequestContext& ctx) {
     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->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground);
+        applet->focus_state = FocusState::InFocus;
+    } else {
+        applet->focus_state = FocusState::NotInFocus;
+    }
+    applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
+
+    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

+ 2 - 0
src/core/hle/service/am/window_controller.h

@@ -18,6 +18,8 @@ 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;
 };

+ 35 - 13
src/core/hle/service/filesystem/fsp/fsp_srv.cpp

@@ -15,11 +15,13 @@
 #include "common/settings.h"
 #include "common/string_util.h"
 #include "core/core.h"
+#include "core/file_sys/content_archive.h"
 #include "core/file_sys/errors.h"
 #include "core/file_sys/fs_directory.h"
 #include "core/file_sys/fs_filesystem.h"
 #include "core/file_sys/nca_metadata.h"
 #include "core/file_sys/patch_manager.h"
+#include "core/file_sys/romfs.h"
 #include "core/file_sys/romfs_factory.h"
 #include "core/file_sys/savedata_factory.h"
 #include "core/file_sys/system_archive/system_archive.h"
@@ -33,18 +35,20 @@
 #include "core/hle/service/filesystem/save_data_controller.h"
 #include "core/hle/service/hle_ipc.h"
 #include "core/hle/service/ipc_helpers.h"
+#include "core/loader/loader.h"
 #include "core/reporter.h"
 
 namespace Service::FileSystem {
-enum class FileSystemType : u8 {
-    Invalid0 = 0,
-    Invalid1 = 1,
+enum class FileSystemProxyType : u8 {
+    Code = 0,
+    Rom = 1,
     Logo = 2,
-    ContentControl = 3,
-    ContentManual = 4,
-    ContentMeta = 5,
-    ContentData = 6,
-    ApplicationPackage = 7,
+    Control = 3,
+    Manual = 4,
+    Meta = 5,
+    Data = 6,
+    Package = 7,
+    RegisteredUpdate = 8,
 };
 
 class ISaveDataInfoReader final : public ServiceFramework<ISaveDataInfoReader> {
@@ -357,12 +361,30 @@ void FSP_SRV::SetCurrentProcess(HLERequestContext& ctx) {
 void FSP_SRV::OpenFileSystemWithPatch(HLERequestContext& ctx) {
     IPC::RequestParser rp{ctx};
 
-    const auto type = rp.PopRaw<FileSystemType>();
-    const auto title_id = rp.PopRaw<u64>();
-    LOG_WARNING(Service_FS, "(STUBBED) called with type={}, title_id={:016X}", type, title_id);
+    struct InputParameters {
+        FileSystemProxyType type;
+        u64 program_id;
+    };
+    static_assert(sizeof(InputParameters) == 0x10, "InputParameters has wrong size");
+
+    const auto params = rp.PopRaw<InputParameters>();
+    LOG_ERROR(Service_FS, "(STUBBED) called with type={}, program_id={:016X}", params.type,
+              params.program_id);
+
+    // FIXME: many issues with this
+    ASSERT(params.type == FileSystemProxyType::Manual);
+    const auto manual_romfs = romfs_controller->OpenPatchedRomFS(
+        params.program_id, FileSys::ContentRecordType::HtmlDocument);
 
-    IPC::ResponseBuilder rb{ctx, 2, 0, 0};
-    rb.Push(ResultUnknown);
+    ASSERT(manual_romfs != nullptr);
+
+    const auto extracted_romfs = FileSys::ExtractRomFS(manual_romfs);
+    ASSERT(extracted_romfs != nullptr);
+
+    IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+    rb.Push(ResultSuccess);
+    rb.PushIpcInterface<IFileSystem>(system, extracted_romfs,
+                                     SizeGetter::FromStorageId(fsc, FileSys::StorageId::NandUser));
 }
 
 void FSP_SRV::OpenSdCardFileSystem(HLERequestContext& ctx) {

+ 11 - 1
src/core/hle/service/nifm/nifm.cpp

@@ -185,7 +185,7 @@ public:
             {3, &IRequest::Cancel, "Cancel"},
             {4, &IRequest::Submit, "Submit"},
             {5, nullptr, "SetRequirement"},
-            {6, nullptr, "SetRequirementPreset"},
+            {6, &IRequest::SetRequirementPreset, "SetRequirementPreset"},
             {8, nullptr, "SetPriority"},
             {9, nullptr, "SetNetworkProfileId"},
             {10, nullptr, "SetRejectable"},
@@ -237,6 +237,16 @@ private:
         rb.PushEnum(state);
     }
 
+    void SetRequirementPreset(HLERequestContext& ctx) {
+        IPC::RequestParser rp{ctx};
+        const auto param_1 = rp.Pop<u32>();
+
+        LOG_WARNING(Service_NIFM, "(STUBBED) called, param_1={}", param_1);
+
+        IPC::ResponseBuilder rb{ctx, 2};
+        rb.Push(ResultSuccess);
+    }
+
     void GetResult(HLERequestContext& ctx) {
         LOG_DEBUG(Service_NIFM, "(STUBBED) called");
 

+ 64 - 3
src/core/hle/service/ns/ns.cpp

@@ -3,6 +3,7 @@
 
 #include "common/logging/log.h"
 #include "common/settings.h"
+#include "core/arm/debug.h"
 #include "core/core.h"
 #include "core/file_sys/control_metadata.h"
 #include "core/file_sys/patch_manager.h"
@@ -544,8 +545,8 @@ IDocumentInterface::IDocumentInterface(Core::System& system_)
     // clang-format off
     static const FunctionInfo functions[] = {
         {21, nullptr, "GetApplicationContentPath"},
-        {23, nullptr, "ResolveApplicationContentPath"},
-        {93, nullptr, "GetRunningApplicationProgramId"},
+        {23, &IDocumentInterface::ResolveApplicationContentPath, "ResolveApplicationContentPath"},
+        {92, &IDocumentInterface::GetRunningApplicationProgramId, "GetRunningApplicationProgramId"},
     };
     // clang-format on
 
@@ -554,6 +555,32 @@ IDocumentInterface::IDocumentInterface(Core::System& system_)
 
 IDocumentInterface::~IDocumentInterface() = default;
 
+void IDocumentInterface::ResolveApplicationContentPath(HLERequestContext& ctx) {
+    struct ContentPath {
+        u8 file_system_proxy_type;
+        u64 program_id;
+    };
+    static_assert(sizeof(ContentPath) == 0x10, "ContentPath has wrong size");
+
+    IPC::RequestParser rp{ctx};
+    auto content_path = rp.PopRaw<ContentPath>();
+    LOG_WARNING(Service_NS, "(STUBBED) called, file_system_proxy_type={}, program_id={:016X}",
+                content_path.file_system_proxy_type, content_path.program_id);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
+void IDocumentInterface::GetRunningApplicationProgramId(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    const auto caller_program_id = rp.PopRaw<u64>();
+    LOG_WARNING(Service_NS, "(STUBBED) called, caller_program_id={:016X}", caller_program_id);
+
+    IPC::ResponseBuilder rb{ctx, 4};
+    rb.Push(ResultSuccess);
+    rb.Push<u64>(system.GetApplicationProcessProgramID());
+}
+
 IDownloadTaskInterface::IDownloadTaskInterface(Core::System& system_)
     : ServiceFramework{system_, "IDownloadTaskInterface"} {
     // clang-format off
@@ -613,6 +640,40 @@ IFactoryResetInterface::IFactoryResetInterface(Core::System& system_)
 
 IFactoryResetInterface::~IFactoryResetInterface() = default;
 
+IReadOnlyApplicationRecordInterface::IReadOnlyApplicationRecordInterface(Core::System& system_)
+    : ServiceFramework{system_, "IReadOnlyApplicationRecordInterface"} {
+    static const FunctionInfo functions[] = {
+        {0, &IReadOnlyApplicationRecordInterface::HasApplicationRecord, "HasApplicationRecord"},
+        {1, nullptr, "NotifyApplicationFailure"},
+        {2, &IReadOnlyApplicationRecordInterface::IsDataCorruptedResult, "IsDataCorruptedResult"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+IReadOnlyApplicationRecordInterface::~IReadOnlyApplicationRecordInterface() = default;
+
+void IReadOnlyApplicationRecordInterface::HasApplicationRecord(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    const u64 program_id = rp.PopRaw<u64>();
+    LOG_WARNING(Service_NS, "(STUBBED) called, program_id={:X}", program_id);
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.Push<u8>(1);
+}
+
+void IReadOnlyApplicationRecordInterface::IsDataCorruptedResult(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    const auto result = rp.PopRaw<Result>();
+    LOG_WARNING(Service_NS, "(STUBBED) called, result={:#x}", result.GetInnerValue());
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.Push<u8>(0);
+}
+
 IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterface(
     Core::System& system_)
     : ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} {
@@ -663,7 +724,7 @@ NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name
     static const FunctionInfo functions[] = {
         {7988, nullptr, "GetDynamicRightsInterface"},
         {7989, &NS::PushInterface<IReadOnlyApplicationControlDataInterface>, "GetReadOnlyApplicationControlDataInterface"},
-        {7991, nullptr, "GetReadOnlyApplicationRecordInterface"},
+        {7991, &NS::PushInterface<IReadOnlyApplicationRecordInterface>, "GetReadOnlyApplicationRecordInterface"},
         {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
         {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"},
         {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"},

+ 15 - 0
src/core/hle/service/ns/ns.h

@@ -58,6 +58,10 @@ class IDocumentInterface final : public ServiceFramework<IDocumentInterface> {
 public:
     explicit IDocumentInterface(Core::System& system_);
     ~IDocumentInterface() override;
+
+private:
+    void ResolveApplicationContentPath(HLERequestContext& ctx);
+    void GetRunningApplicationProgramId(HLERequestContext& ctx);
 };
 
 class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
@@ -78,6 +82,17 @@ public:
     ~IFactoryResetInterface() override;
 };
 
+class IReadOnlyApplicationRecordInterface final
+    : public ServiceFramework<IReadOnlyApplicationRecordInterface> {
+public:
+    explicit IReadOnlyApplicationRecordInterface(Core::System& system_);
+    ~IReadOnlyApplicationRecordInterface() override;
+
+private:
+    void HasApplicationRecord(HLERequestContext& ctx);
+    void IsDataCorruptedResult(HLERequestContext& ctx);
+};
+
 class IReadOnlyApplicationControlDataInterface final
     : public ServiceFramework<IReadOnlyApplicationControlDataInterface> {
 public:

+ 10 - 0
src/core/hle/service/nvnflinger/nvnflinger.cpp

@@ -198,6 +198,16 @@ bool Nvnflinger::CloseLayer(u64 layer_id) {
     return false;
 }
 
+void Nvnflinger::SetLayerVisibility(u64 layer_id, bool visible) {
+    const auto lock_guard = Lock();
+
+    for (auto& display : displays) {
+        if (auto* layer = display.FindLayer(layer_id); layer) {
+            layer->SetVisibility(visible);
+        }
+    }
+}
+
 void Nvnflinger::DestroyLayer(u64 layer_id) {
     const auto lock_guard = Lock();
 

+ 3 - 0
src/core/hle/service/nvnflinger/nvnflinger.h

@@ -79,6 +79,9 @@ public:
     /// Closes a layer on all displays for the given layer ID.
     bool CloseLayer(u64 layer_id);
 
+    /// Makes a layer visible on all displays for the given layer ID.
+    void SetLayerVisibility(u64 layer_id, bool visible);
+
     /// Destroys the given layer ID.
     void DestroyLayer(u64 layer_id);
 

+ 2 - 2
src/core/hle/service/vi/display/vi_display.cpp

@@ -53,7 +53,7 @@ Display::~Display() {
 Layer& Display::GetLayer(std::size_t index) {
     size_t i = 0;
     for (auto& layer : layers) {
-        if (!layer->IsOpen()) {
+        if (!layer->IsOpen() || !layer->IsVisible()) {
             continue;
         }
 
@@ -68,7 +68,7 @@ Layer& Display::GetLayer(std::size_t index) {
 }
 
 size_t Display::GetNumLayers() const {
-    return std::ranges::count_if(layers, [](auto& l) { return l->IsOpen(); });
+    return std::ranges::count_if(layers, [](auto& l) { return l->IsOpen() && l->IsVisible(); });
 }
 
 Kernel::KReadableEvent* Display::GetVSyncEvent() {

+ 1 - 1
src/core/hle/service/vi/layer/vi_layer.cpp

@@ -9,7 +9,7 @@ Layer::Layer(u64 layer_id_, u32 binder_id_, android::BufferQueueCore& core_,
              android::BufferQueueProducer& binder_,
              std::shared_ptr<android::BufferItemConsumer>&& consumer_)
     : layer_id{layer_id_}, binder_id{binder_id_}, core{core_}, binder{binder_},
-      consumer{std::move(consumer_)}, open{false} {}
+      consumer{std::move(consumer_)}, open{false}, visible{true} {}
 
 Layer::~Layer() = default;
 

+ 9 - 0
src/core/hle/service/vi/layer/vi_layer.h

@@ -72,6 +72,14 @@ public:
         return core;
     }
 
+    bool IsVisible() const {
+        return visible;
+    }
+
+    void SetVisibility(bool v) {
+        visible = v;
+    }
+
     bool IsOpen() const {
         return open;
     }
@@ -91,6 +99,7 @@ private:
     android::BufferQueueProducer& binder;
     std::shared_ptr<android::BufferItemConsumer> consumer;
     bool open;
+    bool visible;
 };
 
 } // namespace Service::VI

+ 4 - 1
src/yuzu/main.cpp

@@ -4931,7 +4931,10 @@ void GMainWindow::changeEvent(QEvent* event) {
 }
 
 Service::AM::FrontendAppletParameters GMainWindow::ApplicationAppletParameters() {
-    return Service::AM::FrontendAppletParameters{};
+    return Service::AM::FrontendAppletParameters{
+        .applet_id = Service::AM::AppletId::Application,
+        .applet_type = Service::AM::AppletType::Application,
+    };
 }
 
 Service::AM::FrontendAppletParameters GMainWindow::LibraryAppletParameters(