1 // Copyright 2018 yuzu emulator team 2 // Licensed under GPLv2 or any later version 3 // Refer to the license.txt file included. 4 5 #pragma once 6 7 #include <memory> 8 #include <queue> 9 #include "common/swap.h" 10 #include "core/hle/kernel/object.h" 11 #include "core/hle/kernel/writable_event.h" 12 13 union ResultCode; 14 15 namespace Core { 16 class System; 17 } 18 19 namespace Core::Frontend { 20 class ControllerApplet; 21 class ECommerceApplet; 22 class ErrorApplet; 23 class ParentalControlsApplet; 24 class PhotoViewerApplet; 25 class ProfileSelectApplet; 26 class SoftwareKeyboardApplet; 27 class WebBrowserApplet; 28 } // namespace Core::Frontend 29 30 namespace Kernel { 31 class KernelCore; 32 } 33 34 namespace Service::AM { 35 36 class IStorage; 37 38 namespace Applets { 39 40 enum class AppletId : u32 { 41 OverlayDisplay = 0x02, 42 QLaunch = 0x03, 43 Starter = 0x04, 44 Auth = 0x0A, 45 Cabinet = 0x0B, 46 Controller = 0x0C, 47 DataErase = 0x0D, 48 Error = 0x0E, 49 NetConnect = 0x0F, 50 ProfileSelect = 0x10, 51 SoftwareKeyboard = 0x11, 52 MiiEdit = 0x12, 53 LibAppletWeb = 0x13, 54 LibAppletShop = 0x14, 55 PhotoViewer = 0x15, 56 Settings = 0x16, 57 LibAppletOff = 0x17, 58 LibAppletWhitelisted = 0x18, 59 LibAppletAuth = 0x19, 60 MyPage = 0x1A, 61 }; 62 63 class AppletDataBroker final { 64 public: 65 explicit AppletDataBroker(Kernel::KernelCore& kernel_); 66 ~AppletDataBroker(); 67 68 struct RawChannelData { 69 std::vector<std::vector<u8>> normal; 70 std::vector<std::vector<u8>> interactive; 71 }; 72 73 // Retrieves but does not pop the data sent to applet. 74 RawChannelData PeekDataToAppletForDebug() const; 75 76 std::shared_ptr<IStorage> PopNormalDataToGame(); 77 std::shared_ptr<IStorage> PopNormalDataToApplet(); 78 79 std::shared_ptr<IStorage> PopInteractiveDataToGame(); 80 std::shared_ptr<IStorage> PopInteractiveDataToApplet(); 81 82 void PushNormalDataFromGame(std::shared_ptr<IStorage>&& storage); 83 void PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage); 84 85 void PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage); 86 void PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage); 87 88 void SignalStateChanged() const; 89 90 std::shared_ptr<Kernel::ReadableEvent> GetNormalDataEvent() const; 91 std::shared_ptr<Kernel::ReadableEvent> GetInteractiveDataEvent() const; 92 std::shared_ptr<Kernel::ReadableEvent> GetStateChangedEvent() const; 93 94 private: 95 // Queues are named from applet's perspective 96 97 // PopNormalDataToApplet and PushNormalDataFromGame 98 std::deque<std::shared_ptr<IStorage>> in_channel; 99 100 // PopNormalDataToGame and PushNormalDataFromApplet 101 std::deque<std::shared_ptr<IStorage>> out_channel; 102 103 // PopInteractiveDataToApplet and PushInteractiveDataFromGame 104 std::deque<std::shared_ptr<IStorage>> in_interactive_channel; 105 106 // PopInteractiveDataToGame and PushInteractiveDataFromApplet 107 std::deque<std::shared_ptr<IStorage>> out_interactive_channel; 108 109 Kernel::EventPair state_changed_event; 110 111 // Signaled on PushNormalDataFromApplet 112 Kernel::EventPair pop_out_data_event; 113 114 // Signaled on PushInteractiveDataFromApplet 115 Kernel::EventPair pop_interactive_out_data_event; 116 }; 117 118 class Applet { 119 public: 120 explicit Applet(Kernel::KernelCore& kernel_); 121 virtual ~Applet(); 122 123 virtual void Initialize(); 124 125 virtual bool TransactionComplete() const = 0; 126 virtual ResultCode GetStatus() const = 0; 127 virtual void ExecuteInteractive() = 0; 128 virtual void Execute() = 0; 129 IsInitialized()130 bool IsInitialized() const { 131 return initialized; 132 } 133 GetBroker()134 AppletDataBroker& GetBroker() { 135 return broker; 136 } 137 GetBroker()138 const AppletDataBroker& GetBroker() const { 139 return broker; 140 } 141 142 protected: 143 struct CommonArguments { 144 u32_le arguments_version; 145 u32_le size; 146 u32_le library_version; 147 u32_le theme_color; 148 u8 play_startup_sound; 149 u64_le system_tick; 150 }; 151 static_assert(sizeof(CommonArguments) == 0x20, "CommonArguments has incorrect size."); 152 153 CommonArguments common_args{}; 154 AppletDataBroker broker; 155 bool initialized = false; 156 }; 157 158 struct AppletFrontendSet { 159 using ControllerApplet = std::unique_ptr<Core::Frontend::ControllerApplet>; 160 using ECommerceApplet = std::unique_ptr<Core::Frontend::ECommerceApplet>; 161 using ErrorApplet = std::unique_ptr<Core::Frontend::ErrorApplet>; 162 using ParentalControlsApplet = std::unique_ptr<Core::Frontend::ParentalControlsApplet>; 163 using PhotoViewer = std::unique_ptr<Core::Frontend::PhotoViewerApplet>; 164 using ProfileSelect = std::unique_ptr<Core::Frontend::ProfileSelectApplet>; 165 using SoftwareKeyboard = std::unique_ptr<Core::Frontend::SoftwareKeyboardApplet>; 166 using WebBrowser = std::unique_ptr<Core::Frontend::WebBrowserApplet>; 167 168 AppletFrontendSet(); 169 AppletFrontendSet(ControllerApplet controller, ECommerceApplet e_commerce, ErrorApplet error, 170 ParentalControlsApplet parental_controls, PhotoViewer photo_viewer, 171 ProfileSelect profile_select, SoftwareKeyboard software_keyboard, 172 WebBrowser web_browser); 173 ~AppletFrontendSet(); 174 175 AppletFrontendSet(const AppletFrontendSet&) = delete; 176 AppletFrontendSet& operator=(const AppletFrontendSet&) = delete; 177 178 AppletFrontendSet(AppletFrontendSet&&) noexcept; 179 AppletFrontendSet& operator=(AppletFrontendSet&&) noexcept; 180 181 ControllerApplet controller; 182 ECommerceApplet e_commerce; 183 ErrorApplet error; 184 ParentalControlsApplet parental_controls; 185 PhotoViewer photo_viewer; 186 ProfileSelect profile_select; 187 SoftwareKeyboard software_keyboard; 188 WebBrowser web_browser; 189 }; 190 191 class AppletManager { 192 public: 193 explicit AppletManager(Core::System& system_); 194 ~AppletManager(); 195 196 const AppletFrontendSet& GetAppletFrontendSet() const; 197 198 void SetAppletFrontendSet(AppletFrontendSet set); 199 void SetDefaultAppletFrontendSet(); 200 void SetDefaultAppletsIfMissing(); 201 void ClearAll(); 202 203 std::shared_ptr<Applet> GetApplet(AppletId id) const; 204 205 private: 206 AppletFrontendSet frontend; 207 Core::System& system; 208 }; 209 210 } // namespace Applets 211 } // namespace Service::AM 212