From 136ba33e6a92f87d036842aeff39606ec14048b4 Mon Sep 17 00:00:00 2001 From: Liam Date: Mon, 12 Feb 2024 11:01:37 -0500 Subject: [PATCH] am: move main applet initialization to service process --- src/core/core.cpp | 121 +++++----------- src/core/hle/service/am/am.cpp | 8 +- src/core/hle/service/am/applet_manager.cpp | 133 ++++++------------ src/core/hle/service/am/applet_manager.h | 32 +++-- src/core/hle/service/am/hid_registration.cpp | 8 +- src/core/hle/service/am/process_creation.cpp | 65 +++++---- src/core/hle/service/am/process_creation.h | 12 +- .../all_system_applet_proxies_service.cpp | 16 ++- .../all_system_applet_proxies_service.h | 5 +- .../am/service/application_functions.cpp | 3 +- .../service/am/service/application_proxy.cpp | 11 +- .../service/am/service/application_proxy.h | 4 +- .../am/service/application_proxy_service.cpp | 12 +- .../am/service/application_proxy_service.h | 5 +- .../am/service/home_menu_functions.cpp | 18 ++- .../service/am/service/home_menu_functions.h | 5 +- .../am/service/library_applet_creator.cpp | 37 +++-- .../am/service/library_applet_creator.h | 5 +- .../am/service/library_applet_proxy.cpp | 14 +- .../service/am/service/library_applet_proxy.h | 4 +- .../service/library_applet_self_accessor.cpp | 2 +- .../service/am/service/self_controller.cpp | 21 ++- .../am/service/system_applet_proxy.cpp | 14 +- .../service/am/service/system_applet_proxy.h | 4 +- .../service/am/service/window_controller.cpp | 15 +- .../service/am/service/window_controller.h | 5 +- src/core/hle/service/am/window_system.cpp | 9 +- src/core/hle/service/am/window_system.h | 5 +- src/core/hle/service/hid/hid.cpp | 4 - src/core/hle/service/os/process.cpp | 3 +- src/core/hle/service/os/process.h | 5 +- src/yuzu/main.cpp | 7 - src/yuzu/main.h | 1 - 33 files changed, 288 insertions(+), 325 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 9e8936728..3b506375c 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include @@ -20,7 +19,6 @@ #include "core/cpu_manager.h" #include "core/debugger/debugger.h" #include "core/device_memory.h" -#include "core/file_sys/bis_factory.h" #include "core/file_sys/fs_filesystem.h" #include "core/file_sys/patch_manager.h" #include "core/file_sys/registered_cache.h" @@ -38,6 +36,7 @@ #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/frontend/applets.h" +#include "core/hle/service/am/process_creation.h" #include "core/hle/service/apm/apm_controller.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/glue/glue_manager.h" @@ -72,30 +71,6 @@ MICROPROFILE_DEFINE(ARM_CPU3, "ARM", "CPU 3", MP_RGB(255, 64, 64)); namespace Core { -namespace { - -FileSys::StorageId GetStorageIdForFrontendSlot( - std::optional slot) { - if (!slot.has_value()) { - return FileSys::StorageId::None; - } - - switch (*slot) { - case FileSys::ContentProviderUnionSlot::UserNAND: - return FileSys::StorageId::NandUser; - case FileSys::ContentProviderUnionSlot::SysNAND: - return FileSys::StorageId::NandSystem; - case FileSys::ContentProviderUnionSlot::SDMC: - return FileSys::StorageId::SdCard; - case FileSys::ContentProviderUnionSlot::FrontendManual: - return FileSys::StorageId::Host; - default: - return FileSys::StorageId::None; - } -} - -} // Anonymous namespace - FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, const std::string& path) { // To account for split 00+01+etc files. @@ -297,9 +272,6 @@ struct System::Impl { } SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) { - /// Reset all glue registrations - arp_manager.ResetAll(); - telemetry_session = std::make_unique(); host1x_core = std::make_unique(system); @@ -335,33 +307,17 @@ struct System::Impl { SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window, const std::string& filepath, Service::AM::FrontendAppletParameters& params) { - app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath), - params.program_id, params.program_index); - - if (!app_loader) { - LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); - return SystemResultStatus::ErrorGetLoader; - } - - if (app_loader->ReadProgramId(params.program_id) != Loader::ResultStatus::Success) { - LOG_ERROR(Core, "Failed to find title id for ROM!"); - } - - std::string name = "Unknown program"; - if (app_loader->ReadTitle(name) != Loader::ResultStatus::Success) { - LOG_ERROR(Core, "Failed to read title for ROM!"); - } - - LOG_INFO(Core, "Loading {} ({})", name, params.program_id); - InitializeKernel(system); - // Create the application process. - auto main_process = Kernel::KProcess::Create(system.Kernel()); - Kernel::KProcess::Register(system.Kernel(), main_process); - kernel.AppendNewProcess(main_process); - kernel.MakeApplicationProcess(main_process); - const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); + const auto file = GetGameFileFromPath(virtual_filesystem, filepath); + + // Create the application process + Loader::ResultStatus load_result{}; + std::vector control; + auto process = + Service::AM::CreateApplicationProcess(control, app_loader, load_result, system, file, + params.program_id, params.program_index); + if (load_result != Loader::ResultStatus::Success) { LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); ShutdownMainProcess(); @@ -370,6 +326,25 @@ struct System::Impl { static_cast(SystemResultStatus::ErrorLoader) + static_cast(load_result)); } + if (!app_loader) { + LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); + return SystemResultStatus::ErrorGetLoader; + } + + if (app_loader->ReadProgramId(params.program_id) != Loader::ResultStatus::Success) { + LOG_ERROR(Core, "Failed to find program id for ROM!"); + } + + std::string name = "Unknown program"; + if (app_loader->ReadTitle(name) != Loader::ResultStatus::Success) { + LOG_ERROR(Core, "Failed to read title for ROM!"); + } + + LOG_INFO(Core, "Loading {} ({:016X}) ...", name, params.program_id); + + // Make the process created be the application + kernel.MakeApplicationProcess(process->GetHandle()); + // Set up the rest of the system. SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)}; if (init_result != SystemResultStatus::Success) { @@ -379,7 +354,6 @@ struct System::Impl { return init_result; } - AddGlueRegistrationForProcess(*app_loader, *main_process); telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); // Initialize cheat engine @@ -388,13 +362,7 @@ struct System::Impl { } // Register with applet manager. - applet_manager.CreateAndInsertByFrontendAppletParameters(main_process->GetProcessId(), - params); - - // All threads are started, begin main process execution, now that we're in the clear. - main_process->Run(load_parameters->main_thread_priority, - load_parameters->main_thread_stack_size); - main_process->Close(); + applet_manager.CreateAndInsertByFrontendAppletParameters(std::move(process), params); if (Settings::values.gamecard_inserted) { if (Settings::values.gamecard_current_game) { @@ -466,7 +434,6 @@ struct System::Impl { kernel.SuspendEmulation(true); kernel.CloseServices(); kernel.ShutdownCores(); - applet_manager.Reset(); services.reset(); service_manager.reset(); fs_controller.Reset(); @@ -492,6 +459,9 @@ struct System::Impl { // Workarounds Settings::values.renderer_amdvlk_depth_bias_workaround = false; + // Reset all glue registrations + arp_manager.ResetAll(); + LOG_DEBUG(Core, "Shutdown OK"); } @@ -509,31 +479,6 @@ struct System::Impl { return app_loader->ReadTitle(out); } - void AddGlueRegistrationForProcess(Loader::AppLoader& loader, Kernel::KProcess& process) { - std::vector nacp_data; - FileSys::NACP nacp; - if (loader.ReadControlData(nacp) == Loader::ResultStatus::Success) { - nacp_data = nacp.GetRawBytes(); - } else { - nacp_data.resize(sizeof(FileSys::RawNACP)); - } - - Service::Glue::ApplicationLaunchProperty launch{}; - launch.title_id = process.GetProgramId(); - - FileSys::PatchManager pm{launch.title_id, fs_controller, *content_provider}; - launch.version = pm.GetGameVersion().value_or(0); - - // TODO(DarkLordZach): When FSController/Game Card Support is added, if - // current_process_game_card use correct StorageId - launch.base_game_storage_id = GetStorageIdForFrontendSlot(content_provider->GetSlotForEntry( - launch.title_id, FileSys::ContentRecordType::Program)); - launch.update_storage_id = GetStorageIdForFrontendSlot(content_provider->GetSlotForEntry( - FileSys::GetUpdateTitleID(launch.title_id), FileSys::ContentRecordType::Program)); - - arp_manager.Register(launch.title_id, launch, std::move(nacp_data)); - } - void SetStatus(SystemResultStatus new_status, const char* details = nullptr) { status = new_status; if (details) { diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 741a7cd6e..2ef393439 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -18,10 +18,10 @@ void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); - server_manager->RegisterNamedService("appletAE", - std::make_shared(system)); - server_manager->RegisterNamedService("appletOE", - std::make_shared(system)); + server_manager->RegisterNamedService( + "appletAE", std::make_shared(system, window_system)); + server_manager->RegisterNamedService( + "appletOE", std::make_shared(system, window_system)); ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/am/applet_manager.cpp b/src/core/hle/service/am/applet_manager.cpp index f0b2d28b8..c6b7ec8bb 100644 --- a/src/core/hle/service/am/applet_manager.cpp +++ b/src/core/hle/service/am/applet_manager.cpp @@ -13,6 +13,7 @@ #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/service/storage.h" +#include "core/hle/service/am/window_system.h" #include "hid_core/hid_types.h" namespace Service::AM { @@ -225,55 +226,46 @@ void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& chan } // namespace AppletManager::AppletManager(Core::System& system) : m_system(system) {} -AppletManager::~AppletManager() { - this->Reset(); -} - -void AppletManager::InsertApplet(std::shared_ptr applet) { - std::scoped_lock lk{m_lock}; - - m_applets.emplace(applet->aruid.pid, std::move(applet)); -} - -void AppletManager::TerminateAndRemoveApplet(u64 aruid) { - std::shared_ptr applet; - bool should_stop = false; - { - std::scoped_lock lk{m_lock}; - - const auto it = m_applets.find(aruid); - if (it == m_applets.end()) { - return; - } - - applet = it->second; - m_applets.erase(it); - - should_stop = m_applets.empty(); - } - - // Terminate process. - applet->process->Terminate(); - - { - std::scoped_lock lk{applet->lock}; - applet->OnProcessTerminatedLocked(); - } - - // If there were no applets left, stop emulation. - if (should_stop) { - m_system.Exit(); - } -} +AppletManager::~AppletManager() = default; void AppletManager::CreateAndInsertByFrontendAppletParameters( - u64 aruid, const FrontendAppletParameters& params) { - // TODO: this should be run inside AM so that the events will have a parent process - // TODO: have am create the guest process - auto applet = std::make_shared(m_system, std::make_unique(m_system), + std::unique_ptr process, const FrontendAppletParameters& params) { + { + std::scoped_lock lk{m_lock}; + m_pending_process = std::move(process); + m_pending_parameters = params; + } + m_cv.notify_all(); +} + +void AppletManager::RequestExit() { + std::scoped_lock lk{m_lock}; + if (m_window_system) { + m_window_system->OnExitRequested(); + } +} + +void AppletManager::OperationModeChanged() { + std::scoped_lock lk{m_lock}; + if (m_window_system) { + m_window_system->OnOperationModeChanged(); + } +} + +void AppletManager::SetWindowSystem(WindowSystem* window_system) { + std::unique_lock lk{m_lock}; + + m_window_system = window_system; + if (!m_window_system) { + return; + } + + m_cv.wait(lk, [&] { return m_pending_process != nullptr; }); + + const auto& params = m_pending_parameters; + auto applet = std::make_shared(m_system, std::move(m_pending_process), params.applet_id == AppletId::Application); - applet->aruid.pid = aruid; applet->program_id = params.program_id; applet->applet_id = params.applet_id; applet->type = params.applet_type; @@ -330,50 +322,17 @@ void AppletManager::CreateAndInsertByFrontendAppletParameters( // Applet was started by frontend, so it is foreground. applet->lifecycle_manager.SetFocusState(FocusState::InFocus); - this->InsertApplet(std::move(applet)); -} - -std::shared_ptr AppletManager::GetByAppletResourceUserId(u64 aruid) const { - std::scoped_lock lk{m_lock}; - - if (const auto it = m_applets.find(aruid); it != m_applets.end()) { - return it->second; + if (applet->applet_id == AppletId::QLaunch) { + applet->lifecycle_manager.SetFocusHandlingMode(false); + applet->lifecycle_manager.SetOutOfFocusSuspendingEnabled(false); + m_window_system->TrackApplet(applet, false); + m_window_system->RequestHomeMenuToGetForeground(); + } else { + m_window_system->TrackApplet(applet, true); + m_window_system->RequestApplicationToGetForeground(); } - return {}; -} - -void AppletManager::Reset() { - std::scoped_lock lk{m_lock}; - - m_applets.clear(); -} - -void AppletManager::RequestExit() { - std::scoped_lock lk{m_lock}; - - for (const auto& [aruid, applet] : m_applets) { - std::scoped_lock lk2{applet->lock}; - applet->lifecycle_manager.RequestExit(); - } -} - -void AppletManager::RequestResume() { - std::scoped_lock lk{m_lock}; - - for (const auto& [aruid, applet] : m_applets) { - std::scoped_lock lk2{applet->lock}; - applet->lifecycle_manager.RequestResumeNotification(); - } -} - -void AppletManager::OperationModeChanged() { - std::scoped_lock lk{m_lock}; - - for (const auto& [aruid, applet] : m_applets) { - std::scoped_lock lk2{applet->lock}; - applet->lifecycle_manager.OnOperationAndPerformanceModeChanged(); - } + applet->process->Run(); } } // namespace Service::AM diff --git a/src/core/hle/service/am/applet_manager.h b/src/core/hle/service/am/applet_manager.h index 44143e26a..fbdc77140 100644 --- a/src/core/hle/service/am/applet_manager.h +++ b/src/core/hle/service/am/applet_manager.h @@ -3,17 +3,23 @@ #pragma once -#include +#include #include -#include "core/hle/service/am/applet.h" +#include "core/hle/service/am/am_types.h" namespace Core { class System; } +namespace Service { +class Process; +} + namespace Service::AM { +class WindowSystem; + enum class LaunchType { FrontendInitiated, ApplicationInitiated, @@ -33,26 +39,24 @@ public: explicit AppletManager(Core::System& system); ~AppletManager(); - void InsertApplet(std::shared_ptr applet); - void TerminateAndRemoveApplet(u64 aruid); - - void CreateAndInsertByFrontendAppletParameters(u64 aruid, + void CreateAndInsertByFrontendAppletParameters(std::unique_ptr process, const FrontendAppletParameters& params); - std::shared_ptr GetByAppletResourceUserId(u64 aruid) const; - - void Reset(); - void RequestExit(); - void RequestResume(); void OperationModeChanged(); +public: + void SetWindowSystem(WindowSystem* window_system); + private: Core::System& m_system; - mutable std::mutex m_lock{}; - std::map> m_applets{}; + std::mutex m_lock; + std::condition_variable m_cv; - // AudioController state goes here + WindowSystem* m_window_system{}; + + FrontendAppletParameters m_pending_parameters{}; + std::unique_ptr m_pending_process{}; }; } // namespace Service::AM diff --git a/src/core/hle/service/am/hid_registration.cpp b/src/core/hle/service/am/hid_registration.cpp index 793ba2e14..ea4bd8f45 100644 --- a/src/core/hle/service/am/hid_registration.cpp +++ b/src/core/hle/service/am/hid_registration.cpp @@ -11,16 +11,20 @@ namespace Service::AM { HidRegistration::HidRegistration(Core::System& system, Process& process) : m_process(process) { - m_hid_server = system.ServiceManager().GetService("hid"); + m_hid_server = system.ServiceManager().GetService("hid", true); if (m_process.IsInitialized()) { m_hid_server->GetResourceManager()->RegisterAppletResourceUserId(m_process.GetProcessId(), true); + m_hid_server->GetResourceManager()->SetAruidValidForVibration(m_process.GetProcessId(), + true); } } HidRegistration::~HidRegistration() { if (m_process.IsInitialized()) { + m_hid_server->GetResourceManager()->SetAruidValidForVibration(m_process.GetProcessId(), + false); m_hid_server->GetResourceManager()->UnregisterAppletResourceUserId( m_process.GetProcessId()); } @@ -28,6 +32,8 @@ HidRegistration::~HidRegistration() { void HidRegistration::EnableAppletToGetInput(bool enable) { if (m_process.IsInitialized()) { + m_hid_server->GetResourceManager()->SetAruidValidForVibration(m_process.GetProcessId(), + enable); m_hid_server->GetResourceManager()->EnableInput(m_process.GetProcessId(), enable); } } diff --git a/src/core/hle/service/am/process_creation.cpp b/src/core/hle/service/am/process_creation.cpp index 773f05bb8..237151d06 100644 --- a/src/core/hle/service/am/process_creation.cpp +++ b/src/core/hle/service/am/process_creation.cpp @@ -37,8 +37,30 @@ FileSys::StorageId GetStorageIdForFrontendSlot( } std::unique_ptr CreateProcessImpl(std::unique_ptr& out_loader, - Core::System& system, u64 program_id, - u8 minimum_key_generation, u8 maximum_key_generation) { + Loader::ResultStatus& out_load_result, + Core::System& system, FileSys::VirtualFile file, + u64 program_id, u64 program_index) { + // Get the appropriate loader to parse this NCA. + out_loader = Loader::GetLoader(system, file, program_id, program_index); + + // Ensure we have a loader which can parse the NCA. + if (!out_loader) { + return nullptr; + } + + // Try to load the process. + auto process = std::make_unique(system); + if (process->Initialize(*out_loader, out_load_result)) { + return process; + } + + return nullptr; +} + +} // Anonymous namespace + +std::unique_ptr CreateProcess(Core::System& system, u64 program_id, + u8 minimum_key_generation, u8 maximum_key_generation) { // Attempt to load program NCA. FileSys::VirtualFile nca_raw{}; @@ -63,43 +85,24 @@ std::unique_ptr CreateProcessImpl(std::unique_ptr& o } } - // Get the appropriate loader to parse this NCA. - out_loader = Loader::GetLoader(system, nca_raw, program_id, 0); - - // Ensure we have a loader which can parse the NCA. - if (!out_loader) { - return nullptr; - } - - // Try to load the process. - auto process = std::make_unique(system); - if (process->Initialize(*out_loader)) { - return process; - } - - return nullptr; -} - -} // Anonymous namespace - -std::unique_ptr CreateProcess(Core::System& system, u64 program_id, - u8 minimum_key_generation, u8 maximum_key_generation) { std::unique_ptr loader; - return CreateProcessImpl(loader, system, program_id, minimum_key_generation, - maximum_key_generation); + Loader::ResultStatus status; + return CreateProcessImpl(loader, status, system, nca_raw, program_id, 0); } std::unique_ptr CreateApplicationProcess(std::vector& out_control, - Core::System& system, u64 application_id, - u64 program_id) { - std::unique_ptr loader; - auto process = CreateProcessImpl(loader, system, program_id, 0, 0); + std::unique_ptr& out_loader, + Loader::ResultStatus& out_load_result, + Core::System& system, FileSys::VirtualFile file, + u64 program_id, u64 program_index) { + auto process = + CreateProcessImpl(out_loader, out_load_result, system, file, program_id, program_index); if (!process) { return nullptr; } FileSys::NACP nacp; - if (loader->ReadControlData(nacp) == Loader::ResultStatus::Success) { + if (out_loader->ReadControlData(nacp) == Loader::ResultStatus::Success) { out_control = nacp.GetRawBytes(); } else { out_control.resize(sizeof(FileSys::RawNACP)); @@ -107,7 +110,7 @@ std::unique_ptr CreateApplicationProcess(std::vector& out_control, auto& storage = system.GetContentProviderUnion(); Service::Glue::ApplicationLaunchProperty launch{}; - launch.title_id = program_id; + launch.title_id = process->GetProgramId(); FileSys::PatchManager pm{launch.title_id, system.GetFileSystemController(), storage}; launch.version = pm.GetGameVersion().value_or(0); diff --git a/src/core/hle/service/am/process_creation.h b/src/core/hle/service/am/process_creation.h index 081c5a1af..8cfb9e0c9 100644 --- a/src/core/hle/service/am/process_creation.h +++ b/src/core/hle/service/am/process_creation.h @@ -7,11 +7,17 @@ #include #include "common/common_types.h" +#include "core/file_sys/vfs/vfs_types.h" namespace Core { class System; } +namespace Loader { +class AppLoader; +enum class ResultStatus : u16; +} // namespace Loader + namespace Service { class Process; } @@ -21,7 +27,9 @@ namespace Service::AM { std::unique_ptr CreateProcess(Core::System& system, u64 program_id, u8 minimum_key_generation, u8 maximum_key_generation); std::unique_ptr CreateApplicationProcess(std::vector& out_control, - Core::System& system, u64 application_id, - u64 program_id); + std::unique_ptr& out_loader, + Loader::ResultStatus& out_load_result, + Core::System& system, FileSys::VirtualFile file, + u64 program_id, u64 program_index); } // namespace Service::AM diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp index 21747783a..bc9c86c55 100644 --- a/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp +++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.cpp @@ -6,12 +6,14 @@ #include "core/hle/service/am/service/all_system_applet_proxies_service.h" #include "core/hle/service/am/service/library_applet_proxy.h" #include "core/hle/service/am/service/system_applet_proxy.h" +#include "core/hle/service/am/window_system.h" #include "core/hle/service/cmif_serialization.h" namespace Service::AM { -IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_) - : ServiceFramework{system_, "appletAE"} { +IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_, + WindowSystem& window_system) + : ServiceFramework{system_, "appletAE"}, m_window_system{window_system} { // clang-format off static const FunctionInfo functions[] = { {100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"}, @@ -36,8 +38,8 @@ Result IAllSystemAppletProxiesService::OpenSystemAppletProxy( LOG_DEBUG(Service_AM, "called"); if (const auto applet = this->GetAppletFromProcessId(pid); applet) { - *out_system_applet_proxy = - std::make_shared(system, applet, process_handle.Get()); + *out_system_applet_proxy = std::make_shared( + system, applet, process_handle.Get(), m_window_system); R_SUCCEED(); } else { UNIMPLEMENTED(); @@ -52,8 +54,8 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy( LOG_DEBUG(Service_AM, "called"); if (const auto applet = this->GetAppletFromProcessId(pid); applet) { - *out_library_applet_proxy = - std::make_shared(system, applet, process_handle.Get()); + *out_library_applet_proxy = std::make_shared( + system, applet, process_handle.Get(), m_window_system); R_SUCCEED(); } else { UNIMPLEMENTED(); @@ -73,7 +75,7 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld( std::shared_ptr IAllSystemAppletProxiesService::GetAppletFromProcessId( ProcessId process_id) { - return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid); + return m_window_system.GetByAppletResourceUserId(process_id.pid); } } // namespace Service::AM diff --git a/src/core/hle/service/am/service/all_system_applet_proxies_service.h b/src/core/hle/service/am/service/all_system_applet_proxies_service.h index 0e2dcb86d..e3e79dc4f 100644 --- a/src/core/hle/service/am/service/all_system_applet_proxies_service.h +++ b/src/core/hle/service/am/service/all_system_applet_proxies_service.h @@ -14,11 +14,12 @@ struct Applet; struct AppletAttribute; class ILibraryAppletProxy; class ISystemAppletProxy; +class WindowSystem; class IAllSystemAppletProxiesService final : public ServiceFramework { public: - explicit IAllSystemAppletProxiesService(Core::System& system_); + explicit IAllSystemAppletProxiesService(Core::System& system_, WindowSystem& window_system); ~IAllSystemAppletProxiesService() override; private: @@ -35,6 +36,8 @@ private: private: std::shared_ptr GetAppletFromProcessId(ProcessId pid); + + WindowSystem& m_window_system; }; } // namespace AM diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp index bfccb6b09..3bab5ac5f 100644 --- a/src/core/hle/service/am/service/application_functions.cpp +++ b/src/core/hle/service/am/service/application_functions.cpp @@ -181,7 +181,8 @@ Result IApplicationFunctions::GetDesiredLanguage(Out out_language_code) { } Result IApplicationFunctions::SetTerminateResult(Result terminate_result) { - LOG_INFO(Service_AM, "(STUBBED) called, result={:#x} ({}-{})", terminate_result.GetInnerValue(), + LOG_INFO(Service_AM, "(STUBBED) called, result={:#x} ({:04}-{:04})", + terminate_result.GetInnerValue(), static_cast(terminate_result.GetModule()) + 2000, terminate_result.GetDescription()); diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp index 19d6a3b89..6e1328fee 100644 --- a/src/core/hle/service/am/service/application_proxy.cpp +++ b/src/core/hle/service/am/service/application_proxy.cpp @@ -17,9 +17,9 @@ namespace Service::AM { IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr applet, - Kernel::KProcess* process) - : ServiceFramework{system_, "IApplicationProxy"}, m_process{process}, m_applet{ - std::move(applet)} { + Kernel::KProcess* process, WindowSystem& window_system) + : ServiceFramework{system_, "IApplicationProxy"}, + m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} { // clang-format off static const FunctionInfo functions[] = { {0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, @@ -70,7 +70,7 @@ Result IApplicationProxy::GetDebugFunctions( Result IApplicationProxy::GetWindowController( Out> out_window_controller) { LOG_DEBUG(Service_AM, "called"); - *out_window_controller = std::make_shared(system, m_applet); + *out_window_controller = std::make_shared(system, m_applet, m_window_system); R_SUCCEED(); } @@ -91,7 +91,8 @@ Result IApplicationProxy::GetCommonStateGetter( Result IApplicationProxy::GetLibraryAppletCreator( Out> out_library_applet_creator) { LOG_DEBUG(Service_AM, "called"); - *out_library_applet_creator = std::make_shared(system, m_applet); + *out_library_applet_creator = + std::make_shared(system, m_applet, m_window_system); R_SUCCEED(); } diff --git a/src/core/hle/service/am/service/application_proxy.h b/src/core/hle/service/am/service/application_proxy.h index 6da350df7..8c62459c4 100644 --- a/src/core/hle/service/am/service/application_proxy.h +++ b/src/core/hle/service/am/service/application_proxy.h @@ -18,11 +18,12 @@ class ILibraryAppletCreator; class IProcessWindingController; class ISelfController; class IWindowController; +class WindowSystem; class IApplicationProxy final : public ServiceFramework { public: explicit IApplicationProxy(Core::System& system_, std::shared_ptr applet, - Kernel::KProcess* process); + Kernel::KProcess* process, WindowSystem& window_system); ~IApplicationProxy(); private: @@ -40,6 +41,7 @@ private: Out> out_application_functions); private: + WindowSystem& m_window_system; Kernel::KProcess* const m_process; const std::shared_ptr m_applet; }; diff --git a/src/core/hle/service/am/service/application_proxy_service.cpp b/src/core/hle/service/am/service/application_proxy_service.cpp index fd66e77b9..b7d7b3c2d 100644 --- a/src/core/hle/service/am/service/application_proxy_service.cpp +++ b/src/core/hle/service/am/service/application_proxy_service.cpp @@ -6,12 +6,14 @@ #include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/service/application_proxy.h" #include "core/hle/service/am/service/application_proxy_service.h" +#include "core/hle/service/am/window_system.h" #include "core/hle/service/cmif_serialization.h" namespace Service::AM { -IApplicationProxyService::IApplicationProxyService(Core::System& system_) - : ServiceFramework{system_, "appletOE"} { +IApplicationProxyService::IApplicationProxyService(Core::System& system_, + WindowSystem& window_system) + : ServiceFramework{system_, "appletOE"}, m_window_system{window_system} { static const FunctionInfo functions[] = { {0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"}, }; @@ -26,8 +28,8 @@ Result IApplicationProxyService::OpenApplicationProxy( LOG_DEBUG(Service_AM, "called"); if (const auto applet = this->GetAppletFromProcessId(pid)) { - *out_application_proxy = - std::make_shared(system, applet, process_handle.Get()); + *out_application_proxy = std::make_shared( + system, applet, process_handle.Get(), m_window_system); R_SUCCEED(); } else { UNIMPLEMENTED(); @@ -36,7 +38,7 @@ Result IApplicationProxyService::OpenApplicationProxy( } std::shared_ptr IApplicationProxyService::GetAppletFromProcessId(ProcessId process_id) { - return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid); + return m_window_system.GetByAppletResourceUserId(process_id.pid); } } // namespace Service::AM diff --git a/src/core/hle/service/am/service/application_proxy_service.h b/src/core/hle/service/am/service/application_proxy_service.h index 8efafa31a..e5f4ea345 100644 --- a/src/core/hle/service/am/service/application_proxy_service.h +++ b/src/core/hle/service/am/service/application_proxy_service.h @@ -12,10 +12,11 @@ namespace AM { struct Applet; class IApplicationProxy; +class WindowSystem; class IApplicationProxyService final : public ServiceFramework { public: - explicit IApplicationProxyService(Core::System& system_); + explicit IApplicationProxyService(Core::System& system_, WindowSystem& window_system); ~IApplicationProxyService() override; private: @@ -24,6 +25,8 @@ private: private: std::shared_ptr GetAppletFromProcessId(ProcessId pid); + + WindowSystem& m_window_system; }; } // namespace AM diff --git a/src/core/hle/service/am/service/home_menu_functions.cpp b/src/core/hle/service/am/service/home_menu_functions.cpp index 0c4d24b58..25f78beb5 100644 --- a/src/core/hle/service/am/service/home_menu_functions.cpp +++ b/src/core/hle/service/am/service/home_menu_functions.cpp @@ -4,13 +4,16 @@ #include "core/hle/result.h" #include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/service/home_menu_functions.h" +#include "core/hle/service/am/window_system.h" #include "core/hle/service/cmif_serialization.h" namespace Service::AM { -IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr applet) - : ServiceFramework{system_, "IHomeMenuFunctions"}, m_applet{std::move(applet)}, - m_context{system, "IHomeMenuFunctions"}, m_pop_from_general_channel_event{m_context} { +IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr applet, + WindowSystem& window_system) + : ServiceFramework{system_, "IHomeMenuFunctions"}, m_window_system{window_system}, + m_applet{std::move(applet)}, m_context{system, "IHomeMenuFunctions"}, + m_pop_from_general_channel_event{m_context} { // clang-format off static const FunctionInfo functions[] = { {10, D<&IHomeMenuFunctions::RequestToGetForeground>, "RequestToGetForeground"}, @@ -37,17 +40,20 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr { public: - explicit IHomeMenuFunctions(Core::System& system_, std::shared_ptr applet); + explicit IHomeMenuFunctions(Core::System& system_, std::shared_ptr applet, + WindowSystem& window_system); ~IHomeMenuFunctions() override; private: @@ -26,6 +28,7 @@ private: Result IsForceTerminateApplicationDisabledForDebug( Out out_is_force_terminate_application_disabled_for_debug); + WindowSystem& m_window_system; const std::shared_ptr m_applet; KernelHelpers::ServiceContext m_context; Event m_pop_from_general_channel_event; diff --git a/src/core/hle/service/am/service/library_applet_creator.cpp b/src/core/hle/service/am/service/library_applet_creator.cpp index 13fab28d6..3ffb03bc9 100644 --- a/src/core/hle/service/am/service/library_applet_creator.cpp +++ b/src/core/hle/service/am/service/library_applet_creator.cpp @@ -11,6 +11,7 @@ #include "core/hle/service/am/service/library_applet_accessor.h" #include "core/hle/service/am/service/library_applet_creator.h" #include "core/hle/service/am/service/storage.h" +#include "core/hle/service/am/window_system.h" #include "core/hle/service/cmif_serialization.h" #include "core/hle/service/sm/sm.h" @@ -94,6 +95,7 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) { } std::shared_ptr CreateGuestApplet(Core::System& system, + WindowSystem& window_system, std::shared_ptr caller_applet, AppletId applet_id, LibraryAppletMode mode) { @@ -122,32 +124,20 @@ std::shared_ptr CreateGuestApplet(Core::System& system, applet->applet_id = applet_id; applet->type = AppletType::LibraryApplet; applet->library_applet_mode = mode; - - // Set focus state - switch (mode) { - case LibraryAppletMode::AllForeground: - case LibraryAppletMode::NoUi: - case LibraryAppletMode::PartialForeground: - case LibraryAppletMode::PartialForegroundIndirectDisplay: - applet->lifecycle_manager.SetFocusState(FocusState::InFocus); - applet->SetInteractibleLocked(true); - break; - case LibraryAppletMode::AllForegroundInitiallyHidden: - applet->lifecycle_manager.SetFocusState(FocusState::NotInFocus); - applet->SetInteractibleLocked(false); - break; - } + applet->window_visible = mode != LibraryAppletMode::AllForegroundInitiallyHidden; auto broker = std::make_shared(system); applet->caller_applet = caller_applet; applet->caller_applet_broker = broker; + caller_applet->child_applets.push_back(applet); - system.GetAppletManager().InsertApplet(applet); + window_system.TrackApplet(applet, false); return std::make_shared(system, broker, applet); } std::shared_ptr CreateFrontendApplet(Core::System& system, + WindowSystem& window_system, std::shared_ptr caller_applet, AppletId applet_id, LibraryAppletMode mode) { @@ -164,14 +154,19 @@ std::shared_ptr CreateFrontendApplet(Core::System& syste applet->caller_applet = caller_applet; applet->caller_applet_broker = storage; applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode); + caller_applet->child_applets.push_back(applet); + + window_system.TrackApplet(applet, false); return std::make_shared(system, storage, applet); } } // namespace -ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr applet) - : ServiceFramework{system_, "ILibraryAppletCreator"}, m_applet{std::move(applet)} { +ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr applet, + WindowSystem& window_system) + : ServiceFramework{system_, "ILibraryAppletCreator"}, + m_window_system{window_system}, m_applet{std::move(applet)} { static const FunctionInfo functions[] = { {0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"}, {1, nullptr, "TerminateAllLibraryApplets"}, @@ -193,10 +188,12 @@ Result ILibraryAppletCreator::CreateLibraryApplet( std::shared_ptr library_applet; if (ShouldCreateGuestApplet(applet_id)) { - library_applet = CreateGuestApplet(system, m_applet, applet_id, library_applet_mode); + library_applet = + CreateGuestApplet(system, m_window_system, m_applet, applet_id, library_applet_mode); } if (!library_applet) { - library_applet = CreateFrontendApplet(system, m_applet, applet_id, library_applet_mode); + library_applet = + CreateFrontendApplet(system, m_window_system, m_applet, applet_id, library_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/service/library_applet_creator.h b/src/core/hle/service/am/service/library_applet_creator.h index fe6d40eb3..a10a76982 100644 --- a/src/core/hle/service/am/service/library_applet_creator.h +++ b/src/core/hle/service/am/service/library_applet_creator.h @@ -12,10 +12,12 @@ namespace Service::AM { struct Applet; class ILibraryAppletAccessor; class IStorage; +class WindowSystem; class ILibraryAppletCreator final : public ServiceFramework { public: - explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr applet); + explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr applet, + WindowSystem& window_system); ~ILibraryAppletCreator() override; private: @@ -29,6 +31,7 @@ private: Result CreateHandleStorage(Out> out_storage, s64 size, InCopyHandle transfer_memory_handle); + WindowSystem& m_window_system; const std::shared_ptr m_applet; }; diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp index 58e709347..f9cfb82a9 100644 --- a/src/core/hle/service/am/service/library_applet_proxy.cpp +++ b/src/core/hle/service/am/service/library_applet_proxy.cpp @@ -19,9 +19,9 @@ namespace Service::AM { ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr applet, - Kernel::KProcess* process) - : ServiceFramework{system_, "ILibraryAppletProxy"}, m_process{process}, m_applet{ - std::move(applet)} { + Kernel::KProcess* process, WindowSystem& window_system) + : ServiceFramework{system_, "ILibraryAppletProxy"}, + m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} { // clang-format off static const FunctionInfo functions[] = { {0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, @@ -75,7 +75,7 @@ Result ILibraryAppletProxy::GetDebugFunctions( Result ILibraryAppletProxy::GetWindowController( Out> out_window_controller) { LOG_DEBUG(Service_AM, "called"); - *out_window_controller = std::make_shared(system, m_applet); + *out_window_controller = std::make_shared(system, m_applet, m_window_system); R_SUCCEED(); } @@ -96,7 +96,8 @@ Result ILibraryAppletProxy::GetCommonStateGetter( Result ILibraryAppletProxy::GetLibraryAppletCreator( Out> out_library_applet_creator) { LOG_DEBUG(Service_AM, "called"); - *out_library_applet_creator = std::make_shared(system, m_applet); + *out_library_applet_creator = + std::make_shared(system, m_applet, m_window_system); R_SUCCEED(); } @@ -118,7 +119,8 @@ Result ILibraryAppletProxy::GetAppletCommonFunctions( Result ILibraryAppletProxy::GetHomeMenuFunctions( Out> out_home_menu_functions) { LOG_DEBUG(Service_AM, "called"); - *out_home_menu_functions = std::make_shared(system, m_applet); + *out_home_menu_functions = + std::make_shared(system, m_applet, m_window_system); R_SUCCEED(); } diff --git a/src/core/hle/service/am/service/library_applet_proxy.h b/src/core/hle/service/am/service/library_applet_proxy.h index 7d0714b85..792d58582 100644 --- a/src/core/hle/service/am/service/library_applet_proxy.h +++ b/src/core/hle/service/am/service/library_applet_proxy.h @@ -21,11 +21,12 @@ class ILibraryAppletSelfAccessor; class IProcessWindingController; class ISelfController; class IWindowController; +class WindowSystem; class ILibraryAppletProxy final : public ServiceFramework { public: explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr applet, - Kernel::KProcess* process); + Kernel::KProcess* process, WindowSystem& window_system); ~ILibraryAppletProxy(); private: @@ -47,6 +48,7 @@ private: Result GetGlobalStateController( Out> out_global_state_controller); + WindowSystem& m_window_system; Kernel::KProcess* const m_process; const std::shared_ptr m_applet; }; diff --git a/src/core/hle/service/am/service/library_applet_self_accessor.cpp b/src/core/hle/service/am/service/library_applet_self_accessor.cpp index 8c685098d..3fe36b899 100644 --- a/src/core/hle/service/am/service/library_applet_self_accessor.cpp +++ b/src/core/hle/service/am/service/library_applet_self_accessor.cpp @@ -176,7 +176,7 @@ Result ILibraryAppletSelfAccessor::GetMainAppletStorageId(Outaruid.pid); + m_applet->process->Terminate(); R_SUCCEED(); } diff --git a/src/core/hle/service/am/service/self_controller.cpp b/src/core/hle/service/am/service/self_controller.cpp index 27ebc0598..1db02b88f 100644 --- a/src/core/hle/service/am/service/self_controller.cpp +++ b/src/core/hle/service/am/service/self_controller.cpp @@ -86,8 +86,7 @@ ISelfController::~ISelfController() { Result ISelfController::Exit() { LOG_DEBUG(Service_AM, "called"); - // TODO - system.Exit(); + m_applet->process->Terminate(); R_SUCCEED(); } @@ -95,7 +94,16 @@ Result ISelfController::Exit() { Result ISelfController::LockExit() { LOG_DEBUG(Service_AM, "called"); - system.SetExitLocked(true); + std::scoped_lock lk{m_applet->lock}; + + if (m_applet->lifecycle_manager.GetExitRequested()) { + // With exit already requested, ignore and terminate immediately. + m_applet->process->Terminate(); + } else { + // Otherwise, set exit lock state. + m_applet->exit_locked = true; + system.SetExitLocked(true); + } R_SUCCEED(); } @@ -103,10 +111,13 @@ Result ISelfController::LockExit() { Result ISelfController::UnlockExit() { LOG_DEBUG(Service_AM, "called"); + std::scoped_lock lk{m_applet->lock}; + + m_applet->exit_locked = false; system.SetExitLocked(false); - if (system.GetExitRequested()) { - system.Exit(); + if (m_applet->lifecycle_manager.GetExitRequested()) { + m_applet->process->Terminate(); } R_SUCCEED(); diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp index d1871ef9b..c2c819ede 100644 --- a/src/core/hle/service/am/service/system_applet_proxy.cpp +++ b/src/core/hle/service/am/service/system_applet_proxy.cpp @@ -19,9 +19,9 @@ namespace Service::AM { ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr applet, - Kernel::KProcess* process) - : ServiceFramework{system_, "ISystemAppletProxy"}, m_process{process}, m_applet{ - std::move(applet)} { + Kernel::KProcess* process, WindowSystem& window_system) + : ServiceFramework{system_, "ISystemAppletProxy"}, + m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} { // clang-format off static const FunctionInfo functions[] = { {0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, @@ -75,7 +75,7 @@ Result ISystemAppletProxy::GetDebugFunctions( Result ISystemAppletProxy::GetWindowController( Out> out_window_controller) { LOG_DEBUG(Service_AM, "called"); - *out_window_controller = std::make_shared(system, m_applet); + *out_window_controller = std::make_shared(system, m_applet, m_window_system); R_SUCCEED(); } @@ -96,7 +96,8 @@ Result ISystemAppletProxy::GetCommonStateGetter( Result ISystemAppletProxy::GetLibraryAppletCreator( Out> out_library_applet_creator) { LOG_DEBUG(Service_AM, "called"); - *out_library_applet_creator = std::make_shared(system, m_applet); + *out_library_applet_creator = + std::make_shared(system, m_applet, m_window_system); R_SUCCEED(); } @@ -117,7 +118,8 @@ Result ISystemAppletProxy::GetAppletCommonFunctions( Result ISystemAppletProxy::GetHomeMenuFunctions( Out> out_home_menu_functions) { LOG_DEBUG(Service_AM, "called"); - *out_home_menu_functions = std::make_shared(system, m_applet); + *out_home_menu_functions = + std::make_shared(system, m_applet, m_window_system); R_SUCCEED(); } diff --git a/src/core/hle/service/am/service/system_applet_proxy.h b/src/core/hle/service/am/service/system_applet_proxy.h index 67cd50e03..217d9dc8c 100644 --- a/src/core/hle/service/am/service/system_applet_proxy.h +++ b/src/core/hle/service/am/service/system_applet_proxy.h @@ -21,11 +21,12 @@ class ILibraryAppletCreator; class IProcessWindingController; class ISelfController; class IWindowController; +class WindowSystem; class ISystemAppletProxy final : public ServiceFramework { public: explicit ISystemAppletProxy(Core::System& system, std::shared_ptr applet, - Kernel::KProcess* process); + Kernel::KProcess* process, WindowSystem& window_system); ~ISystemAppletProxy(); private: @@ -46,6 +47,7 @@ private: Result GetGlobalStateController( Out> out_global_state_controller); + WindowSystem& m_window_system; Kernel::KProcess* const m_process; const std::shared_ptr m_applet; }; diff --git a/src/core/hle/service/am/service/window_controller.cpp b/src/core/hle/service/am/service/window_controller.cpp index 09753b22f..54396affb 100644 --- a/src/core/hle/service/am/service/window_controller.cpp +++ b/src/core/hle/service/am/service/window_controller.cpp @@ -4,12 +4,15 @@ #include "core/hle/service/am/applet.h" #include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/service/window_controller.h" +#include "core/hle/service/am/window_system.h" #include "core/hle/service/cmif_serialization.h" namespace Service::AM { -IWindowController::IWindowController(Core::System& system_, std::shared_ptr applet) - : ServiceFramework{system_, "IWindowController"}, m_applet{std::move(applet)} { +IWindowController::IWindowController(Core::System& system_, std::shared_ptr applet, + WindowSystem& window_system) + : ServiceFramework{system_, "IWindowController"}, + m_window_system{window_system}, m_applet{std::move(applet)} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "CreateWindow"}, @@ -63,13 +66,9 @@ Result IWindowController::RejectToChangeIntoBackground() { } Result IWindowController::SetAppletWindowVisibility(bool visible) { - LOG_WARNING(Service_AM, "(STUBBED) called"); + LOG_INFO(Service_AM, "called"); - std::scoped_lock lk{m_applet->lock}; - m_applet->lifecycle_manager.SetFocusState(visible ? FocusState::InFocus - : FocusState::NotInFocus); - m_applet->SetInteractibleLocked(visible); - m_applet->UpdateSuspensionStateLocked(true); + m_window_system.RequestAppletVisibilityState(*m_applet, visible); R_SUCCEED(); } diff --git a/src/core/hle/service/am/service/window_controller.h b/src/core/hle/service/am/service/window_controller.h index bfbad9bcc..a784dd4a4 100644 --- a/src/core/hle/service/am/service/window_controller.h +++ b/src/core/hle/service/am/service/window_controller.h @@ -9,10 +9,12 @@ namespace Service::AM { struct Applet; +class WindowSystem; class IWindowController final : public ServiceFramework { public: - explicit IWindowController(Core::System& system_, std::shared_ptr applet); + explicit IWindowController(Core::System& system_, std::shared_ptr applet, + WindowSystem& window_system); ~IWindowController() override; private: @@ -24,6 +26,7 @@ private: Result SetAppletWindowVisibility(bool visible); Result SetAppletGpuTimeSlice(s64 time_slice); + WindowSystem& m_window_system; const std::shared_ptr m_applet; }; diff --git a/src/core/hle/service/am/window_system.cpp b/src/core/hle/service/am/window_system.cpp index da5aeb60d..00fe099fd 100644 --- a/src/core/hle/service/am/window_system.cpp +++ b/src/core/hle/service/am/window_system.cpp @@ -11,7 +11,14 @@ namespace Service::AM { WindowSystem::WindowSystem(Core::System& system) : m_system(system) {} -WindowSystem::~WindowSystem() {} +WindowSystem::~WindowSystem() { + m_system.GetAppletManager().SetWindowSystem(nullptr); +} + +void WindowSystem::SetEventObserver(EventObserver* observer) { + m_event_observer = observer; + m_system.GetAppletManager().SetWindowSystem(this); +} void WindowSystem::Update() { std::scoped_lock lk{m_lock}; diff --git a/src/core/hle/service/am/window_system.h b/src/core/hle/service/am/window_system.h index 61b9fdafa..69e7a27ba 100644 --- a/src/core/hle/service/am/window_system.h +++ b/src/core/hle/service/am/window_system.h @@ -30,10 +30,7 @@ public: ~WindowSystem(); public: - void SetEventObserver(EventObserver* event_observer) { - m_event_observer = event_observer; - } - + void SetEventObserver(EventObserver* event_observer); void Update(); public: diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 1fa9cfbfb..47eedd73b 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -23,11 +23,7 @@ void LoopProcess(Core::System& system) { std::shared_ptr resource_manager = std::make_shared(system, firmware_settings); - // TODO: Remove this hack when am is emulated properly. resource_manager->Initialize(); - resource_manager->RegisterAppletResourceUserId(system.ApplicationProcess()->GetProcessId(), - true); - resource_manager->SetAruidValidForVibration(system.ApplicationProcess()->GetProcessId(), true); server_manager->RegisterNamedService( "hid", std::make_shared(system, resource_manager, firmware_settings)); diff --git a/src/core/hle/service/os/process.cpp b/src/core/hle/service/os/process.cpp index 3e37c1853..0dbadc315 100644 --- a/src/core/hle/service/os/process.cpp +++ b/src/core/hle/service/os/process.cpp @@ -18,7 +18,7 @@ Process::~Process() { this->Finalize(); } -bool Process::Initialize(Loader::AppLoader& loader) { +bool Process::Initialize(Loader::AppLoader& loader, Loader::ResultStatus& out_load_result) { // First, ensure we are not holding another process. this->Finalize(); @@ -33,6 +33,7 @@ bool Process::Initialize(Loader::AppLoader& loader) { // Insert process modules into memory. const auto [load_result, load_parameters] = loader.Load(*process, m_system); + out_load_result = load_result; // Ensure loading was successful. if (load_result != Loader::ResultStatus::Success) { diff --git a/src/core/hle/service/os/process.h b/src/core/hle/service/os/process.h index 19c78659a..9109b7d0a 100644 --- a/src/core/hle/service/os/process.h +++ b/src/core/hle/service/os/process.h @@ -11,7 +11,8 @@ class System; namespace Loader { class AppLoader; -} +enum class ResultStatus : u16; +} // namespace Loader namespace Kernel { class KProcess; @@ -24,7 +25,7 @@ public: explicit Process(Core::System& system); ~Process(); - bool Initialize(Loader::AppLoader& loader); + bool Initialize(Loader::AppLoader& loader, Loader::ResultStatus& out_load_result); void Finalize(); bool Run(); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index c0c0a19b8..19aaff7c6 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1461,7 +1461,6 @@ void GMainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) { OnPauseGame(); } else if (!emu_thread->IsRunning() && auto_paused && state == Qt::ApplicationActive) { auto_paused = false; - RequestGameResume(); OnStartGame(); } } @@ -1702,7 +1701,6 @@ void GMainWindow::OnPrepareForSleep(bool prepare_sleep) { } else { if (!emu_thread->IsRunning() && auto_paused) { auto_paused = false; - RequestGameResume(); OnStartGame(); } } @@ -3457,7 +3455,6 @@ void GMainWindow::OnPauseContinueGame() { if (emu_thread->IsRunning()) { OnPauseGame(); } else { - RequestGameResume(); OnStartGame(); } } @@ -5013,10 +5010,6 @@ void GMainWindow::RequestGameExit() { system->GetAppletManager().RequestExit(); } -void GMainWindow::RequestGameResume() { - system->GetAppletManager().RequestResume(); -} - void GMainWindow::filterBarSetChecked(bool state) { ui->action_Show_Filter_Bar->setChecked(state); emit(OnToggleFilterBar()); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index fce643f3f..cb68f5a75 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -310,7 +310,6 @@ private: bool ConfirmChangeGame(); bool ConfirmForceLockedExit(); void RequestGameExit(); - void RequestGameResume(); void changeEvent(QEvent* event) override; void closeEvent(QCloseEvent* event) override;