Răsfoiți Sursa

am: return AppletDataBroker and use for frontend applets

Liam 2 ani în urmă
părinte
comite
8a146469c0
31 a modificat fișierele cu 424 adăugiri și 508 ștergeri
  1. 2 0
      src/core/CMakeLists.txt
  2. 1 1
      src/core/hle/service/am/am_types.h
  3. 2 38
      src/core/hle/service/am/applet.cpp
  4. 1 35
      src/core/hle/service/am/applet.h
  5. 67 0
      src/core/hle/service/am/applet_data_broker.cpp
  6. 80 0
      src/core/hle/service/am/applet_data_broker.h
  7. 14 13
      src/core/hle/service/am/applet_manager.cpp
  8. 10 13
      src/core/hle/service/am/frontend/applet_cabinet.cpp
  9. 2 3
      src/core/hle/service/am/frontend/applet_cabinet.h
  10. 10 12
      src/core/hle/service/am/frontend/applet_controller.cpp
  11. 2 3
      src/core/hle/service/am/frontend/applet_controller.h
  12. 5 9
      src/core/hle/service/am/frontend/applet_error.cpp
  13. 2 4
      src/core/hle/service/am/frontend/applet_error.h
  14. 28 47
      src/core/hle/service/am/frontend/applet_general.cpp
  15. 6 9
      src/core/hle/service/am/frontend/applet_general.h
  16. 8 12
      src/core/hle/service/am/frontend/applet_mii_edit.cpp
  17. 2 3
      src/core/hle/service/am/frontend/applet_mii_edit.h
  18. 9 10
      src/core/hle/service/am/frontend/applet_profile_select.cpp
  19. 2 3
      src/core/hle/service/am/frontend/applet_profile_select.h
  20. 28 31
      src/core/hle/service/am/frontend/applet_software_keyboard.cpp
  21. 2 3
      src/core/hle/service/am/frontend/applet_software_keyboard.h
  22. 6 9
      src/core/hle/service/am/frontend/applet_web_browser.cpp
  23. 2 5
      src/core/hle/service/am/frontend/applet_web_browser.h
  24. 39 126
      src/core/hle/service/am/frontend/applets.cpp
  25. 15 74
      src/core/hle/service/am/frontend/applets.h
  26. 34 10
      src/core/hle/service/am/library_applet_accessor.cpp
  27. 7 3
      src/core/hle/service/am/library_applet_accessor.h
  28. 26 16
      src/core/hle/service/am/library_applet_creator.cpp
  29. 9 13
      src/core/hle/service/am/library_applet_self_accessor.cpp
  30. 2 2
      src/core/hle/service/am/library_applet_self_accessor.h
  31. 1 1
      src/core/hle/service/am/process_winding_controller.cpp

+ 2 - 0
src/core/CMakeLists.txt

@@ -420,6 +420,8 @@ add_library(core STATIC
     hle/service/am/applet_ae.cpp
     hle/service/am/applet_ae.cpp
     hle/service/am/applet_ae.h
     hle/service/am/applet_ae.h
     hle/service/am/applet_manager.cpp
     hle/service/am/applet_manager.cpp
+    hle/service/am/applet_data_broker.cpp
+    hle/service/am/applet_data_broker.h
     hle/service/am/applet_manager.h
     hle/service/am/applet_manager.h
     hle/service/am/applet_oe.cpp
     hle/service/am/applet_oe.cpp
     hle/service/am/applet_oe.h
     hle/service/am/applet_oe.h

+ 1 - 1
src/core/hle/service/am/am_types.h

@@ -166,6 +166,6 @@ using AppletResourceUserId = u64;
 using ProgramId = u64;
 using ProgramId = u64;
 
 
 struct Applet;
 struct Applet;
-struct AppletStorageHolder;
+class AppletDataBroker;
 
 
 } // namespace Service::AM
 } // namespace Service::AM

+ 2 - 38
src/core/hle/service/am/applet.cpp

@@ -3,49 +3,13 @@
 
 
 #include "common/scope_exit.h"
 #include "common/scope_exit.h"
 
 
+#include "core/core.h"
 #include "core/hle/service/am/am_results.h"
 #include "core/hle/service/am/am_results.h"
 #include "core/hle/service/am/applet.h"
 #include "core/hle/service/am/applet.h"
