am: move main applet initialization to service process

This commit is contained in:
Liam
2024-02-12 11:01:37 -05:00
committed by Narr the Reg
parent 763f358b41
commit 136ba33e6a
33 changed files with 288 additions and 325 deletions

View File

@@ -3,7 +3,6 @@
#include <array> #include <array>
#include <atomic> #include <atomic>
#include <exception>
#include <memory> #include <memory>
#include <utility> #include <utility>
@@ -20,7 +19,6 @@
#include "core/cpu_manager.h" #include "core/cpu_manager.h"
#include "core/debugger/debugger.h" #include "core/debugger/debugger.h"
#include "core/device_memory.h" #include "core/device_memory.h"
#include "core/file_sys/bis_factory.h"
#include "core/file_sys/fs_filesystem.h" #include "core/file_sys/fs_filesystem.h"
#include "core/file_sys/patch_manager.h" #include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h" #include "core/file_sys/registered_cache.h"
@@ -38,6 +36,7 @@
#include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/applet_manager.h"
#include "core/hle/service/am/frontend/applets.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/apm/apm_controller.h"
#include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/glue/glue_manager.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 Core {
namespace {
FileSys::StorageId GetStorageIdForFrontendSlot(
std::optional<FileSys::ContentProviderUnionSlot> 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, FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
const std::string& path) { const std::string& path) {
// To account for split 00+01+etc files. // To account for split 00+01+etc files.
@@ -297,9 +272,6 @@ struct System::Impl {
} }
SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) { SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) {
/// Reset all glue registrations
arp_manager.ResetAll();
telemetry_session = std::make_unique<Core::TelemetrySession>(); telemetry_session = std::make_unique<Core::TelemetrySession>();
host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system); host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system);
@@ -335,33 +307,17 @@ struct System::Impl {
SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window, SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
const std::string& filepath, const std::string& filepath,
Service::AM::FrontendAppletParameters& params) { 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); InitializeKernel(system);
// Create the application process. const auto file = GetGameFileFromPath(virtual_filesystem, filepath);
auto main_process = Kernel::KProcess::Create(system.Kernel());
Kernel::KProcess::Register(system.Kernel(), main_process); // Create the application process
kernel.AppendNewProcess(main_process); Loader::ResultStatus load_result{};
kernel.MakeApplicationProcess(main_process); std::vector<u8> control;
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); auto process =
Service::AM::CreateApplicationProcess(control, app_loader, load_result, system, file,
params.program_id, params.program_index);
if (load_result != Loader::ResultStatus::Success) { if (load_result != Loader::ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
ShutdownMainProcess(); ShutdownMainProcess();
@@ -370,6 +326,25 @@ struct System::Impl {
static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(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. // Set up the rest of the system.
SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)}; SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)};
if (init_result != SystemResultStatus::Success) { if (init_result != SystemResultStatus::Success) {
@@ -379,7 +354,6 @@ struct System::Impl {
return init_result; return init_result;
} }
AddGlueRegistrationForProcess(*app_loader, *main_process);
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
// Initialize cheat engine // Initialize cheat engine
@@ -388,13 +362,7 @@ struct System::Impl {
} }
// Register with applet manager. // Register with applet manager.
applet_manager.CreateAndInsertByFrontendAppletParameters(main_process->GetProcessId(), applet_manager.CreateAndInsertByFrontendAppletParameters(std::move(process), params);
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();
if (Settings::values.gamecard_inserted) { if (Settings::values.gamecard_inserted) {
if (Settings::values.gamecard_current_game) { if (Settings::values.gamecard_current_game) {
@@ -466,7 +434,6 @@ struct System::Impl {
kernel.SuspendEmulation(true); kernel.SuspendEmulation(true);
kernel.CloseServices(); kernel.CloseServices();
kernel.ShutdownCores(); kernel.ShutdownCores();
applet_manager.Reset();
services.reset(); services.reset();
service_manager.reset(); service_manager.reset();
fs_controller.Reset(); fs_controller.Reset();
@@ -492,6 +459,9 @@ struct System::Impl {
// Workarounds // Workarounds
Settings::values.renderer_amdvlk_depth_bias_workaround = false; Settings::values.renderer_amdvlk_depth_bias_workaround = false;
// Reset all glue registrations
arp_manager.ResetAll();
LOG_DEBUG(Core, "Shutdown OK"); LOG_DEBUG(Core, "Shutdown OK");
} }
@@ -509,31 +479,6 @@ struct System::Impl {
return app_loader->ReadTitle(out); return app_loader->ReadTitle(out);
} }
void AddGlueRegistrationForProcess(Loader::AppLoader& loader, Kernel::KProcess& process) {
std::vector<u8> 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) { void SetStatus(SystemResultStatus new_status, const char* details = nullptr) {
status = new_status; status = new_status;
if (details) { if (details) {

View File

@@ -18,10 +18,10 @@ void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system); auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("appletAE", server_manager->RegisterNamedService(
std::make_shared<IAllSystemAppletProxiesService>(system)); "appletAE", std::make_shared<IAllSystemAppletProxiesService>(system, window_system));
server_manager->RegisterNamedService("appletOE", server_manager->RegisterNamedService(
std::make_shared<IApplicationProxyService>(system)); "appletOE", std::make_shared<IApplicationProxyService>(system, window_system));
ServerManager::RunServer(std::move(server_manager)); ServerManager::RunServer(std::move(server_manager));
} }

View File

@@ -13,6 +13,7 @@
#include "core/hle/service/am/frontend/applet_mii_edit_types.h" #include "core/hle/service/am/frontend/applet_mii_edit_types.h"
#include "core/hle/service/am/frontend/applet_software_keyboard_types.h" #include "core/hle/service/am/frontend/applet_software_keyboard_types.h"
#include "core/hle/service/am/service/storage.h" #include "core/hle/service/am/service/storage.h"
#include "core/hle/service/am/window_system.h"
#include "hid_core/hid_types.h" #include "hid_core/hid_types.h"
namespace Service::AM { namespace Service::AM {
@@ -225,55 +226,46 @@ void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& chan
} // namespace } // namespace
AppletManager::AppletManager(Core::System& system) : m_system(system) {} AppletManager::AppletManager(Core::System& system) : m_system(system) {}
AppletManager::~AppletManager() { AppletManager::~AppletManager() = default;
this->Reset();
}
void AppletManager::InsertApplet(std::shared_ptr<Applet> applet) { void AppletManager::CreateAndInsertByFrontendAppletParameters(
std::scoped_lock lk{m_lock}; std::unique_ptr<Process> process, const FrontendAppletParameters& params) {
m_applets.emplace(applet->aruid.pid, std::move(applet));
}
void AppletManager::TerminateAndRemoveApplet(u64 aruid) {
std::shared_ptr<Applet> applet;
bool should_stop = false;
{ {
std::scoped_lock lk{m_lock}; std::scoped_lock lk{m_lock};
m_pending_process = std::move(process);
m_pending_parameters = params;
}
m_cv.notify_all();
}
const auto it = m_applets.find(aruid); void AppletManager::RequestExit() {
if (it == m_applets.end()) { 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; return;
} }
applet = it->second; m_cv.wait(lk, [&] { return m_pending_process != nullptr; });
m_applets.erase(it);
should_stop = m_applets.empty(); const auto& params = m_pending_parameters;
} auto applet = std::make_shared<Applet>(m_system, std::move(m_pending_process),
// 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();
}
}
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<Applet>(m_system, std::make_unique<Process>(m_system),
params.applet_id == AppletId::Application); params.applet_id == AppletId::Application);
applet->aruid.pid = aruid;
applet->program_id = params.program_id; applet->program_id = params.program_id;
applet->applet_id = params.applet_id; applet->applet_id = params.applet_id;
applet->type = params.applet_type; applet->type = params.applet_type;
@@ -330,50 +322,17 @@ void AppletManager::CreateAndInsertByFrontendAppletParameters(
// Applet was started by frontend, so it is foreground. // Applet was started by frontend, so it is foreground.
applet->lifecycle_manager.SetFocusState(FocusState::InFocus); applet->lifecycle_manager.SetFocusState(FocusState::InFocus);
this->InsertApplet(std::move(applet)); 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();
} }
std::shared_ptr<Applet> AppletManager::GetByAppletResourceUserId(u64 aruid) const { applet->process->Run();
std::scoped_lock lk{m_lock};
if (const auto it = m_applets.find(aruid); it != m_applets.end()) {
return it->second;
}
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();
}
} }
} // namespace Service::AM } // namespace Service::AM

View File

@@ -3,17 +3,23 @@
#pragma once #pragma once
#include <map> #include <condition_variable>
#include <mutex> #include <mutex>
#include "core/hle/service/am/applet.h" #include "core/hle/service/am/am_types.h"
namespace Core { namespace Core {
class System; class System;
} }
namespace Service {
class Process;
}
namespace Service::AM { namespace Service::AM {
class WindowSystem;
enum class LaunchType { enum class LaunchType {
FrontendInitiated, FrontendInitiated,
ApplicationInitiated, ApplicationInitiated,
@@ -33,26 +39,24 @@ public:
explicit AppletManager(Core::System& system); explicit AppletManager(Core::System& system);
~AppletManager(); ~AppletManager();
void InsertApplet(std::shared_ptr<Applet> applet); void CreateAndInsertByFrontendAppletParameters(std::unique_ptr<Process> process,
void TerminateAndRemoveApplet(u64 aruid);
void CreateAndInsertByFrontendAppletParameters(u64 aruid,
const FrontendAppletParameters& params); const FrontendAppletParameters& params);
std::shared_ptr<Applet> GetByAppletResourceUserId(u64 aruid) const;
void Reset();
void RequestExit(); void RequestExit();
void RequestResume();
void OperationModeChanged(); void OperationModeChanged();
public:
void SetWindowSystem(WindowSystem* window_system);
private: private:
Core::System& m_system; Core::System& m_system;
mutable std::mutex m_lock{}; std::mutex m_lock;
std::map<u64, std::shared_ptr<Applet>> m_applets{}; std::condition_variable m_cv;
// AudioController state goes here WindowSystem* m_window_system{};
FrontendAppletParameters m_pending_parameters{};
std::unique_ptr<Process> m_pending_process{};
}; };
} // namespace Service::AM } // namespace Service::AM

View File

@@ -11,16 +11,20 @@
namespace Service::AM { namespace Service::AM {
HidRegistration::HidRegistration(Core::System& system, Process& process) : m_process(process) { HidRegistration::HidRegistration(Core::System& system, Process& process) : m_process(process) {
m_hid_server = system.ServiceManager().GetService<HID::IHidServer>("hid"); m_hid_server = system.ServiceManager().GetService<HID::IHidServer>("hid", true);
if (m_process.IsInitialized()) { if (m_process.IsInitialized()) {
m_hid_server->GetResourceManager()->RegisterAppletResourceUserId(m_process.GetProcessId(), m_hid_server->GetResourceManager()->RegisterAppletResourceUserId(m_process.GetProcessId(),
true); true);
m_hid_server->GetResourceManager()->SetAruidValidForVibration(m_process.GetProcessId(),
true);
} }
} }
HidRegistration::~HidRegistration() { HidRegistration::~HidRegistration() {
if (m_process.IsInitialized()) { if (m_process.IsInitialized()) {
m_hid_server->GetResourceManager()->SetAruidValidForVibration(m_process.GetProcessId(),
false);
m_hid_server->GetResourceManager()->UnregisterAppletResourceUserId( m_hid_server->GetResourceManager()->UnregisterAppletResourceUserId(
m_process.GetProcessId()); m_process.GetProcessId());
} }
@@ -28,6 +32,8 @@ HidRegistration::~HidRegistration() {
void HidRegistration::EnableAppletToGetInput(bool enable) { void HidRegistration::EnableAppletToGetInput(bool enable) {
if (m_process.IsInitialized()) { if (m_process.IsInitialized()) {
m_hid_server->GetResourceManager()->SetAruidValidForVibration(m_process.GetProcessId(),
enable);
m_hid_server->GetResourceManager()->EnableInput(m_process.GetProcessId(), enable); m_hid_server->GetResourceManager()->EnableInput(m_process.GetProcessId(), enable);
} }
} }

View File

@@ -37,7 +37,29 @@ FileSys::StorageId GetStorageIdForFrontendSlot(
} }
std::unique_ptr<Process> CreateProcessImpl(std::unique_ptr<Loader::AppLoader>& out_loader, std::unique_ptr<Process> CreateProcessImpl(std::unique_ptr<Loader::AppLoader>& out_loader,
Core::System& system, u64 program_id, 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<Process>(system);
if (process->Initialize(*out_loader, out_load_result)) {
return process;
}
return nullptr;
}
} // Anonymous namespace
std::unique_ptr<Process> CreateProcess(Core::System& system, u64 program_id,
u8 minimum_key_generation, u8 maximum_key_generation) { u8 minimum_key_generation, u8 maximum_key_generation) {
// Attempt to load program NCA. // Attempt to load program NCA.
FileSys::VirtualFile nca_raw{}; FileSys::VirtualFile nca_raw{};
@@ -63,43 +85,24 @@ std::unique_ptr<Process> CreateProcessImpl(std::unique_ptr<Loader::AppLoader>& 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<Process>(system);
if (process->Initialize(*out_loader)) {
return process;
}
return nullptr;
}
} // Anonymous namespace
std::unique_ptr<Process> CreateProcess(Core::System& system, u64 program_id,
u8 minimum_key_generation, u8 maximum_key_generation) {
std::unique_ptr<Loader::AppLoader> loader; std::unique_ptr<Loader::AppLoader> loader;
return CreateProcessImpl(loader, system, program_id, minimum_key_generation, Loader::ResultStatus status;
maximum_key_generation); return CreateProcessImpl(loader, status, system, nca_raw, program_id, 0);
} }
std::unique_ptr<Process> CreateApplicationProcess(std::vector<u8>& out_control, std::unique_ptr<Process> CreateApplicationProcess(std::vector<u8>& out_control,
Core::System& system, u64 application_id, std::unique_ptr<Loader::AppLoader>& out_loader,
u64 program_id) { Loader::ResultStatus& out_load_result,
std::unique_ptr<Loader::AppLoader> loader; Core::System& system, FileSys::VirtualFile file,
auto process = CreateProcessImpl(loader, system, program_id, 0, 0); u64 program_id, u64 program_index) {
auto process =
CreateProcessImpl(out_loader, out_load_result, system, file, program_id, program_index);
if (!process) { if (!process) {
return nullptr; return nullptr;
} }
FileSys::NACP nacp; FileSys::NACP nacp;
if (loader->ReadControlData(nacp) == Loader::ResultStatus::Success) { if (out_loader->ReadControlData(nacp) == Loader::ResultStatus::Success) {
out_control = nacp.GetRawBytes(); out_control = nacp.GetRawBytes();
} else { } else {
out_control.resize(sizeof(FileSys::RawNACP)); out_control.resize(sizeof(FileSys::RawNACP));
@@ -107,7 +110,7 @@ std::unique_ptr<Process> CreateApplicationProcess(std::vector<u8>& out_control,
auto& storage = system.GetContentProviderUnion(); auto& storage = system.GetContentProviderUnion();
Service::Glue::ApplicationLaunchProperty launch{}; Service::Glue::ApplicationLaunchProperty launch{};
launch.title_id = program_id; launch.title_id = process->GetProgramId();
FileSys::PatchManager pm{launch.title_id, system.GetFileSystemController(), storage}; FileSys::PatchManager pm{launch.title_id, system.GetFileSystemController(), storage};
launch.version = pm.GetGameVersion().value_or(0); launch.version = pm.GetGameVersion().value_or(0);

View File

@@ -7,11 +7,17 @@
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/file_sys/vfs/vfs_types.h"
namespace Core { namespace Core {
class System; class System;
} }
namespace Loader {
class AppLoader;
enum class ResultStatus : u16;
} // namespace Loader
namespace Service { namespace Service {
class Process; class Process;
} }
@@ -21,7 +27,9 @@ namespace Service::AM {
std::unique_ptr<Process> CreateProcess(Core::System& system, u64 program_id, std::unique_ptr<Process> CreateProcess(Core::System& system, u64 program_id,
u8 minimum_key_generation, u8 maximum_key_generation); u8 minimum_key_generation, u8 maximum_key_generation);
std::unique_ptr<Process> CreateApplicationProcess(std::vector<u8>& out_control, std::unique_ptr<Process> CreateApplicationProcess(std::vector<u8>& out_control,
Core::System& system, u64 application_id, std::unique_ptr<Loader::AppLoader>& out_loader,
u64 program_id); Loader::ResultStatus& out_load_result,
Core::System& system, FileSys::VirtualFile file,
u64 program_id, u64 program_index);
} // namespace Service::AM } // namespace Service::AM

View File

@@ -6,12 +6,14 @@
#include "core/hle/service/am/service/all_system_applet_proxies_service.h" #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/library_applet_proxy.h"
#include "core/hle/service/am/service/system_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" #include "core/hle/service/cmif_serialization.h"
namespace Service::AM { namespace Service::AM {
IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_) IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_,
: ServiceFramework{system_, "appletAE"} { WindowSystem& window_system)
: ServiceFramework{system_, "appletAE"}, m_window_system{window_system} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"}, {100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"},
@@ -36,8 +38,8 @@ Result IAllSystemAppletProxiesService::OpenSystemAppletProxy(
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
if (const auto applet = this->GetAppletFromProcessId(pid); applet) { if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
*out_system_applet_proxy = *out_system_applet_proxy = std::make_shared<ISystemAppletProxy>(
std::make_shared<ISystemAppletProxy>(system, applet, process_handle.Get()); system, applet, process_handle.Get(), m_window_system);
R_SUCCEED(); R_SUCCEED();
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();
@@ -52,8 +54,8 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy(
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
if (const auto applet = this->GetAppletFromProcessId(pid); applet) { if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
*out_library_applet_proxy = *out_library_applet_proxy = std::make_shared<ILibraryAppletProxy>(
std::make_shared<ILibraryAppletProxy>(system, applet, process_handle.Get()); system, applet, process_handle.Get(), m_window_system);
R_SUCCEED(); R_SUCCEED();
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();
@@ -73,7 +75,7 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld(
std::shared_ptr<Applet> IAllSystemAppletProxiesService::GetAppletFromProcessId( std::shared_ptr<Applet> IAllSystemAppletProxiesService::GetAppletFromProcessId(
ProcessId process_id) { ProcessId process_id) {
return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid); return m_window_system.GetByAppletResourceUserId(process_id.pid);
} }
} // namespace Service::AM } // namespace Service::AM

View File

@@ -14,11 +14,12 @@ struct Applet;
struct AppletAttribute; struct AppletAttribute;
class ILibraryAppletProxy; class ILibraryAppletProxy;
class ISystemAppletProxy; class ISystemAppletProxy;
class WindowSystem;
class IAllSystemAppletProxiesService final class IAllSystemAppletProxiesService final
: public ServiceFramework<IAllSystemAppletProxiesService> { : public ServiceFramework<IAllSystemAppletProxiesService> {
public: public:
explicit IAllSystemAppletProxiesService(Core::System& system_); explicit IAllSystemAppletProxiesService(Core::System& system_, WindowSystem& window_system);
~IAllSystemAppletProxiesService() override; ~IAllSystemAppletProxiesService() override;
private: private:
@@ -35,6 +36,8 @@ private:
private: private:
std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);
WindowSystem& m_window_system;
}; };
} // namespace AM } // namespace AM

View File

@@ -181,7 +181,8 @@ Result IApplicationFunctions::GetDesiredLanguage(Out<u64> out_language_code) {
} }
Result IApplicationFunctions::SetTerminateResult(Result terminate_result) { 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<u32>(terminate_result.GetModule()) + 2000, static_cast<u32>(terminate_result.GetModule()) + 2000,
terminate_result.GetDescription()); terminate_result.GetDescription());

View File

@@ -17,9 +17,9 @@
namespace Service::AM { namespace Service::AM {
IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
Kernel::KProcess* process) Kernel::KProcess* process, WindowSystem& window_system)
: ServiceFramework{system_, "IApplicationProxy"}, m_process{process}, m_applet{ : ServiceFramework{system_, "IApplicationProxy"},
std::move(applet)} { m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, {0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
@@ -70,7 +70,7 @@ Result IApplicationProxy::GetDebugFunctions(
Result IApplicationProxy::GetWindowController( Result IApplicationProxy::GetWindowController(
Out<SharedPointer<IWindowController>> out_window_controller) { Out<SharedPointer<IWindowController>> out_window_controller) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
*out_window_controller = std::make_shared<IWindowController>(system, m_applet); *out_window_controller = std::make_shared<IWindowController>(system, m_applet, m_window_system);
R_SUCCEED(); R_SUCCEED();
} }
@@ -91,7 +91,8 @@ Result IApplicationProxy::GetCommonStateGetter(
Result IApplicationProxy::GetLibraryAppletCreator( Result IApplicationProxy::GetLibraryAppletCreator(
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
*out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet); *out_library_applet_creator =
std::make_shared<ILibraryAppletCreator>(system, m_applet, m_window_system);
R_SUCCEED(); R_SUCCEED();
} }

View File

@@ -18,11 +18,12 @@ class ILibraryAppletCreator;
class IProcessWindingController; class IProcessWindingController;
class ISelfController; class ISelfController;
class IWindowController; class IWindowController;
class WindowSystem;
class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
public: public:
explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet, explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
Kernel::KProcess* process); Kernel::KProcess* process, WindowSystem& window_system);
~IApplicationProxy(); ~IApplicationProxy();
private: private:
@@ -40,6 +41,7 @@ private:
Out<SharedPointer<IApplicationFunctions>> out_application_functions); Out<SharedPointer<IApplicationFunctions>> out_application_functions);
private: private:
WindowSystem& m_window_system;
Kernel::KProcess* const m_process; Kernel::KProcess* const m_process;
const std::shared_ptr<Applet> m_applet; const std::shared_ptr<Applet> m_applet;
}; };

View File

@@ -6,12 +6,14 @@
#include "core/hle/service/am/applet_manager.h" #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.h"
#include "core/hle/service/am/service/application_proxy_service.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" #include "core/hle/service/cmif_serialization.h"
namespace Service::AM { namespace Service::AM {
IApplicationProxyService::IApplicationProxyService(Core::System& system_) IApplicationProxyService::IApplicationProxyService(Core::System& system_,
: ServiceFramework{system_, "appletOE"} { WindowSystem& window_system)
: ServiceFramework{system_, "appletOE"}, m_window_system{window_system} {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"}, {0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"},
}; };
@@ -26,8 +28,8 @@ Result IApplicationProxyService::OpenApplicationProxy(
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
if (const auto applet = this->GetAppletFromProcessId(pid)) { if (const auto applet = this->GetAppletFromProcessId(pid)) {
*out_application_proxy = *out_application_proxy = std::make_shared<IApplicationProxy>(
std::make_shared<IApplicationProxy>(system, applet, process_handle.Get()); system, applet, process_handle.Get(), m_window_system);
R_SUCCEED(); R_SUCCEED();
} else { } else {
UNIMPLEMENTED(); UNIMPLEMENTED();
@@ -36,7 +38,7 @@ Result IApplicationProxyService::OpenApplicationProxy(
} }
std::shared_ptr<Applet> IApplicationProxyService::GetAppletFromProcessId(ProcessId process_id) { std::shared_ptr<Applet> IApplicationProxyService::GetAppletFromProcessId(ProcessId process_id) {
return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid); return m_window_system.GetByAppletResourceUserId(process_id.pid);
} }
} // namespace Service::AM } // namespace Service::AM

View File

@@ -12,10 +12,11 @@ namespace AM {
struct Applet; struct Applet;
class IApplicationProxy; class IApplicationProxy;
class WindowSystem;
class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> { class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> {
public: public:
explicit IApplicationProxyService(Core::System& system_); explicit IApplicationProxyService(Core::System& system_, WindowSystem& window_system);
~IApplicationProxyService() override; ~IApplicationProxyService() override;
private: private:
@@ -24,6 +25,8 @@ private:
private: private:
std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid); std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);
WindowSystem& m_window_system;
}; };
} // namespace AM } // namespace AM

View File

@@ -4,13 +4,16 @@
#include "core/hle/result.h" #include "core/hle/result.h"
#include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/applet_manager.h"
#include "core/hle/service/am/service/home_menu_functions.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" #include "core/hle/service/cmif_serialization.h"
namespace Service::AM { namespace Service::AM {
IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet) IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet,
: ServiceFramework{system_, "IHomeMenuFunctions"}, m_applet{std::move(applet)}, WindowSystem& window_system)
m_context{system, "IHomeMenuFunctions"}, m_pop_from_general_channel_event{m_context} { : 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 // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{10, D<&IHomeMenuFunctions::RequestToGetForeground>, "RequestToGetForeground"}, {10, D<&IHomeMenuFunctions::RequestToGetForeground>, "RequestToGetForeground"},
@@ -37,17 +40,20 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Ap
IHomeMenuFunctions::~IHomeMenuFunctions() = default; IHomeMenuFunctions::~IHomeMenuFunctions() = default;
Result IHomeMenuFunctions::RequestToGetForeground() { Result IHomeMenuFunctions::RequestToGetForeground() {
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_INFO(Service_AM, "called");
m_window_system.RequestHomeMenuToGetForeground();
R_SUCCEED(); R_SUCCEED();
} }
Result IHomeMenuFunctions::LockForeground() { Result IHomeMenuFunctions::LockForeground() {
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_INFO(Service_AM, "called");
m_window_system.RequestLockHomeMenuIntoForeground();
R_SUCCEED(); R_SUCCEED();
} }
Result IHomeMenuFunctions::UnlockForeground() { Result IHomeMenuFunctions::UnlockForeground() {
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_INFO(Service_AM, "called");
m_window_system.RequestUnlockHomeMenuIntoForeground();
R_SUCCEED(); R_SUCCEED();
} }

View File

@@ -11,10 +11,12 @@
namespace Service::AM { namespace Service::AM {
struct Applet; struct Applet;
class WindowSystem;
class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
public: public:
explicit IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet); explicit IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet,
WindowSystem& window_system);
~IHomeMenuFunctions() override; ~IHomeMenuFunctions() override;
private: private:
@@ -26,6 +28,7 @@ private:
Result IsForceTerminateApplicationDisabledForDebug( Result IsForceTerminateApplicationDisabledForDebug(
Out<bool> out_is_force_terminate_application_disabled_for_debug); Out<bool> out_is_force_terminate_application_disabled_for_debug);
WindowSystem& m_window_system;
const std::shared_ptr<Applet> m_applet; const std::shared_ptr<Applet> m_applet;
KernelHelpers::ServiceContext m_context; KernelHelpers::ServiceContext m_context;
Event m_pop_from_general_channel_event; Event m_pop_from_general_channel_event;

View File

@@ -11,6 +11,7 @@
#include "core/hle/service/am/service/library_applet_accessor.h" #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/library_applet_creator.h"
#include "core/hle/service/am/service/storage.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/cmif_serialization.h"
#include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/sm.h"
@@ -94,6 +95,7 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) {
} }
std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system, std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
WindowSystem& window_system,
std::shared_ptr<Applet> caller_applet, std::shared_ptr<Applet> caller_applet,
AppletId applet_id, AppletId applet_id,
LibraryAppletMode mode) { LibraryAppletMode mode) {
@@ -122,32 +124,20 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
applet->applet_id = applet_id; applet->applet_id = applet_id;
applet->type = AppletType::LibraryApplet; applet->type = AppletType::LibraryApplet;
applet->library_applet_mode = mode; applet->library_applet_mode = mode;
applet->window_visible = mode != LibraryAppletMode::AllForegroundInitiallyHidden;
// 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;
}
auto broker = std::make_shared<AppletDataBroker>(system); auto broker = std::make_shared<AppletDataBroker>(system);
applet->caller_applet = caller_applet; applet->caller_applet = caller_applet;
applet->caller_applet_broker = broker; 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<ILibraryAppletAccessor>(system, broker, applet); return std::make_shared<ILibraryAppletAccessor>(system, broker, applet);
} }
std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system, std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system,
WindowSystem& window_system,
std::shared_ptr<Applet> caller_applet, std::shared_ptr<Applet> caller_applet,
AppletId applet_id, AppletId applet_id,
LibraryAppletMode mode) { LibraryAppletMode mode) {
@@ -164,14 +154,19 @@ std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& syste
applet->caller_applet = caller_applet; applet->caller_applet = caller_applet;
applet->caller_applet_broker = storage; applet->caller_applet_broker = storage;
applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode); 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<ILibraryAppletAccessor>(system, storage, applet); return std::make_shared<ILibraryAppletAccessor>(system, storage, applet);
} }
} // namespace } // namespace
ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet) ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet,
: ServiceFramework{system_, "ILibraryAppletCreator"}, m_applet{std::move(applet)} { WindowSystem& window_system)
: ServiceFramework{system_, "ILibraryAppletCreator"},
m_window_system{window_system}, m_applet{std::move(applet)} {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"}, {0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"},
{1, nullptr, "TerminateAllLibraryApplets"}, {1, nullptr, "TerminateAllLibraryApplets"},
@@ -193,10 +188,12 @@ Result ILibraryAppletCreator::CreateLibraryApplet(
std::shared_ptr<ILibraryAppletAccessor> library_applet; std::shared_ptr<ILibraryAppletAccessor> library_applet;
if (ShouldCreateGuestApplet(applet_id)) { 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) { 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) { if (!library_applet) {
LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);

View File

@@ -12,10 +12,12 @@ namespace Service::AM {
struct Applet; struct Applet;
class ILibraryAppletAccessor; class ILibraryAppletAccessor;
class IStorage; class IStorage;
class WindowSystem;
class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> { class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
public: public:
explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet); explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet,
WindowSystem& window_system);
~ILibraryAppletCreator() override; ~ILibraryAppletCreator() override;
private: private:
@@ -29,6 +31,7 @@ private:
Result CreateHandleStorage(Out<SharedPointer<IStorage>> out_storage, s64 size, Result CreateHandleStorage(Out<SharedPointer<IStorage>> out_storage, s64 size,
InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle); InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle);
WindowSystem& m_window_system;
const std::shared_ptr<Applet> m_applet; const std::shared_ptr<Applet> m_applet;
}; };

