From dfb9fa0144ca79e596f6f2b1bc960b1a44745aa6 Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 31 Dec 2023 09:40:32 -0500 Subject: am: re-namespace frontend applets to frontend directory --- src/core/hle/service/am/frontend/applets.cpp | 341 +++++++++++++++++++++++++++ 1 file changed, 341 insertions(+) create mode 100644 src/core/hle/service/am/frontend/applets.cpp (limited to 'src/core/hle/service/am/frontend/applets.cpp') diff --git a/src/core/hle/service/am/frontend/applets.cpp b/src/core/hle/service/am/frontend/applets.cpp new file mode 100644 index 000000000..4e8f806d7 --- /dev/null +++ b/src/core/hle/service/am/frontend/applets.cpp @@ -0,0 +1,341 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include "common/assert.h" +#include "core/core.h" +#include "core/frontend/applets/cabinet.h" +#include "core/frontend/applets/controller.h" +#include "core/frontend/applets/error.h" +#include "core/frontend/applets/general.h" +#include "core/frontend/applets/mii_edit.h" +#include "core/frontend/applets/profile_select.h" +#include "core/frontend/applets/software_keyboard.h" +#include "core/frontend/applets/web_browser.h" +#include "core/hle/kernel/k_event.h" +#include "core/hle/service/am/am.h" +#include "core/hle/service/am/applet_ae.h" +#include "core/hle/service/am/applet_message_queue.h" +#include "core/hle/service/am/applet_oe.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_error.h" +#include "core/hle/service/am/frontend/applet_general.h" +#include "core/hle/service/am/frontend/applet_mii_edit.h" +#include "core/hle/service/am/frontend/applet_profile_select.h" +#include "core/hle/service/am/frontend/applet_software_keyboard.h" +#include "core/hle/service/am/frontend/applet_web_browser.h" +#include "core/hle/service/am/frontend/applets.h" +#include "core/hle/service/am/storage.h" +#include "core/hle/service/sm/sm.h" + +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> out_normal; + + for (const auto& storage : in_channel) { + out_normal.push_back(storage->GetData()); + } + + std::vector> out_interactive; + + 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 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 AppletDataBroker::PopNormalDataToApplet() { + if (in_channel.empty()) + return nullptr; + + auto out = std::move(in_channel.front()); + in_channel.pop_front(); + return out; +} + +std::shared_ptr 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 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&& storage) { + in_channel.emplace_back(std::move(storage)); +} + +void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr&& storage) { + out_channel.emplace_back(std::move(storage)); + pop_out_data_event->Signal(); +} + +void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr&& storage) { + in_interactive_channel.emplace_back(std::move(storage)); +} + +void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr&& storage) { + out_interactive_channel.emplace_back(std::move(storage)); + pop_interactive_out_data_event->Signal(); +} + +void AppletDataBroker::SignalStateChanged() { + state_changed_event->Signal(); + + switch (applet_mode) { + case LibraryAppletMode::AllForeground: + case LibraryAppletMode::AllForegroundInitiallyHidden: { + auto applet_oe = system.ServiceManager().GetService("appletOE"); + auto applet_ae = system.ServiceManager().GetService("appletAE"); + + if (applet_oe) { + applet_oe->GetMessageQueue()->FocusStateChanged(); + break; + } + + if (applet_ae) { + applet_ae->GetMessageQueue()->FocusStateChanged(); + break; + } + break; + } + default: + break; + } +} + +Kernel::KReadableEvent& AppletDataBroker::GetNormalDataEvent() { + return pop_out_data_event->GetReadableEvent(); +} + +Kernel::KReadableEvent& AppletDataBroker::GetInteractiveDataEvent() { + return pop_interactive_out_data_event->GetReadableEvent(); +} + +Kernel::KReadableEvent& AppletDataBroker::GetStateChangedEvent() { + return state_changed_event->GetReadableEvent(); +} + +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; +} + +FrontendAppletSet::FrontendAppletSet() = default; + +FrontendAppletSet::FrontendAppletSet(CabinetApplet cabinet_applet, + ControllerApplet controller_applet, ErrorApplet error_applet, + MiiEdit mii_edit_, + ParentalControlsApplet parental_controls_applet, + PhotoViewer photo_viewer_, ProfileSelect profile_select_, + SoftwareKeyboard software_keyboard_, WebBrowser web_browser_) + : cabinet{std::move(cabinet_applet)}, controller{std::move(controller_applet)}, + error{std::move(error_applet)}, mii_edit{std::move(mii_edit_)}, + parental_controls{std::move(parental_controls_applet)}, + photo_viewer{std::move(photo_viewer_)}, profile_select{std::move(profile_select_)}, + software_keyboard{std::move(software_keyboard_)}, web_browser{std::move(web_browser_)} {} + +FrontendAppletSet::~FrontendAppletSet() = default; + +FrontendAppletSet::FrontendAppletSet(FrontendAppletSet&&) noexcept = default; + +FrontendAppletSet& FrontendAppletSet::operator=(FrontendAppletSet&&) noexcept = default; + +FrontendAppletHolder::FrontendAppletHolder(Core::System& system_) : system{system_} {} + +FrontendAppletHolder::~FrontendAppletHolder() = default; + +const FrontendAppletSet& FrontendAppletHolder::GetFrontendAppletSet() const { + return frontend; +} + +NFP::CabinetMode FrontendAppletHolder::GetCabinetMode() const { + return cabinet_mode; +} + +AppletId FrontendAppletHolder::GetCurrentAppletId() const { + return current_applet_id; +} + +void FrontendAppletHolder::SetFrontendAppletSet(FrontendAppletSet set) { + if (set.cabinet != nullptr) { + frontend.cabinet = std::move(set.cabinet); + } + + if (set.controller != nullptr) { + frontend.controller = std::move(set.controller); + } + + if (set.error != nullptr) { + frontend.error = std::move(set.error); + } + + if (set.mii_edit != nullptr) { + frontend.mii_edit = std::move(set.mii_edit); + } + + if (set.parental_controls != nullptr) { + frontend.parental_controls = std::move(set.parental_controls); + } + + if (set.photo_viewer != nullptr) { + frontend.photo_viewer = std::move(set.photo_viewer); + } + + if (set.profile_select != nullptr) { + frontend.profile_select = std::move(set.profile_select); + } + + if (set.software_keyboard != nullptr) { + frontend.software_keyboard = std::move(set.software_keyboard); + } + + if (set.web_browser != nullptr) { + frontend.web_browser = std::move(set.web_browser); + } +} + +void FrontendAppletHolder::SetCabinetMode(NFP::CabinetMode mode) { + cabinet_mode = mode; +} + +void FrontendAppletHolder::SetCurrentAppletId(AppletId applet_id) { + current_applet_id = applet_id; +} + +void FrontendAppletHolder::SetDefaultAppletFrontendSet() { + ClearAll(); + SetDefaultAppletsIfMissing(); +} + +void FrontendAppletHolder::SetDefaultAppletsIfMissing() { + if (frontend.cabinet == nullptr) { + frontend.cabinet = std::make_unique(); + } + + if (frontend.controller == nullptr) { + frontend.controller = + std::make_unique(system.HIDCore()); + } + + if (frontend.error == nullptr) { + frontend.error = std::make_unique(); + } + + if (frontend.mii_edit == nullptr) { + frontend.mii_edit = std::make_unique(); + } + + if (frontend.parental_controls == nullptr) { + frontend.parental_controls = + std::make_unique(); + } + + if (frontend.photo_viewer == nullptr) { + frontend.photo_viewer = std::make_unique(); + } + + if (frontend.profile_select == nullptr) { + frontend.profile_select = std::make_unique(); + } + + if (frontend.software_keyboard == nullptr) { + frontend.software_keyboard = + std::make_unique(); + } + + if (frontend.web_browser == nullptr) { + frontend.web_browser = std::make_unique(); + } +} + +void FrontendAppletHolder::ClearAll() { + frontend = {}; +} + +std::shared_ptr FrontendAppletHolder::GetApplet(AppletId id, + LibraryAppletMode mode) const { + switch (id) { + case AppletId::Auth: + return std::make_shared(system, mode, *frontend.parental_controls); + case AppletId::Cabinet: + return std::make_shared(system, mode, *frontend.cabinet); + case AppletId::Controller: + return std::make_shared(system, mode, *frontend.controller); + case AppletId::Error: + return std::make_shared(system, mode, *frontend.error); + case AppletId::ProfileSelect: + return std::make_shared(system, mode, *frontend.profile_select); + case AppletId::SoftwareKeyboard: + return std::make_shared(system, mode, *frontend.software_keyboard); + case AppletId::MiiEdit: + return std::make_shared(system, mode, *frontend.mii_edit); + case AppletId::Web: + case AppletId::Shop: + case AppletId::OfflineWeb: + case AppletId::LoginShare: + case AppletId::WebAuth: + return std::make_shared(system, mode, *frontend.web_browser); + case AppletId::PhotoViewer: + return std::make_shared(system, mode, *frontend.photo_viewer); + default: + UNIMPLEMENTED_MSG( + "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.", + static_cast(id)); + return std::make_shared(system, id, mode); + } +} + +} // namespace Service::AM::Frontend -- cgit v1.2.3 From 182137a9a4b09c8188d2cbffa312550c5dc83641 Mon Sep 17 00:00:00 2001 From: Liam Date: Tue, 2 Jan 2024 18:29:03 -0500 Subject: am: migrate global state to per-applet state structure --- src/core/hle/service/am/frontend/applets.cpp | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) (limited to 'src/core/hle/service/am/frontend/applets.cpp') diff --git a/src/core/hle/service/am/frontend/applets.cpp b/src/core/hle/service/am/frontend/applets.cpp index 4e8f806d7..38495ee19 100644 --- a/src/core/hle/service/am/frontend/applets.cpp +++ b/src/core/hle/service/am/frontend/applets.cpp @@ -16,6 +16,7 @@ #include "core/hle/kernel/k_event.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applet_ae.h" +#include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/applet_message_queue.h" #include "core/hle/service/am/applet_oe.h" #include "core/hle/service/am/frontend/applet_cabinet.h" @@ -122,21 +123,11 @@ void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr&& void AppletDataBroker::SignalStateChanged() { state_changed_event->Signal(); + // TODO proper window management switch (applet_mode) { case LibraryAppletMode::AllForeground: case LibraryAppletMode::AllForegroundInitiallyHidden: { - auto applet_oe = system.ServiceManager().GetService("appletOE"); - auto applet_ae = system.ServiceManager().GetService("appletAE"); - - if (applet_oe) { - applet_oe->GetMessageQueue()->FocusStateChanged(); - break; - } - - if (applet_ae) { - applet_ae->GetMessageQueue()->FocusStateChanged(); - break; - } + system.GetAppletManager().FocusStateChanged(); break; } default: @@ -255,11 +246,6 @@ void FrontendAppletHolder::SetCurrentAppletId(AppletId applet_id) { current_applet_id = applet_id; } -void FrontendAppletHolder::SetDefaultAppletFrontendSet() { - ClearAll(); - SetDefaultAppletsIfMissing(); -} - void FrontendAppletHolder::SetDefaultAppletsIfMissing() { if (frontend.cabinet == nullptr) { frontend.cabinet = std::make_unique(); -- cgit v1.2.3 From 8a146469c0639ff402e77da8843072ce1f2bce0c Mon Sep 17 00:00:00 2001 From: Liam Date: Wed, 3 Jan 2024 01:16:27 -0500 Subject: am: return AppletDataBroker and use for frontend applets --- src/core/hle/service/am/frontend/applets.cpp | 165 +++++++-------------------- 1 file changed, 39 insertions(+), 126 deletions(-) (limited to 'src/core/hle/service/am/frontend/applets.cpp') diff --git a/src/core/hle/service/am/frontend/applets.cpp b/src/core/hle/service/am/frontend/applets.cpp index 38495ee19..db2b04575 100644 --- a/src/core/hle/service/am/frontend/applets.cpp +++ b/src/core/hle/service/am/frontend/applets.cpp @@ -16,6 +16,7 @@ #include "core/hle/kernel/k_event.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applet_ae.h" +#include "core/hle/service/am/applet_data_broker.h" #include "core/hle/service/am/applet_manager.h" #include "core/hle/service/am/applet_message_queue.h" #include "core/hle/service/am/applet_oe.h" @@ -33,135 +34,45 @@ namespace Service::AM::Frontend { -AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_) - : system{system_}, applet_mode{applet_mode_}, - service_context{system, "ILibraryAppletAccessor"} { - state_changed_event = service_context.CreateEvent("ILibraryAppletAccessor:StateChangedEvent"); - pop_out_data_event = service_context.CreateEvent("ILibraryAppletAccessor:PopDataOutEvent"); - pop_interactive_out_data_event = - service_context.CreateEvent("ILibraryAppletAccessor:PopInteractiveDataOutEvent"); -} - -AppletDataBroker::~AppletDataBroker() { - service_context.CloseEvent(state_changed_event); - service_context.CloseEvent(pop_out_data_event); - service_context.CloseEvent(pop_interactive_out_data_event); -} - -AppletDataBroker::RawChannelData AppletDataBroker::PeekDataToAppletForDebug() const { - std::vector> out_normal; - - for (const auto& storage : in_channel) { - out_normal.push_back(storage->GetData()); - } - - std::vector> out_interactive; +FrontendApplet::FrontendApplet(Core::System& system_, std::shared_ptr 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 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 AppletDataBroker::PopNormalDataToApplet() { - if (in_channel.empty()) - return nullptr; - - auto out = std::move(in_channel.front()); - in_channel.pop_front(); - return out; -} - -std::shared_ptr 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 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&& storage) { - in_channel.emplace_back(std::move(storage)); -} +FrontendApplet::~FrontendApplet() = default; -void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr&& storage) { - out_channel.emplace_back(std::move(storage)); - pop_out_data_event->Signal(); -} +void FrontendApplet::Initialize() { + std::shared_ptr common = PopInData(); + ASSERT(common != nullptr); + const auto common_data = common->GetData(); -void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr&& 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&& 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 FrontendApplet::PopInData() { + std::shared_ptr ret; + applet.lock()->caller_applet_broker->GetInData().Pop(&ret); + return ret; } -Kernel::KReadableEvent& AppletDataBroker::GetNormalDataEvent() { - return pop_out_data_event->GetReadableEvent(); +std::shared_ptr FrontendApplet::PopInteractiveInData() { + std::shared_ptr 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 storage) { + applet.lock()->caller_applet_broker->GetOutData().Push(storage); } -Kernel::KReadableEvent& AppletDataBroker::GetStateChangedEvent() { - return state_changed_event->GetReadableEvent(); +void FrontendApplet::PushInteractiveOutData(std::shared_ptr storage) { + applet.lock()->caller_applet_broker->GetInteractiveOutData().Push(storage); } -FrontendApplet::FrontendApplet(Core::System& system_, LibraryAppletMode applet_mode_) - : broker{system_, applet_mode_}, applet_mode{applet_mode_} {} - -FrontendApplet::~FrontendApplet() = default; - -void FrontendApplet::Initialize() { - const auto common = broker.PopNormalDataToApplet(); - ASSERT(common != nullptr); - - const auto common_data = common->GetData(); - - ASSERT(common_data.size() >= sizeof(CommonArguments)); - std::memcpy(&common_args, common_data.data(), sizeof(CommonArguments)); - - initialized = true; +void FrontendApplet::Exit() { + applet.lock()->caller_applet_broker->SignalCompletion(); } FrontendAppletSet::FrontendAppletSet() = default; @@ -291,36 +202,38 @@ void FrontendAppletHolder::ClearAll() { frontend = {}; } -std::shared_ptr FrontendAppletHolder::GetApplet(AppletId id, +std::shared_ptr FrontendAppletHolder::GetApplet(std::shared_ptr applet, + AppletId id, LibraryAppletMode mode) const { switch (id) { case AppletId::Auth: - return std::make_shared(system, mode, *frontend.parental_controls); + return std::make_shared(system, applet, mode, *frontend.parental_controls); case AppletId::Cabinet: - return std::make_shared(system, mode, *frontend.cabinet); + return std::make_shared(system, applet, mode, *frontend.cabinet); case AppletId::Controller: - return std::make_shared(system, mode, *frontend.controller); + return std::make_shared(system, applet, mode, *frontend.controller); case AppletId::Error: - return std::make_shared(system, mode, *frontend.error); + return std::make_shared(system, applet, mode, *frontend.error); case AppletId::ProfileSelect: - return std::make_shared(system, mode, *frontend.profile_select); + return std::make_shared(system, applet, mode, *frontend.profile_select); case AppletId::SoftwareKeyboard: - return std::make_shared(system, mode, *frontend.software_keyboard); + return std::make_shared(system, applet, mode, + *frontend.software_keyboard); case AppletId::MiiEdit: - return std::make_shared(system, mode, *frontend.mii_edit); + return std::make_shared(system, applet, mode, *frontend.mii_edit); case AppletId::Web: case AppletId::Shop: case AppletId::OfflineWeb: case AppletId::LoginShare: case AppletId::WebAuth: - return std::make_shared(system, mode, *frontend.web_browser); + return std::make_shared(system, applet, mode, *frontend.web_browser); case AppletId::PhotoViewer: - return std::make_shared(system, mode, *frontend.photo_viewer); + return std::make_shared(system, applet, mode, *frontend.photo_viewer); default: UNIMPLEMENTED_MSG( "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.", static_cast(id)); - return std::make_shared(system, id, mode); + return std::make_shared(system, applet, id, mode); } } -- cgit v1.2.3