+#include "core/hle/service/am/applet_manager.h"
 
 
 namespace Service::AM {
 namespace Service::AM {
 
 
-AppletStorageChannel::AppletStorageChannel(KernelHelpers::ServiceContext& context)
-    : m_event(context) {}
-AppletStorageChannel::~AppletStorageChannel() = default;
-
-void AppletStorageChannel::PushData(std::shared_ptr<IStorage> storage) {
-    std::scoped_lock lk{m_lock};
-
-    m_data.emplace_back(std::move(storage));
-    m_event.Signal();
-}
-
-Result AppletStorageChannel::PopData(std::shared_ptr<IStorage>* out_storage) {
-    std::scoped_lock lk{m_lock};
-
-    SCOPE_EXIT({
-        if (m_data.empty()) {
-            m_event.Clear();
-        }
-    });
-
-    R_UNLESS(!m_data.empty(), AM::ResultNoDataInChannel);
-
-    *out_storage = std::move(m_data.front());
-    m_data.pop_front();
-
-    R_SUCCEED();
-}
-
-Kernel::KReadableEvent* AppletStorageChannel::GetEvent() {
-    return m_event.GetHandle();
-}
-
-AppletStorageHolder::AppletStorageHolder(Core::System& system)
-    : context(system, "AppletStorageHolder"), in_data(context), interactive_in_data(context),
-      out_data(context), interactive_out_data(context), state_changed_event(context) {}
-
-AppletStorageHolder::~AppletStorageHolder() = default;
-
 Applet::Applet(Core::System& system, std::unique_ptr<Process> process_)
 Applet::Applet(Core::System& system, std::unique_ptr<Process> process_)
     : context(system, "Applet"), message_queue(system), process(std::move(process_)),
     : context(system, "Applet"), message_queue(system), process(std::move(process_)),
       hid_registration(system, *process), gpu_error_detected_event(context),
       hid_registration(system, *process), gpu_error_detected_event(context),

+ 1 - 35
src/core/hle/service/am/applet.h

@@ -21,41 +21,8 @@
 #include "core/hle/service/am/storage.h"
 #include "core/hle/service/am/storage.h"
 #include "core/hle/service/am/system_buffer_manager.h"
 #include "core/hle/service/am/system_buffer_manager.h"
 
 
-namespace Service::Nvnflinger {
-class FbShareBufferManager;
-class Nvnflinger;
-} // namespace Service::Nvnflinger
-
 namespace Service::AM {
 namespace Service::AM {
 
 
-class AppletStorageChannel {
-public:
-    explicit AppletStorageChannel(KernelHelpers::ServiceContext& ctx);
-    ~AppletStorageChannel();
-
-    void PushData(std::shared_ptr<IStorage> storage);
-    Result PopData(std::shared_ptr<IStorage>* out_storage);
-    Kernel::KReadableEvent* GetEvent();
-
-private:
-    std::mutex m_lock{};
-    std::deque<std::shared_ptr<IStorage>> m_data{};
-    Event m_event;
-};
-
-struct AppletStorageHolder {
-    explicit AppletStorageHolder(Core::System& system);
-    ~AppletStorageHolder();
-
-    KernelHelpers::ServiceContext context;
-
-    AppletStorageChannel in_data;
-    AppletStorageChannel interactive_in_data;
-    AppletStorageChannel out_data;
-    AppletStorageChannel interactive_out_data;
-    Event state_changed_event;
-};
-
 struct Applet {
 struct Applet {
     explicit Applet(Core::System& system, std::unique_ptr<Process> process_);
     explicit Applet(Core::System& system, std::unique_ptr<Process> process_);
     ~Applet();
     ~Applet();
@@ -126,8 +93,7 @@ struct Applet {
 
 
     // Caller applet
     // Caller applet
     std::weak_ptr<Applet> caller_applet{};
     std::weak_ptr<Applet> caller_applet{};
-    std::shared_ptr<AppletStorageHolder> caller_applet_storage{};
-    bool is_completed{};
+    std::shared_ptr<AppletDataBroker> caller_applet_broker{};
 
 
     // Self state
     // Self state
     bool exit_locked{};
     bool exit_locked{};

+ 67 - 0
src/core/hle/service/am/applet_data_broker.cpp

@@ -0,0 +1,67 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/scope_exit.h"
+
+#include "core/core.h"
+#include "core/hle/service/am/am_results.h"
+#include "core/hle/service/am/applet_data_broker.h"
+#include "core/hle/service/am/applet_manager.h"
+
+namespace Service::AM {
+
+AppletStorageChannel::AppletStorageChannel(KernelHelpers::ServiceContext& context)
+    : m_event(context) {}
+AppletStorageChannel::~AppletStorageChannel() = default;
+
+void AppletStorageChannel::Push(std::shared_ptr<IStorage> storage) {
+    std::scoped_lock lk{m_lock};
+
+    m_data.emplace_back(std::move(storage));
+    m_event.Signal();
+}
+
+Result AppletStorageChannel::Pop(std::shared_ptr<IStorage>* out_storage) {
+    std::scoped_lock lk{m_lock};
+
+    SCOPE_EXIT({
+        if (m_data.empty()) {
+            m_event.Clear();
+        }
+    });
+
+    R_UNLESS(!m_data.empty(), AM::ResultNoDataInChannel);
+
+    *out_storage = std::move(m_data.front());
+    m_data.pop_front();
+
+    R_SUCCEED();
+}
+
+Kernel::KReadableEvent* AppletStorageChannel::GetEvent() {
+    return m_event.GetHandle();
+}
+
+AppletDataBroker::AppletDataBroker(Core::System& system_)
+    : system(system_), context(system_, "AppletDataBroker"), in_data(context),
+      interactive_in_data(context), out_data(context), interactive_out_data(context),
+      state_changed_event(context), is_completed(false) {}
+
+AppletDataBroker::~AppletDataBroker() = default;
+
+void AppletDataBroker::SignalCompletion() {
+    {
+        std::scoped_lock lk{lock};
+
+        if (is_completed) {
+            return;
+        }
+
+        is_completed = true;
+        state_changed_event.Signal();
+    }
+
+    system.GetAppletManager().FocusStateChanged();
+}
+
+} // namespace Service::AM

+ 80 - 0
src/core/hle/service/am/applet_data_broker.h

@@ -0,0 +1,80 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <deque>
+#include <memory>
+#include <mutex>
+
+#include "core/hle/service/event.h"
+#include "core/hle/service/kernel_helpers.h"
+
+union Result;
+
+namespace Service::AM {
+
+struct Applet;
+class IStorage;
+
+class AppletStorageChannel {
+public:
+    explicit AppletStorageChannel(KernelHelpers::ServiceContext& ctx);
+    ~AppletStorageChannel();
+
+    void Push(std::shared_ptr<IStorage> storage);
+    Result Pop(std::shared_ptr<IStorage>* out_storage);
+    Kernel::KReadableEvent* GetEvent();
+
+private:
+    std::mutex m_lock{};
+    std::deque<std::shared_ptr<IStorage>> m_data{};
+    Event m_event;
+};
+
+class AppletDataBroker {
+public:
+    explicit AppletDataBroker(Core::System& system_);
+    ~AppletDataBroker();
+
+    AppletStorageChannel& GetInData() {
+        return in_data;
+    }
+
+    AppletStorageChannel& GetInteractiveInData() {
+        return interactive_in_data;
+    }
+
+    AppletStorageChannel& GetOutData() {
+        return out_data;
+    }
+
+    AppletStorageChannel& GetInteractiveOutData() {
+        return interactive_out_data;
+    }
+
+    Event& GetStateChangedEvent() {
+        return state_changed_event;
+    }
+
+    bool IsCompleted() const {
+        return is_completed;
+    }
+
+    void SignalCompletion();
+
+private:
+    Core::System& system;
+    KernelHelpers::ServiceContext context;
+
+    AppletStorageChannel in_data;
+    AppletStorageChannel interactive_in_data;
+    AppletStorageChannel out_data;
+    AppletStorageChannel interactive_out_data;
+    Event state_changed_event;
+
+    std::mutex lock;
+    bool is_completed;
+};
+
+} // namespace Service::AM

+ 14 - 13
src/core/hle/service/am/applet_manager.cpp

@@ -6,6 +6,7 @@
 #include "core/core.h"
 #include "core/core.h"
 #include "core/core_timing.h"
 #include "core/core_timing.h"
 #include "core/hle/service/acc/profile_manager.h"
 #include "core/hle/service/acc/profile_manager.h"
+#include "core/hle/service/am/applet_data_broker.h"
 #include "core/hle/service/am/applet_manager.h"
 #include "core/hle/service/am/applet_manager.h"
 #include "core/hle/service/am/frontend/applet_cabinet.h"
 #include "core/hle/service/am/frontend/applet_cabinet.h"
 #include "core/hle/service/am/frontend/applet_controller.h"
 #include "core/hle/service/am/frontend/applet_controller.h"
@@ -29,8 +30,8 @@ static_assert(sizeof(LaunchParameterAccountPreselectedUser) == 0x88);
 
 
 AppletStorageChannel& InitializeFakeCallerApplet(Core::System& system,
 AppletStorageChannel& InitializeFakeCallerApplet(Core::System& system,
                                                  std::shared_ptr<Applet>& applet) {
                                                  std::shared_ptr<Applet>& applet) {
-    applet->caller_applet_storage = std::make_shared<AppletStorageHolder>(system);
-    return applet->caller_applet_storage->in_data;
+    applet->caller_applet_broker = std::make_shared<AppletDataBroker>(system);
+    return applet->caller_applet_broker->GetInData();
 }
 }
 
 
 void PushInShowAlbum(Core::System& system, AppletStorageChannel& channel) {
 void PushInShowAlbum(Core::System& system, AppletStorageChannel& channel) {
@@ -46,8 +47,8 @@ void PushInShowAlbum(Core::System& system, AppletStorageChannel& channel) {
     std::vector<u8> argument_data(sizeof(arguments));
     std::vector<u8> argument_data(sizeof(arguments));
     std::vector<u8> settings_data{2};
     std::vector<u8> settings_data{2};
     std::memcpy(argument_data.data(), &arguments, sizeof(arguments));
     std::memcpy(argument_data.data(), &arguments, sizeof(arguments));
-    channel.PushData(std::make_shared<IStorage>(system, std::move(argument_data)));
-    channel.PushData(std::make_shared<IStorage>(system, std::move(settings_data)));
+    channel.Push(std::make_shared<IStorage>(system, std::move(argument_data)));
+    channel.Push(std::make_shared<IStorage>(system, std::move(settings_data)));
 }
 }
 
 
 void PushInShowController(Core::System& system, AppletStorageChannel& channel) {
 void PushInShowController(Core::System& system, AppletStorageChannel& channel) {
@@ -94,9 +95,9 @@ void PushInShowController(Core::System& system, AppletStorageChannel& channel) {
     std::memcpy(private_args_data.data(), &private_args, sizeof(private_args));
     std::memcpy(private_args_data.data(), &private_args, sizeof(private_args));
     std::memcpy(user_args_data.data(), &user_args, sizeof(user_args));
     std::memcpy(user_args_data.data(), &user_args, sizeof(user_args));
 
 
-    channel.PushData(std::make_shared<IStorage>(system, std::move(common_args_data)));
-    channel.PushData(std::make_shared<IStorage>(system, std::move(private_args_data)));
-    channel.PushData(std::make_shared<IStorage>(system, std::move(user_args_data)));
+    channel.Push(std::make_shared<IStorage>(system, std::move(common_args_data)));
+    channel.Push(std::make_shared<IStorage>(system, std::move(private_args_data)));
+    channel.Push(std::make_shared<IStorage>(system, std::move(user_args_data)));
 }
 }
 
 
 void PushInShowCabinetData(Core::System& system, AppletStorageChannel& channel) {
 void PushInShowCabinetData(Core::System& system, AppletStorageChannel& channel) {
@@ -124,8 +125,8 @@ void PushInShowCabinetData(Core::System& system, AppletStorageChannel& channel)
     std::vector<u8> settings_data(sizeof(amiibo_settings));
     std::vector<u8> settings_data(sizeof(amiibo_settings));
     std::memcpy(argument_data.data(), &arguments, sizeof(arguments));
     std::memcpy(argument_data.data(), &arguments, sizeof(arguments));
     std::memcpy(settings_data.data(), &amiibo_settings, sizeof(amiibo_settings));
     std::memcpy(settings_data.data(), &amiibo_settings, sizeof(amiibo_settings));
-    channel.PushData(std::make_shared<IStorage>(system, std::move(argument_data)));
-    channel.PushData(std::make_shared<IStorage>(system, std::move(settings_data)));
+    channel.Push(std::make_shared<IStorage>(system, std::move(argument_data)));
+    channel.Push(std::make_shared<IStorage>(system, std::move(settings_data)));
 }
 }
 
 
 void PushInShowMiiEditData(Core::System& system, AppletStorageChannel& channel) {
 void PushInShowMiiEditData(Core::System& system, AppletStorageChannel& channel) {
@@ -147,7 +148,7 @@ void PushInShowMiiEditData(Core::System& system, AppletStorageChannel& channel)
     std::vector<u8> argument_data(sizeof(mii_arguments));
     std::vector<u8> argument_data(sizeof(mii_arguments));
     std::memcpy(argument_data.data(), &mii_arguments, sizeof(mii_arguments));
     std::memcpy(argument_data.data(), &mii_arguments, sizeof(mii_arguments));
 
 
-    channel.PushData(std::make_shared<IStorage>(system, std::move(argument_data)));
+    channel.Push(std::make_shared<IStorage>(system, std::move(argument_data)));
 }
 }
 
 
 void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& channel) {
 void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& channel) {
@@ -200,9 +201,9 @@ void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& chan
     std::memcpy(work_buffer.data(), initial_string.data(),
     std::memcpy(work_buffer.data(), initial_string.data(),
                 swkbd_config.initial_string_length * sizeof(char16_t));
                 swkbd_config.initial_string_length * sizeof(char16_t));
 
 
-    channel.PushData(std::make_shared<IStorage>(system, std::move(argument_data)));
-    channel.PushData(std::make_shared<IStorage>(system, std::move(swkbd_data)));
-    channel.PushData(std::make_shared<IStorage>(system, std::move(work_buffer)));
+    channel.Push(std::make_shared<IStorage>(system, std::move(argument_data)));
+    channel.Push(std::make_shared<IStorage>(system, std::move(swkbd_data)));
+    channel.Push(std::make_shared<IStorage>(system, std::move(work_buffer)));
 }
 }
 
 
 } // namespace
 } // namespace

+ 10 - 13
src/core/hle/service/am/frontend/applet_cabinet.cpp

@@ -16,10 +16,11 @@
 
 
 namespace Service::AM::Frontend {
 namespace Service::AM::Frontend {
 
 
-Cabinet::Cabinet(Core::System& system_, LibraryAppletMode applet_mode_,
-                 const Core::Frontend::CabinetApplet& frontend_)
-    : FrontendApplet{system_, applet_mode_}, frontend{frontend_},
-      system{system_}, service_context{system_, "CabinetApplet"} {
+Cabinet::Cabinet(Core::System& system_, std::shared_ptr<Applet> applet_,
+                 LibraryAppletMode applet_mode_, const Core::Frontend::CabinetApplet& frontend_)
+    : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_}, service_context{
+                                                                               system_,
+                                                                               "CabinetApplet"} {
 
 
     availability_change_event =
     availability_change_event =
         service_context.CreateEvent("CabinetApplet:AvailabilityChangeEvent");
         service_context.CreateEvent("CabinetApplet:AvailabilityChangeEvent");
@@ -41,7 +42,7 @@ void Cabinet::Initialize() {
               common_args.play_startup_sound, common_args.size, common_args.system_tick,
               common_args.play_startup_sound, common_args.size, common_args.system_tick,
               common_args.theme_color);
               common_args.theme_color);
 
 
-    const auto storage = broker.PopNormalDataToApplet();
+    std::shared_ptr<IStorage> storage = PopInData();
     ASSERT(storage != nullptr);
     ASSERT(storage != nullptr);
 
 
     const auto applet_input_data = storage->GetData();
     const auto applet_input_data = storage->GetData();
@@ -51,10 +52,6 @@ void Cabinet::Initialize() {
                 sizeof(StartParamForAmiiboSettings));
                 sizeof(StartParamForAmiiboSettings));
 }
 }
 
 
-bool Cabinet::TransactionComplete() const {
-    return is_complete;
-}
-
 Result Cabinet::GetStatus() const {
 Result Cabinet::GetStatus() const {
     return ResultSuccess;
     return ResultSuccess;
 }
 }
@@ -160,8 +157,8 @@ void Cabinet::DisplayCompleted(bool apply_changes, std::string_view amiibo_name)
 
 
     is_complete = true;
     is_complete = true;
 
 
-    broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
-    broker.SignalStateChanged();
+    PushOutData(std::make_shared<IStorage>(system, std::move(out_data)));
+    Exit();
 }
 }
 
 
 void Cabinet::Cancel() {
 void Cabinet::Cancel() {
@@ -175,8 +172,8 @@ void Cabinet::Cancel() {
 
 
     is_complete = true;
     is_complete = true;
 
 
-    broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
-    broker.SignalStateChanged();
+    PushOutData(std::make_shared<IStorage>(system, std::move(out_data)));
+    Exit();
 }
 }
 
 
 Result Cabinet::RequestExit() {
 Result Cabinet::RequestExit() {

+ 2 - 3
src/core/hle/service/am/frontend/applet_cabinet.h

@@ -86,13 +86,13 @@ static_assert(sizeof(ReturnValueForAmiiboSettings) == 0x188,
 
 
 class Cabinet final : public FrontendApplet {
 class Cabinet final : public FrontendApplet {
 public:
 public:
-    explicit Cabinet(Core::System& system_, LibraryAppletMode applet_mode_,
+    explicit Cabinet(Core::System& system_, std::shared_ptr<Applet> applet_,
+                     LibraryAppletMode applet_mode_,
                      const Core::Frontend::CabinetApplet& frontend_);
                      const Core::Frontend::CabinetApplet& frontend_);
     ~Cabinet() override;
     ~Cabinet() override;
 
 
     void Initialize() override;
     void Initialize() override;
 
 
-    bool TransactionComplete() const override;
     Result GetStatus() const override;
     Result GetStatus() const override;
     void ExecuteInteractive() override;
     void ExecuteInteractive() override;
     void Execute() override;
     void Execute() override;
@@ -102,7 +102,6 @@ public:
 
 
 private:
 private:
     const Core::Frontend::CabinetApplet& frontend;
     const Core::Frontend::CabinetApplet& frontend;
-    Core::System& system;
 
 
     bool is_complete{false};
     bool is_complete{false};
     std::shared_ptr<Service::NFC::NfcDevice> nfp_device;
     std::shared_ptr<Service::NFC::NfcDevice> nfp_device;

+ 10 - 12
src/core/hle/service/am/frontend/applet_controller.cpp

@@ -47,9 +47,10 @@ static Core::Frontend::ControllerParameters ConvertToFrontendParameters(
     };
     };
 }
 }
 
 
-Controller::Controller(Core::System& system_, LibraryAppletMode applet_mode_,
+Controller::Controller(Core::System& system_, std::shared_ptr<Applet> applet_,
+                       LibraryAppletMode applet_mode_,
                        const Core::Frontend::ControllerApplet& frontend_)
                        const Core::Frontend::ControllerApplet& frontend_)
-    : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
+    : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {}
 
 
 Controller::~Controller() = default;
 Controller::~Controller() = default;
 
 
@@ -67,7 +68,7 @@ void Controller::Initialize() {
 
 
     controller_applet_version = ControllerAppletVersion{common_args.library_version};
     controller_applet_version = ControllerAppletVersion{common_args.library_version};
 
 
-    const auto private_arg_storage = broker.PopNormalDataToApplet();
+    const std::shared_ptr<IStorage> private_arg_storage = PopInData();
     ASSERT(private_arg_storage != nullptr);
     ASSERT(private_arg_storage != nullptr);
 
 
     const auto& private_arg = private_arg_storage->GetData();
     const auto& private_arg = private_arg_storage->GetData();
@@ -117,7 +118,7 @@ void Controller::Initialize() {
     switch (controller_private_arg.mode) {
     switch (controller_private_arg.mode) {
     case ControllerSupportMode::ShowControllerSupport:
     case ControllerSupportMode::ShowControllerSupport:
     case ControllerSupportMode::ShowControllerStrapGuide: {
     case ControllerSupportMode::ShowControllerStrapGuide: {
-        const auto user_arg_storage = broker.PopNormalDataToApplet();
+        const std::shared_ptr<IStorage> user_arg_storage = PopInData();
         ASSERT(user_arg_storage != nullptr);
         ASSERT(user_arg_storage != nullptr);
 
 
         const auto& user_arg = user_arg_storage->GetData();
         const auto& user_arg = user_arg_storage->GetData();
@@ -143,7 +144,7 @@ void Controller::Initialize() {
         break;
         break;
     }
     }
     case ControllerSupportMode::ShowControllerFirmwareUpdate: {
     case ControllerSupportMode::ShowControllerFirmwareUpdate: {
-        const auto update_arg_storage = broker.PopNormalDataToApplet();
+        const std::shared_ptr<IStorage> update_arg_storage = PopInData();
         ASSERT(update_arg_storage != nullptr);
         ASSERT(update_arg_storage != nullptr);
 
 
         const auto& update_arg = update_arg_storage->GetData();
         const auto& update_arg = update_arg_storage->GetData();
@@ -153,7 +154,7 @@ void Controller::Initialize() {
         break;
         break;
     }
     }
     case ControllerSupportMode::ShowControllerKeyRemappingForSystem: {
     case ControllerSupportMode::ShowControllerKeyRemappingForSystem: {
-        const auto remapping_arg_storage = broker.PopNormalDataToApplet();
+        const std::shared_ptr<IStorage> remapping_arg_storage = PopInData();
         ASSERT(remapping_arg_storage != nullptr);
         ASSERT(remapping_arg_storage != nullptr);
 
 
         const auto& remapping_arg = remapping_arg_storage->GetData();
         const auto& remapping_arg = remapping_arg_storage->GetData();
@@ -169,10 +170,6 @@ void Controller::Initialize() {
     }
     }
 }
 }
 
 
-bool Controller::TransactionComplete() const {
-    return complete;
-}
-
 Result Controller::GetStatus() const {
 Result Controller::GetStatus() const {
     return status;
     return status;
 }
 }
@@ -261,8 +258,9 @@ void Controller::ConfigurationComplete(bool is_success) {
     complete = true;
     complete = true;
     out_data = std::vector<u8>(sizeof(ControllerSupportResultInfo));
     out_data = std::vector<u8>(sizeof(ControllerSupportResultInfo));
     std::memcpy(out_data.data(), &result_info, out_data.size());
     std::memcpy(out_data.data(), &result_info, out_data.size());
-    broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
-    broker.SignalStateChanged();
+
+    PushOutData(std::make_shared<IStorage>(system, std::move(out_data)));
+    Exit();
 }
 }
 
 
 Result Controller::RequestExit() {
 Result Controller::RequestExit() {

+ 2 - 3
src/core/hle/service/am/frontend/applet_controller.h

@@ -124,13 +124,13 @@ static_assert(sizeof(ControllerSupportResultInfo) == 0xC,
 
 
 class Controller final : public FrontendApplet {
 class Controller final : public FrontendApplet {
 public:
 public:
-    explicit Controller(Core::System& system_, LibraryAppletMode applet_mode_,
+    explicit Controller(Core::System& system_, std::shared_ptr<Applet> applet_,
+                        LibraryAppletMode applet_mode_,
                         const Core::Frontend::ControllerApplet& frontend_);
                         const Core::Frontend::ControllerApplet& frontend_);
     ~Controller() override;
     ~Controller() override;
 
 
     void Initialize() override;
     void Initialize() override;
 
 
-    bool TransactionComplete() const override;
     Result GetStatus() const override;
     Result GetStatus() const override;
     void ExecuteInteractive() override;
     void ExecuteInteractive() override;
     void Execute() override;
     void Execute() override;
@@ -140,7 +140,6 @@ public:
 
 
 private:
 private:
     const Core::Frontend::ControllerApplet& frontend;
     const Core::Frontend::ControllerApplet& frontend;
-    Core::System& system;
 
 
     ControllerAppletVersion controller_applet_version;
     ControllerAppletVersion controller_applet_version;
     ControllerSupportArgPrivate controller_private_arg;
     ControllerSupportArgPrivate controller_private_arg;

+ 5 - 9
src/core/hle/service/am/frontend/applet_error.cpp

@@ -104,9 +104,9 @@ Result Decode64BitError(u64 error) {
 
 
 } // Anonymous namespace
 } // Anonymous namespace
 
 
-Error::Error(Core::System& system_, LibraryAppletMode applet_mode_,
+Error::Error(Core::System& system_, std::shared_ptr<Applet> applet_, LibraryAppletMode applet_mode_,
              const Core::Frontend::ErrorApplet& frontend_)
              const Core::Frontend::ErrorApplet& frontend_)
-    : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
+    : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {}
 
 
 Error::~Error() = default;
 Error::~Error() = default;
 
 
@@ -115,7 +115,7 @@ void Error::Initialize() {
     args = std::make_unique<ErrorArguments>();
     args = std::make_unique<ErrorArguments>();
     complete = false;
     complete = false;
 
 
-    const auto storage = broker.PopNormalDataToApplet();
+    const std::shared_ptr<IStorage> storage = PopInData();
     ASSERT(storage != nullptr);
     ASSERT(storage != nullptr);
     const auto data = storage->GetData();
     const auto data = storage->GetData();
 
 
@@ -153,10 +153,6 @@ void Error::Initialize() {
     }
     }
 }
 }
 
 
-bool Error::TransactionComplete() const {
-    return complete;
-}
-
 Result Error::GetStatus() const {
 Result Error::GetStatus() const {
     return ResultSuccess;
     return ResultSuccess;
 }
 }
@@ -211,8 +207,8 @@ void Error::Execute() {
 
 
 void Error::DisplayCompleted() {
 void Error::DisplayCompleted() {
     complete = true;
     complete = true;
-    broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{}));
-    broker.SignalStateChanged();
+    PushOutData(std::make_shared<IStorage>(system, std::vector<u8>()));
+    Exit();
 }
 }
 
 
 Result Error::RequestExit() {
 Result Error::RequestExit() {

+ 2 - 4
src/core/hle/service/am/frontend/applet_error.h

@@ -24,13 +24,12 @@ enum class ErrorAppletMode : u8 {
 
 
 class Error final : public FrontendApplet {
 class Error final : public FrontendApplet {
 public:
 public:
-    explicit Error(Core::System& system_, LibraryAppletMode applet_mode_,
-                   const Core::Frontend::ErrorApplet& frontend_);
+    explicit Error(Core::System& system_, std::shared_ptr<Applet> applet_,
+                   LibraryAppletMode applet_mode_, const Core::Frontend::ErrorApplet& frontend_);
     ~Error() override;
     ~Error() override;
 
 
     void Initialize() override;
     void Initialize() override;
 
 
-    bool TransactionComplete() const override;
     Result GetStatus() const override;
     Result GetStatus() const override;
     void ExecuteInteractive() override;
     void ExecuteInteractive() override;
     void Execute() override;
     void Execute() override;
@@ -47,7 +46,6 @@ private:
     std::unique_ptr<ErrorArguments> args;
     std::unique_ptr<ErrorArguments> args;
 
 
     bool complete = false;
     bool complete = false;
-    Core::System& system;
 };
 };
 
 
 } // namespace Service::AM::Frontend
 } // namespace Service::AM::Frontend

+ 28 - 47
src/core/hle/service/am/frontend/applet_general.cpp

@@ -8,6 +8,7 @@
 #include "core/frontend/applets/general.h"
 #include "core/frontend/applets/general.h"
 #include "core/hle/result.h"
 #include "core/hle/result.h"
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/am.h"
+#include "core/hle/service/am/applet_data_broker.h"
 #include "core/hle/service/am/frontend/applet_general.h"
 #include "core/hle/service/am/frontend/applet_general.h"
 #include "core/hle/service/am/storage.h"
 #include "core/hle/service/am/storage.h"
 #include "core/reporter.h"
 #include "core/reporter.h"
@@ -16,17 +17,16 @@ namespace Service::AM::Frontend {
 
 
 constexpr Result ERROR_INVALID_PIN{ErrorModule::PCTL, 221};
 constexpr Result ERROR_INVALID_PIN{ErrorModule::PCTL, 221};
 
 
-static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) {
-    std::shared_ptr<IStorage> storage = broker.PopNormalDataToApplet();
-    for (; storage != nullptr; storage = broker.PopNormalDataToApplet()) {
+static void LogCurrentStorage(std::shared_ptr<Applet> applet, std::string_view prefix) {
+    std::shared_ptr<IStorage> storage;
+    while (R_SUCCEEDED(applet->caller_applet_broker->GetInData().Pop(&storage))) {
         const auto data = storage->GetData();
         const auto data = storage->GetData();
         LOG_INFO(Service_AM,
         LOG_INFO(Service_AM,
                  "called (STUBBED), during {} received normal data with size={:08X}, data={}",
                  "called (STUBBED), during {} received normal data with size={:08X}, data={}",
                  prefix, data.size(), Common::HexToString(data));
                  prefix, data.size(), Common::HexToString(data));
     }
     }
 
 
-    storage = broker.PopInteractiveDataToApplet();
-    for (; storage != nullptr; storage = broker.PopInteractiveDataToApplet()) {
+    while (R_SUCCEEDED(applet->caller_applet_broker->GetInteractiveInData().Pop(&storage))) {
         const auto data = storage->GetData();
         const auto data = storage->GetData();
         LOG_INFO(Service_AM,
         LOG_INFO(Service_AM,
                  "called (STUBBED), during {} received interactive data with size={:08X}, data={}",
                  "called (STUBBED), during {} received interactive data with size={:08X}, data={}",
@@ -34,9 +34,9 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix)
     }
     }
 }
 }
 
 
-Auth::Auth(Core::System& system_, LibraryAppletMode applet_mode_,
+Auth::Auth(Core::System& system_, std::shared_ptr<Applet> applet_, LibraryAppletMode applet_mode_,
            Core::Frontend::ParentalControlsApplet& frontend_)
            Core::Frontend::ParentalControlsApplet& frontend_)
-    : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
+    : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {}
 
 
 Auth::~Auth() = default;
 Auth::~Auth() = default;
 
 
@@ -44,7 +44,7 @@ void Auth::Initialize() {
     FrontendApplet::Initialize();
     FrontendApplet::Initialize();
     complete = false;
     complete = false;
 
 
-    const auto storage = broker.PopNormalDataToApplet();
+    const std::shared_ptr<IStorage> storage = PopInData();
     ASSERT(storage != nullptr);
     ASSERT(storage != nullptr);
     const auto data = storage->GetData();
     const auto data = storage->GetData();
     ASSERT(data.size() >= 0xC);
     ASSERT(data.size() >= 0xC);
@@ -68,10 +68,6 @@ void Auth::Initialize() {
     arg2 = arg.arg2;
     arg2 = arg.arg2;
 }
 }
 
 
-bool Auth::TransactionComplete() const {
-    return complete;
-}
-
 Result Auth::GetStatus() const {
 Result Auth::GetStatus() const {
     return successful ? ResultSuccess : ERROR_INVALID_PIN;
     return successful ? ResultSuccess : ERROR_INVALID_PIN;
 }
 }
@@ -147,8 +143,8 @@ void Auth::AuthFinished(bool is_successful) {
     std::vector<u8> out(sizeof(Return));
     std::vector<u8> out(sizeof(Return));
     std::memcpy(out.data(), &return_, sizeof(Return));
     std::memcpy(out.data(), &return_, sizeof(Return));
 
 
-    broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out)));
-    broker.SignalStateChanged();
+    PushOutData(std::make_shared<IStorage>(system, std::move(out)));
+    Exit();
 }
 }
 
 
 Result Auth::RequestExit() {
 Result Auth::RequestExit() {
@@ -156,9 +152,10 @@ Result Auth::RequestExit() {
     R_SUCCEED();
     R_SUCCEED();
 }
 }
 
 
-PhotoViewer::PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_,
+PhotoViewer::PhotoViewer(Core::System& system_, std::shared_ptr<Applet> applet_,
+                         LibraryAppletMode applet_mode_,
                          const Core::Frontend::PhotoViewerApplet& frontend_)
                          const Core::Frontend::PhotoViewerApplet& frontend_)
-    : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
+    : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {}
 
 
 PhotoViewer::~PhotoViewer() = default;
 PhotoViewer::~PhotoViewer() = default;
 
 
@@ -166,17 +163,13 @@ void PhotoViewer::Initialize() {
     FrontendApplet::Initialize();
     FrontendApplet::Initialize();
     complete = false;
     complete = false;
 
 
-    const auto storage = broker.PopNormalDataToApplet();
+    const std::shared_ptr<IStorage> storage = PopInData();
     ASSERT(storage != nullptr);
     ASSERT(storage != nullptr);
     const auto data = storage->GetData();
     const auto data = storage->GetData();
     ASSERT(!data.empty());
     ASSERT(!data.empty());
     mode = static_cast<PhotoViewerAppletMode>(data[0]);
     mode = static_cast<PhotoViewerAppletMode>(data[0]);
 }
 }
 
 
-bool PhotoViewer::TransactionComplete() const {
-    return complete;
-}
-
 Result PhotoViewer::GetStatus() const {
 Result PhotoViewer::GetStatus() const {
     return ResultSuccess;
     return ResultSuccess;
 }
 }
@@ -204,8 +197,8 @@ void PhotoViewer::Execute() {
 }
 }
 
 
 void PhotoViewer::ViewFinished() {
 void PhotoViewer::ViewFinished() {
-    broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{}));
-    broker.SignalStateChanged();
+    PushOutData(std::make_shared<IStorage>(system, std::vector<u8>{}));
+    Exit();
 }
 }
 
 
 Result PhotoViewer::RequestExit() {
 Result PhotoViewer::RequestExit() {
@@ -213,8 +206,9 @@ Result PhotoViewer::RequestExit() {
     R_SUCCEED();
     R_SUCCEED();
 }
 }
 
 
-StubApplet::StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_)
-    : FrontendApplet{system_, applet_mode_}, id{id_}, system{system_} {}
+StubApplet::StubApplet(Core::System& system_, std::shared_ptr<Applet> applet_, AppletId id_,
+                       LibraryAppletMode applet_mode_)
+    : FrontendApplet{system_, applet_, applet_mode_}, id{id_} {}
 
 
 StubApplet::~StubApplet() = default;
 StubApplet::~StubApplet() = default;
 
 
@@ -222,18 +216,7 @@ void StubApplet::Initialize() {
     LOG_WARNING(Service_AM, "called (STUBBED)");
     LOG_WARNING(Service_AM, "called (STUBBED)");
     FrontendApplet::Initialize();
     FrontendApplet::Initialize();
 
 
-    const auto data = broker.PeekDataToAppletForDebug();
-    system.GetReporter().SaveUnimplementedAppletReport(
-        static_cast<u32>(id), static_cast<u32>(common_args.arguments_version),
-        common_args.library_version, static_cast<u32>(common_args.theme_color),
-        common_args.play_startup_sound, common_args.system_tick, data.normal, data.interactive);
-
-    LogCurrentStorage(broker, "Initialize");
-}
-
-bool StubApplet::TransactionComplete() const {
-    LOG_WARNING(Service_AM, "called (STUBBED)");
-    return true;
+    LogCurrentStorage(applet.lock(), "Initialize");
 }
 }
 
 
 Result StubApplet::GetStatus() const {
 Result StubApplet::GetStatus() const {
@@ -243,22 +226,20 @@ Result StubApplet::GetStatus() const {
 
 
 void StubApplet::ExecuteInteractive() {
 void StubApplet::ExecuteInteractive() {
     LOG_WARNING(Service_AM, "called (STUBBED)");
     LOG_WARNING(Service_AM, "called (STUBBED)");
-    LogCurrentStorage(broker, "ExecuteInteractive");
+    LogCurrentStorage(applet.lock(), "ExecuteInteractive");
 
 
-    broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
-    broker.PushInteractiveDataFromApplet(
-        std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
-    broker.SignalStateChanged();
+    PushOutData(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
+    Exit();
 }
 }
 
 
 void StubApplet::Execute() {
 void StubApplet::Execute() {
     LOG_WARNING(Service_AM, "called (STUBBED)");
     LOG_WARNING(Service_AM, "called (STUBBED)");
-    LogCurrentStorage(broker, "Execute");
+    LogCurrentStorage(applet.lock(), "Execute");
 
 
-    broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
-    broker.PushInteractiveDataFromApplet(
-        std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
-    broker.SignalStateChanged();
+    PushOutData(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
+    Exit();
 }
 }
 
 
 Result StubApplet::RequestExit() {
 Result StubApplet::RequestExit() {

+ 6 - 9
src/core/hle/service/am/frontend/applet_general.h

@@ -19,12 +19,12 @@ enum class AuthAppletType : u32 {
 
 
 class Auth final : public FrontendApplet {
 class Auth final : public FrontendApplet {
 public:
 public:
-    explicit Auth(Core::System& system_, LibraryAppletMode applet_mode_,
+    explicit Auth(Core::System& system_, std::shared_ptr<Applet> applet_,
+                  LibraryAppletMode applet_mode_,
                   Core::Frontend::ParentalControlsApplet& frontend_);
                   Core::Frontend::ParentalControlsApplet& frontend_);
     ~Auth() override;
     ~Auth() override;
 
 
     void Initialize() override;
     void Initialize() override;
-    bool TransactionComplete() const override;
     Result GetStatus() const override;
     Result GetStatus() const override;
     void ExecuteInteractive() override;
     void ExecuteInteractive() override;
     void Execute() override;
     void Execute() override;
@@ -34,7 +34,6 @@ public:
 
 
 private:
 private:
     Core::Frontend::ParentalControlsApplet& frontend;
     Core::Frontend::ParentalControlsApplet& frontend;
-    Core::System& system;
     bool complete = false;
     bool complete = false;
     bool successful = false;
     bool successful = false;
 
 
@@ -51,12 +50,12 @@ enum class PhotoViewerAppletMode : u8 {
 
 
 class PhotoViewer final : public FrontendApplet {
 class PhotoViewer final : public FrontendApplet {
 public:
 public:
-    explicit PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_,
+    explicit PhotoViewer(Core::System& system_, std::shared_ptr<Applet> applet_,
+                         LibraryAppletMode applet_mode_,
                          const Core::Frontend::PhotoViewerApplet& frontend_);
                          const Core::Frontend::PhotoViewerApplet& frontend_);
     ~PhotoViewer() override;
     ~PhotoViewer() override;
 
 
     void Initialize() override;
     void Initialize() override;
-    bool TransactionComplete() const override;
     Result GetStatus() const override;
     Result GetStatus() const override;
     void ExecuteInteractive() override;
     void ExecuteInteractive() override;
     void Execute() override;
     void Execute() override;
@@ -68,17 +67,16 @@ private:
     const Core::Frontend::PhotoViewerApplet& frontend;
     const Core::Frontend::PhotoViewerApplet& frontend;
     bool complete = false;
     bool complete = false;
     PhotoViewerAppletMode mode = PhotoViewerAppletMode::CurrentApp;
     PhotoViewerAppletMode mode = PhotoViewerAppletMode::CurrentApp;
-    Core::System& system;
 };
 };
 
 
 class StubApplet final : public FrontendApplet {
 class StubApplet final : public FrontendApplet {
 public:
 public:
-    explicit StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_);
+    explicit StubApplet(Core::System& system_, std::shared_ptr<Applet> applet_, AppletId id_,
+                        LibraryAppletMode applet_mode_);
     ~StubApplet() override;
     ~StubApplet() override;
 
 
     void Initialize() override;
     void Initialize() override;
 
 
-    bool TransactionComplete() const override;
     Result GetStatus() const override;
     Result GetStatus() const override;
     void ExecuteInteractive() override;
     void ExecuteInteractive() override;
     void Execute() override;
     void Execute() override;
@@ -86,7 +84,6 @@ public:
 
 
 private:
 private:
     AppletId id;
     AppletId id;
-    Core::System& system;
 };
 };
 
 
 } // namespace Service::AM::Frontend
 } // namespace Service::AM::Frontend

+ 8 - 12
src/core/hle/service/am/frontend/applet_mii_edit.cpp

@@ -14,9 +14,9 @@
 
 
 namespace Service::AM::Frontend {
 namespace Service::AM::Frontend {
 
 
-MiiEdit::MiiEdit(Core::System& system_, LibraryAppletMode applet_mode_,
-                 const Core::Frontend::MiiEditApplet& frontend_)
-    : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
+MiiEdit::MiiEdit(Core::System& system_, std::shared_ptr<Applet> applet_,
+                 LibraryAppletMode applet_mode_, const Core::Frontend::MiiEditApplet& frontend_)
+    : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {}
 
 
 MiiEdit::~MiiEdit() = default;
 MiiEdit::~MiiEdit() = default;
 
 
@@ -25,7 +25,7 @@ void MiiEdit::Initialize() {
     //       Instead, it is initialized by an AppletInput storage with size 0x100 bytes.
     //       Instead, it is initialized by an AppletInput storage with size 0x100 bytes.
     //       Do NOT call Applet::Initialize() here.
     //       Do NOT call Applet::Initialize() here.
 
 
-    const auto storage = broker.PopNormalDataToApplet();
+    const std::shared_ptr<IStorage> storage = PopInData();
     ASSERT(storage != nullptr);
     ASSERT(storage != nullptr);
 
 
     const auto applet_input_data = storage->GetData();
     const auto applet_input_data = storage->GetData();
@@ -67,10 +67,6 @@ void MiiEdit::Initialize() {
     manager->Initialize(metadata);
     manager->Initialize(metadata);
 }
 }
 
 
-bool MiiEdit::TransactionComplete() const {
-    return is_complete;
-}
-
 Result MiiEdit::GetStatus() const {
 Result MiiEdit::GetStatus() const {
     return ResultSuccess;
     return ResultSuccess;
 }
 }
@@ -153,8 +149,8 @@ void MiiEdit::MiiEditOutput(MiiEditResult result, s32 index) {
 
 
     is_complete = true;
     is_complete = true;
 
 
-    broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
-    broker.SignalStateChanged();
+    PushOutData(std::make_shared<IStorage>(system, std::move(out_data)));
+    Exit();
 }
 }
 
 
 void MiiEdit::MiiEditOutputForCharInfoEditing(MiiEditResult result,
 void MiiEdit::MiiEditOutputForCharInfoEditing(MiiEditResult result,
@@ -169,8 +165,8 @@ void MiiEdit::MiiEditOutputForCharInfoEditing(MiiEditResult result,
 
 
     is_complete = true;
     is_complete = true;
 
 
-    broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
-    broker.SignalStateChanged();
+    PushOutData(std::make_shared<IStorage>(system, std::move(out_data)));
+    Exit();
 }
 }
 
 
 Result MiiEdit::RequestExit() {
 Result MiiEdit::RequestExit() {

+ 2 - 3
src/core/hle/service/am/frontend/applet_mii_edit.h

@@ -20,13 +20,13 @@ namespace Service::AM::Frontend {
 
 
 class MiiEdit final : public FrontendApplet {
 class MiiEdit final : public FrontendApplet {
 public:
 public:
-    explicit MiiEdit(Core::System& system_, LibraryAppletMode applet_mode_,
+    explicit MiiEdit(Core::System& system_, std::shared_ptr<Applet> applet_,
+                     LibraryAppletMode applet_mode_,
                      const Core::Frontend::MiiEditApplet& frontend_);
                      const Core::Frontend::MiiEditApplet& frontend_);
     ~MiiEdit() override;
     ~MiiEdit() override;
 
 
     void Initialize() override;
     void Initialize() override;
 
 
-    bool TransactionComplete() const override;
     Result GetStatus() const override;
     Result GetStatus() const override;
     void ExecuteInteractive() override;
     void ExecuteInteractive() override;
     void Execute() override;
     void Execute() override;
@@ -38,7 +38,6 @@ public:
 
 
 private:
 private:
     const Core::Frontend::MiiEditApplet& frontend;
     const Core::Frontend::MiiEditApplet& frontend;
-    Core::System& system;
 
 
     MiiEditAppletInputCommon applet_input_common{};
     MiiEditAppletInputCommon applet_input_common{};
     MiiEditAppletInputV3 applet_input_v3{};
     MiiEditAppletInputV3 applet_input_v3{};

+ 9 - 10
src/core/hle/service/am/frontend/applet_profile_select.cpp

@@ -14,9 +14,10 @@
 
 
 namespace Service::AM::Frontend {
 namespace Service::AM::Frontend {
 
 
-ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_,
+ProfileSelect::ProfileSelect(Core::System& system_, std::shared_ptr<Applet> applet_,
+                             LibraryAppletMode applet_mode_,
                              const Core::Frontend::ProfileSelectApplet& frontend_)
                              const Core::Frontend::ProfileSelectApplet& frontend_)
-    : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
+    : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {}
 
 
 ProfileSelect::~ProfileSelect() = default;
 ProfileSelect::~ProfileSelect() = default;
 
 
@@ -28,7 +29,7 @@ void ProfileSelect::Initialize() {
     FrontendApplet::Initialize();
     FrontendApplet::Initialize();
     profile_select_version = ProfileSelectAppletVersion{common_args.library_version};
     profile_select_version = ProfileSelectAppletVersion{common_args.library_version};
 
 
-    const auto user_config_storage = broker.PopNormalDataToApplet();
+    const std::shared_ptr<IStorage> user_config_storage = PopInData();
     ASSERT(user_config_storage != nullptr);
     ASSERT(user_config_storage != nullptr);
     const auto& user_config = user_config_storage->GetData();
     const auto& user_config = user_config_storage->GetData();
 
 
@@ -51,10 +52,6 @@ void ProfileSelect::Initialize() {
     }
     }
 }
 }
 
 
-bool ProfileSelect::TransactionComplete() const {
-    return complete;
-}
-
 Result ProfileSelect::GetStatus() const {
 Result ProfileSelect::GetStatus() const {
     return status;
     return status;
 }
 }
@@ -65,7 +62,8 @@ void ProfileSelect::ExecuteInteractive() {
 
 
 void ProfileSelect::Execute() {
 void ProfileSelect::Execute() {
     if (complete) {
     if (complete) {
-        broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data)));
+        PushOutData(std::make_shared<IStorage>(system, std::move(final_data)));
+        Exit();
         return;
         return;
     }
     }
 
 
@@ -112,8 +110,9 @@ void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) {
 
 
     final_data = std::vector<u8>(sizeof(UiReturnArg));
     final_data = std::vector<u8>(sizeof(UiReturnArg));
     std::memcpy(final_data.data(), &output, final_data.size());
     std::memcpy(final_data.data(), &output, final_data.size());
-    broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data)));
-    broker.SignalStateChanged();
+
+    PushOutData(std::make_shared<IStorage>(system, std::move(final_data)));
+    Exit();
 }
 }
 
 
 Result ProfileSelect::RequestExit() {
 Result ProfileSelect::RequestExit() {

+ 2 - 3
src/core/hle/service/am/frontend/applet_profile_select.h

@@ -113,13 +113,13 @@ static_assert(sizeof(UiReturnArg) == 0x18, "UiReturnArg has incorrect size.");
 
 
 class ProfileSelect final : public FrontendApplet {
 class ProfileSelect final : public FrontendApplet {
 public:
 public:
-    explicit ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_,
+    explicit ProfileSelect(Core::System& system_, std::shared_ptr<Applet> applet_,
+                           LibraryAppletMode applet_mode_,
                            const Core::Frontend::ProfileSelectApplet& frontend_);
                            const Core::Frontend::ProfileSelectApplet& frontend_);
     ~ProfileSelect() override;
     ~ProfileSelect() override;
 
 
     void Initialize() override;
     void Initialize() override;
 
 
-    bool TransactionComplete() const override;
     Result GetStatus() const override;
     Result GetStatus() const override;
     void ExecuteInteractive() override;
     void ExecuteInteractive() override;
     void Execute() override;
     void Execute() override;
@@ -137,7 +137,6 @@ private:
     bool complete = false;
     bool complete = false;
     Result status = ResultSuccess;
     Result status = ResultSuccess;
     std::vector<u8> final_data;
     std::vector<u8> final_data;
-    Core::System& system;
 };
 };
 
 
 } // namespace Service::AM::Frontend
 } // namespace Service::AM::Frontend

+ 28 - 31
src/core/hle/service/am/frontend/applet_software_keyboard.cpp

@@ -42,9 +42,10 @@ void SetReplyBase(std::vector<u8>& reply, SwkbdState state, SwkbdReplyType reply
 
 
 } // Anonymous namespace
 } // Anonymous namespace
 
 
-SoftwareKeyboard::SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_,
+SoftwareKeyboard::SoftwareKeyboard(Core::System& system_, std::shared_ptr<Applet> applet_,
+                                   LibraryAppletMode applet_mode_,
                                    Core::Frontend::SoftwareKeyboardApplet& frontend_)
                                    Core::Frontend::SoftwareKeyboardApplet& frontend_)
-    : FrontendApplet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
+    : FrontendApplet{system_, applet_, applet_mode_}, frontend{frontend_} {}
 
 
 SoftwareKeyboard::~SoftwareKeyboard() = default;
 SoftwareKeyboard::~SoftwareKeyboard() = default;
 
 
@@ -77,10 +78,6 @@ void SoftwareKeyboard::Initialize() {
     }
     }
 }
 }
 
 
-bool SoftwareKeyboard::TransactionComplete() const {
-    return complete;
-}
-
 Result SoftwareKeyboard::GetStatus() const {
 Result SoftwareKeyboard::GetStatus() const {
     return status;
     return status;
 }
 }
@@ -185,7 +182,7 @@ void SoftwareKeyboard::InitializeForeground() {
 
 
     is_background = false;
     is_background = false;
 
 
-    const auto swkbd_config_storage = broker.PopNormalDataToApplet();
+    const auto swkbd_config_storage = PopInData();
     ASSERT(swkbd_config_storage != nullptr);
     ASSERT(swkbd_config_storage != nullptr);
 
 
     const auto& swkbd_config_data = swkbd_config_storage->GetData();
     const auto& swkbd_config_data = swkbd_config_storage->GetData();
@@ -222,7 +219,7 @@ void SoftwareKeyboard::InitializeForeground() {
         break;
         break;
     }
     }
 
 
-    const auto work_buffer_storage = broker.PopNormalDataToApplet();
+    const auto work_buffer_storage = PopInData();
     ASSERT(work_buffer_storage != nullptr);
     ASSERT(work_buffer_storage != nullptr);
 
 
     if (swkbd_config_common.initial_string_length == 0) {
     if (swkbd_config_common.initial_string_length == 0) {
@@ -251,7 +248,7 @@ void SoftwareKeyboard::InitializeBackground(LibraryAppletMode library_applet_mod
 
 
     is_background = true;
     is_background = true;
 
 
-    const auto swkbd_inline_initialize_arg_storage = broker.PopNormalDataToApplet();
+    const auto swkbd_inline_initialize_arg_storage = PopInData();
     ASSERT(swkbd_inline_initialize_arg_storage != nullptr);
     ASSERT(swkbd_inline_initialize_arg_storage != nullptr);
 
 
     const auto& swkbd_inline_initialize_arg = swkbd_inline_initialize_arg_storage->GetData();
     const auto& swkbd_inline_initialize_arg = swkbd_inline_initialize_arg_storage->GetData();
@@ -268,7 +265,7 @@ void SoftwareKeyboard::InitializeBackground(LibraryAppletMode library_applet_mod
 }
 }
 
 
 void SoftwareKeyboard::ProcessTextCheck() {
 void SoftwareKeyboard::ProcessTextCheck() {
-    const auto text_check_storage = broker.PopInteractiveDataToApplet();
+    const auto text_check_storage = PopInteractiveInData();
     ASSERT(text_check_storage != nullptr);
     ASSERT(text_check_storage != nullptr);
 
 
     const auto& text_check_data = text_check_storage->GetData();
     const auto& text_check_data = text_check_storage->GetData();
@@ -315,7 +312,7 @@ void SoftwareKeyboard::ProcessTextCheck() {
 }
 }
 
 
 void SoftwareKeyboard::ProcessInlineKeyboardRequest() {
 void SoftwareKeyboard::ProcessInlineKeyboardRequest() {
-    const auto request_data_storage = broker.PopInteractiveDataToApplet();
+    const auto request_data_storage = PopInteractiveInData();
     ASSERT(request_data_storage != nullptr);
     ASSERT(request_data_storage != nullptr);
 
 
     const auto& request_data = request_data_storage->GetData();
     const auto& request_data = request_data_storage->GetData();
@@ -378,7 +375,7 @@ void SoftwareKeyboard::SubmitNormalOutputAndExit(SwkbdResult result,
                     submitted_text.size() * sizeof(char16_t));
                     submitted_text.size() * sizeof(char16_t));
     }
     }
 
 
-    broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
+    PushOutData(std::make_shared<IStorage>(system, std::move(out_data)));
 
 
     ExitKeyboard();
     ExitKeyboard();
 }
 }
@@ -411,7 +408,7 @@ void SoftwareKeyboard::SubmitForTextCheck(std::u16string submitted_text) {
                     current_text.size() * sizeof(char16_t));
                     current_text.size() * sizeof(char16_t));
     }
     }
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(out_data)));
 }
 }
 
 
 void SoftwareKeyboard::SendReply(SwkbdReplyType reply_type) {
 void SoftwareKeyboard::SendReply(SwkbdReplyType reply_type) {
@@ -768,7 +765,7 @@ void SoftwareKeyboard::ExitKeyboard() {
 
 
     frontend.ExitKeyboard();
     frontend.ExitKeyboard();
 
 
-    broker.SignalStateChanged();
+    Exit();
 }
 }
 
 
 Result SoftwareKeyboard::RequestExit() {
 Result SoftwareKeyboard::RequestExit() {
@@ -968,7 +965,7 @@ void SoftwareKeyboard::ReplyFinishedInitialize() {
 
 
     SetReplyBase(reply, swkbd_state, SwkbdReplyType::FinishedInitialize);
     SetReplyBase(reply, swkbd_state, SwkbdReplyType::FinishedInitialize);
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 }
 }
 
 
 void SoftwareKeyboard::ReplyDefault() {
 void SoftwareKeyboard::ReplyDefault() {
@@ -978,7 +975,7 @@ void SoftwareKeyboard::ReplyDefault() {
 
 
     SetReplyBase(reply, swkbd_state, SwkbdReplyType::Default);
     SetReplyBase(reply, swkbd_state, SwkbdReplyType::Default);
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 }
 }
 
 
 void SoftwareKeyboard::ReplyChangedString() {
 void SoftwareKeyboard::ReplyChangedString() {
@@ -1000,7 +997,7 @@ void SoftwareKeyboard::ReplyChangedString() {
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &changed_string_arg,
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &changed_string_arg,
                 sizeof(SwkbdChangedStringArg));
                 sizeof(SwkbdChangedStringArg));
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 }
 }
 
 
 void SoftwareKeyboard::ReplyMovedCursor() {
 void SoftwareKeyboard::ReplyMovedCursor() {
@@ -1020,7 +1017,7 @@ void SoftwareKeyboard::ReplyMovedCursor() {
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_cursor_arg,
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_cursor_arg,
                 sizeof(SwkbdMovedCursorArg));
                 sizeof(SwkbdMovedCursorArg));
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 }
 }
 
 
 void SoftwareKeyboard::ReplyMovedTab() {
 void SoftwareKeyboard::ReplyMovedTab() {
@@ -1040,7 +1037,7 @@ void SoftwareKeyboard::ReplyMovedTab() {
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_tab_arg,
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_tab_arg,
                 sizeof(SwkbdMovedTabArg));
                 sizeof(SwkbdMovedTabArg));
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 }
 }
 
 
 void SoftwareKeyboard::ReplyDecidedEnter() {
 void SoftwareKeyboard::ReplyDecidedEnter() {
@@ -1059,7 +1056,7 @@ void SoftwareKeyboard::ReplyDecidedEnter() {
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &decided_enter_arg,
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &decided_enter_arg,
                 sizeof(SwkbdDecidedEnterArg));
                 sizeof(SwkbdDecidedEnterArg));
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 
 
     HideInlineKeyboard();
     HideInlineKeyboard();
 }
 }
