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