am: use WindowSystem to hold state for applets

This commit is contained in:
Liam 2024-02-25 21:22:09 -05:00
parent 23ac21dc6e
commit 3ac9520f83
9 changed files with 82 additions and 115 deletions

View File

@ -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,52 +226,44 @@ 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> 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> 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(
std::unique_ptr<Process> process, 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::move(process),
{
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<Applet>(m_system, std::move(m_pending_process),
params.applet_id == AppletId::Application);
applet->program_id = params.program_id;
@ -328,52 +321,18 @@ void AppletManager::CreateAndInsertByFrontendAppletParameters(
// Applet was started by frontend, so it is foreground.
applet->lifecycle_manager.SetFocusState(FocusState::InFocus);
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();
}
applet->process->Run();
this->InsertApplet(std::move(applet));
}
std::shared_ptr<Applet> 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;
}
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

View File

@ -3,10 +3,10 @@
#pragma once
#include <map>
#include <condition_variable>
#include <mutex>
#include "core/hle/service/am/applet.h"
#include "core/hle/service/am/am_types.h"
namespace Core {
class System;
@ -18,6 +18,8 @@ class Process;
namespace Service::AM {
class WindowSystem;
enum class LaunchType {
FrontendInitiated,
ApplicationInitiated,
@ -37,26 +39,24 @@ public:
explicit AppletManager(Core::System& system);
~AppletManager();
void InsertApplet(std::shared_ptr<Applet> applet);
void TerminateAndRemoveApplet(u64 aruid);
void CreateAndInsertByFrontendAppletParameters(std::unique_ptr<Process> process,
const FrontendAppletParameters& params);
std::shared_ptr<Applet> 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<u64, std::shared_ptr<Applet>> 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<Process> m_pending_process{};
};
} // namespace Service::AM

View File

@ -11,23 +11,29 @@
namespace Service::AM {
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_hid_server && m_process.IsInitialized()) {
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_hid_server && m_process.IsInitialized()) {
if (m_process.IsInitialized()) {
m_hid_server->GetResourceManager()->SetAruidValidForVibration(m_process.GetProcessId(),
false);
m_hid_server->GetResourceManager()->UnregisterAppletResourceUserId(
m_process.GetProcessId());
}
}
void HidRegistration::EnableAppletToGetInput(bool enable) {
if (m_hid_server && 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);
}
}

View File

@ -75,7 +75,7 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld(
std::shared_ptr<Applet> IAllSystemAppletProxiesService::GetAppletFromProcessId(
ProcessId process_id) {
return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid);
return m_window_system.GetByAppletResourceUserId(process_id.pid);
}
} // namespace Service::AM

View File

@ -38,7 +38,7 @@ Result IApplicationProxyService::OpenApplicationProxy(
}
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

View File

@ -144,8 +144,6 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
applet->caller_applet = caller_applet;
applet->caller_applet_broker = broker;
system.GetAppletManager().InsertApplet(applet);
return std::make_shared<ILibraryAppletAccessor>(system, broker, applet);
}

View File

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

View File

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

View File

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