@@ -1071,7 +1068,7 @@ void SoftwareKeyboard::ReplyDecidedCancel() {
 
 
     SetReplyBase(reply, swkbd_state, SwkbdReplyType::DecidedCancel);
     SetReplyBase(reply, swkbd_state, SwkbdReplyType::DecidedCancel);
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 
 
     HideInlineKeyboard();
     HideInlineKeyboard();
 }
 }
@@ -1096,7 +1093,7 @@ void SoftwareKeyboard::ReplyChangedStringUtf8() {
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &changed_string_arg,
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &changed_string_arg,
                 sizeof(SwkbdChangedStringArg));
                 sizeof(SwkbdChangedStringArg));
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 }
 }
 
 
 void SoftwareKeyboard::ReplyMovedCursorUtf8() {
 void SoftwareKeyboard::ReplyMovedCursorUtf8() {
@@ -1117,7 +1114,7 @@ void SoftwareKeyboard::ReplyMovedCursorUtf8() {
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &moved_cursor_arg,
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &moved_cursor_arg,
                 sizeof(SwkbdMovedCursorArg));
                 sizeof(SwkbdMovedCursorArg));
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 }
 }
 
 
 void SoftwareKeyboard::ReplyDecidedEnterUtf8() {
 void SoftwareKeyboard::ReplyDecidedEnterUtf8() {
@@ -1137,7 +1134,7 @@ void SoftwareKeyboard::ReplyDecidedEnterUtf8() {
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &decided_enter_arg,
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &decided_enter_arg,
                 sizeof(SwkbdDecidedEnterArg));
                 sizeof(SwkbdDecidedEnterArg));
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 
 
     HideInlineKeyboard();
     HideInlineKeyboard();
 }
 }