View File

@@ -19,9 +19,9 @@
namespace Service::AM { namespace Service::AM {
ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
Kernel::KProcess* process) Kernel::KProcess* process, WindowSystem& window_system)
: ServiceFramework{system_, "ILibraryAppletProxy"}, m_process{process}, m_applet{ : ServiceFramework{system_, "ILibraryAppletProxy"},
std::move(applet)} { m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, {0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
@@ -75,7 +75,7 @@ Result ILibraryAppletProxy::GetDebugFunctions(
Result ILibraryAppletProxy::GetWindowController( Result ILibraryAppletProxy::GetWindowController(
Out<SharedPointer<IWindowController>> out_window_controller) { Out<SharedPointer<IWindowController>> out_window_controller) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
*out_window_controller = std::make_shared<IWindowController>(system, m_applet); *out_window_controller = std::make_shared<IWindowController>(system, m_applet, m_window_system);
R_SUCCEED(); R_SUCCEED();
} }
@@ -96,7 +96,8 @@ Result ILibraryAppletProxy::GetCommonStateGetter(
Result ILibraryAppletProxy::GetLibraryAppletCreator( Result ILibraryAppletProxy::GetLibraryAppletCreator(
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
*out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet); *out_library_applet_creator =
std::make_shared<ILibraryAppletCreator>(system, m_applet, m_window_system);
R_SUCCEED(); R_SUCCEED();
} }
@@ -118,7 +119,8 @@ Result ILibraryAppletProxy::GetAppletCommonFunctions(
Result ILibraryAppletProxy::GetHomeMenuFunctions( Result ILibraryAppletProxy::GetHomeMenuFunctions(
Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) { Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
*out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system, m_applet); *out_home_menu_functions =
std::make_shared<IHomeMenuFunctions>(system, m_applet, m_window_system);
R_SUCCEED(); R_SUCCEED();
} }

View File

@@ -21,11 +21,12 @@ class ILibraryAppletSelfAccessor;
class IProcessWindingController; class IProcessWindingController;
class ISelfController; class ISelfController;
class IWindowController; class IWindowController;
class WindowSystem;
class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
public: public:
explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
Kernel::KProcess* process); Kernel::KProcess* process, WindowSystem& window_system);
~ILibraryAppletProxy(); ~ILibraryAppletProxy();
private: private:
@@ -47,6 +48,7 @@ private:
Result GetGlobalStateController( Result GetGlobalStateController(
Out<SharedPointer<IGlobalStateController>> out_global_state_controller); Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
WindowSystem& m_window_system;
Kernel::KProcess* const m_process; Kernel::KProcess* const m_process;
const std::shared_ptr<Applet> m_applet; const std::shared_ptr<Applet> m_applet;
}; };

