diff options
Diffstat (limited to 'src/core/hle/service/am')
-rw-r--r-- | src/core/hle/service/am/am_types.h | 6 | ||||
-rw-r--r-- | src/core/hle/service/am/frontend/applet_software_keyboard.cpp | 12 | ||||
-rw-r--r-- | src/core/hle/service/am/frontend/applet_software_keyboard.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/am/library_applet_creator.cpp | 81 | ||||
-rw-r--r-- | src/core/hle/service/am/process.cpp | 23 | ||||
-rw-r--r-- | src/core/hle/service/am/process.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/am/self_controller.cpp | 18 | ||||
-rw-r--r-- | src/core/hle/service/am/self_controller.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/am/system_buffer_manager.cpp | 19 | ||||
-rw-r--r-- | src/core/hle/service/am/system_buffer_manager.h | 3 | ||||
-rw-r--r-- | src/core/hle/service/am/window_controller.cpp | 4 |
11 files changed, 126 insertions, 46 deletions
diff --git a/src/core/hle/service/am/am_types.h b/src/core/hle/service/am/am_types.h index a2b852b12..8c33feb15 100644 --- a/src/core/hle/service/am/am_types.h +++ b/src/core/hle/service/am/am_types.h @@ -130,9 +130,9 @@ enum class AppletProgramId : u64 { enum class LibraryAppletMode : u32 { AllForeground = 0, - Background = 1, - NoUI = 2, - BackgroundIndirectDisplay = 3, + PartialForeground = 1, + NoUi = 2, + PartialForegroundIndirectDisplay = 3, AllForegroundInitiallyHidden = 4, }; diff --git a/src/core/hle/service/am/frontend/applet_software_keyboard.cpp b/src/core/hle/service/am/frontend/applet_software_keyboard.cpp index fbf75d379..034c62f32 100644 --- a/src/core/hle/service/am/frontend/applet_software_keyboard.cpp +++ b/src/core/hle/service/am/frontend/applet_software_keyboard.cpp @@ -68,9 +68,9 @@ void SoftwareKeyboard::Initialize() { case LibraryAppletMode::AllForeground: InitializeForeground(); break; - case LibraryAppletMode::Background: - case LibraryAppletMode::BackgroundIndirectDisplay: - InitializeBackground(applet_mode); + case LibraryAppletMode::PartialForeground: + case LibraryAppletMode::PartialForegroundIndirectDisplay: + InitializePartialForeground(applet_mode); break; default: ASSERT_MSG(false, "Invalid LibraryAppletMode={}", applet_mode); @@ -243,7 +243,7 @@ void SoftwareKeyboard::InitializeForeground() { InitializeFrontendNormalKeyboard(); } -void SoftwareKeyboard::InitializeBackground(LibraryAppletMode library_applet_mode) { +void SoftwareKeyboard::InitializePartialForeground(LibraryAppletMode library_applet_mode) { LOG_INFO(Service_AM, "Initializing Inline Software Keyboard Applet."); is_background = true; @@ -258,9 +258,9 @@ void SoftwareKeyboard::InitializeBackground(LibraryAppletMode library_applet_mod swkbd_inline_initialize_arg.size()); if (swkbd_initialize_arg.library_applet_mode_flag) { - ASSERT(library_applet_mode == LibraryAppletMode::Background); + ASSERT(library_applet_mode == LibraryAppletMode::PartialForeground); } else { - ASSERT(library_applet_mode == LibraryAppletMode::BackgroundIndirectDisplay); + ASSERT(library_applet_mode == LibraryAppletMode::PartialForegroundIndirectDisplay); } } diff --git a/src/core/hle/service/am/frontend/applet_software_keyboard.h b/src/core/hle/service/am/frontend/applet_software_keyboard.h index f464b7e15..2a7d01b96 100644 --- a/src/core/hle/service/am/frontend/applet_software_keyboard.h +++ b/src/core/hle/service/am/frontend/applet_software_keyboard.h @@ -62,7 +62,7 @@ private: void InitializeForeground(); /// Initializes the inline software keyboard. - void InitializeBackground(LibraryAppletMode library_applet_mode); + void InitializePartialForeground(LibraryAppletMode library_applet_mode); /// Processes the text check sent by the application. void ProcessTextCheck(); diff --git a/src/core/hle/service/am/library_applet_creator.cpp b/src/core/hle/service/am/library_applet_creator.cpp index 47bab7528..00d5a0705 100644 --- a/src/core/hle/service/am/library_applet_creator.cpp +++ b/src/core/hle/service/am/library_applet_creator.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/settings.h" #include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/service/am/applet_data_broker.h" #include "core/hle/service/am/applet_manager.h" @@ -16,6 +17,34 @@ namespace Service::AM { namespace { +bool ShouldCreateGuestApplet(AppletId applet_id) { +#define X(Name, name) \ + if (applet_id == AppletId::Name && \ + Settings::values.name##_applet_mode.GetValue() != Settings::AppletMode::LLE) { \ + return false; \ + } + + X(Cabinet, cabinet) + X(Controller, controller) + X(DataErase, data_erase) + X(Error, error) + X(NetConnect, net_connect) + X(ProfileSelect, player_select) + X(SoftwareKeyboard, swkbd) + X(MiiEdit, mii_edit) + X(Web, web) + X(Shop, shop) + X(PhotoViewer, photo_viewer) + X(OfflineWeb, offline_web) + X(LoginShare, login_share) + X(WebAuth, wifi_web_auth) + X(MyPage, my_page) + +#undef X + + return true; +} + AppletProgramId AppletIdToProgramId(AppletId applet_id) { switch (applet_id) { case AppletId::OverlayDisplay: @@ -63,17 +92,26 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) { } } -[[maybe_unused]] std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet( - Core::System& system, std::shared_ptr<Applet> caller_applet, AppletId applet_id, - LibraryAppletMode mode) { +std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system, + std::shared_ptr<Applet> caller_applet, + AppletId applet_id, + LibraryAppletMode mode) { const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id)); if (program_id == 0) { // Unknown applet return {}; } + // TODO: enable other versions of applets + enum : u8 { + Firmware1400 = 14, + Firmware1500 = 15, + Firmware1600 = 16, + Firmware1700 = 17, + }; + auto process = std::make_unique<Process>(system); - if (!process->Initialize(program_id)) { + if (!process->Initialize(program_id, Firmware1400, Firmware1700)) { // Couldn't initialize the guest process return {}; } @@ -87,24 +125,18 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) { // Set focus state switch (mode) { case LibraryAppletMode::AllForeground: - case LibraryAppletMode::NoUI: - applet->focus_state = FocusState::InFocus; + case LibraryAppletMode::NoUi: + case LibraryAppletMode::PartialForeground: + case LibraryAppletMode::PartialForegroundIndirectDisplay: applet->hid_registration.EnableAppletToGetInput(true); + applet->focus_state = FocusState::InFocus; 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); + applet->focus_state = FocusState::NotInFocus; + applet->system_buffer_manager.SetWindowVisibility(false); + applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoBackground); break; } @@ -117,9 +149,10 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) { return std::make_shared<ILibraryAppletAccessor>(system, broker, applet); } -[[maybe_unused]] std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet( - Core::System& system, std::shared_ptr<Applet> caller_applet, AppletId applet_id, - LibraryAppletMode mode) { +std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system, + std::shared_ptr<Applet> caller_applet, + AppletId applet_id, + LibraryAppletMode mode) { const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id)); auto process = std::make_unique<Process>(system); @@ -163,7 +196,13 @@ void ILibraryAppletCreator::CreateLibraryApplet(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id, applet_mode); - auto library_applet = CreateFrontendApplet(system, applet, applet_id, applet_mode); + std::shared_ptr<ILibraryAppletAccessor> library_applet; + if (ShouldCreateGuestApplet(applet_id)) { + library_applet = CreateGuestApplet(system, applet, applet_id, applet_mode); + } + if (!library_applet) { + library_applet = CreateFrontendApplet(system, applet, applet_id, applet_mode); + } if (!library_applet) { LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); diff --git a/src/core/hle/service/am/process.cpp b/src/core/hle/service/am/process.cpp index 16b685f86..992c50713 100644 --- a/src/core/hle/service/am/process.cpp +++ b/src/core/hle/service/am/process.cpp @@ -3,6 +3,7 @@ #include "common/scope_exit.h" +#include "core/file_sys/content_archive.h" #include "core/file_sys/nca_metadata.h" #include "core/file_sys/registered_cache.h" #include "core/hle/kernel/k_process.h" @@ -20,7 +21,7 @@ Process::~Process() { this->Finalize(); } -bool Process::Initialize(u64 program_id) { +bool Process::Initialize(u64 program_id, u8 minimum_key_generation, u8 maximum_key_generation) { // First, ensure we are not holding another process. this->Finalize(); @@ -29,21 +30,33 @@ bool Process::Initialize(u64 program_id) { // Attempt to load program NCA. const FileSys::RegisteredCache* bis_system{}; - FileSys::VirtualFile nca{}; + FileSys::VirtualFile nca_raw{}; // Get the program NCA from built-in storage. bis_system = fsc.GetSystemNANDContents(); if (bis_system) { - nca = bis_system->GetEntryRaw(program_id, FileSys::ContentRecordType::Program); + nca_raw = bis_system->GetEntryRaw(program_id, FileSys::ContentRecordType::Program); } // Ensure we retrieved a program NCA. - if (!nca) { + if (!nca_raw) { return false; } + // Ensure we have a suitable version. + if (minimum_key_generation > 0) { + FileSys::NCA nca(nca_raw); + if (nca.GetStatus() == Loader::ResultStatus::Success && + (nca.GetKeyGeneration() < minimum_key_generation || + nca.GetKeyGeneration() > maximum_key_generation)) { + LOG_WARNING(Service_LDR, "Skipping program {:016X} with generation {}", program_id, + nca.GetKeyGeneration()); + return false; + } + } + // Get the appropriate loader to parse this NCA. - auto app_loader = Loader::GetLoader(m_system, nca, program_id, 0); + auto app_loader = Loader::GetLoader(m_system, nca_raw, program_id, 0); // Ensure we have a loader which can parse the NCA. if (!app_loader) { diff --git a/src/core/hle/service/am/process.h b/src/core/hle/service/am/process.h index 4b908ade4..4b8102fb6 100644 --- a/src/core/hle/service/am/process.h +++ b/src/core/hle/service/am/process.h @@ -21,7 +21,7 @@ public: explicit Process(Core::System& system); ~Process(); - bool Initialize(u64 program_id); + bool Initialize(u64 program_id, u8 minimum_key_generation, u8 maximum_key_generation); void Finalize(); bool Run(); diff --git a/src/core/hle/service/am/self_controller.cpp b/src/core/hle/service/am/self_controller.cpp index 0289f5cf1..65e249c0c 100644 --- a/src/core/hle/service/am/self_controller.cpp +++ b/src/core/hle/service/am/self_controller.cpp @@ -1,10 +1,13 @@ // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/logging/log.h" +#include "core/hle/result.h" #include "core/hle/service/am/am_results.h" #include "core/hle/service/am/frontend/applets.h" #include "core/hle/service/am/self_controller.h" #include "core/hle/service/caps/caps_su.h" +#include "core/hle/service/hle_ipc.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h" #include "core/hle/service/nvnflinger/nvnflinger.h" @@ -47,7 +50,7 @@ ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"}, {51, &ISelfController::ApproveToDisplay, "ApproveToDisplay"}, {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"}, - {61, nullptr, "SetMediaPlaybackState"}, + {61, &ISelfController::SetMediaPlaybackState, "SetMediaPlaybackState"}, {62, &ISelfController::SetIdleTimeDetectionExtension, "SetIdleTimeDetectionExtension"}, {63, &ISelfController::GetIdleTimeDetectionExtension, "GetIdleTimeDetectionExtension"}, {64, nullptr, "SetInputDetectionSourceSet"}, @@ -288,7 +291,8 @@ void ISelfController::GetSystemSharedBufferHandle(HLERequestContext& ctx) { } Result ISelfController::EnsureBufferSharingEnabled(Kernel::KProcess* process) { - if (applet->system_buffer_manager.Initialize(&nvnflinger, process, applet->applet_id)) { + if (applet->system_buffer_manager.Initialize(&nvnflinger, process, applet->applet_id, + applet->library_applet_mode)) { return ResultSuccess; } @@ -323,6 +327,16 @@ void ISelfController::ApproveToDisplay(HLERequestContext& ctx) { rb.Push(ResultSuccess); } +void ISelfController::SetMediaPlaybackState(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u8 state = rp.Pop<u8>(); + + LOG_WARNING(Service_AM, "(STUBBED) called, state={}", state); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; diff --git a/src/core/hle/service/am/self_controller.h b/src/core/hle/service/am/self_controller.h index a63bc2e74..ab21a1881 100644 --- a/src/core/hle/service/am/self_controller.h +++ b/src/core/hle/service/am/self_controller.h @@ -3,6 +3,7 @@ #pragma once +#include "core/hle/service/hle_ipc.h" #include "core/hle/service/kernel_helpers.h" #include "core/hle/service/service.h" @@ -38,6 +39,7 @@ private: void CreateManagedDisplaySeparableLayer(HLERequestContext& ctx); void SetHandlesRequestToDisplay(HLERequestContext& ctx); void ApproveToDisplay(HLERequestContext& ctx); + void SetMediaPlaybackState(HLERequestContext& ctx); void SetIdleTimeDetectionExtension(HLERequestContext& ctx); void GetIdleTimeDetectionExtension(HLERequestContext& ctx); void ReportUserIsActive(HLERequestContext& ctx); diff --git a/src/core/hle/service/am/system_buffer_manager.cpp b/src/core/hle/service/am/system_buffer_manager.cpp index 60a9afc9d..48923fe41 100644 --- a/src/core/hle/service/am/system_buffer_manager.cpp +++ b/src/core/hle/service/am/system_buffer_manager.cpp @@ -17,11 +17,12 @@ SystemBufferManager::~SystemBufferManager() { // Clean up shared layers. if (m_buffer_sharing_enabled) { + m_nvnflinger->GetSystemBufferManager().Finalize(m_process); } } bool SystemBufferManager::Initialize(Nvnflinger::Nvnflinger* nvnflinger, Kernel::KProcess* process, - AppletId applet_id) { + AppletId applet_id, LibraryAppletMode mode) { if (m_nvnflinger) { return m_buffer_sharing_enabled; } @@ -36,9 +37,15 @@ bool SystemBufferManager::Initialize(Nvnflinger::Nvnflinger* nvnflinger, Kernel: return false; } + Nvnflinger::LayerBlending blending = Nvnflinger::LayerBlending::None; + if (mode == LibraryAppletMode::PartialForeground || + mode == LibraryAppletMode::PartialForegroundIndirectDisplay) { + blending = Nvnflinger::LayerBlending::Coverage; + } + const auto display_id = m_nvnflinger->OpenDisplay("Default").value(); const auto res = m_nvnflinger->GetSystemBufferManager().Initialize( - &m_system_shared_buffer_id, &m_system_shared_layer_id, display_id); + m_process, &m_system_shared_buffer_id, &m_system_shared_layer_id, display_id, blending); if (res.IsSuccess()) { m_buffer_sharing_enabled = true; @@ -62,8 +69,12 @@ void SystemBufferManager::SetWindowVisibility(bool visible) { Result SystemBufferManager::WriteAppletCaptureBuffer(bool* out_was_written, s32* out_fbshare_layer_index) { - // TODO - R_SUCCEED(); + if (!m_buffer_sharing_enabled) { + return VI::ResultPermissionDenied; + } + + return m_nvnflinger->GetSystemBufferManager().WriteAppletCaptureBuffer(out_was_written, + out_fbshare_layer_index); } } // namespace Service::AM diff --git a/src/core/hle/service/am/system_buffer_manager.h b/src/core/hle/service/am/system_buffer_manager.h index 98c3cf055..0690f68b6 100644 --- a/src/core/hle/service/am/system_buffer_manager.h +++ b/src/core/hle/service/am/system_buffer_manager.h @@ -27,7 +27,8 @@ public: SystemBufferManager(); ~SystemBufferManager(); - bool Initialize(Nvnflinger::Nvnflinger* flinger, Kernel::KProcess* process, AppletId applet_id); + bool Initialize(Nvnflinger::Nvnflinger* flinger, Kernel::KProcess* process, AppletId applet_id, + LibraryAppletMode mode); void GetSystemSharedLayerHandle(u64* out_system_shared_buffer_id, u64* out_system_shared_layer_id) { diff --git a/src/core/hle/service/am/window_controller.cpp b/src/core/hle/service/am/window_controller.cpp index f00957f83..c07ef228b 100644 --- a/src/core/hle/service/am/window_controller.cpp +++ b/src/core/hle/service/am/window_controller.cpp @@ -62,12 +62,12 @@ void IWindowController::SetAppletWindowVisibility(HLERequestContext& ctx) { applet->hid_registration.EnableAppletToGetInput(visible); if (visible) { - applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground); applet->focus_state = FocusState::InFocus; + applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoForeground); } else { applet->focus_state = FocusState::NotInFocus; + applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::ChangeIntoBackground); } - applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); |