@@ -1149,7 +1146,7 @@ void SoftwareKeyboard::ReplyUnsetCustomizeDic() {
 
 
     SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizeDic);
     SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizeDic);
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 }
 }
 
 
 void SoftwareKeyboard::ReplyReleasedUserWordInfo() {
 void SoftwareKeyboard::ReplyReleasedUserWordInfo() {
@@ -1159,7 +1156,7 @@ void SoftwareKeyboard::ReplyReleasedUserWordInfo() {
 
 
     SetReplyBase(reply, swkbd_state, SwkbdReplyType::ReleasedUserWordInfo);
     SetReplyBase(reply, swkbd_state, SwkbdReplyType::ReleasedUserWordInfo);
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 }
 }
 
 
 void SoftwareKeyboard::ReplyUnsetCustomizedDictionaries() {
 void SoftwareKeyboard::ReplyUnsetCustomizedDictionaries() {
@@ -1169,7 +1166,7 @@ void SoftwareKeyboard::ReplyUnsetCustomizedDictionaries() {
 
 
     SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizedDictionaries);
     SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizedDictionaries);
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 }
 }
 
 
 void SoftwareKeyboard::ReplyChangedStringV2() {
 void SoftwareKeyboard::ReplyChangedStringV2() {
@@ -1195,7 +1192,7 @@ void SoftwareKeyboard::ReplyChangedStringV2() {
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdChangedStringArg),
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdChangedStringArg),
                 &flag, 1);
                 &flag, 1);
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 }
 }
 
 
 void SoftwareKeyboard::ReplyMovedCursorV2() {
 void SoftwareKeyboard::ReplyMovedCursorV2() {
@@ -1219,7 +1216,7 @@ void SoftwareKeyboard::ReplyMovedCursorV2() {
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedCursorArg),
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedCursorArg),
                 &flag, 1);
                 &flag, 1);
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 }
 }
 
 
 void SoftwareKeyboard::ReplyChangedStringUtf8V2() {
 void SoftwareKeyboard::ReplyChangedStringUtf8V2() {
@@ -1246,7 +1243,7 @@ void SoftwareKeyboard::ReplyChangedStringUtf8V2() {
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdChangedStringArg),
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdChangedStringArg),
                 &flag, 1);
                 &flag, 1);
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 }
 }
 
 
 void SoftwareKeyboard::ReplyMovedCursorUtf8V2() {
 void SoftwareKeyboard::ReplyMovedCursorUtf8V2() {
@@ -1271,7 +1268,7 @@ void SoftwareKeyboard::ReplyMovedCursorUtf8V2() {
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdMovedCursorArg),
     std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdMovedCursorArg),
                 &flag, 1);
                 &flag, 1);
 
 
