summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/am/am.cpp92
-rw-r--r--src/core/hle/service/am/applets/applets.cpp95
-rw-r--r--src/core/hle/service/am/applets/applets.h56
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.cpp43
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.h12
5 files changed, 194 insertions, 104 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index d92a46b00..fd14af1e7 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -32,6 +32,9 @@
32 32
33namespace Service::AM { 33namespace Service::AM {
34 34
35constexpr ResultCode ERR_NO_DATA_IN_CHANNEL{ErrorModule::AM, 0x2};
36constexpr ResultCode ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 0x1F7};
37
35enum class AppletId : u32 { 38enum class AppletId : u32 {
36 SoftwareKeyboard = 0x11, 39 SoftwareKeyboard = 0x11,
37}; 40};
@@ -529,7 +532,8 @@ void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
529class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> { 532class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> {
530public: 533public:
531 explicit ILibraryAppletAccessor(std::shared_ptr<Applets::Applet> applet) 534 explicit ILibraryAppletAccessor(std::shared_ptr<Applets::Applet> applet)
532 : ServiceFramework("ILibraryAppletAccessor"), applet(std::move(applet)) { 535 : ServiceFramework("ILibraryAppletAccessor"), applet(std::move(applet)),
536 broker(std::make_shared<Applets::AppletDataBroker>()) {
533 // clang-format off 537 // clang-format off
534 static const FunctionInfo functions[] = { 538 static const FunctionInfo functions[] = {
535 {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"}, 539 {0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"},
@@ -554,34 +558,16 @@ public:
554 // clang-format on 558 // clang-format on
555 559
556 RegisterHandlers(functions); 560 RegisterHandlers(functions);
557
558 auto& kernel = Core::System::GetInstance().Kernel();
559 state_changed_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
560 "ILibraryAppletAccessor:StateChangedEvent");
561 pop_out_data_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
562 "ILibraryAppletAccessor:PopDataOutEvent");
563 pop_interactive_out_data_event =
564 Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
565 "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
566 } 561 }
567 562
568private: 563private:
569 void AppletStorageProxyOutData(IStorage storage) {
570 storage_stack.push(std::make_shared<IStorage>(storage));
571 pop_out_data_event->Signal();
572 }
573
574 void AppletStorageProxyOutInteractiveData(IStorage storage) {
575 interactive_storage_stack.push(std::make_shared<IStorage>(storage));
576 pop_interactive_out_data_event->Signal();
577 }
578
579 void GetAppletStateChangedEvent(Kernel::HLERequestContext& ctx) { 564 void GetAppletStateChangedEvent(Kernel::HLERequestContext& ctx) {
580 state_changed_event->Signal(); 565 const auto event = broker->GetStateChangedEvent();
566 event->Signal();
581 567
582 IPC::ResponseBuilder rb{ctx, 2, 1}; 568 IPC::ResponseBuilder rb{ctx, 2, 1};
583 rb.Push(RESULT_SUCCESS); 569 rb.Push(RESULT_SUCCESS);
584 rb.PushCopyObjects(state_changed_event); 570 rb.PushCopyObjects(event);
585 571
586 LOG_DEBUG(Service_AM, "called"); 572 LOG_DEBUG(Service_AM, "called");
587 } 573 }
@@ -604,14 +590,8 @@ private:
604 void Start(Kernel::HLERequestContext& ctx) { 590 void Start(Kernel::HLERequestContext& ctx) {
605 ASSERT(applet != nullptr); 591 ASSERT(applet != nullptr);
606 592
607 applet->Initialize(storage_stack); 593 applet->Initialize(broker);
608 while (!storage_stack.empty()) 594 applet->Execute();
609 storage_stack.pop();
610 while (!interactive_storage_stack.empty())
611 interactive_storage_stack.pop();
612 applet->Execute([this](IStorage storage) { AppletStorageProxyOutData(storage); },
613 [this](IStorage storage) { AppletStorageProxyOutInteractiveData(storage); },
614 [this] { state_changed_event->Signal(); });
615 595
616 IPC::ResponseBuilder rb{ctx, 2}; 596 IPC::ResponseBuilder rb{ctx, 2};
617 rb.Push(RESULT_SUCCESS); 597 rb.Push(RESULT_SUCCESS);
@@ -621,7 +601,7 @@ private:
621 601
622 void PushInData(Kernel::HLERequestContext& ctx) { 602 void PushInData(Kernel::HLERequestContext& ctx) {
623 IPC::RequestParser rp{ctx}; 603 IPC::RequestParser rp{ctx};
624 storage_stack.push(rp.PopIpcInterface<IStorage>()); 604 broker->PushNormalDataFromGame(*rp.PopIpcInterface<IStorage>());
625 605
626 IPC::ResponseBuilder rb{ctx, 2}; 606 IPC::ResponseBuilder rb{ctx, 2};
627 rb.Push(RESULT_SUCCESS); 607 rb.Push(RESULT_SUCCESS);
@@ -632,28 +612,25 @@ private:
632 void PopOutData(Kernel::HLERequestContext& ctx) { 612 void PopOutData(Kernel::HLERequestContext& ctx) {
633 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 613 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
634 614
635 if (storage_stack.empty()) { 615 const auto storage = broker->PopNormalDataToGame();
636 rb.Push(ResultCode(-1)); 616 if (storage == nullptr) {
617 rb.Push(ERR_NO_DATA_IN_CHANNEL);
637 return; 618 return;
638 } 619 }
639 620
640 rb.Push(RESULT_SUCCESS); 621 rb.Push(RESULT_SUCCESS);
641 rb.PushIpcInterface<IStorage>(std::move(storage_stack.front())); 622 rb.PushIpcInterface<IStorage>(std::move(*storage));
642
643 storage_stack.pop();
644 623
645 LOG_DEBUG(Service_AM, "called"); 624 LOG_DEBUG(Service_AM, "called");
646 } 625 }
647 626
648 void PushInteractiveInData(Kernel::HLERequestContext& ctx) { 627 void PushInteractiveInData(Kernel::HLERequestContext& ctx) {
649 IPC::RequestParser rp{ctx}; 628 IPC::RequestParser rp{ctx};
650 interactive_storage_stack.push(rp.PopIpcInterface<IStorage>()); 629 broker->PushInteractiveDataFromGame(*rp.PopIpcInterface<IStorage>());
651 630
652 ASSERT(applet->IsInitialized()); 631 ASSERT(applet->IsInitialized());
653 applet->ReceiveInteractiveData(interactive_storage_stack.back()); 632 applet->ExecuteInteractive();
654 applet->Execute([this](IStorage storage) { AppletStorageProxyOutData(storage); }, 633 applet->Execute();
655 [this](IStorage storage) { AppletStorageProxyOutInteractiveData(storage); },
656 [this] { state_changed_event->Signal(); });
657 634
658 IPC::ResponseBuilder rb{ctx, 2}; 635 IPC::ResponseBuilder rb{ctx, 2};
659 rb.Push(RESULT_SUCCESS); 636 rb.Push(RESULT_SUCCESS);
@@ -664,15 +641,14 @@ private:
664 void PopInteractiveOutData(Kernel::HLERequestContext& ctx) { 641 void PopInteractiveOutData(Kernel::HLERequestContext& ctx) {
665 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 642 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
666 643
667 if (interactive_storage_stack.empty()) { 644 const auto storage = broker->PopInteractiveDataToGame();
668 rb.Push(ResultCode(-1)); 645 if (storage == nullptr) {
646 rb.Push(ERR_NO_DATA_IN_CHANNEL);
669 return; 647 return;
670 } 648 }
671 649
672 rb.Push(RESULT_SUCCESS); 650 rb.Push(RESULT_SUCCESS);
673 rb.PushIpcInterface<IStorage>(std::move(interactive_storage_stack.front())); 651 rb.PushIpcInterface<IStorage>(std::move(*storage));
674
675 interactive_storage_stack.pop();
676 652
677 LOG_DEBUG(Service_AM, "called"); 653 LOG_DEBUG(Service_AM, "called");
678 } 654 }
@@ -680,7 +656,7 @@ private:
680 void GetPopOutDataEvent(Kernel::HLERequestContext& ctx) { 656 void GetPopOutDataEvent(Kernel::HLERequestContext& ctx) {
681 IPC::ResponseBuilder rb{ctx, 2, 1}; 657 IPC::ResponseBuilder rb{ctx, 2, 1};
682 rb.Push(RESULT_SUCCESS); 658 rb.Push(RESULT_SUCCESS);
683 rb.PushCopyObjects(pop_out_data_event); 659 rb.PushCopyObjects(broker->GetNormalDataEvent());
684 660
685 LOG_DEBUG(Service_AM, "called"); 661 LOG_DEBUG(Service_AM, "called");
686 } 662 }
@@ -688,17 +664,13 @@ private:
688 void GetPopInteractiveOutDataEvent(Kernel::HLERequestContext& ctx) { 664 void GetPopInteractiveOutDataEvent(Kernel::HLERequestContext& ctx) {
689 IPC::ResponseBuilder rb{ctx, 2, 1}; 665 IPC::ResponseBuilder rb{ctx, 2, 1};
690 rb.Push(RESULT_SUCCESS); 666 rb.Push(RESULT_SUCCESS);
691 rb.PushCopyObjects(pop_interactive_out_data_event); 667 rb.PushCopyObjects(broker->GetInteractiveDataEvent());
692 668
693 LOG_DEBUG(Service_AM, "called"); 669 LOG_DEBUG(Service_AM, "called");
694 } 670 }
695 671
696 std::shared_ptr<Applets::Applet> applet; 672 std::shared_ptr<Applets::Applet> applet;
697 std::queue<std::shared_ptr<IStorage>> storage_stack; 673 std::shared_ptr<Applets::AppletDataBroker> broker;
698 std::queue<std::shared_ptr<IStorage>> interactive_storage_stack;
699 Kernel::SharedPtr<Kernel::Event> state_changed_event;
700 Kernel::SharedPtr<Kernel::Event> pop_out_data_event;
701 Kernel::SharedPtr<Kernel::Event> pop_interactive_out_data_event;
702}; 674};
703 675
704void IStorage::Open(Kernel::HLERequestContext& ctx) { 676void IStorage::Open(Kernel::HLERequestContext& ctx) {
@@ -740,9 +712,12 @@ void IStorageAccessor::Write(Kernel::HLERequestContext& ctx) {
740 const u64 offset{rp.Pop<u64>()}; 712 const u64 offset{rp.Pop<u64>()};
741 const std::vector<u8> data{ctx.ReadBuffer()}; 713 const std::vector<u8> data{ctx.ReadBuffer()};
742 714
743 const auto size = std::min<std::size_t>(data.size(), backing.buffer.size() - offset); 715 if (data.size() > backing.buffer.size() - offset) {
716 IPC::ResponseBuilder rb{ctx, 2};
717 rb.Push(ERR_SIZE_OUT_OF_BOUNDS);
718 }
744 719
745 std::memcpy(&backing.buffer[offset], data.data(), size); 720 std::memcpy(backing.buffer.data() + offset, data.data(), data.size());
746 721
747 IPC::ResponseBuilder rb{ctx, 2}; 722 IPC::ResponseBuilder rb{ctx, 2};
748 rb.Push(RESULT_SUCCESS); 723 rb.Push(RESULT_SUCCESS);
@@ -754,9 +729,12 @@ void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) {
754 IPC::RequestParser rp{ctx}; 729 IPC::RequestParser rp{ctx};
755 730
756 const u64 offset{rp.Pop<u64>()}; 731 const u64 offset{rp.Pop<u64>()};
757 std::size_t size{ctx.GetWriteBufferSize()}; 732 const std::size_t size{ctx.GetWriteBufferSize()};
758 733
759 size = std::min<std::size_t>(size, backing.buffer.size() - offset); 734 if (size > backing.buffer.size() - offset) {
735 IPC::ResponseBuilder rb{ctx, 2};
736 rb.Push(ERR_SIZE_OUT_OF_BOUNDS);
737 }
760 738
761 ctx.WriteBuffer(backing.buffer.data() + offset, size); 739 ctx.WriteBuffer(backing.buffer.data() + offset, size);
762 740
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index be950d320..c81bd59b2 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -4,21 +4,108 @@
4 4
5#include <cstring> 5#include <cstring>
6#include "common/assert.h" 6#include "common/assert.h"
7#include "core/core.h"
7#include "core/frontend/applets/software_keyboard.h" 8#include "core/frontend/applets/software_keyboard.h"
9#include "core/hle/kernel/event.h"
10#include "core/hle/kernel/server_port.h"
8#include "core/hle/service/am/am.h" 11#include "core/hle/service/am/am.h"
9#include "core/hle/service/am/applets/applets.h" 12#include "core/hle/service/am/applets/applets.h"
10 13
11namespace Service::AM::Applets { 14namespace Service::AM::Applets {
12 15
16AppletDataBroker::AppletDataBroker() {
17 auto& kernel = Core::System::GetInstance().Kernel();
18 state_changed_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
19 "ILibraryAppletAccessor:StateChangedEvent");
20 pop_out_data_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
21 "ILibraryAppletAccessor:PopDataOutEvent");
22 pop_interactive_out_data_event = Kernel::Event::Create(
23 kernel, Kernel::ResetType::OneShot, "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
24}
25
26AppletDataBroker::~AppletDataBroker() = default;
27
28std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() {
29 if (out_channel.empty())
30 return nullptr;
31
32 auto out = std::move(out_channel.front());
33 out_channel.pop();
34 return out;
35}
36
37std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToApplet() {
38 if (in_channel.empty())
39 return nullptr;
40
41 auto out = std::move(in_channel.front());
42 in_channel.pop();
43 return out;
44}
45
46std::unique_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() {
47 if (out_interactive_channel.empty())
48 return nullptr;
49
50 auto out = std::move(out_interactive_channel.front());
51 out_interactive_channel.pop();
52 return out;
53}
54
55std::unique_ptr<IStorage> AppletDataBroker::PopInteractiveDataToApplet() {
56 if (in_interactive_channel.empty())
57 return nullptr;
58
59 auto out = std::move(in_interactive_channel.front());
60 in_interactive_channel.pop();
61 return out;
62}
63
64void AppletDataBroker::PushNormalDataFromGame(IStorage storage) {
65 in_channel.push(std::make_unique<IStorage>(storage));
66}
67
68void AppletDataBroker::PushNormalDataFromApplet(IStorage storage) {
69 out_channel.push(std::make_unique<IStorage>(storage));
70 pop_out_data_event->Signal();
71}
72
73void AppletDataBroker::PushInteractiveDataFromGame(IStorage storage) {
74 in_interactive_channel.push(std::make_unique<IStorage>(storage));
75}
76
77void AppletDataBroker::PushInteractiveDataFromApplet(IStorage storage) {
78 out_interactive_channel.push(std::make_unique<IStorage>(storage));
79 pop_interactive_out_data_event->Signal();
80}
81
82void AppletDataBroker::SignalStateChanged() const {
83 state_changed_event->Signal();
84}
85
86Kernel::SharedPtr<Kernel::Event> AppletDataBroker::GetNormalDataEvent() const {
87 return pop_out_data_event;
88}
89
90Kernel::SharedPtr<Kernel::Event> AppletDataBroker::GetInteractiveDataEvent() const {
91 return pop_interactive_out_data_event;
92}
93
94Kernel::SharedPtr<Kernel::Event> AppletDataBroker::GetStateChangedEvent() const {
95 return state_changed_event;
96}
97
13Applet::Applet() = default; 98Applet::Applet() = default;
14 99
15Applet::~Applet() = default; 100Applet::~Applet() = default;
16 101
17void Applet::Initialize(std::queue<std::shared_ptr<IStorage>> storage) { 102void Applet::Initialize(std::shared_ptr<AppletDataBroker> broker_) {
18 storage_stack = std::move(storage); 103 broker = std::move(broker_);
104
105 const auto common = broker->PopNormalDataToApplet();
106 ASSERT(common != nullptr);
19 107
20 const auto common_data = storage_stack.front()->GetData(); 108 const auto common_data = common->GetData();
21 storage_stack.pop();
22 109
23 ASSERT(common_data.size() >= sizeof(CommonArguments)); 110 ASSERT(common_data.size() >= sizeof(CommonArguments));
24 std::memcpy(&common_args, common_data.data(), sizeof(CommonArguments)); 111 std::memcpy(&common_args, common_data.data(), sizeof(CommonArguments));
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h
index a6a9bf77b..136445649 100644
--- a/src/core/hle/service/am/applets/applets.h
+++ b/src/core/hle/service/am/applets/applets.h
@@ -8,35 +8,67 @@
8#include <memory> 8#include <memory>
9#include <queue> 9#include <queue>
10#include "common/swap.h" 10#include "common/swap.h"
11#include "core/hle/kernel/event.h"
11 12
12union ResultCode; 13union ResultCode;
13 14
14namespace Frontend {
15class SoftwareKeyboardApplet;
16}
17
18namespace Service::AM { 15namespace Service::AM {
19 16
20class IStorage; 17class IStorage;
21 18
22namespace Applets { 19namespace Applets {
23 20
24using AppletStorageProxyFunction = std::function<void(IStorage)>; 21class AppletDataBroker final {
25using AppletStateProxyFunction = std::function<void()>; 22public:
23 AppletDataBroker();
24 ~AppletDataBroker();
25
26 std::unique_ptr<IStorage> PopNormalDataToGame();
27 std::unique_ptr<IStorage> PopNormalDataToApplet();
28
29 std::unique_ptr<IStorage> PopInteractiveDataToGame();
30 std::unique_ptr<IStorage> PopInteractiveDataToApplet();
31
32 void PushNormalDataFromGame(IStorage storage);
33 void PushNormalDataFromApplet(IStorage storage);
34
35 void PushInteractiveDataFromGame(IStorage storage);
36 void PushInteractiveDataFromApplet(IStorage storage);
37
38 void SignalStateChanged() const;
39
40 Kernel::SharedPtr<Kernel::Event> GetNormalDataEvent() const;
41 Kernel::SharedPtr<Kernel::Event> GetInteractiveDataEvent() const;
42 Kernel::SharedPtr<Kernel::Event> GetStateChangedEvent() const;
43
44private:
45 // Queues are named from applet's perspective
46 std::queue<std::unique_ptr<IStorage>>
47 in_channel; // PopNormalDataToApplet and PushNormalDataFromGame
48 std::queue<std::unique_ptr<IStorage>>
49 out_channel; // PopNormalDataToGame and PushNormalDataFromApplet
50 std::queue<std::unique_ptr<IStorage>>
51 in_interactive_channel; // PopInteractiveDataToApplet and PushInteractiveDataFromGame
52 std::queue<std::unique_ptr<IStorage>>
53 out_interactive_channel; // PopInteractiveDataToGame and PushInteractiveDataFromApplet
54
55 Kernel::SharedPtr<Kernel::Event> state_changed_event;
56 Kernel::SharedPtr<Kernel::Event> pop_out_data_event; // Signaled on PushNormalDataFromApplet
57 Kernel::SharedPtr<Kernel::Event>
58 pop_interactive_out_data_event; // Signaled on PushInteractiveDataFromApplet
59};
26 60
27class Applet { 61class Applet {
28public: 62public:
29 Applet(); 63 Applet();
30 virtual ~Applet(); 64 virtual ~Applet();
31 65
32 virtual void Initialize(std::queue<std::shared_ptr<IStorage>> storage); 66 virtual void Initialize(std::shared_ptr<AppletDataBroker> broker);
33 67
34 virtual bool TransactionComplete() const = 0; 68 virtual bool TransactionComplete() const = 0;
35 virtual ResultCode GetStatus() const = 0; 69 virtual ResultCode GetStatus() const = 0;
36 virtual void ReceiveInteractiveData(std::shared_ptr<IStorage> storage) = 0; 70 virtual void ExecuteInteractive() = 0;
37 virtual void Execute(AppletStorageProxyFunction out_data, 71 virtual void Execute() = 0;
38 AppletStorageProxyFunction out_interactive_data,
39 AppletStateProxyFunction state) = 0;
40 72
41 bool IsInitialized() const { 73 bool IsInitialized() const {
42 return initialized; 74 return initialized;
@@ -54,7 +86,7 @@ protected:
54 static_assert(sizeof(CommonArguments) == 0x20, "CommonArguments has incorrect size."); 86 static_assert(sizeof(CommonArguments) == 0x20, "CommonArguments has incorrect size.");
55 87
56 CommonArguments common_args; 88 CommonArguments common_args;
57 std::queue<std::shared_ptr<IStorage>> storage_stack; 89 std::shared_ptr<AppletDataBroker> broker;
58 bool initialized = false; 90 bool initialized = false;
59}; 91};
60 92
diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp
index 816b5fb5f..ca9ef7e7d 100644
--- a/src/core/hle/service/am/applets/software_keyboard.cpp
+++ b/src/core/hle/service/am/applets/software_keyboard.cpp
@@ -42,22 +42,23 @@ SoftwareKeyboard::SoftwareKeyboard() = default;
42 42
43SoftwareKeyboard::~SoftwareKeyboard() = default; 43SoftwareKeyboard::~SoftwareKeyboard() = default;
44 44
45void SoftwareKeyboard::Initialize(std::queue<std::shared_ptr<IStorage>> storage_) { 45void SoftwareKeyboard::Initialize(std::shared_ptr<AppletDataBroker> broker_) {
46 complete = false; 46 complete = false;
47 initial_text.clear(); 47 initial_text.clear();
48 final_data.clear(); 48 final_data.clear();
49 49
50 Applet::Initialize(std::move(storage_)); 50 Applet::Initialize(std::move(broker_));
51 51
52 ASSERT(storage_stack.size() >= 2); 52 const auto keyboard_config_storage = broker->PopNormalDataToApplet();
53 const auto& keyboard_config = storage_stack.front()->GetData(); 53 ASSERT(keyboard_config_storage != nullptr);
54 storage_stack.pop(); 54 const auto& keyboard_config = keyboard_config_storage->GetData();
55 55
56 ASSERT(keyboard_config.size() >= sizeof(KeyboardConfig)); 56 ASSERT(keyboard_config.size() >= sizeof(KeyboardConfig));
57 std::memcpy(&config, keyboard_config.data(), sizeof(KeyboardConfig)); 57 std::memcpy(&config, keyboard_config.data(), sizeof(KeyboardConfig));
58 58
59 const auto& work_buffer = storage_stack.front()->GetData(); 59 const auto work_buffer_storage = broker->PopNormalDataToApplet();
60 storage_stack.pop(); 60 ASSERT(work_buffer_storage != nullptr);
61 const auto& work_buffer = work_buffer_storage->GetData();
61 62
62 if (config.initial_string_size == 0) 63 if (config.initial_string_size == 0)
63 return; 64 return;
@@ -76,10 +77,12 @@ ResultCode SoftwareKeyboard::GetStatus() const {
76 return status; 77 return status;
77} 78}
78 79
79void SoftwareKeyboard::ReceiveInteractiveData(std::shared_ptr<IStorage> storage) { 80void SoftwareKeyboard::ExecuteInteractive() {
80 if (complete) 81 if (complete)
81 return; 82 return;
82 83
84 const auto storage = broker->PopInteractiveDataToApplet();
85 ASSERT(storage != nullptr);
83 const auto data = storage->GetData(); 86 const auto data = storage->GetData();
84 const auto status = static_cast<bool>(data[0]); 87 const auto status = static_cast<bool>(data[0]);
85 88
@@ -91,15 +94,14 @@ void SoftwareKeyboard::ReceiveInteractiveData(std::shared_ptr<IStorage> storage)
91 std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string; 94 std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string;
92 std::memcpy(string.data(), data.data() + 4, string.size() * 2); 95 std::memcpy(string.data(), data.data() + 4, string.size() * 2);
93 frontend.SendTextCheckDialog( 96 frontend.SendTextCheckDialog(
94 Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size()), state); 97 Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size()),
98 [this] { broker->SignalStateChanged(); });
95 } 99 }
96} 100}
97 101
98void SoftwareKeyboard::Execute(AppletStorageProxyFunction out_data, 102void SoftwareKeyboard::Execute() {
99 AppletStorageProxyFunction out_interactive_data,
100 AppletStateProxyFunction state) {
101 if (complete) { 103 if (complete) {
102 out_data(IStorage{final_data}); 104 broker->PushNormalDataFromApplet(IStorage{final_data});
103 return; 105 return;
104 } 106 }
105 107
@@ -107,9 +109,6 @@ void SoftwareKeyboard::Execute(AppletStorageProxyFunction out_data,
107 109
108 const auto parameters = ConvertToFrontendParameters(config, initial_text); 110 const auto parameters = ConvertToFrontendParameters(config, initial_text);
109 111
110 this->out_data = out_data;
111 this->out_interactive_data = out_interactive_data;
112 this->state = state;
113 frontend.RequestText([this](std::optional<std::u16string> text) { WriteText(text); }, 112 frontend.RequestText([this](std::optional<std::u16string> text) { WriteText(text); },
114 parameters); 113 parameters);
115} 114}
@@ -147,19 +146,19 @@ void SoftwareKeyboard::WriteText(std::optional<std::u16string> text) {
147 final_data = output_main; 146 final_data = output_main;
148 147
149 if (complete) { 148 if (complete) {
150 out_data(IStorage{output_main}); 149 broker->PushNormalDataFromApplet(IStorage{output_main});
151 } else { 150 } else {
152 out_data(IStorage{output_main}); 151 broker->PushNormalDataFromApplet(IStorage{output_main});
153 out_interactive_data(IStorage{output_sub}); 152 broker->PushInteractiveDataFromApplet(IStorage{output_sub});
154 } 153 }
155 154
156 state(); 155 broker->SignalStateChanged();
157 } else { 156 } else {
158 status = ResultCode(-1); 157 status = ResultCode(-1);
159 output_main[0] = 1; 158 output_main[0] = 1;
160 complete = true; 159 complete = true;
161 out_data(IStorage{output_main}); 160 broker->PushNormalDataFromApplet(IStorage{output_main});
162 state(); 161 broker->SignalStateChanged();
163 } 162 }
164} 163}
165} // namespace Service::AM::Applets 164} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/software_keyboard.h b/src/core/hle/service/am/applets/software_keyboard.h
index e0a9479c2..405c58851 100644
--- a/src/core/hle/service/am/applets/software_keyboard.h
+++ b/src/core/hle/service/am/applets/software_keyboard.h
@@ -50,14 +50,12 @@ public:
50 SoftwareKeyboard(); 50 SoftwareKeyboard();
51 ~SoftwareKeyboard() override; 51 ~SoftwareKeyboard() override;
52 52
53 void Initialize(std::queue<std::shared_ptr<IStorage>> storage) override; 53 void Initialize(std::shared_ptr<AppletDataBroker> broker) override;
54 54
55 bool TransactionComplete() const override; 55 bool TransactionComplete() const override;
56 ResultCode GetStatus() const override; 56 ResultCode GetStatus() const override;
57 void ReceiveInteractiveData(std::shared_ptr<IStorage> storage) override; 57 void ExecuteInteractive() override;
58 void Execute(AppletStorageProxyFunction out_data, 58 void Execute() override;
59 AppletStorageProxyFunction out_interactive_data,
60 AppletStateProxyFunction state) override;
61 59
62 void WriteText(std::optional<std::u16string> text); 60 void WriteText(std::optional<std::u16string> text);
63 61
@@ -67,10 +65,6 @@ private:
67 bool complete = false; 65 bool complete = false;
68 std::vector<u8> final_data; 66 std::vector<u8> final_data;
69 ResultCode status = ResultCode(-1); 67 ResultCode status = ResultCode(-1);
70
71 AppletStorageProxyFunction out_data;
72 AppletStorageProxyFunction out_interactive_data;
73 AppletStateProxyFunction state;
74}; 68};
75 69
76} // namespace Service::AM::Applets 70} // namespace Service::AM::Applets