summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Liam2024-01-03 01:16:27 -0500
committerGravatar Liam2024-01-29 20:17:33 -0500
commit8a146469c0639ff402e77da8843072ce1f2bce0c (patch)
treec5dbc016c8ff1affaa06d9bfe7b580b468fed1ba
parentam: rework IStorage for transfer storage (diff)
downloadyuzu-8a146469c0639ff402e77da8843072ce1f2bce0c.tar.gz
yuzu-8a146469c0639ff402e77da8843072ce1f2bce0c.tar.xz
yuzu-8a146469c0639ff402e77da8843072ce1f2bce0c.zip
am: return AppletDataBroker and use for frontend applets
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/service/am/am_types.h2
-rw-r--r--src/core/hle/service/am/applet.cpp40
-rw-r--r--src/core/hle/service/am/applet.h36
-rw-r--r--src/core/hle/service/am/applet_data_broker.cpp67
-rw-r--r--src/core/hle/service/am/applet_data_broker.h80
-rw-r--r--src/core/hle/service/am/applet_manager.cpp27
-rw-r--r--src/core/hle/service/am/frontend/applet_cabinet.cpp23
-rw-r--r--src/core/hle/service/am/frontend/applet_cabinet.h5
-rw-r--r--src/core/hle/service/am/frontend/applet_controller.cpp22
-rw-r--r--src/core/hle/service/am/frontend/applet_controller.h5
-rw-r--r--src/core/hle/service/am/frontend/applet_error.cpp14
-rw-r--r--src/core/hle/service/am/frontend/applet_error.h6
-rw-r--r--src/core/hle/service/am/frontend/applet_general.cpp75
-rw-r--r--src/core/hle/service/am/frontend/applet_general.h15
-rw-r--r--src/core/hle/service/am/frontend/applet_mii_edit.cpp20
-rw-r--r--src/core/hle/service/am/frontend/applet_mii_edit.h5
-rw-r--r--src/core/hle/service/am/frontend/applet_profile_select.cpp19
-rw-r--r--src/core/hle/service/am/frontend/applet_profile_select.h5
-rw-r--r--src/core/hle/service/am/frontend/applet_software_keyboard.cpp59
-rw-r--r--src/core/hle/service/am/frontend/applet_software_keyboard.h5
-rw-r--r--src/core/hle/service/am/frontend/applet_web_browser.cpp15
-rw-r--r--src/core/hle/service/am/frontend/applet_web_browser.h7
-rw-r--r--src/core/hle/service/am/frontend/applets.cpp165
-rw-r--r--src/core/hle/service/am/frontend/applets.h89
-rw-r--r--src/core/hle/service/am/library_applet_accessor.cpp44
-rw-r--r--src/core/hle/service/am/library_applet_accessor.h10
-rw-r--r--src/core/hle/service/am/library_applet_creator.cpp42
-rw-r--r--src/core/hle/service/am/library_applet_self_accessor.cpp22
-rw-r--r--src/core/hle/service/am/library_applet_self_accessor.h4
-rw-r--r--src/core/hle/service/am/process_winding_controller.cpp2
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
420 hle/service/am/applet_ae.cpp 420 hle/service/am/applet_ae.cpp
421 hle/service/am/applet_ae.h 421 hle/service/am/applet_ae.h
422 hle/service/am/applet_manager.cpp 422 hle/service/am/applet_manager.cpp
423 hle/service/am/applet_data_broker.cpp
424 hle/service/am/applet_data_broker.h
423 hle/service/am/applet_manager.h 425 hle/service/am/applet_manager.h
424 hle/service/am/applet_oe.cpp 426 hle/service/am/applet_oe.cpp
425 hle/service/am/applet_oe.h 427 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;
166using ProgramId = u64; 166using ProgramId = u64;
167 167
168struct Applet; 168struct Applet;
169struct AppletStorageHolder; 169class AppletDataBroker;
170 170
171} // namespace Service::AM 171} // 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 @@
3 3
4#include "common/scope_exit.h" 4#include "common/scope_exit.h"
5 5
6#include "core/core.h"
6#include "core/hle/service/am/am_results.h" 7#include "core/hle/service/am/am_results.h"
7#include "core/hle/service/am/applet.h" 8#include "core/hle/service/am/applet.h"
9#include "core/hle/service/am/applet_manager.h"
8 10
9namespace Service::AM { 11namespace Service::AM {
10 12
11AppletStorageChannel::AppletStorageChannel(KernelHelpers::ServiceContext& context)
12 : m_event(context) {}
13AppletStorageChannel::~AppletStorageChannel() = default;
14
15void AppletStorageChannel::PushData(std::shared_ptr<IStorage> storage) {
16 std::scoped_lock lk{m_lock};
17
18 m_data.emplace_back(std::move(storage));
19 m_event.Signal();
20}
21
22Result AppletStorageChannel::PopData(std::shared_ptr<IStorage>* out_storage) {
23 std::scoped_lock lk{m_lock};
24
25 SCOPE_EXIT({
26 if (m_data.empty()) {
27 m_event.Clear();
28 }
29 });
30
31 R_UNLESS(!m_data.empty(), AM::ResultNoDataInChannel);
32
33 *out_storage = std::move(m_data.front());
34 m_data.pop_front();
35
36 R_SUCCEED();
37}
38
39Kernel::KReadableEvent* AppletStorageChannel::GetEvent() {
40 return m_event.GetHandle();
41}
42
43AppletStorageHolder::AppletStorageHolder(Core::System& system)
44 : context(system, "AppletStorageHolder"), in_data(context), interactive_in_data(context),
45 out_data(context), interactive_out_data(context), state_changed_event(context) {}
46
47AppletStorageHolder::~AppletStorageHolder() = default;
48
49Applet::Applet(Core::System& system, std::unique_ptr<Process> process_) 13Applet::Applet(Core::System& system, std::unique_ptr<Process> process_)
50 : context(system, "Applet"), message_queue(system), process(std::move(process_)), 14 : context(system, "Applet"), message_queue(system), process(std::move(process_)),
51 hid_registration(system, *process), gpu_error_detected_event(context), 15 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 @@
21#include "core/hle/service/am/storage.h" 21#include "core/hle/service/am/storage.h"
22#include "core/hle/service/am/system_buffer_manager.h" 22#include "core/hle/service/am/system_buffer_manager.h"
23 23
24namespace Service::Nvnflinger {
25class FbShareBufferManager;
26class Nvnflinger;
27} // namespace Service::Nvnflinger
28
29namespace Service::AM { 24namespace Service::AM {
30 25
31class AppletStorageChannel {
32public:
33 explicit AppletStorageChannel(KernelHelpers::ServiceContext& ctx);
34 ~AppletStorageChannel();
35
36 void PushData(std::shared_ptr<IStorage> storage);
37 Result PopData(std::shared_ptr<IStorage>* out_storage);
38 Kernel::KReadableEvent* GetEvent();
39
40private:
41 std::mutex m_lock{};
42 std::deque<std::shared_ptr<IStorage>> m_data{};
43 Event m_event;
44};
45
46struct AppletStorageHolder {
47 explicit AppletStorageHolder(Core::System& system);
48 ~AppletStorageHolder();
49
50 KernelHelpers::ServiceContext context;
51
52 AppletStorageChannel in_data;
53 AppletStorageChannel interactive_in_data;
54 AppletStorageChannel out_data;
55 AppletStorageChannel interactive_out_data;
56 Event state_changed_event;
57};
58
59struct Applet { 26struct Applet {
60 explicit Applet(Core::System& system, std::unique_ptr<Process> process_); 27 explicit Applet(Core::System& system, std::unique_ptr<Process> process_);
61 ~Applet(); 28 ~Applet();
@@ -126,8 +93,7 @@ struct Applet {
126 93
127 // Caller applet 94 // Caller applet
128 std::weak_ptr<Applet> caller_applet{}; 95 std::weak_ptr<Applet> caller_applet{};
129 std::shared_ptr<AppletStorageHolder> caller_applet_storage{}; 96 std::shared_ptr<AppletDataBroker> caller_applet_broker{};
130 bool is_completed{};
131 97
132 // Self state 98 // Self state
133 bool exit_locked{}; 99 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 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/scope_exit.h"
5
6#include "core/core.h"
7#include "core/hle/service/am/am_results.h"
8#include "core/hle/service/am/applet_data_broker.h"
9#include "core/hle/service/am/applet_manager.h"
10
11namespace Service::AM {
12
13AppletStorageChannel::AppletStorageChannel(KernelHelpers::ServiceContext& context)
14 : m_event(context) {}
15AppletStorageChannel::~AppletStorageChannel() = default;
16
17void AppletStorageChannel::Push(std::shared_ptr<IStorage> storage) {
18 std::scoped_lock lk{m_lock};
19
20 m_data.emplace_back(std::move(storage));
21 m_event.Signal();
22}
23
24Result AppletStorageChannel::Pop(std::shared_ptr<IStorage>* out_storage) {
25 std::scoped_lock lk{m_lock};
26
27 SCOPE_EXIT({
28 if (m_data.empty()) {
29 m_event.Clear();
30 }
31 });
32
33 R_UNLESS(!m_data.empty(), AM::ResultNoDataInChannel);
34
35 *out_storage = std::move(m_data.front());
36 m_data.pop_front();
37
38 R_SUCCEED();
39}
40
41Kernel::KReadableEvent* AppletStorageChannel::GetEvent() {
42 return m_event.GetHandle();
43}
44
45AppletDataBroker::AppletDataBroker(Core::System& system_)
46 : system(system_), context(system_, "AppletDataBroker"), in_data(context),
47 interactive_in_data(context), out_data(context), interactive_out_data(context),
48 state_changed_event(context), is_completed(false) {}
49
50AppletDataBroker::~AppletDataBroker() = default;
51
52void AppletDataBroker::SignalCompletion() {
53 {
54 std::scoped_lock lk{lock};
55
56 if (is_completed) {
57 return;
58 }
59
60 is_completed = true;
61 state_changed_event.Signal();
62 }
63
64 system.GetAppletManager().FocusStateChanged();
65}
66
67} // 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 @@
1// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <deque>
7#include <memory>
8#include <mutex>
9
10#include "core/hle/service/event.h"
11#include "core/hle/service/kernel_helpers.h"
12
13union Result;
14
15namespace Service::AM {
16
17struct Applet;
18class IStorage;
19
20class AppletStorageChannel {
21public:
22 explicit AppletStorageChannel(KernelHelpers::ServiceContext& ctx);
23 ~AppletStorageChannel();
24
25 void Push(std::shared_ptr<IStorage> storage);
26 Result Pop(std::shared_ptr<IStorage>* out_storage);
27 Kernel::KReadableEvent* GetEvent();
28
29private:
30 std::mutex m_lock{};
31 std::deque<std::shared_ptr<IStorage>> m_data{};
32 Event m_event;
33};
34
35class AppletDataBroker {
36public:
37 explicit AppletDataBroker(Core::System& system_);
38 ~AppletDataBroker();
39
40 AppletStorageChannel& GetInData() {
41 return in_data;
42 }
43
44 AppletStorageChannel& GetInteractiveInData() {
45 return interactive_in_data;
46 }
47
48 AppletStorageChannel& GetOutData() {
49 return out_data;
50 }
51
52 AppletStorageChannel& GetInteractiveOutData() {
53 return interactive_out_data;
54 }
55
56 Event& GetStateChangedEvent() {
57 return state_changed_event;
58 }
59
60 bool IsCompleted() const {
61 return is_completed;
62 }
63
64 void SignalCompletion();
65
66private:
67 Core::System& system;
68 KernelHelpers::ServiceContext context;
69
70 AppletStorageChannel in_data;
71 AppletStorageChannel interactive_in_data;
72 AppletStorageChannel out_data;
73 AppletStorageChannel interactive_out_data;
74 Event state_changed_event;
75
76 std::mutex lock;
77 bool is_completed;
78};
79
80} // 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 @@
6#include "core/core.h" 6#include "core/core.h"
7#include "core/core_timing.h" 7#include "core/core_timing.h"
8#include "core/hle/service/acc/profile_manager.h" 8#include "core/hle/service/acc/profile_manager.h"
9#include "core/hle/service/am/applet_data_broker.h"
9#include "core/hle/service/am/applet_manager.h" 10#include "core/hle/service/am/applet_manager.h"
10#include "core/hle/service/am/frontend/applet_cabinet.h" 11#include "core/hle/service/am/frontend/applet_cabinet.h"
11#include "core/hle/service/am/frontend/applet_controller.h" 12#include "core/hle/service/am/frontend/applet_controller.h"
@@ -29,8 +30,8 @@ static_assert(sizeof(LaunchParameterAccountPreselectedUser) == 0x88);
29 30
30AppletStorageChannel& InitializeFakeCallerApplet(Core::System& system, 31AppletStorageChannel& InitializeFakeCallerApplet(Core::System& system,
31 std::shared_ptr<Applet>& applet) { 32 std::shared_ptr<Applet>& applet) {
32 applet->caller_applet_storage = std::make_shared<AppletStorageHolder>(system); 33 applet->caller_applet_broker = std::make_shared<AppletDataBroker>(system);
33 return applet->caller_applet_storage->in_data; 34 return applet->caller_applet_broker->GetInData();
34} 35}
35 36
36void PushInShowAlbum(Core::System& system, AppletStorageChannel& channel) { 37void PushInShowAlbum(Core::System& system, AppletStorageChannel& channel) {
@@ -46,8 +47,8 @@ void PushInShowAlbum(Core::System& system, AppletStorageChannel& channel) {
46 std::vector<u8> argument_data(sizeof(arguments)); 47 std::vector<u8> argument_data(sizeof(arguments));
47 std::vector<u8> settings_data{2}; 48 std::vector<u8> settings_data{2};
48 std::memcpy(argument_data.data(), &arguments, sizeof(arguments)); 49 std::memcpy(argument_data.data(), &arguments, sizeof(arguments));
49 channel.PushData(std::make_shared<IStorage>(system, std::move(argument_data))); 50 channel.Push(std::make_shared<IStorage>(system, std::move(argument_data)));
50 channel.PushData(std::make_shared<IStorage>(system, std::move(settings_data))); 51 channel.Push(std::make_shared<IStorage>(system, std::move(settings_data)));
51} 52}
52 53
53void PushInShowController(Core::System& system, AppletStorageChannel& channel) { 54void PushInShowController(Core::System& system, AppletStorageChannel& channel) {
@@ -94,9 +95,9 @@ void PushInShowController(Core::System& system, AppletStorageChannel& channel) {
94 std::memcpy(private_args_data.data(), &private_args, sizeof(private_args)); 95 std::memcpy(private_args_data.data(), &private_args, sizeof(private_args));
95 std::memcpy(user_args_data.data(), &user_args, sizeof(user_args)); 96 std::memcpy(user_args_data.data(), &user_args, sizeof(user_args));
96 97
97 channel.PushData(std::make_shared<IStorage>(system, std::move(common_args_data))); 98 channel.Push(std::make_shared<IStorage>(system, std::move(common_args_data)));
98 channel.PushData(std::make_shared<IStorage>(system, std::move(private_args_data))); 99 channel.Push(std::make_shared<IStorage>(system, std::move(private_args_data)));
99 channel.PushData(std::make_shared<IStorage>(system, std::move(user_args_data))); 100 channel.Push(std::make_shared<IStorage>(system, std::move(user_args_data)));
100} 101}
101 102
102void PushInShowCabinetData(Core::System& system, AppletStorageChannel& channel) { 103void PushInShowCabinetData(Core::System& system, AppletStorageChannel& channel) {
@@ -124,8 +125,8 @@ void PushInShowCabinetData(Core::System& system, AppletStorageChannel& channel)
124 std::vector<u8> settings_data(sizeof(amiibo_settings)); 125 std::vector<u8> settings_data(sizeof(amiibo_settings));
125 std::memcpy(argument_data.data(), &arguments, sizeof(arguments)); 126 std::memcpy(argument_data.data(), &arguments, sizeof(arguments));
126 std::memcpy(settings_data.data(), &amiibo_settings, sizeof(amiibo_settings)); 127 std::memcpy(settings_data.data(), &amiibo_settings, sizeof(amiibo_settings));
127 channel.PushData(std::make_shared<IStorage>(system, std::move(argument_data))); 128 channel.Push(std::make_shared<IStorage>(system, std::move(argument_data)));
128 channel.PushData(std::make_shared<IStorage>(system, std::move(settings_data))); 129 channel.Push(std::make_shared<IStorage>(system, std::move(settings_data)));
129} 130}
130 131
131void PushInShowMiiEditData(Core::System& system, AppletStorageChannel& channel) { 132void PushInShowMiiEditData(Core::System& system, AppletStorageChannel& channel) {
@@ -147,7 +148,7 @@ void PushInShowMiiEditData(Core::System& system, AppletStorageChannel& channel)
147 std::vector<u8> argument_data(sizeof(mii_arguments)); 148 std::vector<u8> argument_data(sizeof(mii_arguments));
148 std::memcpy(argument_data.data(), &mii_arguments, sizeof(mii_arguments)); 149 std::memcpy(argument_data.data(), &mii_arguments, sizeof(mii_arguments));
149 150
150 channel.PushData(std::make_shared<IStorage>(system, std::move(argument_data))); 151 channel.Push(std::make_shared<IStorage>(system, std::move(argument_data)));
151} 152}
152 153
153void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& channel) { 154void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& channel) {
@@ -200,9 +201,9 @@ void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& chan
200 std::memcpy(work_buffer.data(), initial_string.data(), 201 std::memcpy(work_buffer.data(), initial_string.data(),
201 swkbd_config.initial_string_length * sizeof(char16_t)); 202 swkbd_config.initial_string_length * sizeof(char16_t));
202 203
203 channel.PushData(std::make_shared<IStorage>(system, std::move(argument_data))); 204 channel.Push(std::make_shared<IStorage>(system, std::move(argument_data)));
204 channel.PushData(std::make_shared<IStorage>(system, std::move(swkbd_data))); 205 channel.Push(std::make_shared<IStorage>(system, std::move(swkbd_data)));
205 channel.PushData(std::make_shared<IStorage>(system, std::move(work_buffer))); 206 channel.Push(std::make_shared<IStorage>(system, std::move(work_buffer)));
206} 207}
207 208
208} // namespace 209} // 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 @@
16 16
17namespace Service::AM::Frontend { 17namespace Service::AM::Frontend {
18 18
19Cabinet::Cabinet(Core::System& system_, LibraryAppletMode applet_mode_, 19Cabinet::Cabinet(Core::System& system_, std::shared_ptr<Applet> applet_,
20 const Core::Frontend::CabinetApplet& frontend_) 20 LibraryAppletMode applet_mode_, const Core::Frontend::CabinetApplet& frontend_)
21 : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, 21 : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_}, service_context{
22 system{system_}, service_context{system_, "CabinetApplet"} { 22 system_,
23 "CabinetApplet"} {
23 24
24 availability_change_event = 25 availability_change_event =
25 service_context.CreateEvent("CabinetApplet:AvailabilityChangeEvent"); 26 service_context.CreateEvent("CabinetApplet:AvailabilityChangeEvent");
@@ -41,7 +42,7 @@ void Cabinet::Initialize() {
41 common_args.play_startup_sound, common_args.size, common_args.system_tick, 42 common_args.play_startup_sound, common_args.size, common_args.system_tick,
42 common_args.theme_color); 43 common_args.theme_color);
43 44
44 const auto storage = broker.PopNormalDataToApplet(); 45 std::shared_ptr<IStorage> storage = PopInData();
45 ASSERT(storage != nullptr); 46 ASSERT(storage != nullptr);
46 47
47 const auto applet_input_data = storage->GetData(); 48 const auto applet_input_data = storage->GetData();
@@ -51,10 +52,6 @@ void Cabinet::Initialize() {
51 sizeof(StartParamForAmiiboSettings)); 52 sizeof(StartParamForAmiiboSettings));
52} 53}
53 54
54bool Cabinet::TransactionComplete() const {
55 return is_complete;
56}
57
58Result Cabinet::GetStatus() const { 55Result Cabinet::GetStatus() const {
59 return ResultSuccess; 56 return ResultSuccess;
60} 57}
@@ -160,8 +157,8 @@ void Cabinet::DisplayCompleted(bool apply_changes, std::string_view amiibo_name)
160 157
161 is_complete = true; 158 is_complete = true;
162 159
163 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); 160 PushOutData(std::make_shared<IStorage>(system, std::move(out_data)));
164 broker.SignalStateChanged(); 161 Exit();
165} 162}
166 163
167void Cabinet::Cancel() { 164void Cabinet::Cancel() {
@@ -175,8 +172,8 @@ void Cabinet::Cancel() {
175 172
176 is_complete = true; 173 is_complete = true;
177 174
178 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); 175 PushOutData(std::make_shared<IStorage>(system, std::move(out_data)));
179 broker.SignalStateChanged(); 176 Exit();
180} 177}
181 178
182Result Cabinet::RequestExit() { 179Result 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,
86 86
87class Cabinet final : public FrontendApplet { 87class Cabinet final : public FrontendApplet {
88public: 88public:
89 explicit Cabinet(Core::System& system_, LibraryAppletMode applet_mode_, 89 explicit Cabinet(Core::System& system_, std::shared_ptr<Applet> applet_,
90 LibraryAppletMode applet_mode_,
90 const Core::Frontend::CabinetApplet& frontend_); 91 const Core::Frontend::CabinetApplet& frontend_);
91 ~Cabinet() override; 92 ~Cabinet() override;
92 93
93 void Initialize() override; 94 void Initialize() override;
94 95
95 bool TransactionComplete() const override;
96 Result GetStatus() const override; 96 Result GetStatus() const override;
97 void ExecuteInteractive() override; 97 void ExecuteInteractive() override;
98 void Execute() override; 98 void Execute() override;
@@ -102,7 +102,6 @@ public:
102 102
103private: 103private:
104 const Core::Frontend::CabinetApplet& frontend; 104 const Core::Frontend::CabinetApplet& frontend;
105 Core::System& system;
106 105
107 bool is_complete{false}; 106 bool is_complete{false};
108 std::shared_ptr<Service::NFC::NfcDevice> nfp_device; 107 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(
47 }; 47 };
48} 48}
49 49
50Controller::Controller(Core::System& system_, LibraryAppletMode applet_mode_, 50Controller::Controller(Core::System& system_, std::shared_ptr<Applet> applet_,
51 LibraryAppletMode applet_mode_,
51 const Core::Frontend::ControllerApplet& frontend_) 52 const Core::Frontend::ControllerApplet& frontend_)
52 : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} 53 : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {}
53 54
54Controller::~Controller() = default; 55Controller::~Controller() = default;
55 56
@@ -67,7 +68,7 @@ void Controller::Initialize() {
67 68
68 controller_applet_version = ControllerAppletVersion{common_args.library_version}; 69 controller_applet_version = ControllerAppletVersion{common_args.library_version};
69 70
70 const auto private_arg_storage = broker.PopNormalDataToApplet(); 71 const std::shared_ptr<IStorage> private_arg_storage = PopInData();
71 ASSERT(private_arg_storage != nullptr); 72 ASSERT(private_arg_storage != nullptr);
72 73
73 const auto& private_arg = private_arg_storage->GetData(); 74 const auto& private_arg = private_arg_storage->GetData();
@@ -117,7 +118,7 @@ void Controller::Initialize() {
117 switch (controller_private_arg.mode) { 118 switch (controller_private_arg.mode) {
118 case ControllerSupportMode::ShowControllerSupport: 119 case ControllerSupportMode::ShowControllerSupport:
119 case ControllerSupportMode::ShowControllerStrapGuide: { 120 case ControllerSupportMode::ShowControllerStrapGuide: {
120 const auto user_arg_storage = broker.PopNormalDataToApplet(); 121 const std::shared_ptr<IStorage> user_arg_storage = PopInData();
121 ASSERT(user_arg_storage != nullptr); 122 ASSERT(user_arg_storage != nullptr);
122 123
123 const auto& user_arg = user_arg_storage->GetData(); 124 const auto& user_arg = user_arg_storage->GetData();
@@ -143,7 +144,7 @@ void Controller::Initialize() {
143 break; 144 break;
144 } 145 }
145 case ControllerSupportMode::ShowControllerFirmwareUpdate: { 146 case ControllerSupportMode::ShowControllerFirmwareUpdate: {
146 const auto update_arg_storage = broker.PopNormalDataToApplet(); 147 const std::shared_ptr<IStorage> update_arg_storage = PopInData();
147 ASSERT(update_arg_storage != nullptr); 148 ASSERT(update_arg_storage != nullptr);
148 149
149 const auto& update_arg = update_arg_storage->GetData(); 150 const auto& update_arg = update_arg_storage->GetData();
@@ -153,7 +154,7 @@ void Controller::Initialize() {
153 break; 154 break;
154 } 155 }
155 case ControllerSupportMode::ShowControllerKeyRemappingForSystem: { 156 case ControllerSupportMode::ShowControllerKeyRemappingForSystem: {
156 const auto remapping_arg_storage = broker.PopNormalDataToApplet(); 157 const std::shared_ptr<IStorage> remapping_arg_storage = PopInData();
157 ASSERT(remapping_arg_storage != nullptr); 158 ASSERT(remapping_arg_storage != nullptr);
158 159
159 const auto& remapping_arg = remapping_arg_storage->GetData(); 160 const auto& remapping_arg = remapping_arg_storage->GetData();
@@ -169,10 +170,6 @@ void Controller::Initialize() {
169 } 170 }
170} 171}
171 172
172bool Controller::TransactionComplete() const {
173 return complete;
174}
175
176Result Controller::GetStatus() const { 173Result Controller::GetStatus() const {
177 return status; 174 return status;
178} 175}
@@ -261,8 +258,9 @@ void Controller::ConfigurationComplete(bool is_success) {
261 complete = true; 258 complete = true;
262 out_data = std::vector<u8>(sizeof(ControllerSupportResultInfo)); 259 out_data = std::vector<u8>(sizeof(ControllerSupportResultInfo));
263 std::memcpy(out_data.data(), &result_info, out_data.size()); 260 std::memcpy(out_data.data(), &result_info, out_data.size());
264 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); 261
265 broker.SignalStateChanged(); 262 PushOutData(std::make_shared<IStorage>(system, std::move(out_data)));
263 Exit();
266} 264}
267 265
268Result Controller::RequestExit() { 266Result 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,
124 124
125class Controller final : public FrontendApplet { 125class Controller final : public FrontendApplet {
126public: 126public:
127 explicit Controller(Core::System& system_, LibraryAppletMode applet_mode_, 127 explicit Controller(Core::System& system_, std::shared_ptr<Applet> applet_,
128 LibraryAppletMode applet_mode_,
128 const Core::Frontend::ControllerApplet& frontend_); 129 const Core::Frontend::ControllerApplet& frontend_);
129 ~Controller() override; 130 ~Controller() override;
130 131
131 void Initialize() override; 132 void Initialize() override;
132 133
133 bool TransactionComplete() const override;
134 Result GetStatus() const override; 134 Result GetStatus() const override;
135 void ExecuteInteractive() override; 135 void ExecuteInteractive() override;
136 void Execute() override; 136 void Execute() override;
@@ -140,7 +140,6 @@ public:
140 140
141private: 141private:
142 const Core::Frontend::ControllerApplet& frontend; 142 const Core::Frontend::ControllerApplet& frontend;
143 Core::System& system;
144 143
145 ControllerAppletVersion controller_applet_version; 144 ControllerAppletVersion controller_applet_version;
146 ControllerSupportArgPrivate controller_private_arg; 145 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) {
104 104
105} // Anonymous namespace 105} // Anonymous namespace
106 106
107Error::Error(Core::System& system_, LibraryAppletMode applet_mode_, 107Error::Error(Core::System& system_, std::shared_ptr<Applet> applet_, LibraryAppletMode applet_mode_,
108 const Core::Frontend::ErrorApplet& frontend_) 108 const Core::Frontend::ErrorApplet& frontend_)
109 : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} 109 : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {}
110 110
111Error::~Error() = default; 111Error::~Error() = default;
112 112
@@ -115,7 +115,7 @@ void Error::Initialize() {
115 args = std::make_unique<ErrorArguments>(); 115 args = std::make_unique<ErrorArguments>();
116 complete = false; 116 complete = false;
117 117
118 const auto storage = broker.PopNormalDataToApplet(); 118 const std::shared_ptr<IStorage> storage = PopInData();
119 ASSERT(storage != nullptr); 119 ASSERT(storage != nullptr);
120 const auto data = storage->GetData(); 120 const auto data = storage->GetData();
121 121
@@ -153,10 +153,6 @@ void Error::Initialize() {
153 } 153 }
154} 154}
155 155
156bool Error::TransactionComplete() const {
157 return complete;
158}
159
160Result Error::GetStatus() const { 156Result Error::GetStatus() const {
161 return ResultSuccess; 157 return ResultSuccess;
162} 158}
@@ -211,8 +207,8 @@ void Error::Execute() {
211 207
212void Error::DisplayCompleted() { 208void Error::DisplayCompleted() {
213 complete = true; 209 complete = true;
214 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{})); 210 PushOutData(std::make_shared<IStorage>(system, std::vector<u8>()));
215 broker.SignalStateChanged(); 211 Exit();
216} 212}
217 213
218Result Error::RequestExit() { 214Result 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 {
24 24
25class Error final : public FrontendApplet { 25class Error final : public FrontendApplet {
26public: 26public:
27 explicit Error(Core::System& system_, LibraryAppletMode applet_mode_, 27 explicit Error(Core::System& system_, std::shared_ptr<Applet> applet_,
28 const Core::Frontend::ErrorApplet& frontend_); 28 LibraryAppletMode applet_mode_, const Core::Frontend::ErrorApplet& frontend_);
29 ~Error() override; 29 ~Error() override;
30 30
31 void Initialize() override; 31 void Initialize() override;
32 32
33 bool TransactionComplete() const override;
34 Result GetStatus() const override; 33 Result GetStatus() const override;
35 void ExecuteInteractive() override; 34 void ExecuteInteractive() override;
36 void Execute() override; 35 void Execute() override;
@@ -47,7 +46,6 @@ private:
47 std::unique_ptr<ErrorArguments> args; 46 std::unique_ptr<ErrorArguments> args;
48 47
49 bool complete = false; 48 bool complete = false;
50 Core::System& system;
51}; 49};
52 50
53} // namespace Service::AM::Frontend 51} // 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 @@
8#include "core/frontend/applets/general.h" 8#include "core/frontend/applets/general.h"
9#include "core/hle/result.h" 9#include "core/hle/result.h"
10#include "core/hle/service/am/am.h" 10#include "core/hle/service/am/am.h"
11#include "core/hle/service/am/applet_data_broker.h"
11#include "core/hle/service/am/frontend/applet_general.h" 12#include "core/hle/service/am/frontend/applet_general.h"
12#include "core/hle/service/am/storage.h" 13#include "core/hle/service/am/storage.h"
13#include "core/reporter.h" 14#include "core/reporter.h"
@@ -16,17 +17,16 @@ namespace Service::AM::Frontend {
16 17
17constexpr Result ERROR_INVALID_PIN{ErrorModule::PCTL, 221}; 18constexpr Result ERROR_INVALID_PIN{ErrorModule::PCTL, 221};
18 19
19static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) { 20static void LogCurrentStorage(std::shared_ptr<Applet> applet, std::string_view prefix) {
20 std::shared_ptr<IStorage> storage = broker.PopNormalDataToApplet(); 21 std::shared_ptr<IStorage> storage;
21 for (; storage != nullptr; storage = broker.PopNormalDataToApplet()) { 22 while (R_SUCCEEDED(applet->caller_applet_broker->GetInData().Pop(&storage))) {
22 const auto data = storage->GetData(); 23 const auto data = storage->GetData();
23 LOG_INFO(Service_AM, 24 LOG_INFO(Service_AM,
24 "called (STUBBED), during {} received normal data with size={:08X}, data={}", 25 "called (STUBBED), during {} received normal data with size={:08X}, data={}",
25 prefix, data.size(), Common::HexToString(data)); 26 prefix, data.size(), Common::HexToString(data));
26 } 27 }
27 28
28 storage = broker.PopInteractiveDataToApplet(); 29 while (R_SUCCEEDED(applet->caller_applet_broker->GetInteractiveInData().Pop(&storage))) {
29 for (; storage != nullptr; storage = broker.PopInteractiveDataToApplet()) {
30 const auto data = storage->GetData(); 30 const auto data = storage->GetData();
31 LOG_INFO(Service_AM, 31 LOG_INFO(Service_AM,
32 "called (STUBBED), during {} received interactive data with size={:08X}, data={}", 32 "called (STUBBED), during {} received interactive data with size={:08X}, data={}",
@@ -34,9 +34,9 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix)
34 } 34 }
35} 35}
36 36
37Auth::Auth(Core::System& system_, LibraryAppletMode applet_mode_, 37Auth::Auth(Core::System& system_, std::shared_ptr<Applet> applet_, LibraryAppletMode applet_mode_,
38 Core::Frontend::ParentalControlsApplet& frontend_) 38 Core::Frontend::ParentalControlsApplet& frontend_)
39 : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} 39 : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {}
40 40
41Auth::~Auth() = default; 41Auth::~Auth() = default;
42 42
@@ -44,7 +44,7 @@ void Auth::Initialize() {
44 FrontendApplet::Initialize(); 44 FrontendApplet::Initialize();
45 complete = false; 45 complete = false;
46 46
47 const auto storage = broker.PopNormalDataToApplet(); 47 const std::shared_ptr<IStorage> storage = PopInData();
48 ASSERT(storage != nullptr); 48 ASSERT(storage != nullptr);
49 const auto data = storage->GetData(); 49 const auto data = storage->GetData();
50 ASSERT(data.size() >= 0xC); 50 ASSERT(data.size() >= 0xC);
@@ -68,10 +68,6 @@ void Auth::Initialize() {
68 arg2 = arg.arg2; 68 arg2 = arg.arg2;
69} 69}
70 70
71bool Auth::TransactionComplete() const {
72 return complete;
73}
74
75Result Auth::GetStatus() const { 71Result Auth::GetStatus() const {
76 return successful ? ResultSuccess : ERROR_INVALID_PIN; 72 return successful ? ResultSuccess : ERROR_INVALID_PIN;
77} 73}
@@ -147,8 +143,8 @@ void Auth::AuthFinished(bool is_successful) {
147 std::vector<u8> out(sizeof(Return)); 143 std::vector<u8> out(sizeof(Return));
148 std::memcpy(out.data(), &return_, sizeof(Return)); 144 std::memcpy(out.data(), &return_, sizeof(Return));
149 145
150 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out))); 146 PushOutData(std::make_shared<IStorage>(system, std::move(out)));
151 broker.SignalStateChanged(); 147 Exit();
152} 148}
153 149
154Result Auth::RequestExit() { 150Result Auth::RequestExit() {
@@ -156,9 +152,10 @@ Result Auth::RequestExit() {
156 R_SUCCEED(); 152 R_SUCCEED();
157} 153}
158 154
159PhotoViewer::PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_, 155PhotoViewer::PhotoViewer(Core::System& system_, std::shared_ptr<Applet> applet_,
156 LibraryAppletMode applet_mode_,
160 const Core::Frontend::PhotoViewerApplet& frontend_) 157 const Core::Frontend::PhotoViewerApplet& frontend_)
161 : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} 158 : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {}
162 159
163PhotoViewer::~PhotoViewer() = default; 160PhotoViewer::~PhotoViewer() = default;
164 161
@@ -166,17 +163,13 @@ void PhotoViewer::Initialize() {
166 FrontendApplet::Initialize(); 163 FrontendApplet::Initialize();
167 complete = false; 164 complete = false;
168 165
169 const auto storage = broker.PopNormalDataToApplet(); 166 const std::shared_ptr<IStorage> storage = PopInData();
170 ASSERT(storage != nullptr); 167 ASSERT(storage != nullptr);
171 const auto data = storage->GetData(); 168 const auto data = storage->GetData();
172 ASSERT(!data.empty()); 169 ASSERT(!data.empty());
173 mode = static_cast<PhotoViewerAppletMode>(data[0]); 170 mode = static_cast<PhotoViewerAppletMode>(data[0]);
174} 171}
175 172
176bool PhotoViewer::TransactionComplete() const {
177 return complete;
178}
179
180Result PhotoViewer::GetStatus() const { 173Result PhotoViewer::GetStatus() const {
181 return ResultSuccess; 174 return ResultSuccess;
182} 175}
@@ -204,8 +197,8 @@ void PhotoViewer::Execute() {
204} 197}
205 198
206void PhotoViewer::ViewFinished() { 199void PhotoViewer::ViewFinished() {
207 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{})); 200 PushOutData(std::make_shared<IStorage>(system, std::vector<u8>{}));
208 broker.SignalStateChanged(); 201 Exit();
209} 202}
210 203
211Result PhotoViewer::RequestExit() { 204Result PhotoViewer::RequestExit() {
@@ -213,8 +206,9 @@ Result PhotoViewer::RequestExit() {
213 R_SUCCEED(); 206 R_SUCCEED();
214} 207}
215 208
216StubApplet::StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_) 209StubApplet::StubApplet(Core::System& system_, std::shared_ptr<Applet> applet_, AppletId id_,
217 : FrontendApplet{system_, applet_mode_}, id{id_}, system{system_} {} 210 LibraryAppletMode applet_mode_)
211 : FrontendApplet{system_, applet_, applet_mode_}, id{id_} {}
218 212
219StubApplet::~StubApplet() = default; 213StubApplet::~StubApplet() = default;
220 214
@@ -222,18 +216,7 @@ void StubApplet::Initialize() {
222 LOG_WARNING(Service_AM, "called (STUBBED)"); 216 LOG_WARNING(Service_AM, "called (STUBBED)");
223 FrontendApplet::Initialize(); 217 FrontendApplet::Initialize();
224 218
225 const auto data = broker.PeekDataToAppletForDebug(); 219 LogCurrentStorage(applet.lock(), "Initialize");
226 system.GetReporter().SaveUnimplementedAppletReport(
227 static_cast<u32>(id), static_cast<u32>(common_args.arguments_version),
228 common_args.library_version, static_cast<u32>(common_args.theme_color),
229 common_args.play_startup_sound, common_args.system_tick, data.normal, data.interactive);
230
231 LogCurrentStorage(broker, "Initialize");
232}
233
234bool StubApplet::TransactionComplete() const {
235 LOG_WARNING(Service_AM, "called (STUBBED)");
236 return true;
237} 220}
238 221
239Result StubApplet::GetStatus() const { 222Result StubApplet::GetStatus() const {
@@ -243,22 +226,20 @@ Result StubApplet::GetStatus() const {
243 226
244void StubApplet::ExecuteInteractive() { 227void StubApplet::ExecuteInteractive() {
245 LOG_WARNING(Service_AM, "called (STUBBED)"); 228 LOG_WARNING(Service_AM, "called (STUBBED)");
246 LogCurrentStorage(broker, "ExecuteInteractive"); 229 LogCurrentStorage(applet.lock(), "ExecuteInteractive");
247 230
248 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); 231 PushOutData(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
249 broker.PushInteractiveDataFromApplet( 232 PushInteractiveOutData(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
250 std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); 233 Exit();
251 broker.SignalStateChanged();
252} 234}
253 235
254void StubApplet::Execute() { 236void StubApplet::Execute() {
255 LOG_WARNING(Service_AM, "called (STUBBED)"); 237 LOG_WARNING(Service_AM, "called (STUBBED)");
256 LogCurrentStorage(broker, "Execute"); 238 LogCurrentStorage(applet.lock(), "Execute");
257 239
258 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); 240 PushOutData(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
259 broker.PushInteractiveDataFromApplet( 241 PushInteractiveOutData(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
260 std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); 242 Exit();
261 broker.SignalStateChanged();
262} 243}
263 244
264Result StubApplet::RequestExit() { 245Result 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 {
19 19
20class Auth final : public FrontendApplet { 20class Auth final : public FrontendApplet {
21public: 21public:
22 explicit Auth(Core::System& system_, LibraryAppletMode applet_mode_, 22 explicit Auth(Core::System& system_, std::shared_ptr<Applet> applet_,
23 LibraryAppletMode applet_mode_,
23 Core::Frontend::ParentalControlsApplet& frontend_); 24 Core::Frontend::ParentalControlsApplet& frontend_);
24 ~Auth() override; 25 ~Auth() override;
25 26
26 void Initialize() override; 27 void Initialize() override;
27 bool TransactionComplete() const override;
28 Result GetStatus() const override; 28 Result GetStatus() const override;
29 void ExecuteInteractive() override; 29 void ExecuteInteractive() override;
30 void Execute() override; 30 void Execute() override;
@@ -34,7 +34,6 @@ public:
34 34
35private: 35private:
36 Core::Frontend::ParentalControlsApplet& frontend; 36 Core::Frontend::ParentalControlsApplet& frontend;
37 Core::System& system;
38 bool complete = false; 37 bool complete = false;
39 bool successful = false; 38 bool successful = false;
40 39
@@ -51,12 +50,12 @@ enum class PhotoViewerAppletMode : u8 {
51 50
52class PhotoViewer final : public FrontendApplet { 51class PhotoViewer final : public FrontendApplet {
53public: 52public:
54 explicit PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_, 53 explicit PhotoViewer(Core::System& system_, std::shared_ptr<Applet> applet_,
54 LibraryAppletMode applet_mode_,
55 const Core::Frontend::PhotoViewerApplet& frontend_); 55 const Core::Frontend::PhotoViewerApplet& frontend_);
56 ~PhotoViewer() override; 56 ~PhotoViewer() override;
57 57
58 void Initialize() override; 58 void Initialize() override;
59 bool TransactionComplete() const override;
60 Result GetStatus() const override; 59 Result GetStatus() const override;
61 void ExecuteInteractive() override; 60 void ExecuteInteractive() override;
62 void Execute() override; 61 void Execute() override;
@@ -68,17 +67,16 @@ private:
68 const Core::Frontend::PhotoViewerApplet& frontend; 67 const Core::Frontend::PhotoViewerApplet& frontend;
69 bool complete = false; 68 bool complete = false;
70 PhotoViewerAppletMode mode = PhotoViewerAppletMode::CurrentApp; 69 PhotoViewerAppletMode mode = PhotoViewerAppletMode::CurrentApp;
71 Core::System& system;
72}; 70};
73 71
74class StubApplet final : public FrontendApplet { 72class StubApplet final : public FrontendApplet {
75public: 73public:
76 explicit StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_); 74 explicit StubApplet(Core::System& system_, std::shared_ptr<Applet> applet_, AppletId id_,
75 LibraryAppletMode applet_mode_);
77 ~StubApplet() override; 76 ~StubApplet() override;
78 77
79 void Initialize() override; 78 void Initialize() override;
80 79
81 bool TransactionComplete() const override;
82 Result GetStatus() const override; 80 Result GetStatus() const override;
83 void ExecuteInteractive() override; 81 void ExecuteInteractive() override;
84 void Execute() override; 82 void Execute() override;
@@ -86,7 +84,6 @@ public:
86 84
87private: 85private:
88 AppletId id; 86 AppletId id;
89 Core::System& system;
90}; 87};
91 88
92} // namespace Service::AM::Frontend 89} // 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 @@
14 14
15namespace Service::AM::Frontend { 15namespace Service::AM::Frontend {
16 16
17MiiEdit::MiiEdit(Core::System& system_, LibraryAppletMode applet_mode_, 17MiiEdit::MiiEdit(Core::System& system_, std::shared_ptr<Applet> applet_,
18 const Core::Frontend::MiiEditApplet& frontend_) 18 LibraryAppletMode applet_mode_, const Core::Frontend::MiiEditApplet& frontend_)
19 : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} 19 : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {}
20 20
21MiiEdit::~MiiEdit() = default; 21MiiEdit::~MiiEdit() = default;
22 22
@@ -25,7 +25,7 @@ void MiiEdit::Initialize() {
25 // Instead, it is initialized by an AppletInput storage with size 0x100 bytes. 25 // Instead, it is initialized by an AppletInput storage with size 0x100 bytes.
26 // Do NOT call Applet::Initialize() here. 26 // Do NOT call Applet::Initialize() here.
27 27
28 const auto storage = broker.PopNormalDataToApplet(); 28 const std::shared_ptr<IStorage> storage = PopInData();
29 ASSERT(storage != nullptr); 29 ASSERT(storage != nullptr);
30 30
31 const auto applet_input_data = storage->GetData(); 31 const auto applet_input_data = storage->GetData();
@@ -67,10 +67,6 @@ void MiiEdit::Initialize() {
67 manager->Initialize(metadata); 67 manager->Initialize(metadata);
68} 68}
69 69
70bool MiiEdit::TransactionComplete() const {
71 return is_complete;
72}
73
74Result MiiEdit::GetStatus() const { 70Result MiiEdit::GetStatus() const {
75 return ResultSuccess; 71 return ResultSuccess;
76} 72}
@@ -153,8 +149,8 @@ void MiiEdit::MiiEditOutput(MiiEditResult result, s32 index) {
153 149
154 is_complete = true; 150 is_complete = true;
155 151
156 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); 152 PushOutData(std::make_shared<IStorage>(system, std::move(out_data)));
157 broker.SignalStateChanged(); 153 Exit();
158} 154}
159 155
160void MiiEdit::MiiEditOutputForCharInfoEditing(MiiEditResult result, 156void MiiEdit::MiiEditOutputForCharInfoEditing(MiiEditResult result,
@@ -169,8 +165,8 @@ void MiiEdit::MiiEditOutputForCharInfoEditing(MiiEditResult result,
169 165
170 is_complete = true; 166 is_complete = true;
171 167
172 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); 168 PushOutData(std::make_shared<IStorage>(system, std::move(out_data)));
173 broker.SignalStateChanged(); 169 Exit();
174} 170}
175 171
176Result MiiEdit::RequestExit() { 172Result 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 {
20 20
21class MiiEdit final : public FrontendApplet { 21class MiiEdit final : public FrontendApplet {
22public: 22public:
23 explicit MiiEdit(Core::System& system_, LibraryAppletMode applet_mode_, 23 explicit MiiEdit(Core::System& system_, std::shared_ptr<Applet> applet_,
24 LibraryAppletMode applet_mode_,
24 const Core::Frontend::MiiEditApplet& frontend_); 25 const Core::Frontend::MiiEditApplet& frontend_);
25 ~MiiEdit() override; 26 ~MiiEdit() override;
26 27
27 void Initialize() override; 28 void Initialize() override;
28 29
29 bool TransactionComplete() const override;
30 Result GetStatus() const override; 30 Result GetStatus() const override;
31 void ExecuteInteractive() override; 31 void ExecuteInteractive() override;
32 void Execute() override; 32 void Execute() override;
@@ -38,7 +38,6 @@ public:
38 38
39private: 39private:
40 const Core::Frontend::MiiEditApplet& frontend; 40 const Core::Frontend::MiiEditApplet& frontend;
41 Core::System& system;
42 41
43 MiiEditAppletInputCommon applet_input_common{}; 42 MiiEditAppletInputCommon applet_input_common{};
44 MiiEditAppletInputV3 applet_input_v3{}; 43 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 @@
14 14
15namespace Service::AM::Frontend { 15namespace Service::AM::Frontend {
16 16
17ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_, 17ProfileSelect::ProfileSelect(Core::System& system_, std::shared_ptr<Applet> applet_,
18 LibraryAppletMode applet_mode_,
18 const Core::Frontend::ProfileSelectApplet& frontend_) 19 const Core::Frontend::ProfileSelectApplet& frontend_)
19 : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} 20 : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {}
20 21
21ProfileSelect::~ProfileSelect() = default; 22ProfileSelect::~ProfileSelect() = default;
22 23
@@ -28,7 +29,7 @@ void ProfileSelect::Initialize() {
28 FrontendApplet::Initialize(); 29 FrontendApplet::Initialize();
29 profile_select_version = ProfileSelectAppletVersion{common_args.library_version}; 30 profile_select_version = ProfileSelectAppletVersion{common_args.library_version};
30 31
31 const auto user_config_storage = broker.PopNormalDataToApplet(); 32 const std::shared_ptr<IStorage> user_config_storage = PopInData();
32 ASSERT(user_config_storage != nullptr); 33 ASSERT(user_config_storage != nullptr);
33 const auto& user_config = user_config_storage->GetData(); 34 const auto& user_config = user_config_storage->GetData();
34 35
@@ -51,10 +52,6 @@ void ProfileSelect::Initialize() {
51 } 52 }
52} 53}
53 54
54bool ProfileSelect::TransactionComplete() const {
55 return complete;
56}
57
58Result ProfileSelect::GetStatus() const { 55Result ProfileSelect::GetStatus() const {
59 return status; 56 return status;
60} 57}
@@ -65,7 +62,8 @@ void ProfileSelect::ExecuteInteractive() {
65 62
66void ProfileSelect::Execute() { 63void ProfileSelect::Execute() {
67 if (complete) { 64 if (complete) {
68 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data))); 65 PushOutData(std::make_shared<IStorage>(system, std::move(final_data)));
66 Exit();
69 return; 67 return;
70 } 68 }
71 69
@@ -112,8 +110,9 @@ void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) {
112 110
113 final_data = std::vector<u8>(sizeof(UiReturnArg)); 111 final_data = std::vector<u8>(sizeof(UiReturnArg));
114 std::memcpy(final_data.data(), &output, final_data.size()); 112 std::memcpy(final_data.data(), &output, final_data.size());
115 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data))); 113
116 broker.SignalStateChanged(); 114 PushOutData(std::make_shared<IStorage>(system, std::move(final_data)));
115 Exit();
117} 116}
118 117
119Result ProfileSelect::RequestExit() { 118Result 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.");
113 113
114class ProfileSelect final : public FrontendApplet { 114class ProfileSelect final : public FrontendApplet {
115public: 115public:
116 explicit ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_, 116 explicit ProfileSelect(Core::System& system_, std::shared_ptr<Applet> applet_,
117 LibraryAppletMode applet_mode_,
117 const Core::Frontend::ProfileSelectApplet& frontend_); 118 const Core::Frontend::ProfileSelectApplet& frontend_);
118 ~ProfileSelect() override; 119 ~ProfileSelect() override;
119 120
120 void Initialize() override; 121 void Initialize() override;
121 122
122 bool TransactionComplete() const override;
123 Result GetStatus() const override; 123 Result GetStatus() const override;
124 void ExecuteInteractive() override; 124 void ExecuteInteractive() override;
125 void Execute() override; 125 void Execute() override;
@@ -137,7 +137,6 @@ private:
137 bool complete = false; 137 bool complete = false;
138 Result status = ResultSuccess; 138 Result status = ResultSuccess;
139 std::vector<u8> final_data; 139 std::vector<u8> final_data;
140 Core::System& system;
141}; 140};
142 141
143} // namespace Service::AM::Frontend 142} // 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
42 42
43} // Anonymous namespace 43} // Anonymous namespace
44 44
45SoftwareKeyboard::SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_, 45SoftwareKeyboard::SoftwareKeyboard(Core::System& system_, std::shared_ptr<Applet> applet_,
46 LibraryAppletMode applet_mode_,
46 Core::Frontend::SoftwareKeyboardApplet& frontend_) 47 Core::Frontend::SoftwareKeyboardApplet& frontend_)
47 : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} 48 : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {}
48 49
49SoftwareKeyboard::~SoftwareKeyboard() = default; 50SoftwareKeyboard::~SoftwareKeyboard() = default;
50 51
@@ -77,10 +78,6 @@ void SoftwareKeyboard::Initialize() {
77 } 78 }
78} 79}
79 80
80bool SoftwareKeyboard::TransactionComplete() const {
81 return complete;
82}
83
84Result SoftwareKeyboard::GetStatus() const { 81Result SoftwareKeyboard::GetStatus() const {
85 return status; 82 return status;
86} 83}
@@ -185,7 +182,7 @@ void SoftwareKeyboard::InitializeForeground() {
185 182
186 is_background = false; 183 is_background = false;
187 184
188 const auto swkbd_config_storage = broker.PopNormalDataToApplet(); 185 const auto swkbd_config_storage = PopInData();
189 ASSERT(swkbd_config_storage != nullptr); 186 ASSERT(swkbd_config_storage != nullptr);
190 187
191 const auto& swkbd_config_data = swkbd_config_storage->GetData(); 188 const auto& swkbd_config_data = swkbd_config_storage->GetData();
@@ -222,7 +219,7 @@ void SoftwareKeyboard::InitializeForeground() {
222 break; 219 break;
223 } 220 }
224 221
225 const auto work_buffer_storage = broker.PopNormalDataToApplet(); 222 const auto work_buffer_storage = PopInData();
226 ASSERT(work_buffer_storage != nullptr); 223 ASSERT(work_buffer_storage != nullptr);
227 224
228 if (swkbd_config_common.initial_string_length == 0) { 225 if (swkbd_config_common.initial_string_length == 0) {
@@ -251,7 +248,7 @@ void SoftwareKeyboard::InitializeBackground(LibraryAppletMode library_applet_mod
251 248
252 is_background = true; 249 is_background = true;
253 250
254 const auto swkbd_inline_initialize_arg_storage = broker.PopNormalDataToApplet(); 251 const auto swkbd_inline_initialize_arg_storage = PopInData();
255 ASSERT(swkbd_inline_initialize_arg_storage != nullptr); 252 ASSERT(swkbd_inline_initialize_arg_storage != nullptr);
256 253
257 const auto& swkbd_inline_initialize_arg = swkbd_inline_initialize_arg_storage->GetData(); 254 const auto& swkbd_inline_initialize_arg = swkbd_inline_initialize_arg_storage->GetData();
@@ -268,7 +265,7 @@ void SoftwareKeyboard::InitializeBackground(LibraryAppletMode library_applet_mod
268} 265}
269 266
270void SoftwareKeyboard::ProcessTextCheck() { 267void SoftwareKeyboard::ProcessTextCheck() {
271 const auto text_check_storage = broker.PopInteractiveDataToApplet(); 268 const auto text_check_storage = PopInteractiveInData();
272 ASSERT(text_check_storage != nullptr); 269 ASSERT(text_check_storage != nullptr);
273 270
274 const auto& text_check_data = text_check_storage->GetData(); 271 const auto& text_check_data = text_check_storage->GetData();
@@ -315,7 +312,7 @@ void SoftwareKeyboard::ProcessTextCheck() {
315} 312}
316 313
317void SoftwareKeyboard::ProcessInlineKeyboardRequest() { 314void SoftwareKeyboard::ProcessInlineKeyboardRequest() {
318 const auto request_data_storage = broker.PopInteractiveDataToApplet(); 315 const auto request_data_storage = PopInteractiveInData();
319 ASSERT(request_data_storage != nullptr); 316 ASSERT(request_data_storage != nullptr);
320 317
321 const auto& request_data = request_data_storage->GetData(); 318 const auto& request_data = request_data_storage->GetData();
@@ -378,7 +375,7 @@ void SoftwareKeyboard::SubmitNormalOutputAndExit(SwkbdResult result,
378 submitted_text.size() * sizeof(char16_t)); 375 submitted_text.size() * sizeof(char16_t));
379 } 376 }
380 377
381 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); 378 PushOutData(std::make_shared<IStorage>(system, std::move(out_data)));
382 379
383 ExitKeyboard(); 380 ExitKeyboard();
384} 381}
@@ -411,7 +408,7 @@ void SoftwareKeyboard::SubmitForTextCheck(std::u16string submitted_text) {
411 current_text.size() * sizeof(char16_t)); 408 current_text.size() * sizeof(char16_t));
412 } 409 }
413 410
414 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); 411 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(out_data)));
415} 412}
416 413
417void SoftwareKeyboard::SendReply(SwkbdReplyType reply_type) { 414void SoftwareKeyboard::SendReply(SwkbdReplyType reply_type) {
@@ -768,7 +765,7 @@ void SoftwareKeyboard::ExitKeyboard() {
768 765
769 frontend.ExitKeyboard(); 766 frontend.ExitKeyboard();
770 767
771 broker.SignalStateChanged(); 768 Exit();
772} 769}
773 770
774Result SoftwareKeyboard::RequestExit() { 771Result SoftwareKeyboard::RequestExit() {
@@ -968,7 +965,7 @@ void SoftwareKeyboard::ReplyFinishedInitialize() {
968 965
969 SetReplyBase(reply, swkbd_state, SwkbdReplyType::FinishedInitialize); 966 SetReplyBase(reply, swkbd_state, SwkbdReplyType::FinishedInitialize);
970 967
971 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 968 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
972} 969}
973 970
974void SoftwareKeyboard::ReplyDefault() { 971void SoftwareKeyboard::ReplyDefault() {
@@ -978,7 +975,7 @@ void SoftwareKeyboard::ReplyDefault() {
978 975
979 SetReplyBase(reply, swkbd_state, SwkbdReplyType::Default); 976 SetReplyBase(reply, swkbd_state, SwkbdReplyType::Default);
980 977
981 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 978 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
982} 979}
983 980
984void SoftwareKeyboard::ReplyChangedString() { 981void SoftwareKeyboard::ReplyChangedString() {
@@ -1000,7 +997,7 @@ void SoftwareKeyboard::ReplyChangedString() {
1000 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &changed_string_arg, 997 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &changed_string_arg,
1001 sizeof(SwkbdChangedStringArg)); 998 sizeof(SwkbdChangedStringArg));
1002 999
1003 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1000 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1004} 1001}
1005 1002
1006void SoftwareKeyboard::ReplyMovedCursor() { 1003void SoftwareKeyboard::ReplyMovedCursor() {
@@ -1020,7 +1017,7 @@ void SoftwareKeyboard::ReplyMovedCursor() {
1020 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_cursor_arg, 1017 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_cursor_arg,
1021 sizeof(SwkbdMovedCursorArg)); 1018 sizeof(SwkbdMovedCursorArg));
1022 1019
1023 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1020 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1024} 1021}
1025 1022
1026void SoftwareKeyboard::ReplyMovedTab() { 1023void SoftwareKeyboard::ReplyMovedTab() {
@@ -1040,7 +1037,7 @@ void SoftwareKeyboard::ReplyMovedTab() {
1040 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_tab_arg, 1037 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_tab_arg,
1041 sizeof(SwkbdMovedTabArg)); 1038 sizeof(SwkbdMovedTabArg));
1042 1039
1043 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1040 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1044} 1041}
1045 1042
1046void SoftwareKeyboard::ReplyDecidedEnter() { 1043void SoftwareKeyboard::ReplyDecidedEnter() {
@@ -1059,7 +1056,7 @@ void SoftwareKeyboard::ReplyDecidedEnter() {
1059 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &decided_enter_arg, 1056 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &decided_enter_arg,
1060 sizeof(SwkbdDecidedEnterArg)); 1057 sizeof(SwkbdDecidedEnterArg));
1061 1058
1062 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1059 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1063 1060
1064 HideInlineKeyboard(); 1061 HideInlineKeyboard();
1065} 1062}
@@ -1071,7 +1068,7 @@ void SoftwareKeyboard::ReplyDecidedCancel() {
1071 1068
1072 SetReplyBase(reply, swkbd_state, SwkbdReplyType::DecidedCancel); 1069 SetReplyBase(reply, swkbd_state, SwkbdReplyType::DecidedCancel);
1073 1070
1074 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1071 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1075 1072
1076 HideInlineKeyboard(); 1073 HideInlineKeyboard();
1077} 1074}
@@ -1096,7 +1093,7 @@ void SoftwareKeyboard::ReplyChangedStringUtf8() {
1096 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &changed_string_arg, 1093 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &changed_string_arg,
1097 sizeof(SwkbdChangedStringArg)); 1094 sizeof(SwkbdChangedStringArg));
1098 1095
1099 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1096 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1100} 1097}
1101 1098
1102void SoftwareKeyboard::ReplyMovedCursorUtf8() { 1099void SoftwareKeyboard::ReplyMovedCursorUtf8() {
@@ -1117,7 +1114,7 @@ void SoftwareKeyboard::ReplyMovedCursorUtf8() {
1117 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &moved_cursor_arg, 1114 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &moved_cursor_arg,
1118 sizeof(SwkbdMovedCursorArg)); 1115 sizeof(SwkbdMovedCursorArg));
1119 1116
1120 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1117 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1121} 1118}
1122 1119
1123void SoftwareKeyboard::ReplyDecidedEnterUtf8() { 1120void SoftwareKeyboard::ReplyDecidedEnterUtf8() {
@@ -1137,7 +1134,7 @@ void SoftwareKeyboard::ReplyDecidedEnterUtf8() {
1137 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &decided_enter_arg, 1134 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &decided_enter_arg,
1138 sizeof(SwkbdDecidedEnterArg)); 1135 sizeof(SwkbdDecidedEnterArg));
1139 1136
1140 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1137 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1141 1138
1142 HideInlineKeyboard(); 1139 HideInlineKeyboard();
1143} 1140}
@@ -1149,7 +1146,7 @@ void SoftwareKeyboard::ReplyUnsetCustomizeDic() {
1149 1146
1150 SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizeDic); 1147 SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizeDic);
1151 1148
1152 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1149 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1153} 1150}
1154 1151
1155void SoftwareKeyboard::ReplyReleasedUserWordInfo() { 1152void SoftwareKeyboard::ReplyReleasedUserWordInfo() {
@@ -1159,7 +1156,7 @@ void SoftwareKeyboard::ReplyReleasedUserWordInfo() {
1159 1156
1160 SetReplyBase(reply, swkbd_state, SwkbdReplyType::ReleasedUserWordInfo); 1157 SetReplyBase(reply, swkbd_state, SwkbdReplyType::ReleasedUserWordInfo);
1161 1158
1162 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1159 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1163} 1160}
1164 1161
1165void SoftwareKeyboard::ReplyUnsetCustomizedDictionaries() { 1162void SoftwareKeyboard::ReplyUnsetCustomizedDictionaries() {
@@ -1169,7 +1166,7 @@ void SoftwareKeyboard::ReplyUnsetCustomizedDictionaries() {
1169 1166
1170 SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizedDictionaries); 1167 SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizedDictionaries);
1171 1168
1172 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1169 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1173} 1170}
1174 1171
1175void SoftwareKeyboard::ReplyChangedStringV2() { 1172void SoftwareKeyboard::ReplyChangedStringV2() {
@@ -1195,7 +1192,7 @@ void SoftwareKeyboard::ReplyChangedStringV2() {
1195 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdChangedStringArg), 1192 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdChangedStringArg),
1196 &flag, 1); 1193 &flag, 1);
1197 1194
1198 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1195 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1199} 1196}
1200 1197
1201void SoftwareKeyboard::ReplyMovedCursorV2() { 1198void SoftwareKeyboard::ReplyMovedCursorV2() {
@@ -1219,7 +1216,7 @@ void SoftwareKeyboard::ReplyMovedCursorV2() {
1219 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedCursorArg), 1216 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedCursorArg),
1220 &flag, 1); 1217 &flag, 1);
1221 1218
1222 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1219 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1223} 1220}
1224 1221
1225void SoftwareKeyboard::ReplyChangedStringUtf8V2() { 1222void SoftwareKeyboard::ReplyChangedStringUtf8V2() {
@@ -1246,7 +1243,7 @@ void SoftwareKeyboard::ReplyChangedStringUtf8V2() {
1246 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdChangedStringArg), 1243 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdChangedStringArg),
1247 &flag, 1); 1244 &flag, 1);
1248 1245
1249 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1246 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1250} 1247}
1251 1248
1252void SoftwareKeyboard::ReplyMovedCursorUtf8V2() { 1249void SoftwareKeyboard::ReplyMovedCursorUtf8V2() {
@@ -1271,7 +1268,7 @@ void SoftwareKeyboard::ReplyMovedCursorUtf8V2() {
1271 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdMovedCursorArg), 1268 std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdMovedCursorArg),
1272 &flag, 1); 1269 &flag, 1);
1273 1270
1274 broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); 1271 PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
1275} 1272}
1276 1273
1277} // namespace Service::AM::Frontend 1274} // 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 {
21 21
22class SoftwareKeyboard final : public FrontendApplet { 22class SoftwareKeyboard final : public FrontendApplet {
23public: 23public:
24 explicit SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_, 24 explicit SoftwareKeyboard(Core::System& system_, std::shared_ptr<Applet> applet_,
25 LibraryAppletMode applet_mode_,
25 Core::Frontend::SoftwareKeyboardApplet& frontend_); 26 Core::Frontend::SoftwareKeyboardApplet& frontend_);
26 ~SoftwareKeyboard() override; 27 ~SoftwareKeyboard() override;
27 28
28 void Initialize() override; 29 void Initialize() override;
29 30
30 bool TransactionComplete() const override;
31 Result GetStatus() const override; 31 Result GetStatus() const override;
32 void ExecuteInteractive() override; 32 void ExecuteInteractive() override;
33 void Execute() override; 33 void Execute() override;
@@ -156,7 +156,6 @@ private:
156 void ReplyMovedCursorUtf8V2(); 156 void ReplyMovedCursorUtf8V2();
157 157
158 Core::Frontend::SoftwareKeyboardApplet& frontend; 158 Core::Frontend::SoftwareKeyboardApplet& frontend;
159 Core::System& system;
160 159
161 SwkbdAppletVersion swkbd_applet_version; 160 SwkbdAppletVersion swkbd_applet_version;
162 161
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) {
224 224
225} // namespace 225} // namespace
226 226
227WebBrowser::WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_, 227WebBrowser::WebBrowser(Core::System& system_, std::shared_ptr<Applet> applet_,
228 LibraryAppletMode applet_mode_,
228 const Core::Frontend::WebBrowserApplet& frontend_) 229 const Core::Frontend::WebBrowserApplet& frontend_)
229 : FrontendApplet{system_, applet_mode_}, frontend(frontend_), system{system_} {} 230 : FrontendApplet{system_, applet_, applet_mode_}, frontend(frontend_) {}
230 231
231WebBrowser::~WebBrowser() = default; 232WebBrowser::~WebBrowser() = default;
232 233
@@ -244,7 +245,7 @@ void WebBrowser::Initialize() {
244 245
245 web_applet_version = WebAppletVersion{common_args.library_version}; 246 web_applet_version = WebAppletVersion{common_args.library_version};
246 247
247 const auto web_arg_storage = broker.PopNormalDataToApplet(); 248 const auto web_arg_storage = PopInData();
248 ASSERT(web_arg_storage != nullptr); 249 ASSERT(web_arg_storage != nullptr);
249 250
250 const auto& web_arg = web_arg_storage->GetData(); 251 const auto& web_arg = web_arg_storage->GetData();
@@ -285,10 +286,6 @@ void WebBrowser::Initialize() {
285 } 286 }
286} 287}
287 288
288bool WebBrowser::TransactionComplete() const {
289 return complete;
290}
291
292Result WebBrowser::GetStatus() const { 289Result WebBrowser::GetStatus() const {
293 return status; 290 return status;
294} 291}
@@ -359,8 +356,8 @@ void WebBrowser::WebBrowserExit(WebExitReason exit_reason, std::string last_url)
359 complete = true; 356 complete = true;
360 std::vector<u8> out_data(sizeof(WebCommonReturnValue)); 357 std::vector<u8> out_data(sizeof(WebCommonReturnValue));
361 std::memcpy(out_data.data(), &web_common_return_value, out_data.size()); 358 std::memcpy(out_data.data(), &web_common_return_value, out_data.size());
362 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); 359 PushOutData(std::make_shared<IStorage>(system, std::move(out_data)));
363 broker.SignalStateChanged(); 360 Exit();
364} 361}
365 362
366Result WebBrowser::RequestExit() { 363Result 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 {
24 24
25class WebBrowser final : public FrontendApplet { 25class WebBrowser final : public FrontendApplet {
26public: 26public:
27 WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_, 27 WebBrowser(Core::System& system_, std::shared_ptr<Applet> applet_,
28 const Core::Frontend::WebBrowserApplet& frontend_); 28 LibraryAppletMode applet_mode_, const Core::Frontend::WebBrowserApplet& frontend_);
29 29
30 ~WebBrowser() override; 30 ~WebBrowser() override;
31 31
32 void Initialize() override; 32 void Initialize() override;
33 33
34 bool TransactionComplete() const override;
35 Result GetStatus() const override; 34 Result GetStatus() const override;
36 void ExecuteInteractive() override; 35 void ExecuteInteractive() override;
37 void Execute() override; 36 void Execute() override;
@@ -80,8 +79,6 @@ private:
80 FileSys::VirtualFile offline_romfs; 79 FileSys::VirtualFile offline_romfs;
81 80
82 std::string external_url; 81 std::string external_url;
83
84 Core::System& system;
85}; 82};
86 83
87} // namespace Service::AM::Frontend 84} // 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 @@
16#include "core/hle/kernel/k_event.h" 16#include "core/hle/kernel/k_event.h"
17#include "core/hle/service/am/am.h" 17#include "core/hle/service/am/am.h"
18#include "core/hle/service/am/applet_ae.h" 18#include "core/hle/service/am/applet_ae.h"
19#include "core/hle/service/am/applet_data_broker.h"
19#include "core/hle/service/am/applet_manager.h" 20#include "core/hle/service/am/applet_manager.h"
20#include "core/hle/service/am/applet_message_queue.h" 21#include "core/hle/service/am/applet_message_queue.h"
21#include "core/hle/service/am/applet_oe.h" 22#include "core/hle/service/am/applet_oe.h"
@@ -33,135 +34,45 @@
33 34
34namespace Service::AM::Frontend { 35namespace Service::AM::Frontend {
35 36
36AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_) 37FrontendApplet::FrontendApplet(Core::System& system_, std::shared_ptr<Applet> applet_,
37 : system{system_}, applet_mode{applet_mode_}, 38 LibraryAppletMode applet_mode_)
38 service_context{system, "ILibraryAppletAccessor"} { 39 : system{system_}, applet{std::move(applet_)}, applet_mode{applet_mode_} {}
39 state_changed_event = service_context.CreateEvent("ILibraryAppletAccessor:StateChangedEvent");
40 pop_out_data_event = service_context.CreateEvent("ILibraryAppletAccessor:PopDataOutEvent");
41 pop_interactive_out_data_event =
42 service_context.CreateEvent("ILibraryAppletAccessor:PopInteractiveDataOutEvent");
43}
44
45AppletDataBroker::~AppletDataBroker() {
46 service_context.CloseEvent(state_changed_event);
47 service_context.CloseEvent(pop_out_data_event);
48 service_context.CloseEvent(pop_interactive_out_data_event);
49}
50
51AppletDataBroker::RawChannelData AppletDataBroker::PeekDataToAppletForDebug() const {
52 std::vector<std::vector<u8>> out_normal;
53
54 for (const auto& storage : in_channel) {
55 out_normal.push_back(storage->GetData());
56 }
57
58 std::vector<std::vector<u8>> out_interactive;
59 40
60 for (const auto& storage : in_interactive_channel) { 41FrontendApplet::~FrontendApplet() = default;
61 out_interactive.push_back(storage->GetData());
62 }
63
64 return {std::move(out_normal), std::move(out_interactive)};
65}
66
67std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() {
68 if (out_channel.empty())
69 return nullptr;
70
71 auto out = std::move(out_channel.front());
72 out_channel.pop_front();
73 pop_out_data_event->Clear();
74 return out;
75}
76
77std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToApplet() {
78 if (in_channel.empty())
79 return nullptr;
80
81 auto out = std::move(in_channel.front());
82 in_channel.pop_front();
83 return out;
84}
85
86std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() {
87 if (out_interactive_channel.empty())
88 return nullptr;
89
90 auto out = std::move(out_interactive_channel.front());
91 out_interactive_channel.pop_front();
92 pop_interactive_out_data_event->Clear();
93 return out;
94}
95
96std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToApplet() {
97 if (in_interactive_channel.empty())
98 return nullptr;
99
100 auto out = std::move(in_interactive_channel.front());
101 in_interactive_channel.pop_front();
102 return out;
103}
104
105void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr<IStorage>&& storage) {
106 in_channel.emplace_back(std::move(storage));
107}
108 42
109void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) { 43void FrontendApplet::Initialize() {
110 out_channel.emplace_back(std::move(storage)); 44 std::shared_ptr<IStorage> common = PopInData();
111 pop_out_data_event->Signal(); 45 ASSERT(common != nullptr);
112} 46 const auto common_data = common->GetData();
113 47
114void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) { 48 ASSERT(common_data.size() >= sizeof(CommonArguments));
115 in_interactive_channel.emplace_back(std::move(storage)); 49 std::memcpy(&common_args, common_data.data(), sizeof(CommonArguments));
116}
117 50
118void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) { 51 initialized = true;
119 out_interactive_channel.emplace_back(std::move(storage));
120 pop_interactive_out_data_event->Signal();
121} 52}
122 53
123void AppletDataBroker::SignalStateChanged() { 54std::shared_ptr<IStorage> FrontendApplet::PopInData() {
124 state_changed_event->Signal(); 55 std::shared_ptr<IStorage> ret;
125 56 applet.lock()->caller_applet_broker->GetInData().Pop(&ret);
126 // TODO proper window management 57 return ret;
127 switch (applet_mode) {
128 case LibraryAppletMode::AllForeground:
129 case LibraryAppletMode::AllForegroundInitiallyHidden: {
130 system.GetAppletManager().FocusStateChanged();
131 break;
132 }
133 default:
134 break;
135 }
136} 58}
137 59
138Kernel::KReadableEvent& AppletDataBroker::GetNormalDataEvent() { 60std::shared_ptr<IStorage> FrontendApplet::PopInteractiveInData() {
139 return pop_out_data_event->GetReadableEvent(); 61 std::shared_ptr<IStorage> ret;
62 applet.lock()->caller_applet_broker->GetInteractiveInData().Pop(&ret);
63 return ret;
140} 64}
141 65
142Kernel::KReadableEvent& AppletDataBroker::GetInteractiveDataEvent() { 66void FrontendApplet::PushOutData(std::shared_ptr<IStorage> storage) {
143 return pop_interactive_out_data_event->GetReadableEvent(); 67 applet.lock()->caller_applet_broker->GetOutData().Push(storage);
144} 68}
145 69
146Kernel::KReadableEvent& AppletDataBroker::GetStateChangedEvent() { 70void FrontendApplet::PushInteractiveOutData(std::shared_ptr<IStorage> storage) {
147 return state_changed_event->GetReadableEvent(); 71 applet.lock()->caller_applet_broker->GetInteractiveOutData().Push(storage);
148} 72}
149 73
150FrontendApplet::FrontendApplet(Core::System& system_, LibraryAppletMode applet_mode_) 74void FrontendApplet::Exit() {
151 : broker{system_, applet_mode_}, applet_mode{applet_mode_} {} 75 applet.lock()->caller_applet_broker->SignalCompletion();
152
153FrontendApplet::~FrontendApplet() = default;
154
155void FrontendApplet::Initialize() {
156 const auto common = broker.PopNormalDataToApplet();
157 ASSERT(common != nullptr);
158
159 const auto common_data = common->GetData();
160
161 ASSERT(common_data.size() >= sizeof(CommonArguments));
162 std::memcpy(&common_args, common_data.data(), sizeof(CommonArguments));
163
164 initialized = true;
165} 76}
166 77
167FrontendAppletSet::FrontendAppletSet() = default; 78FrontendAppletSet::FrontendAppletSet() = default;
@@ -291,36 +202,38 @@ void FrontendAppletHolder::ClearAll() {
291 frontend = {}; 202 frontend = {};
292} 203}
293 204
294std::shared_ptr<FrontendApplet> FrontendAppletHolder::GetApplet(AppletId id, 205std::shared_ptr<FrontendApplet> FrontendAppletHolder::GetApplet(std::shared_ptr<Applet> applet,
206 AppletId id,
295 LibraryAppletMode mode) const { 207 LibraryAppletMode mode) const {
296 switch (id) { 208 switch (id) {
297 case AppletId::Auth: 209 case AppletId::Auth:
298 return std::make_shared<Auth>(system, mode, *frontend.parental_controls); 210 return std::make_shared<Auth>(system, applet, mode, *frontend.parental_controls);
299 case AppletId::Cabinet: 211 case AppletId::Cabinet:
300 return std::make_shared<Cabinet>(system, mode, *frontend.cabinet); 212 return std::make_shared<Cabinet>(system, applet, mode, *frontend.cabinet);
301 case AppletId::Controller: 213 case AppletId::Controller:
302 return std::make_shared<Controller>(system, mode, *frontend.controller); 214 return std::make_shared<Controller>(system, applet, mode, *frontend.controller);
303 case AppletId::Error: 215 case AppletId::Error:
304 return std::make_shared<Error>(system, mode, *frontend.error); 216 return std::make_shared<Error>(system, applet, mode, *frontend.error);
305 case AppletId::ProfileSelect: 217 case AppletId::ProfileSelect:
306 return std::make_shared<ProfileSelect>(system, mode, *frontend.profile_select); 218 return std::make_shared<ProfileSelect>(system, applet, mode, *frontend.profile_select);
307 case AppletId::SoftwareKeyboard: 219 case AppletId::SoftwareKeyboard:
308 return std::make_shared<SoftwareKeyboard>(system, mode, *frontend.software_keyboard); 220 return std::make_shared<SoftwareKeyboard>(system, applet, mode,
221 *frontend.software_keyboard);
309 case AppletId::MiiEdit: 222 case AppletId::MiiEdit:
310 return std::make_shared<MiiEdit>(system, mode, *frontend.mii_edit); 223 return std::make_shared<MiiEdit>(system, applet, mode, *frontend.mii_edit);
311 case AppletId::Web: 224 case AppletId::Web:
312 case AppletId::Shop: 225 case AppletId::Shop:
313 case AppletId::OfflineWeb: 226 case AppletId::OfflineWeb:
314 case AppletId::LoginShare: 227 case AppletId::LoginShare:
315 case AppletId::WebAuth: 228 case AppletId::WebAuth:
316 return std::make_shared<WebBrowser>(system, mode, *frontend.web_browser); 229 return std::make_shared<WebBrowser>(system, applet, mode, *frontend.web_browser);
317 case AppletId::PhotoViewer: 230 case AppletId::PhotoViewer:
318 return std::make_shared<PhotoViewer>(system, mode, *frontend.photo_viewer); 231 return std::make_shared<PhotoViewer>(system, applet, mode, *frontend.photo_viewer);
319 default: 232 default:
320 UNIMPLEMENTED_MSG( 233 UNIMPLEMENTED_MSG(
321 "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.", 234 "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.",
322 static_cast<u8>(id)); 235 static_cast<u8>(id));
323 return std::make_shared<StubApplet>(system, id, mode); 236 return std::make_shared<StubApplet>(system, applet, id, mode);
324 } 237 }
325} 238}
326 239
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;
44 44
45namespace Frontend { 45namespace Frontend {
46 46
47class AppletDataBroker final {
48public:
49 explicit AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_);
50 ~AppletDataBroker();
51
52 struct RawChannelData {
53 std::vector<std::vector<u8>> normal;
54 std::vector<std::vector<u8>> interactive;
55 };
56
57 // Retrieves but does not pop the data sent to applet.
58 RawChannelData PeekDataToAppletForDebug() const;
59
60 std::shared_ptr<IStorage> PopNormalDataToGame();
61 std::shared_ptr<IStorage> PopNormalDataToApplet();
62
63 std::shared_ptr<IStorage> PopInteractiveDataToGame();
64 std::shared_ptr<IStorage> PopInteractiveDataToApplet();
65
66 void PushNormalDataFromGame(std::shared_ptr<IStorage>&& storage);
67 void PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage);
68
69 void PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage);
70 void PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage);
71
72 void SignalStateChanged();
73
74 Kernel::KReadableEvent& GetNormalDataEvent();
75 Kernel::KReadableEvent& GetInteractiveDataEvent();
76 Kernel::KReadableEvent& GetStateChangedEvent();
77
78private:
79 Core::System& system;
80 LibraryAppletMode applet_mode;
81
82 KernelHelpers::ServiceContext service_context;
83
84 // Queues are named from applet's perspective
85
86 // PopNormalDataToApplet and PushNormalDataFromGame
87 std::deque<std::shared_ptr<IStorage>> in_channel;
88
89 // PopNormalDataToGame and PushNormalDataFromApplet
90 std::deque<std::shared_ptr<IStorage>> out_channel;
91
92 // PopInteractiveDataToApplet and PushInteractiveDataFromGame
93 std::deque<std::shared_ptr<IStorage>> in_interactive_channel;
94
95 // PopInteractiveDataToGame and PushInteractiveDataFromApplet
96 std::deque<std::shared_ptr<IStorage>> out_interactive_channel;
97
98 Kernel::KEvent* state_changed_event;
99
100 // Signaled on PushNormalDataFromApplet
101 Kernel::KEvent* pop_out_data_event;
102
103 // Signaled on PushInteractiveDataFromApplet
104 Kernel::KEvent* pop_interactive_out_data_event;
105};
106
107class FrontendApplet { 47class FrontendApplet {
108public: 48public:
109 explicit FrontendApplet(Core::System& system_, LibraryAppletMode applet_mode_); 49 explicit FrontendApplet(Core::System& system_, std::shared_ptr<Applet> applet_,
50 LibraryAppletMode applet_mode_);
110 virtual ~FrontendApplet(); 51 virtual ~FrontendApplet();
111 52
112 virtual void Initialize(); 53 virtual void Initialize();
113 54
114 virtual bool TransactionComplete() const = 0;
115 virtual Result GetStatus() const = 0; 55 virtual Result GetStatus() const = 0;
116 virtual void ExecuteInteractive() = 0; 56 virtual void ExecuteInteractive() = 0;
117 virtual void Execute() = 0; 57 virtual void Execute() = 0;
118 virtual Result RequestExit() = 0; 58 virtual Result RequestExit() = 0;
119 59
120 AppletDataBroker& GetBroker() {
121 return broker;
122 }
123
124 const AppletDataBroker& GetBroker() const {
125 return broker;
126 }
127
128 LibraryAppletMode GetLibraryAppletMode() const { 60 LibraryAppletMode GetLibraryAppletMode() const {
129 return applet_mode; 61 return applet_mode;
130 } 62 }
@@ -134,10 +66,18 @@ public:
134 } 66 }
135 67
136protected: 68protected:
69 std::shared_ptr<IStorage> PopInData();
70 std::shared_ptr<IStorage> PopInteractiveInData();
71 void PushOutData(std::shared_ptr<IStorage> storage);
72 void PushInteractiveOutData(std::shared_ptr<IStorage> storage);
73 void Exit();
74
75protected:
76 Core::System& system;
137 CommonArguments common_args{}; 77 CommonArguments common_args{};
138 AppletDataBroker broker; 78 std::weak_ptr<Applet> applet{};
139 LibraryAppletMode applet_mode; 79 LibraryAppletMode applet_mode{};
140 bool initialized = false; 80 bool initialized{false};
141}; 81};
142 82
143struct FrontendAppletSet { 83struct FrontendAppletSet {
@@ -191,7 +131,8 @@ public:
191 void SetDefaultAppletsIfMissing(); 131 void SetDefaultAppletsIfMissing();
192 void ClearAll(); 132 void ClearAll();
193 133
194 std::shared_ptr<FrontendApplet> GetApplet(AppletId id, LibraryAppletMode mode) const; 134 std::shared_ptr<FrontendApplet> GetApplet(std::shared_ptr<Applet> applet, AppletId id,
135 LibraryAppletMode mode) const;
195 136
196private: 137private:
197 AppletId current_applet_id{}; 138 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 @@
3 3
4#include "common/scope_exit.h" 4#include "common/scope_exit.h"
5#include "core/hle/service/am/am_results.h" 5#include "core/hle/service/am/am_results.h"
6#include "core/hle/service/am/applet_data_broker.h"
6#include "core/hle/service/am/frontend/applets.h" 7#include "core/hle/service/am/frontend/applets.h"
7#include "core/hle/service/am/library_applet_accessor.h" 8#include "core/hle/service/am/library_applet_accessor.h"
8#include "core/hle/service/am/storage.h" 9#include "core/hle/service/am/storage.h"
@@ -11,9 +12,9 @@
11namespace Service::AM { 12namespace Service::AM {
12 13
13ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_, 14ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_,
14 std::shared_ptr<AppletStorageHolder> storage_, 15 std::shared_ptr<AppletDataBroker> broker_,
15 std::shared_ptr<Applet> applet_) 16 std::shared_ptr<Applet> applet_)
16 : ServiceFramework{system_, "ILibraryAppletAccessor"}, storage{std::move(storage_)}, 17 : ServiceFramework{system_, "ILibraryAppletAccessor"}, broker{std::move(broker_)},
17 applet{std::move(applet_)} { 18 applet{std::move(applet_)} {
18 // clang-format off 19 // clang-format off
19 static const FunctionInfo functions[] = { 20 static const FunctionInfo functions[] = {
@@ -49,7 +50,7 @@ void ILibraryAppletAccessor::GetAppletStateChangedEvent(HLERequestContext& ctx)
49 50
50 IPC::ResponseBuilder rb{ctx, 2, 1}; 51 IPC::ResponseBuilder rb{ctx, 2, 1};
51 rb.Push(ResultSuccess); 52 rb.Push(ResultSuccess);
52 rb.PushCopyObjects(storage->state_changed_event.GetHandle()); 53 rb.PushCopyObjects(broker->GetStateChangedEvent().GetHandle());
53} 54}
54 55
55void ILibraryAppletAccessor::IsCompleted(HLERequestContext& ctx) { 56void ILibraryAppletAccessor::IsCompleted(HLERequestContext& ctx) {
@@ -59,7 +60,7 @@ void ILibraryAppletAccessor::IsCompleted(HLERequestContext& ctx) {
59 60
60 IPC::ResponseBuilder rb{ctx, 3}; 61 IPC::ResponseBuilder rb{ctx, 3};
61 rb.Push(ResultSuccess); 62 rb.Push(ResultSuccess);
62 rb.Push<u32>(applet->is_completed); 63 rb.Push<u32>(broker->IsCompleted());
63} 64}
64 65
65void ILibraryAppletAccessor::GetResult(HLERequestContext& ctx) { 66void ILibraryAppletAccessor::GetResult(HLERequestContext& ctx) {
@@ -80,6 +81,7 @@ void ILibraryAppletAccessor::Start(HLERequestContext& ctx) {
80 LOG_DEBUG(Service_AM, "called"); 81 LOG_DEBUG(Service_AM, "called");
81 82
82 applet->process->Run(); 83 applet->process->Run();
84 FrontendExecute();
83 85
84 IPC::ResponseBuilder rb{ctx, 2}; 86 IPC::ResponseBuilder rb{ctx, 2};
85 rb.Push(ResultSuccess); 87 rb.Push(ResultSuccess);
@@ -90,6 +92,7 @@ void ILibraryAppletAccessor::RequestExit(HLERequestContext& ctx) {
90 92
91 ASSERT(applet != nullptr); 93 ASSERT(applet != nullptr);
92 applet->message_queue.RequestExit(); 94 applet->message_queue.RequestExit();
95 FrontendRequestExit();
93 96
94 IPC::ResponseBuilder rb{ctx, 2}; 97 IPC::ResponseBuilder rb{ctx, 2};
95 rb.Push(ResultSuccess); 98 rb.Push(ResultSuccess);
@@ -99,7 +102,7 @@ void ILibraryAppletAccessor::PushInData(HLERequestContext& ctx) {
99 LOG_DEBUG(Service_AM, "called"); 102 LOG_DEBUG(Service_AM, "called");
100 103
101 IPC::RequestParser rp{ctx}; 104 IPC::RequestParser rp{ctx};
102 storage->in_data.PushData(rp.PopIpcInterface<IStorage>().lock()); 105 broker->GetInData().Push(rp.PopIpcInterface<IStorage>().lock());
103 106
104 IPC::ResponseBuilder rb{ctx, 2}; 107 IPC::ResponseBuilder rb{ctx, 2};
105 rb.Push(ResultSuccess); 108 rb.Push(ResultSuccess);
@@ -109,7 +112,7 @@ void ILibraryAppletAccessor::PopOutData(HLERequestContext& ctx) {
109 LOG_DEBUG(Service_AM, "called"); 112 LOG_DEBUG(Service_AM, "called");
110 113
111 std::shared_ptr<IStorage> data; 114 std::shared_ptr<IStorage> data;
112 const auto res = storage->out_data.PopData(&data); 115 const auto res = broker->GetOutData().Pop(&data);
113 116
114 if (res.IsSuccess()) { 117 if (res.IsSuccess()) {
115 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 118 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -125,7 +128,8 @@ void ILibraryAppletAccessor::PushInteractiveInData(HLERequestContext& ctx) {
125 LOG_DEBUG(Service_AM, "called"); 128 LOG_DEBUG(Service_AM, "called");
126 129
127 IPC::RequestParser rp{ctx}; 130 IPC::RequestParser rp{ctx};
128 storage->interactive_in_data.PushData(rp.PopIpcInterface<IStorage>().lock()); 131 broker->GetInteractiveInData().Push(rp.PopIpcInterface<IStorage>().lock());
132 FrontendExecuteInteractive();
129 133
130 IPC::ResponseBuilder rb{ctx, 2}; 134 IPC::ResponseBuilder rb{ctx, 2};
131 rb.Push(ResultSuccess); 135 rb.Push(ResultSuccess);
@@ -135,7 +139,7 @@ void ILibraryAppletAccessor::PopInteractiveOutData(HLERequestContext& ctx) {
135 LOG_DEBUG(Service_AM, "called"); 139 LOG_DEBUG(Service_AM, "called");
136 140
137 std::shared_ptr<IStorage> data; 141 std::shared_ptr<IStorage> data;
138 const auto res = storage->interactive_out_data.PopData(&data); 142 const auto res = broker->GetInteractiveOutData().Pop(&data);
139 143
140 if (res.IsSuccess()) { 144 if (res.IsSuccess()) {
141 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 145 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -152,7 +156,7 @@ void ILibraryAppletAccessor::GetPopOutDataEvent(HLERequestContext& ctx) {
152 156
153 IPC::ResponseBuilder rb{ctx, 2, 1}; 157 IPC::ResponseBuilder rb{ctx, 2, 1};
154 rb.Push(ResultSuccess); 158 rb.Push(ResultSuccess);
155 rb.PushCopyObjects(storage->out_data.GetEvent()); 159 rb.PushCopyObjects(broker->GetOutData().GetEvent());
156} 160}
157 161
158void ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(HLERequestContext& ctx) { 162void ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(HLERequestContext& ctx) {
@@ -160,7 +164,7 @@ void ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(HLERequestContext& ct
160 164
161 IPC::ResponseBuilder rb{ctx, 2, 1}; 165 IPC::ResponseBuilder rb{ctx, 2, 1};
162 rb.Push(ResultSuccess); 166 rb.Push(ResultSuccess);
163 rb.PushCopyObjects(storage->interactive_out_data.GetEvent()); 167 rb.PushCopyObjects(broker->GetInteractiveOutData().GetEvent());
164} 168}
165 169
166void ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(HLERequestContext& ctx) { 170void ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(HLERequestContext& ctx) {
@@ -175,4 +179,24 @@ void ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(HLERequestContext& c
175 rb.Push(handle); 179 rb.Push(handle);
176} 180}
177 181
182void ILibraryAppletAccessor::FrontendExecute() {
183 if (applet->frontend) {
184 applet->frontend->Initialize();
185 applet->frontend->Execute();
186 }
187}
188
189void ILibraryAppletAccessor::FrontendExecuteInteractive() {
190 if (applet->frontend) {
191 applet->frontend->ExecuteInteractive();
192 applet->frontend->Execute();
193 }
194}
195
196void ILibraryAppletAccessor::FrontendRequestExit() {
197 if (applet->frontend) {
198 applet->frontend->RequestExit();
199 }
200}
201
178} // namespace Service::AM 202} // 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 @@
7 7
8namespace Service::AM { 8namespace Service::AM {
9 9
10struct AppletStorageHolder; 10class AppletDataBroker;
11struct Applet; 11struct Applet;
12 12
13class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { 13class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> {
14public: 14public:
15 explicit ILibraryAppletAccessor(Core::System& system_, 15 explicit ILibraryAppletAccessor(Core::System& system_,
16 std::shared_ptr<AppletStorageHolder> storage_, 16 std::shared_ptr<AppletDataBroker> broker_,
17 std::shared_ptr<Applet> applet_); 17 std::shared_ptr<Applet> applet_);
18 ~ILibraryAppletAccessor(); 18 ~ILibraryAppletAccessor();
19 19
@@ -32,7 +32,11 @@ protected:
32 void GetPopInteractiveOutDataEvent(HLERequestContext& ctx); 32 void GetPopInteractiveOutDataEvent(HLERequestContext& ctx);
33 void GetIndirectLayerConsumerHandle(HLERequestContext& ctx); 33 void GetIndirectLayerConsumerHandle(HLERequestContext& ctx);
34 34
35 const std::shared_ptr<AppletStorageHolder> storage; 35 void FrontendExecute();
36 void FrontendExecuteInteractive();
37 void FrontendRequestExit();
38
39 const std::shared_ptr<AppletDataBroker> broker;
36 const std::shared_ptr<Applet> applet; 40 const std::shared_ptr<Applet> applet;
37}; 41};
38 42
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 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/kernel/k_transfer_memory.h" 4#include "core/hle/kernel/k_transfer_memory.h"
5#include "core/hle/service/am/applet_data_broker.h"
5#include "core/hle/service/am/applet_manager.h" 6#include "core/hle/service/am/applet_manager.h"
6#include "core/hle/service/am/frontend/applets.h" 7#include "core/hle/service/am/frontend/applets.h"
7#include "core/hle/service/am/library_applet_accessor.h" 8#include "core/hle/service/am/library_applet_accessor.h"
@@ -62,10 +63,9 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) {
62 } 63 }
63} 64}
64 65
65std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system, 66[[maybe_unused]] std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(
66 std::shared_ptr<Applet> caller_applet, 67 Core::System& system, std::shared_ptr<Applet> caller_applet, AppletId applet_id,
67 AppletId applet_id, 68 LibraryAppletMode mode) {
68 LibraryAppletMode mode) {
69 const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id)); 69 const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id));
70 if (program_id == 0) { 70 if (program_id == 0) {
71 // Unknown applet 71 // Unknown applet
@@ -89,20 +89,33 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
89 applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); 89 applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
90 applet->focus_state = FocusState::InFocus; 90 applet->focus_state = FocusState::InFocus;
91 91
92 auto storage = std::make_shared<AppletStorageHolder>(system); 92 auto broker = std::make_shared<AppletDataBroker>(system);
93 applet->caller_applet = caller_applet; 93 applet->caller_applet = caller_applet;
94 applet->caller_applet_storage = storage; 94 applet->caller_applet_broker = broker;
95 95
96 system.GetAppletManager().InsertApplet(applet); 96 system.GetAppletManager().InsertApplet(applet);
97 97
98 return std::make_shared<ILibraryAppletAccessor>(system, storage, applet); 98 return std::make_shared<ILibraryAppletAccessor>(system, broker, applet);
99} 99}
100 100
101std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system, 101[[maybe_unused]] std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(
102 AppletId applet_id, 102 Core::System& system, std::shared_ptr<Applet> caller_applet, AppletId applet_id,
103 LibraryAppletMode mode) { 103 LibraryAppletMode mode) {
104 UNREACHABLE(); 104 const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id));
105 return {}; 105
106 auto process = std::make_unique<Process>(system);
107 auto applet = std::make_shared<Applet>(system, std::move(process));
108 applet->program_id = program_id;
109 applet->applet_id = applet_id;
110 applet->type = AppletType::LibraryApplet;
111 applet->library_applet_mode = mode;
112
113 auto storage = std::make_shared<AppletDataBroker>(system);
114 applet->caller_applet = caller_applet;
115 applet->caller_applet_broker = storage;
116 applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode);
117
118 return std::make_shared<ILibraryAppletAccessor>(system, storage, applet);
106} 119}
107 120
108} // namespace 121} // namespace
@@ -131,10 +144,7 @@ void ILibraryAppletCreator::CreateLibraryApplet(HLERequestContext& ctx) {
131 LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id, 144 LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id,
132 applet_mode); 145 applet_mode);
133 146
134 auto library_applet = CreateGuestApplet(system, applet, applet_id, applet_mode); 147 auto library_applet = CreateFrontendApplet(system, applet, applet_id, applet_mode);
135 if (!library_applet) {
136 library_applet = CreateFrontendApplet(system, applet_id, applet_mode);
137 }
138 if (!library_applet) { 148 if (!library_applet) {
139 LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); 149 LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
140 150
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 @@
5#include "core/core_timing.h" 5#include "core/core_timing.h"
6#include "core/hle/service/acc/profile_manager.h" 6#include "core/hle/service/acc/profile_manager.h"
7#include "core/hle/service/am/am_results.h" 7#include "core/hle/service/am/am_results.h"
8#include "core/hle/service/am/applet_data_broker.h"
8#include "core/hle/service/am/applet_manager.h" 9#include "core/hle/service/am/applet_manager.h"
9#include "core/hle/service/am/frontend/applet_cabinet.h" 10#include "core/hle/service/am/frontend/applet_cabinet.h"
10#include "core/hle/service/am/frontend/applet_controller.h" 11#include "core/hle/service/am/frontend/applet_controller.h"
@@ -47,7 +48,7 @@ AppletIdentityInfo GetCallerIdentity(std::shared_ptr<Applet> applet) {
47ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_, 48ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
48 std::shared_ptr<Applet> applet_) 49 std::shared_ptr<Applet> applet_)
49 : ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, applet{std::move(applet_)}, 50 : ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, applet{std::move(applet_)},
50 storage{applet->caller_applet_storage} { 51 broker{applet->caller_applet_broker} {
51 // clang-format off 52 // clang-format off
52 static const FunctionInfo functions[] = { 53 static const FunctionInfo functions[] = {
53 {0, &ILibraryAppletSelfAccessor::PopInData, "PopInData"}, 54 {0, &ILibraryAppletSelfAccessor::PopInData, "PopInData"},
@@ -96,7 +97,7 @@ void ILibraryAppletSelfAccessor::PopInData(HLERequestContext& ctx) {
96 LOG_INFO(Service_AM, "called"); 97 LOG_INFO(Service_AM, "called");
97 98
98 std::shared_ptr<IStorage> data; 99 std::shared_ptr<IStorage> data;
99 const auto res = storage->in_data.PopData(&data); 100 const auto res = broker->GetInData().Pop(&data);
100 101
101 if (res.IsSuccess()) { 102 if (res.IsSuccess()) {
102 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 103 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -112,7 +113,7 @@ void ILibraryAppletSelfAccessor::PushOutData(HLERequestContext& ctx) {
112 LOG_INFO(Service_AM, "called"); 113 LOG_INFO(Service_AM, "called");
113 114
114 IPC::RequestParser rp{ctx}; 115 IPC::RequestParser rp{ctx};
115 storage->out_data.PushData(rp.PopIpcInterface<IStorage>().lock()); 116 broker->GetOutData().Push(rp.PopIpcInterface<IStorage>().lock());
116 117
117 IPC::ResponseBuilder rb{ctx, 2}; 118 IPC::ResponseBuilder rb{ctx, 2};
118 rb.Push(ResultSuccess); 119 rb.Push(ResultSuccess);
@@ -122,7 +123,7 @@ void ILibraryAppletSelfAccessor::PopInteractiveInData(HLERequestContext& ctx) {
122 LOG_INFO(Service_AM, "called"); 123 LOG_INFO(Service_AM, "called");
123 124
124 std::shared_ptr<IStorage> data; 125 std::shared_ptr<IStorage> data;
125 const auto res = storage->interactive_in_data.PopData(&data); 126 const auto res = broker->GetInteractiveInData().Pop(&data);
126 127
127 if (res.IsSuccess()) { 128 if (res.IsSuccess()) {
128 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 129 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -138,7 +139,7 @@ void ILibraryAppletSelfAccessor::PushInteractiveOutData(HLERequestContext& ctx)
138 LOG_INFO(Service_AM, "called"); 139 LOG_INFO(Service_AM, "called");
139 140
140 IPC::RequestParser rp{ctx}; 141 IPC::RequestParser rp{ctx};
141 storage->interactive_out_data.PushData(rp.PopIpcInterface<IStorage>().lock()); 142 broker->GetInteractiveOutData().Push(rp.PopIpcInterface<IStorage>().lock());
142 143
143 IPC::ResponseBuilder rb{ctx, 2}; 144 IPC::ResponseBuilder rb{ctx, 2};
144 rb.Push(ResultSuccess); 145 rb.Push(ResultSuccess);
@@ -149,7 +150,7 @@ void ILibraryAppletSelfAccessor::GetPopInDataEvent(HLERequestContext& ctx) {
149 150
150 IPC::ResponseBuilder rb{ctx, 2, 1}; 151 IPC::ResponseBuilder rb{ctx, 2, 1};
151 rb.Push(ResultSuccess); 152 rb.Push(ResultSuccess);
152 rb.PushCopyObjects(storage->in_data.GetEvent()); 153 rb.PushCopyObjects(broker->GetInData().GetEvent());
153} 154}
154 155
155void ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent(HLERequestContext& ctx) { 156void ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent(HLERequestContext& ctx) {
@@ -157,19 +158,14 @@ void ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent(HLERequestContext&
157 158
158 IPC::ResponseBuilder rb{ctx, 2, 1}; 159 IPC::ResponseBuilder rb{ctx, 2, 1};
159 rb.Push(ResultSuccess); 160 rb.Push(ResultSuccess);
160 rb.PushCopyObjects(storage->interactive_in_data.GetEvent()); 161 rb.PushCopyObjects(broker->GetInteractiveInData().GetEvent());
161} 162}
162 163
163void ILibraryAppletSelfAccessor::ExitProcessAndReturn(HLERequestContext& ctx) { 164void ILibraryAppletSelfAccessor::ExitProcessAndReturn(HLERequestContext& ctx) {
164 LOG_INFO(Service_AM, "called"); 165 LOG_INFO(Service_AM, "called");
165 166
166 system.GetAppletManager().TerminateAndRemoveApplet(applet->aruid); 167 system.GetAppletManager().TerminateAndRemoveApplet(applet->aruid);
167 168 broker->SignalCompletion();
168 {
169 std::scoped_lock lk{applet->lock};
170 applet->is_completed = true;
171 storage->state_changed_event.Signal();
172 }
173 169
174 IPC::ResponseBuilder rb{ctx, 2}; 170 IPC::ResponseBuilder rb{ctx, 2};
175 rb.Push(ResultSuccess); 171 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 @@
10 10
11namespace Service::AM { 11namespace Service::AM {
12 12
13struct AppletStorageHolder; 13class AppletDataBroker;
14struct Applet; 14struct Applet;
15 15
16class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> { 16class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> {
@@ -34,7 +34,7 @@ private:
34 void ShouldSetGpuTimeSliceManually(HLERequestContext& ctx); 34 void ShouldSetGpuTimeSliceManually(HLERequestContext& ctx);
35 35
36 const std::shared_ptr<Applet> applet; 36 const std::shared_ptr<Applet> applet;
37 const std::shared_ptr<AppletStorageHolder> storage; 37 const std::shared_ptr<AppletDataBroker> broker;
38}; 38};
39 39
40} // namespace Service::AM 40} // 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)
49 49
50 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 50 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
51 rb.Push(ResultSuccess); 51 rb.Push(ResultSuccess);
52 rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet->caller_applet_storage, 52 rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet->caller_applet_broker,
53 caller_applet); 53 caller_applet);
54} 54}
55 55