-    broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply)));
+    PushInteractiveOutData(std::make_shared<IStorage>(system, std::move(reply)));
 }
 }
 
 
 } // namespace Service::AM::Frontend
 } // namespace Service::AM::Frontend

+ 2 - 3
src/core/hle/service/am/frontend/applet_software_keyboard.h

@@ -21,13 +21,13 @@ namespace Service::AM::Frontend {
 
 
 class SoftwareKeyboard final : public FrontendApplet {
 class SoftwareKeyboard final : public FrontendApplet {
 public:
 public:
-    explicit SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_,
+    explicit SoftwareKeyboard(Core::System& system_, std::shared_ptr<Applet> applet_,
+                              LibraryAppletMode applet_mode_,
                               Core::Frontend::SoftwareKeyboardApplet& frontend_);
                               Core::Frontend::SoftwareKeyboardApplet& frontend_);
     ~SoftwareKeyboard() override;
     ~SoftwareKeyboard() override;
 
 
     void Initialize() override;
     void Initialize() override;
 
 
-    bool TransactionComplete() const override;
     Result GetStatus() const override;
     Result GetStatus() const override;
     void ExecuteInteractive() override;
     void ExecuteInteractive() override;
     void Execute() override;
     void Execute() override;
@@ -156,7 +156,6 @@ private:
     void ReplyMovedCursorUtf8V2();
     void ReplyMovedCursorUtf8V2();
 
 
     Core::Frontend::SoftwareKeyboardApplet& frontend;
     Core::Frontend::SoftwareKeyboardApplet& frontend;
-    Core::System& system;
 
 
     SwkbdAppletVersion swkbd_applet_version;
     SwkbdAppletVersion swkbd_applet_version;
 
 

+ 6 - 9
src/core/hle/service/am/frontend/applet_web_browser.cpp

@@ -224,9 +224,10 @@ void ExtractSharedFonts(Core::System& system) {
 
 
 } // namespace
 } // namespace
 
 
-WebBrowser::WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_,
+WebBrowser::WebBrowser(Core::System& system_, std::shared_ptr<Applet> applet_,
+                       LibraryAppletMode applet_mode_,
                        const Core::Frontend::WebBrowserApplet& frontend_)
                        const Core::Frontend::WebBrowserApplet& frontend_)
