From 51ca93981de55ebb813981c24a8ba20fcf2b75d9 Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Sat, 17 Apr 2021 09:19:02 -0400 Subject: [PATCH] applets: Send focus state change message on applet state change Fixes the softlock after the controller applet exits in Mario Kart 8 Deluxe. --- src/core/hle/service/am/am.cpp | 12 ++++-- src/core/hle/service/am/am.h | 3 +- src/core/hle/service/am/applets/applets.cpp | 40 +++++++++++++++---- src/core/hle/service/am/applets/applets.h | 7 +++- .../hle/service/am/applets/controller.cpp | 2 +- src/core/hle/service/am/applets/error.cpp | 2 +- .../service/am/applets/general_backend.cpp | 6 +-- .../hle/service/am/applets/profile_select.cpp | 2 +- .../service/am/applets/software_keyboard.cpp | 2 +- .../hle/service/am/applets/web_browser.cpp | 2 +- 10 files changed, 56 insertions(+), 22 deletions(-) diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index c59054468f..4c8216b473 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -619,16 +619,20 @@ std::size_t AppletMessageQueue::GetMessageCount() const { return messages.size(); } +void AppletMessageQueue::RequestExit() { + PushMessage(AppletMessage::ExitRequested); +} + +void AppletMessageQueue::FocusStateChanged() { + PushMessage(AppletMessage::FocusStateChanged); +} + void AppletMessageQueue::OperationModeChanged() { PushMessage(AppletMessage::OperationModeChanged); PushMessage(AppletMessage::PerformanceModeChanged); on_operation_mode_changed->GetWritableEvent()->Signal(); } -void AppletMessageQueue::RequestExit() { - PushMessage(AppletMessage::ExitRequested); -} - ICommonStateGetter::ICommonStateGetter(Core::System& system_, std::shared_ptr msg_queue_) : ServiceFramework{system_, "ICommonStateGetter"}, msg_queue{std::move(msg_queue_)} { diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index aefbdf0d55..756434716e 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -61,8 +61,9 @@ public: void PushMessage(AppletMessage msg); AppletMessage PopMessage(); std::size_t GetMessageCount() const; - void OperationModeChanged(); void RequestExit(); + void FocusStateChanged(); + void OperationModeChanged(); private: std::queue messages; diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index 6a15947cf7..a56df6a7e2 100644 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp @@ -17,6 +17,8 @@ #include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/server_session.h" #include "core/hle/service/am/am.h" +#include "core/hle/service/am/applet_ae.h" +#include "core/hle/service/am/applet_oe.h" #include "core/hle/service/am/applets/applets.h" #include "core/hle/service/am/applets/controller.h" #include "core/hle/service/am/applets/error.h" @@ -24,17 +26,20 @@ #include "core/hle/service/am/applets/profile_select.h" #include "core/hle/service/am/applets/software_keyboard.h" #include "core/hle/service/am/applets/web_browser.h" +#include "core/hle/service/sm/sm.h" namespace Service::AM::Applets { -AppletDataBroker::AppletDataBroker(Kernel::KernelCore& kernel) { +AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_) + : system{system_}, applet_mode{applet_mode_} { state_changed_event = - Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:StateChangedEvent"); + Kernel::KEvent::Create(system.Kernel(), "ILibraryAppletAccessor:StateChangedEvent"); state_changed_event->Initialize(); - pop_out_data_event = Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:PopDataOutEvent"); + pop_out_data_event = + Kernel::KEvent::Create(system.Kernel(), "ILibraryAppletAccessor:PopDataOutEvent"); pop_out_data_event->Initialize(); - pop_interactive_out_data_event = - Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:PopInteractiveDataOutEvent"); + pop_interactive_out_data_event = Kernel::KEvent::Create( + system.Kernel(), "ILibraryAppletAccessor:PopInteractiveDataOutEvent"); pop_interactive_out_data_event->Initialize(); } @@ -114,6 +119,27 @@ void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr&& void AppletDataBroker::SignalStateChanged() const { state_changed_event->GetWritableEvent()->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; + } } std::shared_ptr AppletDataBroker::GetNormalDataEvent() const { @@ -128,8 +154,8 @@ std::shared_ptr AppletDataBroker::GetStateChangedEvent() return state_changed_event->GetReadableEvent(); } -Applet::Applet(Kernel::KernelCore& kernel_, LibraryAppletMode applet_mode_) - : broker{kernel_}, applet_mode{applet_mode_} {} +Applet::Applet(Core::System& system_, LibraryAppletMode applet_mode_) + : broker{system_, applet_mode_}, applet_mode{applet_mode_} {} Applet::~Applet() = default; diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index 49a561813a..4215d22325 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h @@ -72,7 +72,7 @@ enum class LibraryAppletMode : u32 { class AppletDataBroker final { public: - explicit AppletDataBroker(Kernel::KernelCore& kernel_); + explicit AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_); ~AppletDataBroker(); struct RawChannelData { @@ -102,6 +102,9 @@ public: std::shared_ptr GetStateChangedEvent() const; private: + Core::System& system; + LibraryAppletMode applet_mode; + // Queues are named from applet's perspective // PopNormalDataToApplet and PushNormalDataFromGame @@ -127,7 +130,7 @@ private: class Applet { public: - explicit Applet(Kernel::KernelCore& kernel_, LibraryAppletMode applet_mode_); + explicit Applet(Core::System& system_, LibraryAppletMode applet_mode_); virtual ~Applet(); virtual void Initialize(); diff --git a/src/core/hle/service/am/applets/controller.cpp b/src/core/hle/service/am/applets/controller.cpp index baaac64462..218c8d1e41 100644 --- a/src/core/hle/service/am/applets/controller.cpp +++ b/src/core/hle/service/am/applets/controller.cpp @@ -47,7 +47,7 @@ static Core::Frontend::ControllerParameters ConvertToFrontendParameters( Controller::Controller(Core::System& system_, LibraryAppletMode applet_mode_, const Core::Frontend::ControllerApplet& frontend_) - : Applet{system_.Kernel(), applet_mode_}, frontend{frontend_}, system{system_} {} + : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} Controller::~Controller() = default; diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp index 28d7f8e241..23e30aa45f 100644 --- a/src/core/hle/service/am/applets/error.cpp +++ b/src/core/hle/service/am/applets/error.cpp @@ -88,7 +88,7 @@ ResultCode Decode64BitError(u64 error) { Error::Error(Core::System& system_, LibraryAppletMode applet_mode_, const Core::Frontend::ErrorApplet& frontend_) - : Applet{system_.Kernel(), applet_mode_}, frontend{frontend_}, system{system_} {} + : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} Error::~Error() = default; diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/general_backend.cpp index 6a37c9e141..b26abad367 100644 --- a/src/core/hle/service/am/applets/general_backend.cpp +++ b/src/core/hle/service/am/applets/general_backend.cpp @@ -39,7 +39,7 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) Auth::Auth(Core::System& system_, LibraryAppletMode applet_mode_, Core::Frontend::ParentalControlsApplet& frontend_) - : Applet{system_.Kernel(), applet_mode_}, frontend{frontend_}, system{system_} {} + : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} Auth::~Auth() = default; @@ -155,7 +155,7 @@ void Auth::AuthFinished(bool is_successful) { PhotoViewer::PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_, const Core::Frontend::PhotoViewerApplet& frontend_) - : Applet{system_.Kernel(), applet_mode_}, frontend{frontend_}, system{system_} {} + : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} PhotoViewer::~PhotoViewer() = default; @@ -205,7 +205,7 @@ void PhotoViewer::ViewFinished() { } StubApplet::StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_) - : Applet{system_.Kernel(), applet_mode_}, id{id_}, system{system_} {} + : Applet{system_, applet_mode_}, id{id_}, system{system_} {} StubApplet::~StubApplet() = default; diff --git a/src/core/hle/service/am/applets/profile_select.cpp b/src/core/hle/service/am/applets/profile_select.cpp index b691406b42..c91a9776a3 100644 --- a/src/core/hle/service/am/applets/profile_select.cpp +++ b/src/core/hle/service/am/applets/profile_select.cpp @@ -17,7 +17,7 @@ constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1}; ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_, const Core::Frontend::ProfileSelectApplet& frontend_) - : Applet{system_.Kernel(), applet_mode_}, frontend{frontend_}, system{system_} {} + : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} ProfileSelect::~ProfileSelect() = default; diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp index ed5f8162d8..73a06def15 100644 --- a/src/core/hle/service/am/applets/software_keyboard.cpp +++ b/src/core/hle/service/am/applets/software_keyboard.cpp @@ -44,7 +44,7 @@ void SetReplyBase(std::vector& reply, SwkbdState state, SwkbdReplyType reply SoftwareKeyboard::SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_, Core::Frontend::SoftwareKeyboardApplet& frontend_) - : Applet{system_.Kernel(), applet_mode_}, frontend{frontend_}, system{system_} {} + : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} SoftwareKeyboard::~SoftwareKeyboard() = default; diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp index 0db9592ec2..2404921fd6 100644 --- a/src/core/hle/service/am/applets/web_browser.cpp +++ b/src/core/hle/service/am/applets/web_browser.cpp @@ -210,7 +210,7 @@ void ExtractSharedFonts(Core::System& system) { WebBrowser::WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_, const Core::Frontend::WebBrowserApplet& frontend_) - : Applet{system_.Kernel(), applet_mode_}, frontend(frontend_), system{system_} {} + : Applet{system_, applet_mode_}, frontend(frontend_), system{system_} {} WebBrowser::~WebBrowser() = default;