diff options
author | Liam <byteslice@airmail.cc> | 2024-01-03 07:16:27 +0100 |
---|---|---|
committer | Liam <byteslice@airmail.cc> | 2024-01-30 02:17:33 +0100 |
commit | 8a146469c0639ff402e77da8843072ce1f2bce0c (patch) | |
tree | c5dbc016c8ff1affaa06d9bfe7b580b468fed1ba | |
parent | am: rework IStorage for transfer storage (diff) | |
download | yuzu-8a146469c0639ff402e77da8843072ce1f2bce0c.tar yuzu-8a146469c0639ff402e77da8843072ce1f2bce0c.tar.gz yuzu-8a146469c0639ff402e77da8843072ce1f2bce0c.tar.bz2 yuzu-8a146469c0639ff402e77da8843072ce1f2bce0c.tar.lz yuzu-8a146469c0639ff402e77da8843072ce1f2bce0c.tar.xz yuzu-8a146469c0639ff402e77da8843072ce1f2bce0c.tar.zst yuzu-8a146469c0639ff402e77da8843072ce1f2bce0c.zip |
Diffstat (limited to '')
31 files changed, 424 insertions, 508 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 5fb0ad822..570acb193 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -420,6 +420,8 @@ add_library(core STATIC hle/service/am/applet_ae.cpp hle/service/am/applet_ae.h hle/service/am/applet_manager.cpp + hle/service/am/applet_data_broker.cpp + hle/service/am/applet_data_broker.h hle/service/am/applet_manager.h hle/service/am/applet_oe.cpp hle/service/am/applet_oe.h diff --git a/src/core/hle/service/am/am_types.h b/src/core/hle/service/am/am_types.h index d0a237a7e..d47028b80 100644 --- a/src/core/hle/service/am/am_types.h +++ b/src/core/hle/service/am/am_types.h @@ -166,6 +166,6 @@ using AppletResourceUserId = u64; using ProgramId = u64; struct Applet; -struct AppletStorageHolder; +class AppletDataBroker; } // namespace Service::AM diff --git a/src/core/hle/service/am/applet.cpp b/src/core/hle/service/am/applet.cpp index 8f44fab33..5b9056c12 100644 --- a/src/core/hle/service/am/applet.cpp +++ b/src/core/hle/service/am/applet.cpp @@ -3,49 +3,13 @@ #include "common/scope_exit.h" +#include "core/core.h" #include "core/hle/service/am/am_results.h" #include "core/hle/service/am/applet.h" +#include "core/hle/service/am/applet_manager.h" namespace Service::AM { -AppletStorageChannel::AppletStorageChannel(KernelHelpers::ServiceContext& context) - : m_event(context) {} -AppletStorageChannel::~AppletStorageChannel() = default; - -void AppletStorageChannel::PushData(std::shared_ptr<IStorage> storage) { - std::scoped_lock lk{m_lock}; - - m_data.emplace_back(std::move(storage)); - m_event.Signal(); -} - -Result AppletStorageChannel::PopData(std::shared_ptr<IStorage>* out_storage) { - std::scoped_lock lk{m_lock}; - - SCOPE_EXIT({ - if (m_data.empty()) { - m_event.Clear(); - } - }); - - R_UNLESS(!m_data.empty(), AM::ResultNoDataInChannel); - - *out_storage = std::move(m_data.front()); - m_data.pop_front(); - - R_SUCCEED(); -} - -Kernel::KReadableEvent* AppletStorageChannel::GetEvent() { - return m_event.GetHandle(); -} - -AppletStorageHolder::AppletStorageHolder(Core::System& system) - : context(system, "AppletStorageHolder"), in_data(context), interactive_in_data(context), - out_data(context), interactive_out_data(context), state_changed_event(context) {} - -AppletStorageHolder::~AppletStorageHolder() = default; - Applet::Applet(Core::System& system, std::unique_ptr<Process> process_) : context(system, "Applet"), message_queue(system), process(std::move(process_)), hid_registration(system, *process), gpu_error_detected_event(context), diff --git a/src/core/hle/service/am/applet.h b/src/core/hle/service/am/applet.h index 9650a2615..65bfbc250 100644 --- a/src/core/hle/service/am/applet.h +++ b/src/core/hle/service/am/applet.h @@ -21,41 +21,8 @@ #include "core/hle/service/am/storage.h" #include "core/hle/service/am/system_buffer_manager.h" -namespace Service::Nvnflinger { -class FbShareBufferManager; -class Nvnflinger; -} // namespace Service::Nvnflinger - namespace Service::AM { -class AppletStorageChannel { -public: - explicit AppletStorageChannel(KernelHelpers::ServiceContext& ctx); - ~AppletStorageChannel(); - - void PushData(std::shared_ptr<IStorage> storage); - Result PopData(std::shared_ptr<IStorage>* out_storage); - Kernel::KReadableEvent* GetEvent(); - -private: - std::mutex m_lock{}; - std::deque<std::shared_ptr<IStorage>> m_data{}; - Event m_event; -}; - -struct AppletStorageHolder { - explicit AppletStorageHolder(Core::System& system); - ~AppletStorageHolder(); - - KernelHelpers::ServiceContext context; - - AppletStorageChannel in_data; - AppletStorageChannel interactive_in_data; - AppletStorageChannel out_data; - AppletStorageChannel interactive_out_data; - Event state_changed_event; -}; - struct Applet { explicit Applet(Core::System& system, std::unique_ptr<Process> process_); ~Applet(); @@ -126,8 +93,7 @@ struct Applet { // Caller applet std::weak_ptr<Applet> caller_applet{}; - std::shared_ptr<AppletStorageHolder> caller_applet_storage{}; - bool is_completed{}; + std::shared_ptr<AppletDataBroker> caller_applet_broker{}; // Self state bool exit_locked{}; diff --git a/src/core/hle/service/am/applet_data_broker.cpp b/src/core/hle/service/am/applet_data_broker.cpp new file mode 100644 index 000000000..4d58c4db5 --- /dev/null +++ b/src/core/hle/service/am/applet_data_broker.cpp @@ -0,0 +1,67 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/scope_exit.h" + +#include "core/core.h" +#include "core/hle/service/am/am_results.h" +#include "core/hle/service/am/applet_data_broker.h" +#include "core/hle/service/am/applet_manager.h" + +namespace Service::AM { + +AppletStorageChannel::AppletStorageChannel(KernelHelpers::ServiceContext& context) + : m_event(context) {} +AppletStorageChannel::~AppletStorageChannel() = default; + +void AppletStorageChannel::Push(std::shared_ptr<IStorage> storage) { + std::scoped_lock lk{m_lock}; + + m_data.emplace_back(std::move(storage)); + m_event.Signal(); +} + +Result AppletStorageChannel::Pop(std::shared_ptr<IStorage>* out_storage) { + std::scoped_lock lk{m_lock}; + + SCOPE_EXIT({ + if (m_data.empty()) { + m_event.Clear(); + } + }); + + R_UNLESS(!m_data.empty(), AM::ResultNoDataInChannel); + + *out_storage = std::move(m_data.front()); + m_data.pop_front(); + + R_SUCCEED(); +} + +Kernel::KReadableEvent* AppletStorageChannel::GetEvent() { + return m_event.GetHandle(); +} + +AppletDataBroker::AppletDataBroker(Core::System& system_) + : system(system_), context(system_, "AppletDataBroker"), in_data(context), + interactive_in_data(context), out_data(context), interactive_out_data(context), + state_changed_event(context), is_completed(false) {} + +AppletDataBroker::~AppletDataBroker() = default; + +void AppletDataBroker::SignalCompletion() { + { + std::scoped_lock lk{lock}; + + if (is_completed) { + return; + } + + is_completed = true; + state_changed_event.Signal(); + } + + system.GetAppletManager().FocusStateChanged(); +} + +} // namespace Service::AM diff --git a/src/core/hle/service/am/applet_data_broker.h b/src/core/hle/service/am/applet_data_broker.h new file mode 100644 index 000000000..12326fd04 --- /dev/null +++ b/src/core/hle/service/am/applet_data_broker.h @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <deque> +#include <memory> +#include <mutex> + +#include "core/hle/service/event.h" +#include "core/hle/service/kernel_helpers.h" + +union Result; + +namespace Service::AM { + +struct Applet; +class IStorage; + +class AppletStorageChannel { +public: + explicit AppletStorageChannel(KernelHelpers::ServiceContext& ctx); + ~AppletStorageChannel(); + + void Push(std::shared_ptr<IStorage> storage); + Result Pop(std::shared_ptr<IStorage>* out_storage); + Kernel::KReadableEvent* GetEvent(); + +private: + std::mutex m_lock{}; + std::deque<std::shared_ptr<IStorage>> m_data{}; + Event m_event; +}; + +class AppletDataBroker { +public: + explicit AppletDataBroker(Core::System& system_); + ~AppletDataBroker(); + + AppletStorageChannel& GetInData() { + return in_data; + } + + AppletStorageChannel& GetInteractiveInData() { + return interactive_in_data; + } + + AppletStorageChannel& GetOutData() { + return out_data; + } + + AppletStorageChannel& GetInteractiveOutData() { + return interactive_out_data; + } + + Event& GetStateChangedEvent() { + return state_changed_event; + } + + bool IsCompleted() const { + return is_completed; + } + + void SignalCompletion(); + +private: + Core::System& system; + KernelHelpers::ServiceContext context; + + AppletStorageChannel in_data; + AppletStorageChannel interactive_in_data; + AppletStorageChannel out_data; + AppletStorageChannel interactive_out_data; + Event state_changed_event; + + std::mutex lock; + bool is_completed; +}; + +} // namespace Service::AM diff --git a/src/core/hle/service/am/applet_manager.cpp b/src/core/hle/service/am/applet_manager.cpp index efbd0108c..a733525a2 100644 --- a/src/core/hle/service/am/applet_manager.cpp +++ b/src/core/hle/service/am/applet_manager.cpp @@ -6,6 +6,7 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/hle/service/acc/profile_manager.h" +#include "core/hle/service/am/applet_data_broker.h" #include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/frontend/applet_cabinet.h" #include "core/hle/service/am/frontend/applet_controller.h" @@ -29,8 +30,8 @@ static_assert(sizeof(LaunchParameterAccountPreselectedUser) == 0x88); AppletStorageChannel& InitializeFakeCallerApplet(Core::System& system, std::shared_ptr<Applet>& applet) { - applet->caller_applet_storage = std::make_shared<AppletStorageHolder>(system); - return applet->caller_applet_storage->in_data; + applet->caller_applet_broker = std::make_shared<AppletDataBroker>(system); + return applet->caller_applet_broker->GetInData(); } void PushInShowAlbum(Core::System& system, AppletStorageChannel& channel) { @@ -46,8 +47,8 @@ void PushInShowAlbum(Core::System& system, AppletStorageChannel& channel) { std::vector<u8> argument_data(sizeof(arguments)); std::vector<u8> settings_data{2}; std::memcpy(argument_data.data(), &arguments, sizeof(arguments)); - channel.PushData(std::make_shared<IStorage>(system, std::move(argument_data))); - channel.PushData(std::make_shared<IStorage>(system, std::move(settings_data))); + channel.Push(std::make_shared<IStorage>(system, std::move(argument_data))); + channel.Push(std::make_shared<IStorage>(system, std::move(settings_data))); } void PushInShowController(Core::System& system, AppletStorageChannel& channel) { @@ -94,9 +95,9 @@ void PushInShowController(Core::System& system, AppletStorageChannel& channel) { std::memcpy(private_args_data.data(), &private_args, sizeof(private_args)); std::memcpy(user_args_data.data(), &user_args, sizeof(user_args)); - channel.PushData(std::make_shared<IStorage>(system, std::move(common_args_data))); - channel.PushData(std::make_shared<IStorage>(system, std::move(private_args_data))); - channel.PushData(std::make_shared<IStorage>(system, std::move(user_args_data))); + channel.Push(std::make_shared<IStorage>(system, std::move(common_args_data))); + channel.Push(std::make_shared<IStorage>(system, std::move(private_args_data))); + channel.Push(std::make_shared<IStorage>(system, std::move(user_args_data))); } void PushInShowCabinetData(Core::System& system, AppletStorageChannel& channel) { @@ -124,8 +125,8 @@ void PushInShowCabinetData(Core::System& system, AppletStorageChannel& channel) std::vector<u8> settings_data(sizeof(amiibo_settings)); std::memcpy(argument_data.data(), &arguments, sizeof(arguments)); std::memcpy(settings_data.data(), &amiibo_settings, sizeof(amiibo_settings)); - channel.PushData(std::make_shared<IStorage>(system, std::move(argument_data))); - channel.PushData(std::make_shared<IStorage>(system, std::move(settings_data))); + channel.Push(std::make_shared<IStorage>(system, std::move(argument_data))); + channel.Push(std::make_shared<IStorage>(system, std::move(settings_data))); } void PushInShowMiiEditData(Core::System& system, AppletStorageChannel& channel) { @@ -147,7 +148,7 @@ void PushInShowMiiEditData(Core::System& system, AppletStorageChannel& channel) std::vector<u8> argument_data(sizeof(mii_arguments)); std::memcpy(argument_data.data(), &mii_arguments, sizeof(mii_arguments)); - channel.PushData(std::make_shared<IStorage>(system, std::move(argument_data))); + channel.Push(std::make_shared<IStorage>(system, std::move(argument_data))); } void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& channel) { @@ -200,9 +201,9 @@ void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& chan std::memcpy(work_buffer.data(), initial_string.data(), swkbd_config.initial_string_length * sizeof(char16_t)); - channel.PushData(std::make_shared<IStorage>(system, std::move(argument_data))); - channel.PushData(std::make_shared<IStorage>(system, std::move(swkbd_data))); - channel.PushData(std::make_shared<IStorage>(system, std::move(work_buffer))); + channel.Push(std::make_shared<IStorage>(system, std::move(argument_data))); + channel.Push(std::make_shared<IStorage>(system, std::move(swkbd_data))); + channel.Push(std::make_shared<IStorage>(system, std::move(work_buffer))); } } // namespace diff --git a/src/core/hle/service/am/frontend/applet_cabinet.cpp b/src/core/hle/service/am/frontend/applet_cabinet.cpp index f1f49e83b..0862c81b6 100644 --- a/src/core/hle/service/am/frontend/applet_cabinet.cpp +++ b/src/core/hle/service/am/frontend/applet_cabinet.cpp @@ -16,10 +16,11 @@ namespace Service::AM::Frontend { -Cabinet::Cabinet(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::CabinetApplet& frontend_) - : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, - system{system_}, service_context{system_, "CabinetApplet"} { +Cabinet::Cabinet(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, const Core::Frontend::CabinetApplet& frontend_) + : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_}, service_context{ + system_, + "CabinetApplet"} { availability_change_event = service_context.CreateEvent("CabinetApplet:AvailabilityChangeEvent"); @@ -41,7 +42,7 @@ void Cabinet::Initialize() { common_args.play_startup_sound, common_args.size, common_args.system_tick, common_args.theme_color); - const auto storage = broker.PopNormalDataToApplet(); + std::shared_ptr<IStorage> storage = PopInData(); ASSERT(storage != nullptr); const auto applet_input_data = storage->GetData(); @@ -51,10 +52,6 @@ void Cabinet::Initialize() { sizeof(StartParamForAmiiboSettings)); } -bool Cabinet::TransactionComplete() const { - return is_complete; -} - Result Cabinet::GetStatus() const { return ResultSuccess; } @@ -160,8 +157,8 @@ void Cabinet::DisplayCompleted(bool apply_changes, std::string_view amiibo_name) is_complete = true; - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); - broker.SignalStateChanged(); + PushOutData(std::make_shared<IStorage>(system, std::move(out_data))); + Exit(); } void Cabinet::Cancel() { @@ -175,8 +172,8 @@ void Cabinet::Cancel() { is_complete = true; - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); - broker.SignalStateChanged(); + PushOutData(std::make_shared<IStorage>(system, std::move(out_data))); + Exit(); } Result Cabinet::RequestExit() { diff --git a/src/core/hle/service/am/frontend/applet_cabinet.h b/src/core/hle/service/am/frontend/applet_cabinet.h index 85d25bcb3..3a211ed37 100644 --- a/src/core/hle/service/am/frontend/applet_cabinet.h +++ b/src/core/hle/service/am/frontend/applet_cabinet.h @@ -86,13 +86,13 @@ static_assert(sizeof(ReturnValueForAmiiboSettings) == 0x188, class Cabinet final : public FrontendApplet { public: - explicit Cabinet(Core::System& system_, LibraryAppletMode applet_mode_, + explicit Cabinet(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, const Core::Frontend::CabinetApplet& frontend_); ~Cabinet() override; void Initialize() override; - bool TransactionComplete() const override; Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; @@ -102,7 +102,6 @@ public: private: const Core::Frontend::CabinetApplet& frontend; - Core::System& system; bool is_complete{false}; std::shared_ptr<Service::NFC::NfcDevice> nfp_device; diff --git a/src/core/hle/service/am/frontend/applet_controller.cpp b/src/core/hle/service/am/frontend/applet_controller.cpp index b4114f6a3..bd3e49fc4 100644 --- a/src/core/hle/service/am/frontend/applet_controller.cpp +++ b/src/core/hle/service/am/frontend/applet_controller.cpp @@ -47,9 +47,10 @@ static Core::Frontend::ControllerParameters ConvertToFrontendParameters( }; } -Controller::Controller(Core::System& system_, LibraryAppletMode applet_mode_, +Controller::Controller(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, const Core::Frontend::ControllerApplet& frontend_) - : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} + : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {} Controller::~Controller() = default; @@ -67,7 +68,7 @@ void Controller::Initialize() { controller_applet_version = ControllerAppletVersion{common_args.library_version}; - const auto private_arg_storage = broker.PopNormalDataToApplet(); + const std::shared_ptr<IStorage> private_arg_storage = PopInData(); ASSERT(private_arg_storage != nullptr); const auto& private_arg = private_arg_storage->GetData(); @@ -117,7 +118,7 @@ void Controller::Initialize() { switch (controller_private_arg.mode) { case ControllerSupportMode::ShowControllerSupport: case ControllerSupportMode::ShowControllerStrapGuide: { - const auto user_arg_storage = broker.PopNormalDataToApplet(); + const std::shared_ptr<IStorage> user_arg_storage = PopInData(); ASSERT(user_arg_storage != nullptr); const auto& user_arg = user_arg_storage->GetData(); @@ -143,7 +144,7 @@ void Controller::Initialize() { break; } case ControllerSupportMode::ShowControllerFirmwareUpdate: { - const auto update_arg_storage = broker.PopNormalDataToApplet(); + const std::shared_ptr<IStorage> update_arg_storage = PopInData(); ASSERT(update_arg_storage != nullptr); const auto& update_arg = update_arg_storage->GetData(); @@ -153,7 +154,7 @@ void Controller::Initialize() { break; } case ControllerSupportMode::ShowControllerKeyRemappingForSystem: { - const auto remapping_arg_storage = broker.PopNormalDataToApplet(); + const std::shared_ptr<IStorage> remapping_arg_storage = PopInData(); ASSERT(remapping_arg_storage != nullptr); const auto& remapping_arg = remapping_arg_storage->GetData(); @@ -169,10 +170,6 @@ void Controller::Initialize() { } } -bool Controller::TransactionComplete() const { - return complete; -} - Result Controller::GetStatus() const { return status; } @@ -261,8 +258,9 @@ void Controller::ConfigurationComplete(bool is_success) { complete = true; out_data = std::vector<u8>(sizeof(ControllerSupportResultInfo)); std::memcpy(out_data.data(), &result_info, out_data.size()); - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); - broker.SignalStateChanged(); + + PushOutData(std::make_shared<IStorage>(system, std::move(out_data))); + Exit(); } Result Controller::RequestExit() { diff --git a/src/core/hle/service/am/frontend/applet_controller.h b/src/core/hle/service/am/frontend/applet_controller.h index bf2bed332..2f219429c 100644 --- a/src/core/hle/service/am/frontend/applet_controller.h +++ b/src/core/hle/service/am/frontend/applet_controller.h @@ -124,13 +124,13 @@ static_assert(sizeof(ControllerSupportResultInfo) == 0xC, class Controller final : public FrontendApplet { public: - explicit Controller(Core::System& system_, LibraryAppletMode applet_mode_, + explicit Controller(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, const Core::Frontend::ControllerApplet& frontend_); ~Controller() override; void Initialize() override; - bool TransactionComplete() const override; Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; @@ -140,7 +140,6 @@ public: private: const Core::Frontend::ControllerApplet& frontend; - Core::System& system; ControllerAppletVersion controller_applet_version; ControllerSupportArgPrivate controller_private_arg; diff --git a/src/core/hle/service/am/frontend/applet_error.cpp b/src/core/hle/service/am/frontend/applet_error.cpp index 48be77da2..d6db345b6 100644 --- a/src/core/hle/service/am/frontend/applet_error.cpp +++ b/src/core/hle/service/am/frontend/applet_error.cpp @@ -104,9 +104,9 @@ Result Decode64BitError(u64 error) { } // Anonymous namespace -Error::Error(Core::System& system_, LibraryAppletMode applet_mode_, +Error::Error(Core::System& system_, std::shared_ptr<Applet> applet_, LibraryAppletMode applet_mode_, const Core::Frontend::ErrorApplet& frontend_) - : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} + : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {} Error::~Error() = default; @@ -115,7 +115,7 @@ void Error::Initialize() { args = std::make_unique<ErrorArguments>(); complete = false; - const auto storage = broker.PopNormalDataToApplet(); + const std::shared_ptr<IStorage> storage = PopInData(); ASSERT(storage != nullptr); const auto data = storage->GetData(); @@ -153,10 +153,6 @@ void Error::Initialize() { } } -bool Error::TransactionComplete() const { - return complete; -} - Result Error::GetStatus() const { return ResultSuccess; } @@ -211,8 +207,8 @@ void Error::Execute() { void Error::DisplayCompleted() { complete = true; - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{})); - broker.SignalStateChanged(); + PushOutData(std::make_shared<IStorage>(system, std::vector<u8>())); + Exit(); } Result Error::RequestExit() { diff --git a/src/core/hle/service/am/frontend/applet_error.h b/src/core/hle/service/am/frontend/applet_error.h index 639e3c224..678bf33fa 100644 --- a/src/core/hle/service/am/frontend/applet_error.h +++ b/src/core/hle/service/am/frontend/applet_error.h @@ -24,13 +24,12 @@ enum class ErrorAppletMode : u8 { class Error final : public FrontendApplet { public: - explicit Error(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::ErrorApplet& frontend_); + explicit Error(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, const Core::Frontend::ErrorApplet& frontend_); ~Error() override; void Initialize() override; - bool TransactionComplete() const override; Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; @@ -47,7 +46,6 @@ private: std::unique_ptr<ErrorArguments> args; bool complete = false; - Core::System& system; }; } // namespace Service::AM::Frontend diff --git a/src/core/hle/service/am/frontend/applet_general.cpp b/src/core/hle/service/am/frontend/applet_general.cpp index e51171525..3c091a602 100644 --- a/src/core/hle/service/am/frontend/applet_general.cpp +++ b/src/core/hle/service/am/frontend/applet_general.cpp @@ -8,6 +8,7 @@ #include "core/frontend/applets/general.h" #include "core/hle/result.h" #include "core/hle/service/am/am.h" +#include "core/hle/service/am/applet_data_broker.h" #include "core/hle/service/am/frontend/applet_general.h" #include "core/hle/service/am/storage.h" #include "core/reporter.h" @@ -16,17 +17,16 @@ namespace Service::AM::Frontend { constexpr Result ERROR_INVALID_PIN{ErrorModule::PCTL, 221}; -static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) { - std::shared_ptr<IStorage> storage = broker.PopNormalDataToApplet(); - for (; storage != nullptr; storage = broker.PopNormalDataToApplet()) { +static void LogCurrentStorage(std::shared_ptr<Applet> applet, std::string_view prefix) { + std::shared_ptr<IStorage> storage; + while (R_SUCCEEDED(applet->caller_applet_broker->GetInData().Pop(&storage))) { const auto data = storage->GetData(); LOG_INFO(Service_AM, "called (STUBBED), during {} received normal data with size={:08X}, data={}", prefix, data.size(), Common::HexToString(data)); } - storage = broker.PopInteractiveDataToApplet(); - for (; storage != nullptr; storage = broker.PopInteractiveDataToApplet()) { + while (R_SUCCEEDED(applet->caller_applet_broker->GetInteractiveInData().Pop(&storage))) { const auto data = storage->GetData(); LOG_INFO(Service_AM, "called (STUBBED), during {} received interactive data with size={:08X}, data={}", @@ -34,9 +34,9 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) } } -Auth::Auth(Core::System& system_, LibraryAppletMode applet_mode_, +Auth::Auth(Core::System& system_, std::shared_ptr<Applet> applet_, LibraryAppletMode applet_mode_, Core::Frontend::ParentalControlsApplet& frontend_) - : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} + : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {} Auth::~Auth() = default; @@ -44,7 +44,7 @@ void Auth::Initialize() { FrontendApplet::Initialize(); complete = false; - const auto storage = broker.PopNormalDataToApplet(); + const std::shared_ptr<IStorage> storage = PopInData(); ASSERT(storage != nullptr); const auto data = storage->GetData(); ASSERT(data.size() >= 0xC); @@ -68,10 +68,6 @@ void Auth::Initialize() { arg2 = arg.arg2; } -bool Auth::TransactionComplete() const { - return complete; -} - Result Auth::GetStatus() const { return successful ? ResultSuccess : ERROR_INVALID_PIN; } @@ -147,8 +143,8 @@ void Auth::AuthFinished(bool is_successful) { std::vector<u8> out(sizeof(Return)); std::memcpy(out.data(), &return_, sizeof(Return)); - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out))); - broker.SignalStateChanged(); + PushOutData(std::make_shared<IStorage>(system, std::move(out))); + Exit(); } Result Auth::RequestExit() { @@ -156,9 +152,10 @@ Result Auth::RequestExit() { R_SUCCEED(); } -PhotoViewer::PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_, +PhotoViewer::PhotoViewer(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, const Core::Frontend::PhotoViewerApplet& frontend_) - : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} + : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {} PhotoViewer::~PhotoViewer() = default; @@ -166,17 +163,13 @@ void PhotoViewer::Initialize() { FrontendApplet::Initialize(); complete = false; - const auto storage = broker.PopNormalDataToApplet(); + const std::shared_ptr<IStorage> storage = PopInData(); ASSERT(storage != nullptr); const auto data = storage->GetData(); ASSERT(!data.empty()); mode = static_cast<PhotoViewerAppletMode>(data[0]); } -bool PhotoViewer::TransactionComplete() const { - return complete; -} - Result PhotoViewer::GetStatus() const { return ResultSuccess; } @@ -204,8 +197,8 @@ void PhotoViewer::Execute() { } void PhotoViewer::ViewFinished() { - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{})); - broker.SignalStateChanged(); + PushOutData(std::make_shared<IStorage>(system, std::vector<u8>{})); + Exit(); } Result PhotoViewer::RequestExit() { @@ -213,8 +206,9 @@ Result PhotoViewer::RequestExit() { R_SUCCEED(); } -StubApplet::StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_) - : FrontendApplet{system_, applet_mode_}, id{id_}, system{system_} {} +StubApplet::StubApplet(Core::System& system_, std::shared_ptr<Applet> applet_, AppletId id_, + LibraryAppletMode applet_mode_) + : FrontendApplet{system_, applet_, applet_mode_}, id{id_} {} StubApplet::~StubApplet() = default; @@ -222,18 +216,7 @@ void StubApplet::Initialize() { LOG_WARNING(Service_AM, "called (STUBBED)"); FrontendApplet::Initialize(); - const auto data = broker.PeekDataToAppletForDebug(); - system.GetReporter().SaveUnimplementedAppletReport( - static_cast<u32>(id), static_cast<u32>(common_args.arguments_version), - common_args.library_version, static_cast<u32>(common_args.theme_color), - common_args.play_startup_sound, common_args.system_tick, data.normal, data.interactive); - - LogCurrentStorage(broker, "Initialize"); -} - -bool StubApplet::TransactionComplete() const { - LOG_WARNING(Service_AM, "called (STUBBED)"); - return true; + LogCurrentStorage(applet.lock(), "Initialize"); } Result StubApplet::GetStatus() const { @@ -243,22 +226,20 @@ Result StubApplet::GetStatus() const { void StubApplet::ExecuteInteractive() { LOG_WARNING(Service_AM, "called (STUBBED)"); - LogCurrentStorage(broker, "ExecuteInteractive"); + LogCurrentStorage(applet.lock(), "ExecuteInteractive"); - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); - broker.PushInteractiveDataFromApplet( - std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); - broker.SignalStateChanged(); + PushOutData(std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); + Exit(); } void StubApplet::Execute() { LOG_WARNING(Service_AM, "called (STUBBED)"); - LogCurrentStorage(broker, "Execute"); + LogCurrentStorage(applet.lock(), "Execute"); - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); - broker.PushInteractiveDataFromApplet( - std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); - broker.SignalStateChanged(); + PushOutData(std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); + Exit(); } Result StubApplet::RequestExit() { diff --git a/src/core/hle/service/am/frontend/applet_general.h b/src/core/hle/service/am/frontend/applet_general.h index b39a9a3f1..eaa7ae25f 100644 --- a/src/core/hle/service/am/frontend/applet_general.h +++ b/src/core/hle/service/am/frontend/applet_general.h @@ -19,12 +19,12 @@ enum class AuthAppletType : u32 { class Auth final : public FrontendApplet { public: - explicit Auth(Core::System& system_, LibraryAppletMode applet_mode_, + explicit Auth(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, Core::Frontend::ParentalControlsApplet& frontend_); ~Auth() override; void Initialize() override; - bool TransactionComplete() const override; Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; @@ -34,7 +34,6 @@ public: private: Core::Frontend::ParentalControlsApplet& frontend; - Core::System& system; bool complete = false; bool successful = false; @@ -51,12 +50,12 @@ enum class PhotoViewerAppletMode : u8 { class PhotoViewer final : public FrontendApplet { public: - explicit PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_, + explicit PhotoViewer(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, const Core::Frontend::PhotoViewerApplet& frontend_); ~PhotoViewer() override; void Initialize() override; - bool TransactionComplete() const override; Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; @@ -68,17 +67,16 @@ private: const Core::Frontend::PhotoViewerApplet& frontend; bool complete = false; PhotoViewerAppletMode mode = PhotoViewerAppletMode::CurrentApp; - Core::System& system; }; class StubApplet final : public FrontendApplet { public: - explicit StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_); + explicit StubApplet(Core::System& system_, std::shared_ptr<Applet> applet_, AppletId id_, + LibraryAppletMode applet_mode_); ~StubApplet() override; void Initialize() override; - bool TransactionComplete() const override; Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; @@ -86,7 +84,6 @@ public: private: AppletId id; - Core::System& system; }; } // namespace Service::AM::Frontend diff --git a/src/core/hle/service/am/frontend/applet_mii_edit.cpp b/src/core/hle/service/am/frontend/applet_mii_edit.cpp index 6203ebd2e..e3d19fb3d 100644 --- a/src/core/hle/service/am/frontend/applet_mii_edit.cpp +++ b/src/core/hle/service/am/frontend/applet_mii_edit.cpp @@ -14,9 +14,9 @@ namespace Service::AM::Frontend { -MiiEdit::MiiEdit(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::MiiEditApplet& frontend_) - : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} +MiiEdit::MiiEdit(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, const Core::Frontend::MiiEditApplet& frontend_) + : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {} MiiEdit::~MiiEdit() = default; @@ -25,7 +25,7 @@ void MiiEdit::Initialize() { // Instead, it is initialized by an AppletInput storage with size 0x100 bytes. // Do NOT call Applet::Initialize() here. - const auto storage = broker.PopNormalDataToApplet(); + const std::shared_ptr<IStorage> storage = PopInData(); ASSERT(storage != nullptr); const auto applet_input_data = storage->GetData(); @@ -67,10 +67,6 @@ void MiiEdit::Initialize() { manager->Initialize(metadata); } -bool MiiEdit::TransactionComplete() const { - return is_complete; -} - Result MiiEdit::GetStatus() const { return ResultSuccess; } @@ -153,8 +149,8 @@ void MiiEdit::MiiEditOutput(MiiEditResult result, s32 index) { is_complete = true; - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); - broker.SignalStateChanged(); + PushOutData(std::make_shared<IStorage>(system, std::move(out_data))); + Exit(); } void MiiEdit::MiiEditOutputForCharInfoEditing(MiiEditResult result, @@ -169,8 +165,8 @@ void MiiEdit::MiiEditOutputForCharInfoEditing(MiiEditResult result, is_complete = true; - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); - broker.SignalStateChanged(); + PushOutData(std::make_shared<IStorage>(system, std::move(out_data))); + Exit(); } Result MiiEdit::RequestExit() { diff --git a/src/core/hle/service/am/frontend/applet_mii_edit.h b/src/core/hle/service/am/frontend/applet_mii_edit.h index ebde37028..5db792f7d 100644 --- a/src/core/hle/service/am/frontend/applet_mii_edit.h +++ b/src/core/hle/service/am/frontend/applet_mii_edit.h @@ -20,13 +20,13 @@ namespace Service::AM::Frontend { class MiiEdit final : public FrontendApplet { public: - explicit MiiEdit(Core::System& system_, LibraryAppletMode applet_mode_, + explicit MiiEdit(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, const Core::Frontend::MiiEditApplet& frontend_); ~MiiEdit() override; void Initialize() override; - bool TransactionComplete() const override; Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; @@ -38,7 +38,6 @@ public: private: const Core::Frontend::MiiEditApplet& frontend; - Core::System& system; MiiEditAppletInputCommon applet_input_common{}; MiiEditAppletInputV3 applet_input_v3{}; diff --git a/src/core/hle/service/am/frontend/applet_profile_select.cpp b/src/core/hle/service/am/frontend/applet_profile_select.cpp index 5d71f985e..efb4053b8 100644 --- a/src/core/hle/service/am/frontend/applet_profile_select.cpp +++ b/src/core/hle/service/am/frontend/applet_profile_select.cpp @@ -14,9 +14,10 @@ namespace Service::AM::Frontend { -ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_, +ProfileSelect::ProfileSelect(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, const Core::Frontend::ProfileSelectApplet& frontend_) - : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} + : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {} ProfileSelect::~ProfileSelect() = default; @@ -28,7 +29,7 @@ void ProfileSelect::Initialize() { FrontendApplet::Initialize(); profile_select_version = ProfileSelectAppletVersion{common_args.library_version}; - const auto user_config_storage = broker.PopNormalDataToApplet(); + const std::shared_ptr<IStorage> user_config_storage = PopInData(); ASSERT(user_config_storage != nullptr); const auto& user_config = user_config_storage->GetData(); @@ -51,10 +52,6 @@ void ProfileSelect::Initialize() { } } -bool ProfileSelect::TransactionComplete() const { - return complete; -} - Result ProfileSelect::GetStatus() const { return status; } @@ -65,7 +62,8 @@ void ProfileSelect::ExecuteInteractive() { void ProfileSelect::Execute() { if (complete) { - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data))); + PushOutData(std::make_shared<IStorage>(system, std::move(final_data))); + Exit(); return; } @@ -112,8 +110,9 @@ void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) { final_data = std::vector<u8>(sizeof(UiReturnArg)); std::memcpy(final_data.data(), &output, final_data.size()); - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data))); - broker.SignalStateChanged(); + + PushOutData(std::make_shared<IStorage>(system, std::move(final_data))); + Exit(); } Result ProfileSelect::RequestExit() { diff --git a/src/core/hle/service/am/frontend/applet_profile_select.h b/src/core/hle/service/am/frontend/applet_profile_select.h index 43ec67c8e..674e7afe1 100644 --- a/src/core/hle/service/am/frontend/applet_profile_select.h +++ b/src/core/hle/service/am/frontend/applet_profile_select.h @@ -113,13 +113,13 @@ static_assert(sizeof(UiReturnArg) == 0x18, "UiReturnArg has incorrect size."); class ProfileSelect final : public FrontendApplet { public: - explicit ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_, + explicit ProfileSelect(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, const Core::Frontend::ProfileSelectApplet& frontend_); ~ProfileSelect() override; void Initialize() override; - bool TransactionComplete() const override; Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; @@ -137,7 +137,6 @@ private: bool complete = false; Result status = ResultSuccess; std::vector<u8> final_data; - Core::System& system; }; } // namespace Service::AM::Frontend diff --git a/src/core/hle/service/am/frontend/applet_software_keyboard.cpp b/src/core/hle/service/am/frontend/applet_software_keyboard.cpp index 7974995cc..fbf75d379 100644 --- a/src/core/hle/service/am/frontend/applet_software_keyboard.cpp +++ b/src/core/hle/service/am/frontend/applet_software_keyboard.cpp @@ -42,9 +42,10 @@ void SetReplyBase(std::vector<u8>& reply, SwkbdState state, SwkbdReplyType reply } // Anonymous namespace -SoftwareKeyboard::SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_, +SoftwareKeyboard::SoftwareKeyboard(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, Core::Frontend::SoftwareKeyboardApplet& frontend_) - : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} + : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {} SoftwareKeyboard::~SoftwareKeyboard() = default; @@ -77,10 +78,6 @@ void SoftwareKeyboard::Initialize() { } } -bool SoftwareKeyboard::TransactionComplete() const { - return complete; -} - Result SoftwareKeyboard::GetStatus() const { return status; } @@ -185,7 +182,7 @@ void SoftwareKeyboard::InitializeForeground() { is_background = false; - const auto swkbd_config_storage = broker.PopNormalDataToApplet(); + const auto swkbd_config_storage = PopInData(); ASSERT(swkbd_config_storage != nullptr); const auto& swkbd_config_data = swkbd_config_storage->GetData(); @@ -222,7 +219,7 @@ void SoftwareKeyboard::InitializeForeground() { break; } - const auto work_buffer_storage = broker.PopNormalDataToApplet(); + const auto work_buffer_storage = PopInData(); ASSERT(work_buffer_storage != nullptr); if (swkbd_config_common.initial_string_length == 0) { @@ -251,7 +248,7 @@ void SoftwareKeyboard::InitializeBackground(LibraryAppletMode library_applet_mod is_background = true; - const auto swkbd_inline_initialize_arg_storage = broker.PopNormalDataToApplet(); + const auto swkbd_inline_initialize_arg_storage = PopInData(); ASSERT(swkbd_inline_initialize_arg_storage != nullptr); const auto& swkbd_inline_initialize_arg = swkbd_inline_initialize_arg_storage->GetData(); @@ -268,7 +265,7 @@ void SoftwareKeyboard::InitializeBackground(LibraryAppletMode library_applet_mod } void SoftwareKeyboard::ProcessTextCheck() { - const auto text_check_storage = broker.PopInteractiveDataToApplet(); + const auto text_check_storage = PopInteractiveInData(); ASSERT(text_check_storage != nullptr); const auto& text_check_data = text_check_storage->GetData(); @@ -315,7 +312,7 @@ void SoftwareKeyboard::ProcessTextCheck() { } void SoftwareKeyboard::ProcessInlineKeyboardRequest() { - const auto request_data_storage = broker.PopInteractiveDataToApplet(); + const auto request_data_storage = PopInteractiveInData(); ASSERT(request_data_storage != nullptr); const auto& request_data = request_data_storage->GetData(); @@ -378,7 +375,7 @@ void SoftwareKeyboard::SubmitNormalOutputAndExit(SwkbdResult result, submitted_text.size() * sizeof(char16_t)); } - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); + PushOutData(std::make_shared<IStorage>(system, std::move(out_data))); ExitKeyboard(); } @@ -411,7 +408,7 @@ void SoftwareKeyboard::SubmitForTextCheck(std::u16string submitted_text) { current_text.size() * sizeof(char16_t)); } - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(out_data))); } void SoftwareKeyboard::SendReply(SwkbdReplyType reply_type) { @@ -768,7 +765,7 @@ void SoftwareKeyboard::ExitKeyboard() { frontend.ExitKeyboard(); - broker.SignalStateChanged(); + Exit(); } Result SoftwareKeyboard::RequestExit() { @@ -968,7 +965,7 @@ void SoftwareKeyboard::ReplyFinishedInitialize() { SetReplyBase(reply, swkbd_state, SwkbdReplyType::FinishedInitialize); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); } void SoftwareKeyboard::ReplyDefault() { @@ -978,7 +975,7 @@ void SoftwareKeyboard::ReplyDefault() { SetReplyBase(reply, swkbd_state, SwkbdReplyType::Default); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); } void SoftwareKeyboard::ReplyChangedString() { @@ -1000,7 +997,7 @@ void SoftwareKeyboard::ReplyChangedString() { std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &changed_string_arg, sizeof(SwkbdChangedStringArg)); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); } void SoftwareKeyboard::ReplyMovedCursor() { @@ -1020,7 +1017,7 @@ void SoftwareKeyboard::ReplyMovedCursor() { std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_cursor_arg, sizeof(SwkbdMovedCursorArg)); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); } void SoftwareKeyboard::ReplyMovedTab() { @@ -1040,7 +1037,7 @@ void SoftwareKeyboard::ReplyMovedTab() { std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_tab_arg, sizeof(SwkbdMovedTabArg)); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); } void SoftwareKeyboard::ReplyDecidedEnter() { @@ -1059,7 +1056,7 @@ void SoftwareKeyboard::ReplyDecidedEnter() { std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &decided_enter_arg, sizeof(SwkbdDecidedEnterArg)); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); HideInlineKeyboard(); } @@ -1071,7 +1068,7 @@ void SoftwareKeyboard::ReplyDecidedCancel() { SetReplyBase(reply, swkbd_state, SwkbdReplyType::DecidedCancel); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); HideInlineKeyboard(); } @@ -1096,7 +1093,7 @@ void SoftwareKeyboard::ReplyChangedStringUtf8() { std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &changed_string_arg, sizeof(SwkbdChangedStringArg)); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); } void SoftwareKeyboard::ReplyMovedCursorUtf8() { @@ -1117,7 +1114,7 @@ void SoftwareKeyboard::ReplyMovedCursorUtf8() { std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &moved_cursor_arg, sizeof(SwkbdMovedCursorArg)); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); } void SoftwareKeyboard::ReplyDecidedEnterUtf8() { @@ -1137,7 +1134,7 @@ void SoftwareKeyboard::ReplyDecidedEnterUtf8() { std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &decided_enter_arg, sizeof(SwkbdDecidedEnterArg)); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); HideInlineKeyboard(); } @@ -1149,7 +1146,7 @@ void SoftwareKeyboard::ReplyUnsetCustomizeDic() { SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizeDic); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); } void SoftwareKeyboard::ReplyReleasedUserWordInfo() { @@ -1159,7 +1156,7 @@ void SoftwareKeyboard::ReplyReleasedUserWordInfo() { SetReplyBase(reply, swkbd_state, SwkbdReplyType::ReleasedUserWordInfo); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); } void SoftwareKeyboard::ReplyUnsetCustomizedDictionaries() { @@ -1169,7 +1166,7 @@ void SoftwareKeyboard::ReplyUnsetCustomizedDictionaries() { SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizedDictionaries); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); } void SoftwareKeyboard::ReplyChangedStringV2() { @@ -1195,7 +1192,7 @@ void SoftwareKeyboard::ReplyChangedStringV2() { std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdChangedStringArg), &flag, 1); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); } void SoftwareKeyboard::ReplyMovedCursorV2() { @@ -1219,7 +1216,7 @@ void SoftwareKeyboard::ReplyMovedCursorV2() { std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedCursorArg), &flag, 1); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); } void SoftwareKeyboard::ReplyChangedStringUtf8V2() { @@ -1246,7 +1243,7 @@ void SoftwareKeyboard::ReplyChangedStringUtf8V2() { std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdChangedStringArg), &flag, 1); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); } void SoftwareKeyboard::ReplyMovedCursorUtf8V2() { @@ -1271,7 +1268,7 @@ void SoftwareKeyboard::ReplyMovedCursorUtf8V2() { std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdMovedCursorArg), &flag, 1); - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); + PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply))); } } // namespace Service::AM::Frontend diff --git a/src/core/hle/service/am/frontend/applet_software_keyboard.h b/src/core/hle/service/am/frontend/applet_software_keyboard.h index 00ad0add3..f464b7e15 100644 --- a/src/core/hle/service/am/frontend/applet_software_keyboard.h +++ b/src/core/hle/service/am/frontend/applet_software_keyboard.h @@ -21,13 +21,13 @@ namespace Service::AM::Frontend { class SoftwareKeyboard final : public FrontendApplet { public: - explicit SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_, + explicit SoftwareKeyboard(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, Core::Frontend::SoftwareKeyboardApplet& frontend_); ~SoftwareKeyboard() override; void Initialize() override; - bool TransactionComplete() const override; Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; @@ -156,7 +156,6 @@ private: void ReplyMovedCursorUtf8V2(); Core::Frontend::SoftwareKeyboardApplet& frontend; - Core::System& system; SwkbdAppletVersion swkbd_applet_version; diff --git a/src/core/hle/service/am/frontend/applet_web_browser.cpp b/src/core/hle/service/am/frontend/applet_web_browser.cpp index 28a20c72b..6ee4caf34 100644 --- a/src/core/hle/service/am/frontend/applet_web_browser.cpp +++ b/src/core/hle/service/am/frontend/applet_web_browser.cpp @@ -224,9 +224,10 @@ void ExtractSharedFonts(Core::System& system) { } // namespace -WebBrowser::WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_, +WebBrowser::WebBrowser(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, const Core::Frontend::WebBrowserApplet& frontend_) - : FrontendApplet{system_, applet_mode_}, frontend(frontend_), system{system_} {} + : FrontendApplet{system_, applet_, applet_mode_}, frontend(frontend_) {} WebBrowser::~WebBrowser() = default; @@ -244,7 +245,7 @@ void WebBrowser::Initialize() { web_applet_version = WebAppletVersion{common_args.library_version}; - const auto web_arg_storage = broker.PopNormalDataToApplet(); + const auto web_arg_storage = PopInData(); ASSERT(web_arg_storage != nullptr); const auto& web_arg = web_arg_storage->GetData(); @@ -285,10 +286,6 @@ void WebBrowser::Initialize() { } } -bool WebBrowser::TransactionComplete() const { - return complete; -} - Result WebBrowser::GetStatus() const { return status; } @@ -359,8 +356,8 @@ void WebBrowser::WebBrowserExit(WebExitReason exit_reason, std::string last_url) complete = true; std::vector<u8> out_data(sizeof(WebCommonReturnValue)); std::memcpy(out_data.data(), &web_common_return_value, out_data.size()); - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); - broker.SignalStateChanged(); + PushOutData(std::make_shared<IStorage>(system, std::move(out_data))); + Exit(); } Result WebBrowser::RequestExit() { diff --git a/src/core/hle/service/am/frontend/applet_web_browser.h b/src/core/hle/service/am/frontend/applet_web_browser.h index 613d8e9ea..ba20b7a4c 100644 --- a/src/core/hle/service/am/frontend/applet_web_browser.h +++ b/src/core/hle/service/am/frontend/applet_web_browser.h @@ -24,14 +24,13 @@ namespace Service::AM::Frontend { class WebBrowser final : public FrontendApplet { public: - WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::WebBrowserApplet& frontend_); + WebBrowser(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_, const Core::Frontend::WebBrowserApplet& frontend_); ~WebBrowser() override; void Initialize() override; - bool TransactionComplete() const override; Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; @@ -80,8 +79,6 @@ private: FileSys::VirtualFile offline_romfs; std::string external_url; - - Core::System& system; }; } // namespace Service::AM::Frontend diff --git a/src/core/hle/service/am/frontend/applets.cpp b/src/core/hle/service/am/frontend/applets.cpp index 38495ee19..db2b04575 100644 --- a/src/core/hle/service/am/frontend/applets.cpp +++ b/src/core/hle/service/am/frontend/applets.cpp @@ -16,6 +16,7 @@ #include "core/hle/kernel/k_event.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applet_ae.h" +#include "core/hle/service/am/applet_data_broker.h" #include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/applet_message_queue.h" #include "core/hle/service/am/applet_oe.h" @@ -33,135 +34,45 @@ namespace Service::AM::Frontend { -AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_) - : system{system_}, applet_mode{applet_mode_}, - service_context{system, "ILibraryAppletAccessor"} { - state_changed_event = service_context.CreateEvent("ILibraryAppletAccessor:StateChangedEvent"); - pop_out_data_event = service_context.CreateEvent("ILibraryAppletAccessor:PopDataOutEvent"); - pop_interactive_out_data_event = - service_context.CreateEvent("ILibraryAppletAccessor:PopInteractiveDataOutEvent"); -} - -AppletDataBroker::~AppletDataBroker() { - service_context.CloseEvent(state_changed_event); - service_context.CloseEvent(pop_out_data_event); - service_context.CloseEvent(pop_interactive_out_data_event); -} - -AppletDataBroker::RawChannelData AppletDataBroker::PeekDataToAppletForDebug() const { - std::vector<std::vector<u8>> out_normal; - - for (const auto& storage : in_channel) { - out_normal.push_back(storage->GetData()); - } - - std::vector<std::vector<u8>> out_interactive; +FrontendApplet::FrontendApplet(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_) + : system{system_}, applet{std::move(applet_)}, applet_mode{applet_mode_} {} - for (const auto& storage : in_interactive_channel) { - out_interactive.push_back(storage->GetData()); - } - - return {std::move(out_normal), std::move(out_interactive)}; -} - -std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() { - if (out_channel.empty()) - return nullptr; - - auto out = std::move(out_channel.front()); - out_channel.pop_front(); - pop_out_data_event->Clear(); - return out; -} - -std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToApplet() { - if (in_channel.empty()) - return nullptr; - - auto out = std::move(in_channel.front()); - in_channel.pop_front(); - return out; -} - -std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() { - if (out_interactive_channel.empty()) - return nullptr; - - auto out = std::move(out_interactive_channel.front()); - out_interactive_channel.pop_front(); - pop_interactive_out_data_event->Clear(); - return out; -} - -std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToApplet() { - if (in_interactive_channel.empty()) - return nullptr; - - auto out = std::move(in_interactive_channel.front()); - in_interactive_channel.pop_front(); - return out; -} - -void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr<IStorage>&& storage) { - in_channel.emplace_back(std::move(storage)); -} +FrontendApplet::~FrontendApplet() = default; -void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) { - out_channel.emplace_back(std::move(storage)); - pop_out_data_event->Signal(); -} +void FrontendApplet::Initialize() { + std::shared_ptr<IStorage> common = PopInData(); + ASSERT(common != nullptr); + const auto common_data = common->GetData(); -void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) { - in_interactive_channel.emplace_back(std::move(storage)); -} + ASSERT(common_data.size() >= sizeof(CommonArguments)); + std::memcpy(&common_args, common_data.data(), sizeof(CommonArguments)); -void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) { - out_interactive_channel.emplace_back(std::move(storage)); - pop_interactive_out_data_event->Signal(); + initialized = true; } -void AppletDataBroker::SignalStateChanged() { - state_changed_event->Signal(); - - // TODO proper window management - switch (applet_mode) { - case LibraryAppletMode::AllForeground: - case LibraryAppletMode::AllForegroundInitiallyHidden: { - system.GetAppletManager().FocusStateChanged(); - break; - } - default: - break; - } +std::shared_ptr<IStorage> FrontendApplet::PopInData() { + std::shared_ptr<IStorage> ret; + applet.lock()->caller_applet_broker->GetInData().Pop(&ret); + return ret; } -Kernel::KReadableEvent& AppletDataBroker::GetNormalDataEvent() { - return pop_out_data_event->GetReadableEvent(); +std::shared_ptr<IStorage> FrontendApplet::PopInteractiveInData() { + std::shared_ptr<IStorage> ret; + applet.lock()->caller_applet_broker->GetInteractiveInData().Pop(&ret); + return ret; } -Kernel::KReadableEvent& AppletDataBroker::GetInteractiveDataEvent() { - return pop_interactive_out_data_event->GetReadableEvent(); +void FrontendApplet::PushOutData(std::shared_ptr<IStorage> storage) { + applet.lock()->caller_applet_broker->GetOutData().Push(storage); } -Kernel::KReadableEvent& AppletDataBroker::GetStateChangedEvent() { - return state_changed_event->GetReadableEvent(); +void FrontendApplet::PushInteractiveOutData(std::shared_ptr<IStorage> storage) { + applet.lock()->caller_applet_broker->GetInteractiveOutData().Push(storage); } -FrontendApplet::FrontendApplet(Core::System& system_, LibraryAppletMode applet_mode_) - : broker{system_, applet_mode_}, applet_mode{applet_mode_} {} - -FrontendApplet::~FrontendApplet() = default; - -void FrontendApplet::Initialize() { - const auto common = broker.PopNormalDataToApplet(); - ASSERT(common != nullptr); - - const auto common_data = common->GetData(); - - ASSERT(common_data.size() >= sizeof(CommonArguments)); - std::memcpy(&common_args, common_data.data(), sizeof(CommonArguments)); - - initialized = true; +void FrontendApplet::Exit() { + applet.lock()->caller_applet_broker->SignalCompletion(); } FrontendAppletSet::FrontendAppletSet() = default; @@ -291,36 +202,38 @@ void FrontendAppletHolder::ClearAll() { frontend = {}; } -std::shared_ptr<FrontendApplet> FrontendAppletHolder::GetApplet(AppletId id, +std::shared_ptr<FrontendApplet> FrontendAppletHolder::GetApplet(std::shared_ptr<Applet> applet, + AppletId id, LibraryAppletMode mode) const { switch (id) { case AppletId::Auth: - return std::make_shared<Auth>(system, mode, *frontend.parental_controls); + return std::make_shared<Auth>(system, applet, mode, *frontend.parental_controls); case AppletId::Cabinet: - return std::make_shared<Cabinet>(system, mode, *frontend.cabinet); + return std::make_shared<Cabinet>(system, applet, mode, *frontend.cabinet); case AppletId::Controller: - return std::make_shared<Controller>(system, mode, *frontend.controller); + return std::make_shared<Controller>(system, applet, mode, *frontend.controller); case AppletId::Error: - return std::make_shared<Error>(system, mode, *frontend.error); + return std::make_shared<Error>(system, applet, mode, *frontend.error); case AppletId::ProfileSelect: - return std::make_shared<ProfileSelect>(system, mode, *frontend.profile_select); + return std::make_shared<ProfileSelect>(system, applet, mode, *frontend.profile_select); case AppletId::SoftwareKeyboard: - return std::make_shared<SoftwareKeyboard>(system, mode, *frontend.software_keyboard); + return std::make_shared<SoftwareKeyboard>(system, applet, mode, + *frontend.software_keyboard); case AppletId::MiiEdit: - return std::make_shared<MiiEdit>(system, mode, *frontend.mii_edit); + return std::make_shared<MiiEdit>(system, applet, mode, *frontend.mii_edit); case AppletId::Web: case AppletId::Shop: case AppletId::OfflineWeb: case AppletId::LoginShare: case AppletId::WebAuth: - return std::make_shared<WebBrowser>(system, mode, *frontend.web_browser); + return std::make_shared<WebBrowser>(system, applet, mode, *frontend.web_browser); case AppletId::PhotoViewer: - return std::make_shared<PhotoViewer>(system, mode, *frontend.photo_viewer); + return std::make_shared<PhotoViewer>(system, applet, mode, *frontend.photo_viewer); default: UNIMPLEMENTED_MSG( "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.", static_cast<u8>(id)); - return std::make_shared<StubApplet>(system, id, mode); + return std::make_shared<StubApplet>(system, applet, id, mode); } } diff --git a/src/core/hle/service/am/frontend/applets.h b/src/core/hle/service/am/frontend/applets.h index dec1d63b2..1e1fd28b8 100644 --- a/src/core/hle/service/am/frontend/applets.h +++ b/src/core/hle/service/am/frontend/applets.h @@ -44,87 +44,19 @@ class IStorage; namespace Frontend { -class AppletDataBroker final { -public: - explicit AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_); - ~AppletDataBroker(); - - struct RawChannelData { - std::vector<std::vector<u8>> normal; - std::vector<std::vector<u8>> interactive; - }; - - // Retrieves but does not pop the data sent to applet. - RawChannelData PeekDataToAppletForDebug() const; - - std::shared_ptr<IStorage> PopNormalDataToGame(); - std::shared_ptr<IStorage> PopNormalDataToApplet(); - - std::shared_ptr<IStorage> PopInteractiveDataToGame(); - std::shared_ptr<IStorage> PopInteractiveDataToApplet(); - - void PushNormalDataFromGame(std::shared_ptr<IStorage>&& storage); - void PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage); - - void PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage); - void PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage); - - void SignalStateChanged(); - - Kernel::KReadableEvent& GetNormalDataEvent(); - Kernel::KReadableEvent& GetInteractiveDataEvent(); - Kernel::KReadableEvent& GetStateChangedEvent(); - -private: - Core::System& system; - LibraryAppletMode applet_mode; - - KernelHelpers::ServiceContext service_context; - - // Queues are named from applet's perspective - - // PopNormalDataToApplet and PushNormalDataFromGame - std::deque<std::shared_ptr<IStorage>> in_channel; - - // PopNormalDataToGame and PushNormalDataFromApplet - std::deque<std::shared_ptr<IStorage>> out_channel; - - // PopInteractiveDataToApplet and PushInteractiveDataFromGame - std::deque<std::shared_ptr<IStorage>> in_interactive_channel; - - // PopInteractiveDataToGame and PushInteractiveDataFromApplet - std::deque<std::shared_ptr<IStorage>> out_interactive_channel; - - Kernel::KEvent* state_changed_event; - - // Signaled on PushNormalDataFromApplet - Kernel::KEvent* pop_out_data_event; - - // Signaled on PushInteractiveDataFromApplet - Kernel::KEvent* pop_interactive_out_data_event; -}; - class FrontendApplet { public: - explicit FrontendApplet(Core::System& system_, LibraryAppletMode applet_mode_); + explicit FrontendApplet(Core::System& system_, std::shared_ptr<Applet> applet_, + LibraryAppletMode applet_mode_); virtual ~FrontendApplet(); virtual void Initialize(); - virtual bool TransactionComplete() const = 0; virtual Result GetStatus() const = 0; virtual void ExecuteInteractive() = 0; virtual void Execute() = 0; virtual Result RequestExit() = 0; - AppletDataBroker& GetBroker() { - return broker; - } - - const AppletDataBroker& GetBroker() const { - return broker; - } - LibraryAppletMode GetLibraryAppletMode() const { return applet_mode; } @@ -134,10 +66,18 @@ public: } protected: + std::shared_ptr<IStorage> PopInData(); + std::shared_ptr<IStorage> PopInteractiveInData(); + void PushOutData(std::shared_ptr<IStorage> storage); + void PushInteractiveOutData(std::shared_ptr<IStorage> storage); + void Exit(); + +protected: + Core::System& system; CommonArguments common_args{}; - AppletDataBroker broker; - LibraryAppletMode applet_mode; - bool initialized = false; + std::weak_ptr<Applet> applet{}; + LibraryAppletMode applet_mode{}; + bool initialized{false}; }; struct FrontendAppletSet { @@ -191,7 +131,8 @@ public: void SetDefaultAppletsIfMissing(); void ClearAll(); - std::shared_ptr<FrontendApplet> GetApplet(AppletId id, LibraryAppletMode mode) const; + std::shared_ptr<FrontendApplet> GetApplet(std::shared_ptr<Applet> applet, AppletId id, + LibraryAppletMode mode) const; private: AppletId current_applet_id{}; diff --git a/src/core/hle/service/am/library_applet_accessor.cpp b/src/core/hle/service/am/library_applet_accessor.cpp index d3be493e6..6b20814f8 100644 --- a/src/core/hle/service/am/library_applet_accessor.cpp +++ b/src/core/hle/service/am/library_applet_accessor.cpp @@ -3,6 +3,7 @@ #include "common/scope_exit.h" #include "core/hle/service/am/am_results.h" +#include "core/hle/service/am/applet_data_broker.h" #include "core/hle/service/am/frontend/applets.h" #include "core/hle/service/am/library_applet_accessor.h" #include "core/hle/service/am/storage.h" @@ -11,9 +12,9 @@ namespace Service::AM { ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_, - std::shared_ptr<AppletStorageHolder> storage_, + std::shared_ptr<AppletDataBroker> broker_, std::shared_ptr<Applet> applet_) - : ServiceFramework{system_, "ILibraryAppletAccessor"}, storage{std::move(storage_)}, + : ServiceFramework{system_, "ILibraryAppletAccessor"}, broker{std::move(broker_)}, applet{std::move(applet_)} { // clang-format off static const FunctionInfo functions[] = { @@ -49,7 +50,7 @@ void ILibraryAppletAccessor::GetAppletStateChangedEvent(HLERequestContext& ctx) IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(ResultSuccess); - rb.PushCopyObjects(storage->state_changed_event.GetHandle()); + rb.PushCopyObjects(broker->GetStateChangedEvent().GetHandle()); } void ILibraryAppletAccessor::IsCompleted(HLERequestContext& ctx) { @@ -59,7 +60,7 @@ void ILibraryAppletAccessor::IsCompleted(HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push<u32>(applet->is_completed); + rb.Push<u32>(broker->IsCompleted()); } void ILibraryAppletAccessor::GetResult(HLERequestContext& ctx) { @@ -80,6 +81,7 @@ void ILibraryAppletAccessor::Start(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); applet->process->Run(); + FrontendExecute(); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -90,6 +92,7 @@ void ILibraryAppletAccessor::RequestExit(HLERequestContext& ctx) { ASSERT(applet != nullptr); applet->message_queue.RequestExit(); + FrontendRequestExit(); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -99,7 +102,7 @@ void ILibraryAppletAccessor::PushInData(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); IPC::RequestParser rp{ctx}; - storage->in_data.PushData(rp.PopIpcInterface<IStorage>().lock()); + broker->GetInData().Push(rp.PopIpcInterface<IStorage>().lock()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -109,7 +112,7 @@ void ILibraryAppletAccessor::PopOutData(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); std::shared_ptr<IStorage> data; - const auto res = storage->out_data.PopData(&data); + const auto res = broker->GetOutData().Pop(&data); if (res.IsSuccess()) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; @@ -125,7 +128,8 @@ void ILibraryAppletAccessor::PushInteractiveInData(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); IPC::RequestParser rp{ctx}; - storage->interactive_in_data.PushData(rp.PopIpcInterface<IStorage>().lock()); + broker->GetInteractiveInData().Push(rp.PopIpcInterface<IStorage>().lock()); + FrontendExecuteInteractive(); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -135,7 +139,7 @@ void ILibraryAppletAccessor::PopInteractiveOutData(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); std::shared_ptr<IStorage> data; - const auto res = storage->interactive_out_data.PopData(&data); + const auto res = broker->GetInteractiveOutData().Pop(&data); if (res.IsSuccess()) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; @@ -152,7 +156,7 @@ void ILibraryAppletAccessor::GetPopOutDataEvent(HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(ResultSuccess); - rb.PushCopyObjects(storage->out_data.GetEvent()); + rb.PushCopyObjects(broker->GetOutData().GetEvent()); } void ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(HLERequestContext& ctx) { @@ -160,7 +164,7 @@ void ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(HLERequestContext& ct IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(ResultSuccess); - rb.PushCopyObjects(storage->interactive_out_data.GetEvent()); + rb.PushCopyObjects(broker->GetInteractiveOutData().GetEvent()); } void ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(HLERequestContext& ctx) { @@ -175,4 +179,24 @@ void ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(HLERequestContext& c rb.Push(handle); } +void ILibraryAppletAccessor::FrontendExecute() { + if (applet->frontend) { + applet->frontend->Initialize(); + applet->frontend->Execute(); + } +} + +void ILibraryAppletAccessor::FrontendExecuteInteractive() { + if (applet->frontend) { + applet->frontend->ExecuteInteractive(); + applet->frontend->Execute(); + } +} + +void ILibraryAppletAccessor::FrontendRequestExit() { + if (applet->frontend) { + applet->frontend->RequestExit(); + } +} + } // namespace Service::AM diff --git a/src/core/hle/service/am/library_applet_accessor.h b/src/core/hle/service/am/library_applet_accessor.h index c34a1cbca..8be29e003 100644 --- a/src/core/hle/service/am/library_applet_accessor.h +++ b/src/core/hle/service/am/library_applet_accessor.h @@ -7,13 +7,13 @@ namespace Service::AM { -struct AppletStorageHolder; +class AppletDataBroker; struct Applet; class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { public: explicit ILibraryAppletAccessor(Core::System& system_, - std::shared_ptr<AppletStorageHolder> storage_, + std::shared_ptr<AppletDataBroker> broker_, std::shared_ptr<Applet> applet_); ~ILibraryAppletAccessor(); @@ -32,7 +32,11 @@ protected: void GetPopInteractiveOutDataEvent(HLERequestContext& ctx); void GetIndirectLayerConsumerHandle(HLERequestContext& ctx); - const std::shared_ptr<AppletStorageHolder> storage; + void FrontendExecute(); + void FrontendExecuteInteractive(); + void FrontendRequestExit(); + + const std::shared_ptr<AppletDataBroker> broker; const std::shared_ptr<Applet> applet; }; diff --git a/src/core/hle/service/am/library_applet_creator.cpp b/src/core/hle/service/am/library_applet_creator.cpp index 888b8b44b..e69764670 100644 --- a/src/core/hle/service/am/library_applet_creator.cpp +++ b/src/core/hle/service/am/library_applet_creator.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/kernel/k_transfer_memory.h" +#include "core/hle/service/am/applet_data_broker.h" #include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/frontend/applets.h" #include "core/hle/service/am/library_applet_accessor.h" @@ -62,10 +63,9 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) { } } -std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system, - std::shared_ptr<Applet> caller_applet, - AppletId applet_id, - LibraryAppletMode mode) { +[[maybe_unused]] std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet( + Core::System& system, std::shared_ptr<Applet> caller_applet, AppletId applet_id, + LibraryAppletMode mode) { const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id)); if (program_id == 0) { // Unknown applet @@ -89,20 +89,33 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system, applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); applet->focus_state = FocusState::InFocus; - auto storage = std::make_shared<AppletStorageHolder>(system); + auto broker = std::make_shared<AppletDataBroker>(system); applet->caller_applet = caller_applet; - applet->caller_applet_storage = storage; + applet->caller_applet_broker = broker; system.GetAppletManager().InsertApplet(applet); - return std::make_shared<ILibraryAppletAccessor>(system, storage, applet); + return std::make_shared<ILibraryAppletAccessor>(system, broker, applet); } -std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system, - AppletId applet_id, - LibraryAppletMode mode) { - UNREACHABLE(); - return {}; +[[maybe_unused]] std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet( + Core::System& system, std::shared_ptr<Applet> caller_applet, AppletId applet_id, + LibraryAppletMode mode) { + const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id)); + + auto process = std::make_unique<Process>(system); + auto applet = std::make_shared<Applet>(system, std::move(process)); + applet->program_id = program_id; + applet->applet_id = applet_id; + applet->type = AppletType::LibraryApplet; + applet->library_applet_mode = mode; + + auto storage = std::make_shared<AppletDataBroker>(system); + applet->caller_applet = caller_applet; + applet->caller_applet_broker = storage; + applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode); + + return std::make_shared<ILibraryAppletAccessor>(system, storage, applet); } } // namespace @@ -131,10 +144,7 @@ void ILibraryAppletCreator::CreateLibraryApplet(HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id, applet_mode); - auto library_applet = CreateGuestApplet(system, applet, applet_id, applet_mode); - if (!library_applet) { - library_applet = CreateFrontendApplet(system, applet_id, applet_mode); - } + auto library_applet = CreateFrontendApplet(system, applet, applet_id, applet_mode); if (!library_applet) { LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); diff --git a/src/core/hle/service/am/library_applet_self_accessor.cpp b/src/core/hle/service/am/library_applet_self_accessor.cpp index 74ee33213..bc66bcb6b 100644 --- a/src/core/hle/service/am/library_applet_self_accessor.cpp +++ b/src/core/hle/service/am/library_applet_self_accessor.cpp @@ -5,6 +5,7 @@ #include "core/core_timing.h" #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/am/am_results.h" +#include "core/hle/service/am/applet_data_broker.h" #include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/frontend/applet_cabinet.h" #include "core/hle/service/am/frontend/applet_controller.h" @@ -47,7 +48,7 @@ AppletIdentityInfo GetCallerIdentity(std::shared_ptr<Applet> applet) { ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_, std::shared_ptr<Applet> applet_) : ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, applet{std::move(applet_)}, - storage{applet->caller_applet_storage} { + broker{applet->caller_applet_broker} { // clang-format off static const FunctionInfo functions[] = { {0, &ILibraryAppletSelfAccessor::PopInData, "PopInData"}, @@ -96,7 +97,7 @@ void ILibraryAppletSelfAccessor::PopInData(HLERequestContext& ctx) { LOG_INFO(Service_AM, "called"); std::shared_ptr<IStorage> data; - const auto res = storage->in_data.PopData(&data); + const auto res = broker->GetInData().Pop(&data); if (res.IsSuccess()) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; @@ -112,7 +113,7 @@ void ILibraryAppletSelfAccessor::PushOutData(HLERequestContext& ctx) { LOG_INFO(Service_AM, "called"); IPC::RequestParser rp{ctx}; - storage->out_data.PushData(rp.PopIpcInterface<IStorage>().lock()); + broker->GetOutData().Push(rp.PopIpcInterface<IStorage>().lock()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -122,7 +123,7 @@ void ILibraryAppletSelfAccessor::PopInteractiveInData(HLERequestContext& ctx) { LOG_INFO(Service_AM, "called"); std::shared_ptr<IStorage> data; - const auto res = storage->interactive_in_data.PopData(&data); + const auto res = broker->GetInteractiveInData().Pop(&data); if (res.IsSuccess()) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; @@ -138,7 +139,7 @@ void ILibraryAppletSelfAccessor::PushInteractiveOutData(HLERequestContext& ctx) LOG_INFO(Service_AM, "called"); IPC::RequestParser rp{ctx}; - storage->interactive_out_data.PushData(rp.PopIpcInterface<IStorage>().lock()); + broker->GetInteractiveOutData().Push(rp.PopIpcInterface<IStorage>().lock()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -149,7 +150,7 @@ void ILibraryAppletSelfAccessor::GetPopInDataEvent(HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(ResultSuccess); - rb.PushCopyObjects(storage->in_data.GetEvent()); + rb.PushCopyObjects(broker->GetInData().GetEvent()); } void ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent(HLERequestContext& ctx) { @@ -157,19 +158,14 @@ void ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent(HLERequestContext& IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(ResultSuccess); - rb.PushCopyObjects(storage->interactive_in_data.GetEvent()); + rb.PushCopyObjects(broker->GetInteractiveInData().GetEvent()); } void ILibraryAppletSelfAccessor::ExitProcessAndReturn(HLERequestContext& ctx) { LOG_INFO(Service_AM, "called"); system.GetAppletManager().TerminateAndRemoveApplet(applet->aruid); - - { - std::scoped_lock lk{applet->lock}; - applet->is_completed = true; - storage->state_changed_event.Signal(); - } + broker->SignalCompletion(); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); diff --git a/src/core/hle/service/am/library_applet_self_accessor.h b/src/core/hle/service/am/library_applet_self_accessor.h index b15040539..596cea0df 100644 --- a/src/core/hle/service/am/library_applet_self_accessor.h +++ b/src/core/hle/service/am/library_applet_self_accessor.h @@ -10,7 +10,7 @@ namespace Service::AM { -struct AppletStorageHolder; +class AppletDataBroker; struct Applet; class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> { @@ -34,7 +34,7 @@ private: void ShouldSetGpuTimeSliceManually(HLERequestContext& ctx); const std::shared_ptr<Applet> applet; - const std::shared_ptr<AppletStorageHolder> storage; + const std::shared_ptr<AppletDataBroker> broker; }; } // namespace Service::AM diff --git a/src/core/hle/service/am/process_winding_controller.cpp b/src/core/hle/service/am/process_winding_controller.cpp index f5ccc4643..b48b52797 100644 --- a/src/core/hle/service/am/process_winding_controller.cpp +++ b/src/core/hle/service/am/process_winding_controller.cpp @@ -49,7 +49,7 @@ void IProcessWindingController::OpenCallingLibraryApplet(HLERequestContext& ctx) IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); - rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet->caller_applet_storage, + rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet->caller_applet_broker, caller_applet); } |