-    : FrontendApplet{system_, applet_mode_}, frontend(frontend_), system{system_} {}
+    : FrontendApplet{system_, applet_, applet_mode_}, frontend(frontend_) {}
 
 
 WebBrowser::~WebBrowser() = default;
 WebBrowser::~WebBrowser() = default;
 
 
@@ -244,7 +245,7 @@ void WebBrowser::Initialize() {
 
 
     web_applet_version = WebAppletVersion{common_args.library_version};
     web_applet_version = WebAppletVersion{common_args.library_version};
 
 
-    const auto web_arg_storage = broker.PopNormalDataToApplet();
+    const auto web_arg_storage = PopInData();
     ASSERT(web_arg_storage != nullptr);
     ASSERT(web_arg_storage != nullptr);
 
 
     const auto& web_arg = web_arg_storage->GetData();
     const auto& web_arg = web_arg_storage->GetData();
@@ -285,10 +286,6 @@ void WebBrowser::Initialize() {
     }
     }
 }
 }
 
 
-bool WebBrowser::TransactionComplete() const {
-    return complete;
-}
-
 Result WebBrowser::GetStatus() const {
 Result WebBrowser::GetStatus() const {
     return status;
     return status;
 }
 }
@@ -359,8 +356,8 @@ void WebBrowser::WebBrowserExit(WebExitReason exit_reason, std::string last_url)
     complete = true;
     complete = true;
     std::vector<u8> out_data(sizeof(WebCommonReturnValue));
     std::vector<u8> out_data(sizeof(WebCommonReturnValue));
     std::memcpy(out_data.data(), &web_common_return_value, out_data.size());
     std::memcpy(out_data.data(), &web_common_return_value, out_data.size());
-    broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
-    broker.SignalStateChanged();
+    PushOutData(std::make_shared<IStorage>(system, std::move(out_data)));
+    Exit();
 }
 }
 
 
 Result WebBrowser::RequestExit() {
 Result WebBrowser::RequestExit() {

+ 2 - 5
src/core/hle/service/am/frontend/applet_web_browser.h

@@ -24,14 +24,13 @@ namespace Service::AM::Frontend {
 
 
 class WebBrowser final : public FrontendApplet {
 class WebBrowser final : public FrontendApplet {
 public:
 public:
-    WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_,
-               const Core::Frontend::WebBrowserApplet& frontend_);
+    WebBrowser(Core::System& system_, std::shared_ptr<Applet> applet_,
+               LibraryAppletMode applet_mode_, const Core::Frontend::WebBrowserApplet& frontend_);
 
 
     ~WebBrowser() override;
     ~WebBrowser() override;
 
 
     void Initialize() override;
     void Initialize() override;
 
 
-    bool TransactionComplete() const override;
     Result GetStatus() const override;
     Result GetStatus() const override;
     void ExecuteInteractive() override;
     void ExecuteInteractive() override;
     void Execute() override;
     void Execute() override;
@@ -80,8 +79,6 @@ private:
     FileSys::VirtualFile offline_romfs;
     FileSys::VirtualFile offline_romfs;
 
 
     std::string external_url;
     std::string external_url;
-
-    Core::System& system;
 };
 };
 
 
 } // namespace Service::AM::Frontend
 } // namespace Service::AM::Frontend

+ 39 - 126
src/core/hle/service/am/frontend/applets.cpp

@@ -16,6 +16,7 @@
 #include "core/hle/kernel/k_event.h"
 #include "core/hle/kernel/k_event.h"
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/applet_ae.h"
 #include "core/hle/service/am/applet_ae.h"
+#include "core/hle/service/am/applet_data_broker.h"
 #include "core/hle/service/am/applet_manager.h"
 #include "core/hle/service/am/applet_manager.h"
 #include "core/hle/service/am/applet_message_queue.h"
 #include "core/hle/service/am/applet_message_queue.h"
 #include "core/hle/service/am/applet_oe.h"
 #include "core/hle/service/am/applet_oe.h"
@@ -33,135 +34,45 @@
 
 
 namespace Service::AM::Frontend {
 namespace Service::AM::Frontend {
 
 
-AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_)
-    : system{system_}, applet_mode{applet_mode_},
-      service_context{system, "ILibraryAppletAccessor"} {
-    state_changed_event = service_context.CreateEvent("ILibraryAppletAccessor:StateChangedEvent");
-    pop_out_data_event = service_context.CreateEvent("ILibraryAppletAccessor:PopDataOutEvent");
-    pop_interactive_out_data_event =
-        service_context.CreateEvent("ILibraryAppletAccessor:PopInteractiveDataOutEvent");
-}
-
-AppletDataBroker::~AppletDataBroker() {
-    service_context.CloseEvent(state_changed_event);
-    service_context.CloseEvent(pop_out_data_event);
-    service_context.CloseEvent(pop_interactive_out_data_event);
-}
-
-AppletDataBroker::RawChannelData AppletDataBroker::PeekDataToAppletForDebug() const {
-    std::vector<std::vector<u8>> out_normal;
-
-    for (const auto& storage : in_channel) {
-        out_normal.push_back(storage->GetData());
-    }
-
-    std::vector<std::vector<u8>> out_interactive;
+FrontendApplet::FrontendApplet(Core::System& system_, std::shared_ptr<Applet> applet_,
+                               LibraryAppletMode applet_mode_)
+    : system{system_}, applet{std::move(applet_)}, applet_mode{applet_mode_} {}
 
 
-    for (const auto& storage : in_interactive_channel) {
-        out_interactive.push_back(storage->GetData());
-    }
-
-    return {std::move(out_normal), std::move(out_interactive)};
-}
-
-std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() {
-    if (out_channel.empty())
-        return nullptr;
-
-    auto out = std::move(out_channel.front());
-    out_channel.pop_front();
-    pop_out_data_event->Clear();
-    return out;
-}
-
-std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToApplet() {
-    if (in_channel.empty())
-        return nullptr;
-
-    auto out = std::move(in_channel.front());
-    in_channel.pop_front();
-    return out;
-}
-
-std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() {
-    if (out_interactive_channel.empty())
-        return nullptr;
-
-    auto out = std::move(out_interactive_channel.front());
-    out_interactive_channel.pop_front();
-    pop_interactive_out_data_event->Clear();
-    return out;
-}
-
-std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToApplet() {
-    if (in_interactive_channel.empty())
-        return nullptr;
-
-    auto out = std::move(in_interactive_channel.front());
-    in_interactive_channel.pop_front();
-    return out;
-}
-
-void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr<IStorage>&& storage) {
-    in_channel.emplace_back(std::move(storage));
-}
+FrontendApplet::~FrontendApplet() = default;
 
 
-void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) {
-    out_channel.emplace_back(std::move(storage));
-    pop_out_data_event->Signal();
-}
+void FrontendApplet::Initialize() {
+    std::shared_ptr<IStorage> common = PopInData();
+    ASSERT(common != nullptr);
+    const auto common_data = common->GetData();
 
 
-void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) {
-    in_interactive_channel.emplace_back(std::move(storage));
-}
+    ASSERT(common_data.size() >= sizeof(CommonArguments));
+    std::memcpy(&common_args, common_data.data(), sizeof(CommonArguments));
 
 
-void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) {
-    out_interactive_channel.emplace_back(std::move(storage));
-    pop_interactive_out_data_event->Signal();
+    initialized = true;
 }
 }
 
 
-void AppletDataBroker::SignalStateChanged() {
-    state_changed_event->Signal();
-
-    // TODO proper window management
-    switch (applet_mode) {
-    case LibraryAppletMode::AllForeground:
-    case LibraryAppletMode::AllForegroundInitiallyHidden: {
-        system.GetAppletManager().FocusStateChanged();
-        break;
-    }
-    default:
-        break;
-    }
+std::shared_ptr<IStorage> FrontendApplet::PopInData() {
+    std::shared_ptr<IStorage> ret;
+    applet.lock()->caller_applet_broker->GetInData().Pop(&ret);
+    return ret;
 }
 }
 
 
-Kernel::KReadableEvent& AppletDataBroker::GetNormalDataEvent() {
-    return pop_out_data_event->GetReadableEvent();
+std::shared_ptr<IStorage> FrontendApplet::PopInteractiveInData() {
+    std::shared_ptr<IStorage> ret;
+    applet.lock()->caller_applet_broker->GetInteractiveInData().Pop(&ret);
+    return ret;
 }
 }
 
 
-Kernel::KReadableEvent& AppletDataBroker::GetInteractiveDataEvent() {
-    return pop_interactive_out_data_event->GetReadableEvent();
+void FrontendApplet::PushOutData(std::shared_ptr<IStorage> storage) {
+    applet.lock()->caller_applet_broker->GetOutData().Push(storage);
 }
 }
 
 
-Kernel::KReadableEvent& AppletDataBroker::GetStateChangedEvent() {
-    return state_changed_event->GetReadableEvent();
+void FrontendApplet::PushInteractiveOutData(std::shared_ptr<IStorage> storage) {
+    applet.lock()->caller_applet_broker->GetInteractiveOutData().Push(storage);
 }
 }
 
 
-FrontendApplet::FrontendApplet(Core::System& system_, LibraryAppletMode applet_mode_)
-    : broker{system_, applet_mode_}, applet_mode{applet_mode_} {}
-
-FrontendApplet::~FrontendApplet() = default;
-
-void FrontendApplet::Initialize() {
-    const auto common = broker.PopNormalDataToApplet();
-    ASSERT(common != nullptr);
-
-    const auto common_data = common->GetData();
-
-    ASSERT(common_data.size() >= sizeof(CommonArguments));
-    std::memcpy(&common_args, common_data.data(), sizeof(CommonArguments));
-
-    initialized = true;
+void FrontendApplet::Exit() {
+    applet.lock()->caller_applet_broker->SignalCompletion();
 }
 }
 
 
 FrontendAppletSet::FrontendAppletSet() = default;
 FrontendAppletSet::FrontendAppletSet() = default;
@@ -291,36 +202,38 @@ void FrontendAppletHolder::ClearAll() {
     frontend = {};
     frontend = {};
 }
 }
 
 
-std::shared_ptr<FrontendApplet> FrontendAppletHolder::GetApplet(AppletId id,
+std::shared_ptr<FrontendApplet> FrontendAppletHolder::GetApplet(std::shared_ptr<Applet> applet,
+                                                                AppletId id,
                                                                 LibraryAppletMode mode) const {
                                                                 LibraryAppletMode mode) const {
     switch (id) {
     switch (id) {
     case AppletId::Auth:
     case AppletId::Auth:
-        return std::make_shared<Auth>(system, mode, *frontend.parental_controls);
+        return std::make_shared<Auth>(system, applet, mode, *frontend.parental_controls);
     case AppletId::Cabinet:
     case AppletId::Cabinet:
-        return std::make_shared<Cabinet>(system, mode, *frontend.cabinet);
+        return std::make_shared<Cabinet>(system, applet, mode, *frontend.cabinet);
     case AppletId::Controller:
     case AppletId::Controller:
-        return std::make_shared<Controller>(system, mode, *frontend.controller);
+        return std::make_shared<Controller>(system, applet, mode, *frontend.controller);
     case AppletId::Error:
     case AppletId::Error:
-        return std::make_shared<Error>(system, mode, *frontend.error);
+        return std::make_shared<Error>(system, applet, mode, *frontend.error);
     case AppletId::ProfileSelect:
     case AppletId::ProfileSelect:
-        return std::make_shared<ProfileSelect>(system, mode, *frontend.profile_select);
+        return std::make_shared<ProfileSelect>(system, applet, mode, *frontend.profile_select);
     case AppletId::SoftwareKeyboard:
     case AppletId::SoftwareKeyboard:
-        return std::make_shared<SoftwareKeyboard>(system, mode, *frontend.software_keyboard);
+        return std::make_shared<SoftwareKeyboard>(system, applet, mode,
+                                                  *frontend.software_keyboard);
     case AppletId::MiiEdit:
     case AppletId::MiiEdit:
-        return std::make_shared<MiiEdit>(system, mode, *frontend.mii_edit);
+        return std::make_shared<MiiEdit>(system, applet, mode, *frontend.mii_edit);
     case AppletId::Web:
     case AppletId::Web:
     case AppletId::Shop:
     case AppletId::Shop:
     case AppletId::OfflineWeb:
     case AppletId::OfflineWeb:
     case AppletId::LoginShare:
     case AppletId::LoginShare:
     case AppletId::WebAuth:
     case AppletId::WebAuth:
-        return std::make_shared<WebBrowser>(system, mode, *frontend.web_browser);
+        return std::make_shared<WebBrowser>(system, applet, mode, *frontend.web_browser);
     case AppletId::PhotoViewer:
     case AppletId::PhotoViewer:
-        return std::make_shared<PhotoViewer>(system, mode, *frontend.photo_viewer);
+        return std::make_shared<PhotoViewer>(system, applet, mode, *frontend.photo_viewer);
     default:
     default:
         UNIMPLEMENTED_MSG(
         UNIMPLEMENTED_MSG(
             "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.",
             "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.",
             static_cast<u8>(id));
             static_cast<u8>(id));
-        return std::make_shared<StubApplet>(system, id, mode);
+        return std::make_shared<StubApplet>(system, applet, id, mode);
     }
     }
 }
 }
 
 