View File

@@ -176,7 +176,7 @@ Result ILibraryAppletSelfAccessor::GetMainAppletStorageId(Out<FileSys::StorageId
Result ILibraryAppletSelfAccessor::ExitProcessAndReturn() { Result ILibraryAppletSelfAccessor::ExitProcessAndReturn() {
LOG_INFO(Service_AM, "called"); LOG_INFO(Service_AM, "called");
system.GetAppletManager().TerminateAndRemoveApplet(m_applet->aruid.pid); m_applet->process->Terminate();
R_SUCCEED(); R_SUCCEED();
} }

View File

@@ -86,8 +86,7 @@ ISelfController::~ISelfController() {
Result ISelfController::Exit() { Result ISelfController::Exit() {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
// TODO m_applet->process->Terminate();
system.Exit();
R_SUCCEED(); R_SUCCEED();
} }
@@ -95,7 +94,16 @@ Result ISelfController::Exit() {
Result ISelfController::LockExit() { Result ISelfController::LockExit() {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
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); system.SetExitLocked(true);
}
R_SUCCEED(); R_SUCCEED();
} }
@@ -103,10 +111,13 @@ Result ISelfController::LockExit() {
Result ISelfController::UnlockExit() { Result ISelfController::UnlockExit() {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
std::scoped_lock lk{m_applet->lock};
m_applet->exit_locked = false;
system.SetExitLocked(false); system.SetExitLocked(false);
if (system.GetExitRequested()) { if (m_applet->lifecycle_manager.GetExitRequested()) {
system.Exit(); m_applet->process->Terminate();
} }
R_SUCCEED(); R_SUCCEED();

View File

@@ -19,9 +19,9 @@
namespace Service::AM { namespace Service::AM {
ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
Kernel::KProcess* process) Kernel::KProcess* process, WindowSystem& window_system)
: ServiceFramework{system_, "ISystemAppletProxy"}, m_process{process}, m_applet{ : ServiceFramework{system_, "ISystemAppletProxy"},
std::move(applet)} { m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"}, {0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
@@ -75,7 +75,7 @@ Result ISystemAppletProxy::GetDebugFunctions(
Result ISystemAppletProxy::GetWindowController( Result ISystemAppletProxy::GetWindowController(
Out<SharedPointer<IWindowController>> out_window_controller) { Out<SharedPointer<IWindowController>> out_window_controller) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
*out_window_controller = std::make_shared<IWindowController>(system, m_applet); *out_window_controller = std::make_shared<IWindowController>(system, m_applet, m_window_system);
R_SUCCEED(); R_SUCCEED();
} }
@@ -96,7 +96,8 @@ Result ISystemAppletProxy::GetCommonStateGetter(
Result ISystemAppletProxy::GetLibraryAppletCreator( Result ISystemAppletProxy::GetLibraryAppletCreator(
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) { Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
*out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet); *out_library_applet_creator =
std::make_shared<ILibraryAppletCreator>(system, m_applet, m_window_system);
R_SUCCEED(); R_SUCCEED();
} }
@@ -117,7 +118,8 @@ Result ISystemAppletProxy::GetAppletCommonFunctions(
Result ISystemAppletProxy::GetHomeMenuFunctions( Result ISystemAppletProxy::GetHomeMenuFunctions(
Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) { Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
*out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system, m_applet); *out_home_menu_functions =
std::make_shared<IHomeMenuFunctions>(system, m_applet, m_window_system);
R_SUCCEED(); R_SUCCEED();
} }

View File

@@ -21,11 +21,12 @@ class ILibraryAppletCreator;
class IProcessWindingController; class IProcessWindingController;
class ISelfController; class ISelfController;
class IWindowController; class IWindowController;
class WindowSystem;
class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
public: public:
explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet, explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet,
Kernel::KProcess* process); Kernel::KProcess* process, WindowSystem& window_system);
~ISystemAppletProxy(); ~ISystemAppletProxy();
private: private:
@@ -46,6 +47,7 @@ private:
Result GetGlobalStateController( Result GetGlobalStateController(
Out<SharedPointer<IGlobalStateController>> out_global_state_controller); Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
WindowSystem& m_window_system;
Kernel::KProcess* const m_process; Kernel::KProcess* const m_process;
const std::shared_ptr<Applet> m_applet; const std::shared_ptr<Applet> m_applet;
}; };

View File

@@ -4,12 +4,15 @@
#include "core/hle/service/am/applet.h" #include "core/hle/service/am/applet.h"
#include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/applet_manager.h"
#include "core/hle/service/am/service/window_controller.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" #include "core/hle/service/cmif_serialization.h"
namespace Service::AM { namespace Service::AM {
IWindowController::IWindowController(Core::System& system_, std::shared_ptr<Applet> applet) IWindowController::IWindowController(Core::System& system_, std::shared_ptr<Applet> applet,
: ServiceFramework{system_, "IWindowController"}, m_applet{std::move(applet)} { WindowSystem& window_system)
: ServiceFramework{system_, "IWindowController"},
m_window_system{window_system}, m_applet{std::move(applet)} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, nullptr, "CreateWindow"}, {0, nullptr, "CreateWindow"},
@@ -63,13 +66,9 @@ Result IWindowController::RejectToChangeIntoBackground() {
} }
Result IWindowController::SetAppletWindowVisibility(bool visible) { Result IWindowController::SetAppletWindowVisibility(bool visible) {
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_INFO(Service_AM, "called");
std::scoped_lock lk{m_applet->lock}; m_window_system.RequestAppletVisibilityState(*m_applet, visible);
m_applet->lifecycle_manager.SetFocusState(visible ? FocusState::InFocus
: FocusState::NotInFocus);
m_applet->SetInteractibleLocked(visible);
m_applet->UpdateSuspensionStateLocked(true);
R_SUCCEED(); R_SUCCEED();
} }

View File

@@ -9,10 +9,12 @@
namespace Service::AM { namespace Service::AM {
struct Applet; struct Applet;
class WindowSystem;
class IWindowController final : public ServiceFramework<IWindowController> { class IWindowController final : public ServiceFramework<IWindowController> {
public: public:
explicit IWindowController(Core::System& system_, std::shared_ptr<Applet> applet); explicit IWindowController(Core::System& system_, std::shared_ptr<Applet> applet,
WindowSystem& window_system);
~IWindowController() override; ~IWindowController() override;
private: private:
@@ -24,6 +26,7 @@ private:
Result SetAppletWindowVisibility(bool visible); Result SetAppletWindowVisibility(bool visible);
Result SetAppletGpuTimeSlice(s64 time_slice); Result SetAppletGpuTimeSlice(s64 time_slice);
WindowSystem& m_window_system;
const std::shared_ptr<Applet> m_applet; const std::shared_ptr<Applet> m_applet;
}; };

View File

@@ -11,7 +11,14 @@ namespace Service::AM {
WindowSystem::WindowSystem(Core::System& system) : m_system(system) {} 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() { void WindowSystem::Update() {
std::scoped_lock lk{m_lock}; std::scoped_lock lk{m_lock};

View File

@@ -30,10 +30,7 @@ public:
~WindowSystem(); ~WindowSystem();
public: public:
void SetEventObserver(EventObserver* event_observer) { void SetEventObserver(EventObserver* event_observer);
m_event_observer = event_observer;
}
void Update(); void Update();
public: public:

View File

@@ -23,11 +23,7 @@ void LoopProcess(Core::System& system) {
std::shared_ptr<ResourceManager> resource_manager = std::shared_ptr<ResourceManager> resource_manager =
std::make_shared<ResourceManager>(system, firmware_settings); std::make_shared<ResourceManager>(system, firmware_settings);
// TODO: Remove this hack when am is emulated properly.
resource_manager->Initialize(); resource_manager->Initialize();
resource_manager->RegisterAppletResourceUserId(system.ApplicationProcess()->GetProcessId(),
true);
resource_manager->SetAruidValidForVibration(system.ApplicationProcess()->GetProcessId(), true);
server_manager->RegisterNamedService( server_manager->RegisterNamedService(
"hid", std::make_shared<IHidServer>(system, resource_manager, firmware_settings)); "hid", std::make_shared<IHidServer>(system, resource_manager, firmware_settings));

View File

@@ -18,7 +18,7 @@ Process::~Process() {
this->Finalize(); 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. // First, ensure we are not holding another process.
this->Finalize(); this->Finalize();
@@ -33,6 +33,7 @@ bool Process::Initialize(Loader::AppLoader& loader) {
// Insert process modules into memory. // Insert process modules into memory.
const auto [load_result, load_parameters] = loader.Load(*process, m_system); const auto [load_result, load_parameters] = loader.Load(*process, m_system);
out_load_result = load_result;
// Ensure loading was successful. // Ensure loading was successful.
if (load_result != Loader::ResultStatus::Success) { if (load_result != Loader::ResultStatus::Success) {

View File

@@ -11,7 +11,8 @@ class System;
namespace Loader { namespace Loader {
class AppLoader; class AppLoader;
} enum class ResultStatus : u16;
} // namespace Loader
namespace Kernel { namespace Kernel {
class KProcess; class KProcess;
@@ -24,7 +25,7 @@ public:
explicit Process(Core::System& system); explicit Process(Core::System& system);
~Process(); ~Process();
bool Initialize(Loader::AppLoader& loader); bool Initialize(Loader::AppLoader& loader, Loader::ResultStatus& out_load_result);
void Finalize(); void Finalize();
bool Run(); bool Run();

View File

@@ -1461,7 +1461,6 @@ void GMainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) {
OnPauseGame(); OnPauseGame();
} else if (!emu_thread->IsRunning() && auto_paused && state == Qt::ApplicationActive) { } else if (!emu_thread->IsRunning() && auto_paused && state == Qt::ApplicationActive) {
auto_paused = false; auto_paused = false;
RequestGameResume();
OnStartGame(); OnStartGame();
} }
} }
@@ -1702,7 +1701,6 @@ void GMainWindow::OnPrepareForSleep(bool prepare_sleep) {
} else { } else {
if (!emu_thread->IsRunning() && auto_paused) { if (!emu_thread->IsRunning() && auto_paused) {
auto_paused = false; auto_paused = false;
RequestGameResume();
OnStartGame(); OnStartGame();
} }
} }
@@ -3457,7 +3455,6 @@ void GMainWindow::OnPauseContinueGame() {
if (emu_thread->IsRunning()) { if (emu_thread->IsRunning()) {
OnPauseGame(); OnPauseGame();
} else { } else {
RequestGameResume();
OnStartGame(); OnStartGame();
} }
} }
@@ -5013,10 +5010,6 @@ void GMainWindow::RequestGameExit() {
system->GetAppletManager().RequestExit(); system->GetAppletManager().RequestExit();
} }
void GMainWindow::RequestGameResume() {
system->GetAppletManager().RequestResume();
}
void GMainWindow::filterBarSetChecked(bool state) { void GMainWindow::filterBarSetChecked(bool state) {
ui->action_Show_Filter_Bar->setChecked(state); ui->action_Show_Filter_Bar->setChecked(state);
emit(OnToggleFilterBar()); emit(OnToggleFilterBar());

View File

@@ -310,7 +310,6 @@ private:
bool ConfirmChangeGame(); bool ConfirmChangeGame();
bool ConfirmForceLockedExit(); bool ConfirmForceLockedExit();
void RequestGameExit(); void RequestGameExit();
void RequestGameResume();
void changeEvent(QEvent* event) override; void changeEvent(QEvent* event) override;
void closeEvent(QCloseEvent* event) override; void closeEvent(QCloseEvent* event) override;