+ 15 - 74
src/core/hle/service/am/frontend/applets.h

@@ -44,87 +44,19 @@ class IStorage;
 
 
 namespace Frontend {
 namespace Frontend {
 
 
-class AppletDataBroker final {
-public:
-    explicit AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_);
-    ~AppletDataBroker();
-
-    struct RawChannelData {
-        std::vector<std::vector<u8>> normal;
-        std::vector<std::vector<u8>> interactive;
-    };
-
-    // Retrieves but does not pop the data sent to applet.
-    RawChannelData PeekDataToAppletForDebug() const;
-
-    std::shared_ptr<IStorage> PopNormalDataToGame();
-    std::shared_ptr<IStorage> PopNormalDataToApplet();
-
-    std::shared_ptr<IStorage> PopInteractiveDataToGame();
-    std::shared_ptr<IStorage> PopInteractiveDataToApplet();
-
-    void PushNormalDataFromGame(std::shared_ptr<IStorage>&& storage);
-    void PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage);
-
-    void PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage);
-    void PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage);
-
-    void SignalStateChanged();
-
-    Kernel::KReadableEvent& GetNormalDataEvent();
-    Kernel::KReadableEvent& GetInteractiveDataEvent();
-    Kernel::KReadableEvent& GetStateChangedEvent();
-
-private:
-    Core::System& system;
-    LibraryAppletMode applet_mode;
-
-    KernelHelpers::ServiceContext service_context;
-
-    // Queues are named from applet's perspective
-
-    // PopNormalDataToApplet and PushNormalDataFromGame
-    std::deque<std::shared_ptr<IStorage>> in_channel;
-
-    // PopNormalDataToGame and PushNormalDataFromApplet
-    std::deque<std::shared_ptr<IStorage>> out_channel;
-
-    // PopInteractiveDataToApplet and PushInteractiveDataFromGame
-    std::deque<std::shared_ptr<IStorage>> in_interactive_channel;
-
-    // PopInteractiveDataToGame and PushInteractiveDataFromApplet
-    std::deque<std::shared_ptr<IStorage>> out_interactive_channel;
-
-    Kernel::KEvent* state_changed_event;
-
-    // Signaled on PushNormalDataFromApplet
-    Kernel::KEvent* pop_out_data_event;
-
-    // Signaled on PushInteractiveDataFromApplet
-    Kernel::KEvent* pop_interactive_out_data_event;
-};
-
 class FrontendApplet {
 class FrontendApplet {
 public:
 public:
-    explicit FrontendApplet(Core::System& system_, LibraryAppletMode applet_mode_);
+    explicit FrontendApplet(Core::System& system_, std::shared_ptr<Applet> applet_,
+                            LibraryAppletMode applet_mode_);
     virtual ~FrontendApplet();
     virtual ~FrontendApplet();
 
 
     virtual void Initialize();
     virtual void Initialize();
 
 
-    virtual bool TransactionComplete() const = 0;
     virtual Result GetStatus() const = 0;
     virtual Result GetStatus() const = 0;
     virtual void ExecuteInteractive() = 0;
     virtual void ExecuteInteractive() = 0;
     virtual void Execute() = 0;
     virtual void Execute() = 0;
     virtual Result RequestExit() = 0;
     virtual Result RequestExit() = 0;
 
 
-    AppletDataBroker& GetBroker() {
-        return broker;
-    }
-
-    const AppletDataBroker& GetBroker() const {
-        return broker;
-    }
-
     LibraryAppletMode GetLibraryAppletMode() const {
     LibraryAppletMode GetLibraryAppletMode() const {
         return applet_mode;
         return applet_mode;
     }
     }
@@ -134,10 +66,18 @@ public:
     }
     }
 
 
 protected:
 protected:
+    std::shared_ptr<IStorage> PopInData();
+    std::shared_ptr<IStorage> PopInteractiveInData();
+    void PushOutData(std::shared_ptr<IStorage> storage);
+    void PushInteractiveOutData(std::shared_ptr<IStorage> storage);
+    void Exit();
+
+protected:
+    Core::System& system;
     CommonArguments common_args{};
     CommonArguments common_args{};
-    AppletDataBroker broker;
-    LibraryAppletMode applet_mode;
-    bool initialized = false;
+    std::weak_ptr<Applet> applet{};
+    LibraryAppletMode applet_mode{};
+    bool initialized{false};
 };
 };
 
 
 struct FrontendAppletSet {
 struct FrontendAppletSet {
@@ -191,7 +131,8 @@ public:
     void SetDefaultAppletsIfMissing();
     void SetDefaultAppletsIfMissing();
     void ClearAll();
     void ClearAll();
 
 
-    std::shared_ptr<FrontendApplet> GetApplet(AppletId id, LibraryAppletMode mode) const;
+    std::shared_ptr<FrontendApplet> GetApplet(std::shared_ptr<Applet> applet, AppletId id,
+                                              LibraryAppletMode mode) const;
 
 
 private:
 private:
     AppletId current_applet_id{};
     AppletId current_applet_id{};

+ 34 - 10
src/core/hle/service/am/library_applet_accessor.cpp

@@ -3,6 +3,7 @@
 
 
 #include "common/scope_exit.h"
 #include "common/scope_exit.h"
 #include "core/hle/service/am/am_results.h"
 #include "core/hle/service/am/am_results.h"
+#include "core/hle/service/am/applet_data_broker.h"
 #include "core/hle/service/am/frontend/applets.h"
 #include "core/hle/service/am/frontend/applets.h"
 #include "core/hle/service/am/library_applet_accessor.h"
 #include "core/hle/service/am/library_applet_accessor.h"
 #include "core/hle/service/am/storage.h"
 #include "core/hle/service/am/storage.h"
@@ -11,9 +12,9 @@
 namespace Service::AM {
 namespace Service::AM {
 
 
 ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_,
 ILibraryAppletAccessor::ILibraryAppletAccessor(Core::System& system_,
-                                               std::shared_ptr<AppletStorageHolder> storage_,
+                                               std::shared_ptr<AppletDataBroker> broker_,
                                                std::shared_ptr<Applet> applet_)
                                                std::shared_ptr<Applet> applet_)
-    : ServiceFramework{system_, "ILibraryAppletAccessor"}, storage{std::move(storage_)},
+    : ServiceFramework{system_, "ILibraryAppletAccessor"}, broker{std::move(broker_)},
       applet{std::move(applet_)} {
       applet{std::move(applet_)} {
     // clang-format off
     // clang-format off
     static const FunctionInfo functions[] = {
     static const FunctionInfo functions[] = {
@@ -49,7 +50,7 @@ void ILibraryAppletAccessor::GetAppletStateChangedEvent(HLERequestContext& ctx)
 
 
     IPC::ResponseBuilder rb{ctx, 2, 1};
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(ResultSuccess);
     rb.Push(ResultSuccess);
-    rb.PushCopyObjects(storage->state_changed_event.GetHandle());
+    rb.PushCopyObjects(broker->GetStateChangedEvent().GetHandle());
 }
 }
 
 
 void ILibraryAppletAccessor::IsCompleted(HLERequestContext& ctx) {
 void ILibraryAppletAccessor::IsCompleted(HLERequestContext& ctx) {
@@ -59,7 +60,7 @@ void ILibraryAppletAccessor::IsCompleted(HLERequestContext& ctx) {
 
 
     IPC::ResponseBuilder rb{ctx, 3};
     IPC::ResponseBuilder rb{ctx, 3};
     rb.Push(ResultSuccess);
     rb.Push(ResultSuccess);
-    rb.Push<u32>(applet->is_completed);
+    rb.Push<u32>(broker->IsCompleted());
 }
 }
 
 
 void ILibraryAppletAccessor::GetResult(HLERequestContext& ctx) {
 void ILibraryAppletAccessor::GetResult(HLERequestContext& ctx) {
@@ -80,6 +81,7 @@ void ILibraryAppletAccessor::Start(HLERequestContext& ctx) {
     LOG_DEBUG(Service_AM, "called");
     LOG_DEBUG(Service_AM, "called");
 
 
     applet->process->Run();
     applet->process->Run();
+    FrontendExecute();
 
 
     IPC::ResponseBuilder rb{ctx, 2};
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(ResultSuccess);
     rb.Push(ResultSuccess);
@@ -90,6 +92,7 @@ void ILibraryAppletAccessor::RequestExit(HLERequestContext& ctx) {
 
 
     ASSERT(applet != nullptr);
     ASSERT(applet != nullptr);
     applet->message_queue.RequestExit();
     applet->message_queue.RequestExit();
+    FrontendRequestExit();
 
 
     IPC::ResponseBuilder rb{ctx, 2};
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(ResultSuccess);
     rb.Push(ResultSuccess);
@@ -99,7 +102,7 @@ void ILibraryAppletAccessor::PushInData(HLERequestContext& ctx) {
     LOG_DEBUG(Service_AM, "called");
     LOG_DEBUG(Service_AM, "called");
 
 
     IPC::RequestParser rp{ctx};
     IPC::RequestParser rp{ctx};
-    storage->in_data.PushData(rp.PopIpcInterface<IStorage>().lock());
+    broker->GetInData().Push(rp.PopIpcInterface<IStorage>().lock());
 
 
     IPC::ResponseBuilder rb{ctx, 2};
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(ResultSuccess);
     rb.Push(ResultSuccess);
@@ -109,7 +112,7 @@ void ILibraryAppletAccessor::PopOutData(HLERequestContext& ctx) {
     LOG_DEBUG(Service_AM, "called");
     LOG_DEBUG(Service_AM, "called");
 
 
     std::shared_ptr<IStorage> data;
     std::shared_ptr<IStorage> data;
-    const auto res = storage->out_data.PopData(&data);
+    const auto res = broker->GetOutData().Pop(&data);
 
 
     if (res.IsSuccess()) {
     if (res.IsSuccess()) {
         IPC::ResponseBuilder rb{ctx, 2, 0, 1};
         IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -125,7 +128,8 @@ void ILibraryAppletAccessor::PushInteractiveInData(HLERequestContext& ctx) {
     LOG_DEBUG(Service_AM, "called");
     LOG_DEBUG(Service_AM, "called");
 
 
     IPC::RequestParser rp{ctx};
     IPC::RequestParser rp{ctx};
-    storage->interactive_in_data.PushData(rp.PopIpcInterface<IStorage>().lock());
+    broker->GetInteractiveInData().Push(rp.PopIpcInterface<IStorage>().lock());
+    FrontendExecuteInteractive();
 
 
     IPC::ResponseBuilder rb{ctx, 2};
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(ResultSuccess);
     rb.Push(ResultSuccess);
@@ -135,7 +139,7 @@ void ILibraryAppletAccessor::PopInteractiveOutData(HLERequestContext& ctx) {
     LOG_DEBUG(Service_AM, "called");
     LOG_DEBUG(Service_AM, "called");
 
 
     std::shared_ptr<IStorage> data;
     std::shared_ptr<IStorage> data;
-    const auto res = storage->interactive_out_data.PopData(&data);
+    const auto res = broker->GetInteractiveOutData().Pop(&data);
 
 
     if (res.IsSuccess()) {
     if (res.IsSuccess()) {
         IPC::ResponseBuilder rb{ctx, 2, 0, 1};
         IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -152,7 +156,7 @@ void ILibraryAppletAccessor::GetPopOutDataEvent(HLERequestContext& ctx) {
 
 
     IPC::ResponseBuilder rb{ctx, 2, 1};
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(ResultSuccess);
     rb.Push(ResultSuccess);
-    rb.PushCopyObjects(storage->out_data.GetEvent());
+    rb.PushCopyObjects(broker->GetOutData().GetEvent());
 }
 }
 
 
 void ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(HLERequestContext& ctx) {
 void ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(HLERequestContext& ctx) {
@@ -160,7 +164,7 @@ void ILibraryAppletAccessor::GetPopInteractiveOutDataEvent(HLERequestContext& ct
 
 
     IPC::ResponseBuilder rb{ctx, 2, 1};
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(ResultSuccess);
     rb.Push(ResultSuccess);
-    rb.PushCopyObjects(storage->interactive_out_data.GetEvent());
+    rb.PushCopyObjects(broker->GetInteractiveOutData().GetEvent());
 }
 }
 
 
 void ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(HLERequestContext& ctx) {
 void ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(HLERequestContext& ctx) {
@@ -175,4 +179,24 @@ void ILibraryAppletAccessor::GetIndirectLayerConsumerHandle(HLERequestContext& c
     rb.Push(handle);
     rb.Push(handle);
 }
 }
 
 
+void ILibraryAppletAccessor::FrontendExecute() {
+    if (applet->frontend) {
+        applet->frontend->Initialize();
+        applet->frontend->Execute();
+    }
+}
+
+void ILibraryAppletAccessor::FrontendExecuteInteractive() {
+    if (applet->frontend) {
+        applet->frontend->ExecuteInteractive();
+        applet->frontend->Execute();
+    }
+}
+
+void ILibraryAppletAccessor::FrontendRequestExit() {
+    if (applet->frontend) {
+        applet->frontend->RequestExit();
+    }
+}
+
 } // namespace Service::AM
 } // namespace Service::AM

+ 7 - 3
src/core/hle/service/am/library_applet_accessor.h

@@ -7,13 +7,13 @@
 
 
 namespace Service::AM {
 namespace Service::AM {
 
 
-struct AppletStorageHolder;
+class AppletDataBroker;
 struct Applet;
 struct Applet;
 
 
 class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> {
 class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> {
 public:
 public:
     explicit ILibraryAppletAccessor(Core::System& system_,
     explicit ILibraryAppletAccessor(Core::System& system_,
-                                    std::shared_ptr<AppletStorageHolder> storage_,
+                                    std::shared_ptr<AppletDataBroker> broker_,
                                     std::shared_ptr<Applet> applet_);
                                     std::shared_ptr<Applet> applet_);
     ~ILibraryAppletAccessor();
     ~ILibraryAppletAccessor();
 
 
@@ -32,7 +32,11 @@ protected:
     void GetPopInteractiveOutDataEvent(HLERequestContext& ctx);
     void GetPopInteractiveOutDataEvent(HLERequestContext& ctx);
     void GetIndirectLayerConsumerHandle(HLERequestContext& ctx);
     void GetIndirectLayerConsumerHandle(HLERequestContext& ctx);
 
 
-    const std::shared_ptr<AppletStorageHolder> storage;
+    void FrontendExecute();
+    void FrontendExecuteInteractive();
+    void FrontendRequestExit();
+
+    const std::shared_ptr<AppletDataBroker> broker;
     const std::shared_ptr<Applet> applet;
     const std::shared_ptr<Applet> applet;
 };
 };
 
 

+ 26 - 16
src/core/hle/service/am/library_applet_creator.cpp

@@ -2,6 +2,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 
 #include "core/hle/kernel/k_transfer_memory.h"
 #include "core/hle/kernel/k_transfer_memory.h"
+#include "core/hle/service/am/applet_data_broker.h"
 #include "core/hle/service/am/applet_manager.h"
 #include "core/hle/service/am/applet_manager.h"
 #include "core/hle/service/am/frontend/applets.h"
 #include "core/hle/service/am/frontend/applets.h"
 #include "core/hle/service/am/library_applet_accessor.h"
 #include "core/hle/service/am/library_applet_accessor.h"
@@ -62,10 +63,9 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) {
     }
     }
 }
 }
 
 
-std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
-                                                          std::shared_ptr<Applet> caller_applet,
-                                                          AppletId applet_id,
-                                                          LibraryAppletMode mode) {
+[[maybe_unused]] std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(
+    Core::System& system, std::shared_ptr<Applet> caller_applet, AppletId applet_id,
+    LibraryAppletMode mode) {
     const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id));
     const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id));
     if (program_id == 0) {
     if (program_id == 0) {
         // Unknown applet
         // Unknown applet
@@ -89,20 +89,33 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
     applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
     applet->message_queue.PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
     applet->focus_state = FocusState::InFocus;
     applet->focus_state = FocusState::InFocus;
 
 
-    auto storage = std::make_shared<AppletStorageHolder>(system);
+    auto broker = std::make_shared<AppletDataBroker>(system);
     applet->caller_applet = caller_applet;
     applet->caller_applet = caller_applet;
-    applet->caller_applet_storage = storage;
+    applet->caller_applet_broker = broker;
 
 
     system.GetAppletManager().InsertApplet(applet);
     system.GetAppletManager().InsertApplet(applet);
 
 
-    return std::make_shared<ILibraryAppletAccessor>(system, storage, applet);
+    return std::make_shared<ILibraryAppletAccessor>(system, broker, applet);
 }
 }
 
 
-std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system,
-                                                             AppletId applet_id,
-                                                             LibraryAppletMode mode) {
-    UNREACHABLE();
-    return {};
+[[maybe_unused]] std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(
+    Core::System& system, std::shared_ptr<Applet> caller_applet, AppletId applet_id,
+    LibraryAppletMode mode) {
+    const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id));
+
+    auto process = std::make_unique<Process>(system);
+    auto applet = std::make_shared<Applet>(system, std::move(process));
+    applet->program_id = program_id;
+    applet->applet_id = applet_id;
+    applet->type = AppletType::LibraryApplet;
+    applet->library_applet_mode = mode;
+
+    auto storage = std::make_shared<AppletDataBroker>(system);
+    applet->caller_applet = caller_applet;
+    applet->caller_applet_broker = storage;
+    applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode);
+
+    return std::make_shared<ILibraryAppletAccessor>(system, storage, applet);
 }
 }
 
 
 } // namespace
 } // namespace
@@ -131,10 +144,7 @@ void ILibraryAppletCreator::CreateLibraryApplet(HLERequestContext& ctx) {
     LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id,
     LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id,
               applet_mode);
               applet_mode);
 
 
-    auto library_applet = CreateGuestApplet(system, applet, applet_id, applet_mode);
-    if (!library_applet) {
-        library_applet = CreateFrontendApplet(system, applet_id, applet_mode);
-    }
+    auto library_applet = CreateFrontendApplet(system, applet, applet_id, applet_mode);
     if (!library_applet) {
     if (!library_applet) {
         LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
         LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
 
 

+ 9 - 13
src/core/hle/service/am/library_applet_self_accessor.cpp

@@ -5,6 +5,7 @@
 #include "core/core_timing.h"
 #include "core/core_timing.h"
 #include "core/hle/service/acc/profile_manager.h"
 #include "core/hle/service/acc/profile_manager.h"
 #include "core/hle/service/am/am_results.h"
 #include "core/hle/service/am/am_results.h"
+#include "core/hle/service/am/applet_data_broker.h"
 #include "core/hle/service/am/applet_manager.h"
 #include "core/hle/service/am/applet_manager.h"
 #include "core/hle/service/am/frontend/applet_cabinet.h"
 #include "core/hle/service/am/frontend/applet_cabinet.h"
 #include "core/hle/service/am/frontend/applet_controller.h"
 #include "core/hle/service/am/frontend/applet_controller.h"
@@ -47,7 +48,7 @@ AppletIdentityInfo GetCallerIdentity(std::shared_ptr<Applet> applet) {
 ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
 ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_,
                                                        std::shared_ptr<Applet> applet_)
                                                        std::shared_ptr<Applet> applet_)
     : ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, applet{std::move(applet_)},
     : ServiceFramework{system_, "ILibraryAppletSelfAccessor"}, applet{std::move(applet_)},
-      storage{applet->caller_applet_storage} {
+      broker{applet->caller_applet_broker} {
     // clang-format off
     // clang-format off
     static const FunctionInfo functions[] = {
     static const FunctionInfo functions[] = {
         {0, &ILibraryAppletSelfAccessor::PopInData, "PopInData"},
         {0, &ILibraryAppletSelfAccessor::PopInData, "PopInData"},
@@ -96,7 +97,7 @@ void ILibraryAppletSelfAccessor::PopInData(HLERequestContext& ctx) {
     LOG_INFO(Service_AM, "called");
     LOG_INFO(Service_AM, "called");
 
 
     std::shared_ptr<IStorage> data;
     std::shared_ptr<IStorage> data;
-    const auto res = storage->in_data.PopData(&data);
+    const auto res = broker->GetInData().Pop(&data);
 
 
     if (res.IsSuccess()) {
     if (res.IsSuccess()) {
         IPC::ResponseBuilder rb{ctx, 2, 0, 1};
         IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -112,7 +113,7 @@ void ILibraryAppletSelfAccessor::PushOutData(HLERequestContext& ctx) {
     LOG_INFO(Service_AM, "called");
     LOG_INFO(Service_AM, "called");
 
 
     IPC::RequestParser rp{ctx};
     IPC::RequestParser rp{ctx};
-    storage->out_data.PushData(rp.PopIpcInterface<IStorage>().lock());
+    broker->GetOutData().Push(rp.PopIpcInterface<IStorage>().lock());
 
 
     IPC::ResponseBuilder rb{ctx, 2};
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(ResultSuccess);
     rb.Push(ResultSuccess);
@@ -122,7 +123,7 @@ void ILibraryAppletSelfAccessor::PopInteractiveInData(HLERequestContext& ctx) {
     LOG_INFO(Service_AM, "called");
     LOG_INFO(Service_AM, "called");
 
 
     std::shared_ptr<IStorage> data;
     std::shared_ptr<IStorage> data;
-    const auto res = storage->interactive_in_data.PopData(&data);
+    const auto res = broker->GetInteractiveInData().Pop(&data);
 
 
     if (res.IsSuccess()) {
     if (res.IsSuccess()) {
         IPC::ResponseBuilder rb{ctx, 2, 0, 1};
         IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -138,7 +139,7 @@ void ILibraryAppletSelfAccessor::PushInteractiveOutData(HLERequestContext& ctx)
     LOG_INFO(Service_AM, "called");
     LOG_INFO(Service_AM, "called");
 
 
     IPC::RequestParser rp{ctx};
     IPC::RequestParser rp{ctx};
-    storage->interactive_out_data.PushData(rp.PopIpcInterface<IStorage>().lock());
+    broker->GetInteractiveOutData().Push(rp.PopIpcInterface<IStorage>().lock());
 
 
     IPC::ResponseBuilder rb{ctx, 2};
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(ResultSuccess);
     rb.Push(ResultSuccess);
@@ -149,7 +150,7 @@ void ILibraryAppletSelfAccessor::GetPopInDataEvent(HLERequestContext& ctx) {
 
 
     IPC::ResponseBuilder rb{ctx, 2, 1};
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(ResultSuccess);
     rb.Push(ResultSuccess);
-    rb.PushCopyObjects(storage->in_data.GetEvent());
+    rb.PushCopyObjects(broker->GetInData().GetEvent());
 }
 }
 
 
 void ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent(HLERequestContext& ctx) {
 void ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent(HLERequestContext& ctx) {
@@ -157,19 +158,14 @@ void ILibraryAppletSelfAccessor::GetPopInteractiveInDataEvent(HLERequestContext&
 
 
     IPC::ResponseBuilder rb{ctx, 2, 1};
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(ResultSuccess);
     rb.Push(ResultSuccess);
-    rb.PushCopyObjects(storage->interactive_in_data.GetEvent());
+    rb.PushCopyObjects(broker->GetInteractiveInData().GetEvent());
 }
 }
 
 
 void ILibraryAppletSelfAccessor::ExitProcessAndReturn(HLERequestContext& ctx) {
 void ILibraryAppletSelfAccessor::ExitProcessAndReturn(HLERequestContext& ctx) {
     LOG_INFO(Service_AM, "called");
     LOG_INFO(Service_AM, "called");
 
 
     system.GetAppletManager().TerminateAndRemoveApplet(applet->aruid);
     system.GetAppletManager().TerminateAndRemoveApplet(applet->aruid);
-
-    {
-        std::scoped_lock lk{applet->lock};
-        applet->is_completed = true;
-        storage->state_changed_event.Signal();
-    }
+    broker->SignalCompletion();
 
 
     IPC::ResponseBuilder rb{ctx, 2};
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(ResultSuccess);
     rb.Push(ResultSuccess);

+ 2 - 2
src/core/hle/service/am/library_applet_self_accessor.h

@@ -10,7 +10,7 @@
 
 
 namespace Service::AM {
 namespace Service::AM {
 
 
-struct AppletStorageHolder;
+class AppletDataBroker;
 struct Applet;
 struct Applet;
 
 
 class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> {
 class ILibraryAppletSelfAccessor final : public ServiceFramework<ILibraryAppletSelfAccessor> {
@@ -34,7 +34,7 @@ private:
     void ShouldSetGpuTimeSliceManually(HLERequestContext& ctx);
     void ShouldSetGpuTimeSliceManually(HLERequestContext& ctx);
 
 
     const std::shared_ptr<Applet> applet;
     const std::shared_ptr<Applet> applet;
-    const std::shared_ptr<AppletStorageHolder> storage;
+    const std::shared_ptr<AppletDataBroker> broker;
 };
 };
 
 
 } // namespace Service::AM
 } // namespace Service::AM

+ 1 - 1
src/core/hle/service/am/process_winding_controller.cpp

@@ -49,7 +49,7 @@ void IProcessWindingController::OpenCallingLibraryApplet(HLERequestContext& ctx)
 
 
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
     IPC::ResponseBuilder rb{ctx, 2, 0, 1};
     rb.Push(ResultSuccess);
     rb.Push(ResultSuccess);
-    rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet->caller_applet_storage,
+    rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet->caller_applet_broker,
                                                 caller_applet);
                                                 caller_applet);
 }
 }