summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Morph2020-11-08 23:27:33 -0500
committerGravatar Morph2020-12-18 10:33:27 -0500
commita5750f437d58e63ed76235d171732ca25dd34be2 (patch)
tree7bfe08b3fe89b463abe08c71f1be0e3ab8c79968 /src
parentapplets: Remove the previous web browser applet implementation (diff)
downloadyuzu-a5750f437d58e63ed76235d171732ca25dd34be2.tar.gz
yuzu-a5750f437d58e63ed76235d171732ca25dd34be2.tar.xz
yuzu-a5750f437d58e63ed76235d171732ca25dd34be2.zip
applets/web: Initial implementation of the web browser applet
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/am/applets/web_browser.cpp227
-rw-r--r--src/core/hle/service/am/applets/web_browser.h25
-rw-r--r--src/core/hle/service/am/applets/web_types.h178
3 files changed, 428 insertions, 2 deletions
diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp
index 74ef037fe..7f398254e 100644
--- a/src/core/hle/service/am/applets/web_browser.cpp
+++ b/src/core/hle/service/am/applets/web_browser.cpp
@@ -2,8 +2,11 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <optional>
6
5#include "common/assert.h" 7#include "common/assert.h"
6#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "common/string_util.h"
7#include "core/core.h" 10#include "core/core.h"
8#include "core/frontend/applets/web_browser.h" 11#include "core/frontend/applets/web_browser.h"
9#include "core/hle/result.h" 12#include "core/hle/result.h"
@@ -12,6 +15,76 @@
12 15
13namespace Service::AM::Applets { 16namespace Service::AM::Applets {
14 17
18namespace {
19
20template <typename T>
21void ParseRawValue(T& value, const std::vector<u8>& data) {
22 static_assert(std::is_trivially_copyable_v<T>,
23 "It's undefined behavior to use memcpy with non-trivially copyable objects");
24 std::memcpy(&value, data.data(), data.size());
25}
26
27template <typename T>
28T ParseRawValue(const std::vector<u8>& data) {
29 T value;
30 ParseRawValue(value, data);
31 return value;
32}
33
34std::string ParseStringValue(const std::vector<u8>& data) {
35 return Common::StringFromFixedZeroTerminatedBuffer(reinterpret_cast<const char*>(data.data()),
36 data.size());
37}
38
39WebArgInputTLVMap ReadWebArgs(const std::vector<u8>& web_arg, WebArgHeader& web_arg_header) {
40 std::memcpy(&web_arg_header, web_arg.data(), sizeof(WebArgHeader));
41
42 if (web_arg.size() == sizeof(WebArgHeader)) {
43 return {};
44 }
45
46 WebArgInputTLVMap input_tlv_map;
47
48 u64 current_offset = sizeof(WebArgHeader);
49
50 for (std::size_t i = 0; i < web_arg_header.total_tlv_entries; ++i) {
51 if (web_arg.size() < current_offset + sizeof(WebArgInputTLV)) {
52 return input_tlv_map;
53 }
54
55 WebArgInputTLV input_tlv;
56 std::memcpy(&input_tlv, web_arg.data() + current_offset, sizeof(WebArgInputTLV));
57
58 current_offset += sizeof(WebArgInputTLV);
59
60 if (web_arg.size() < current_offset + input_tlv.arg_data_size) {
61 return input_tlv_map;
62 }
63
64 std::vector<u8> data(input_tlv.arg_data_size);
65 std::memcpy(data.data(), web_arg.data() + current_offset, input_tlv.arg_data_size);
66
67 current_offset += input_tlv.arg_data_size;
68
69 input_tlv_map.insert_or_assign(input_tlv.input_tlv_type, std::move(data));
70 }
71
72 return input_tlv_map;
73}
74
75std::optional<std::vector<u8>> GetInputTLVData(const WebArgInputTLVMap& input_tlv_map,
76 WebArgInputTLVType input_tlv_type) {
77 const auto map_it = input_tlv_map.find(input_tlv_type);
78
79 if (map_it == input_tlv_map.end()) {
80 return std::nullopt;
81 }
82
83 return map_it->second;
84}
85
86} // namespace
87
15WebBrowser::WebBrowser(Core::System& system_, const Core::Frontend::WebBrowserApplet& frontend_) 88WebBrowser::WebBrowser(Core::System& system_, const Core::Frontend::WebBrowserApplet& frontend_)
16 : Applet{system_.Kernel()}, frontend(frontend_), system{system_} {} 89 : Applet{system_.Kernel()}, frontend(frontend_), system{system_} {}
17 90
@@ -19,6 +92,55 @@ WebBrowser::~WebBrowser() = default;
19 92
20void WebBrowser::Initialize() { 93void WebBrowser::Initialize() {
21 Applet::Initialize(); 94 Applet::Initialize();
95
96 LOG_INFO(Service_AM, "Initializing Web Browser Applet.");
97
98 LOG_DEBUG(Service_AM,
99 "Initializing Applet with common_args: arg_version={}, lib_version={}, "
100 "play_startup_sound={}, size={}, system_tick={}, theme_color={}",
101 common_args.arguments_version, common_args.library_version,
102 common_args.play_startup_sound, common_args.size, common_args.system_tick,
103 common_args.theme_color);
104
105 web_applet_version = WebAppletVersion{common_args.library_version};
106
107 const auto web_arg_storage = broker.PopNormalDataToApplet();
108 ASSERT(web_arg_storage != nullptr);
109
110 const auto& web_arg = web_arg_storage->GetData();
111 ASSERT_OR_EXECUTE(web_arg.size() >= sizeof(WebArgHeader), { return; });
112
113 web_arg_input_tlv_map = ReadWebArgs(web_arg, web_arg_header);
114
115 LOG_DEBUG(Service_AM, "WebArgHeader: total_tlv_entries={}, shim_kind={}",
116 web_arg_header.total_tlv_entries, web_arg_header.shim_kind);
117
118 switch (web_arg_header.shim_kind) {
119 case ShimKind::Shop:
120 InitializeShop();
121 break;
122 case ShimKind::Login:
123 InitializeLogin();
124 break;
125 case ShimKind::Offline:
126 InitializeOffline();
127 break;
128 case ShimKind::Share:
129 InitializeShare();
130 break;
131 case ShimKind::Web:
132 InitializeWeb();
133 break;
134 case ShimKind::Wifi:
135 InitializeWifi();
136 break;
137 case ShimKind::Lobby:
138 InitializeLobby();
139 break;
140 default:
141 UNREACHABLE_MSG("Invalid ShimKind={}", web_arg_header.shim_kind);
142 break;
143 }
22} 144}
23 145
24bool WebBrowser::TransactionComplete() const { 146bool WebBrowser::TransactionComplete() const {
@@ -30,9 +152,110 @@ ResultCode WebBrowser::GetStatus() const {
30} 152}
31 153
32void WebBrowser::ExecuteInteractive() { 154void WebBrowser::ExecuteInteractive() {
33 UNIMPLEMENTED_MSG("Unexpected interactive data recieved!"); 155 UNIMPLEMENTED_MSG("WebSession is not implemented");
156}
157
158void WebBrowser::Execute() {
159 switch (web_arg_header.shim_kind) {
160 case ShimKind::Shop:
161 ExecuteShop();
162 break;
163 case ShimKind::Login:
164 ExecuteLogin();
165 break;
166 case ShimKind::Offline:
167 ExecuteOffline();
168 break;
169 case ShimKind::Share:
170 ExecuteShare();
171 break;
172 case ShimKind::Web:
173 ExecuteWeb();
174 break;
175 case ShimKind::Wifi:
176 ExecuteWifi();
177 break;
178 case ShimKind::Lobby:
179 ExecuteLobby();
180 break;
181 default:
182 UNREACHABLE_MSG("Invalid ShimKind={}", web_arg_header.shim_kind);
183 WebBrowserExit(WebExitReason::EndButtonPressed);
184 break;
185 }
186}
187
188void WebBrowser::WebBrowserExit(WebExitReason exit_reason, std::string last_url) {
189 if ((web_arg_header.shim_kind == ShimKind::Share &&
190 web_applet_version >= WebAppletVersion::Version196608) ||
191 (web_arg_header.shim_kind == ShimKind::Web &&
192 web_applet_version >= WebAppletVersion::Version524288)) {
193 // TODO: Push Output TLVs instead of a WebCommonReturnValue
194 }
195
196 WebCommonReturnValue web_common_return_value;
197
198 web_common_return_value.exit_reason = exit_reason;
199 std::memcpy(&web_common_return_value.last_url, last_url.data(), last_url.size());
200 web_common_return_value.last_url_size = last_url.size();
201
202 LOG_DEBUG(Service_AM, "WebCommonReturnValue: exit_reason={}, last_url={}, last_url_size={}",
203 exit_reason, last_url, last_url.size());
204
205 complete = true;
206 std::vector<u8> out_data(sizeof(WebCommonReturnValue));
207 std::memcpy(out_data.data(), &web_common_return_value, out_data.size());
208 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
209 broker.SignalStateChanged();
34} 210}
35 211
36void WebBrowser::Execute() {} 212void WebBrowser::InitializeShop() {}
213
214void WebBrowser::InitializeLogin() {}
215
216void WebBrowser::InitializeOffline() {}
217
218void WebBrowser::InitializeShare() {}
219
220void WebBrowser::InitializeWeb() {}
221
222void WebBrowser::InitializeWifi() {}
223
224void WebBrowser::InitializeLobby() {}
225
226void WebBrowser::ExecuteShop() {
227 LOG_WARNING(Service_AM, "(STUBBED) called, Shop Applet is not implemented");
228 WebBrowserExit(WebExitReason::EndButtonPressed);
229}
230
231void WebBrowser::ExecuteLogin() {
232 LOG_WARNING(Service_AM, "(STUBBED) called, Login Applet is not implemented");
233 WebBrowserExit(WebExitReason::EndButtonPressed);
234}
235
236void WebBrowser::ExecuteOffline() {
237 LOG_WARNING(Service_AM, "(STUBBED) called, Offline Applet is not implemented");
238 WebBrowserExit(WebExitReason::EndButtonPressed);
239}
240
241void WebBrowser::ExecuteShare() {
242 LOG_WARNING(Service_AM, "(STUBBED) called, Share Applet is not implemented");
243 WebBrowserExit(WebExitReason::EndButtonPressed);
244}
245
246void WebBrowser::ExecuteWeb() {
247 LOG_WARNING(Service_AM, "(STUBBED) called, Web Applet is not implemented");
248 WebBrowserExit(WebExitReason::EndButtonPressed);
249}
250
251void WebBrowser::ExecuteWifi() {
252 LOG_WARNING(Service_AM, "(STUBBED) called, Wifi Applet is not implemented");
253 WebBrowserExit(WebExitReason::EndButtonPressed);
254}
255
256void WebBrowser::ExecuteLobby() {
257 LOG_WARNING(Service_AM, "(STUBBED) called, Lobby Applet is not implemented");
258 WebBrowserExit(WebExitReason::EndButtonPressed);
259}
37 260
38} // namespace Service::AM::Applets 261} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/web_browser.h b/src/core/hle/service/am/applets/web_browser.h
index 0584142e5..a1ed5fd1d 100644
--- a/src/core/hle/service/am/applets/web_browser.h
+++ b/src/core/hle/service/am/applets/web_browser.h
@@ -8,6 +8,7 @@
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/hle/result.h" 9#include "core/hle/result.h"
10#include "core/hle/service/am/applets/applets.h" 10#include "core/hle/service/am/applets/applets.h"
11#include "core/hle/service/am/applets/web_types.h"
11 12
12namespace Core { 13namespace Core {
13class System; 14class System;
@@ -28,12 +29,36 @@ public:
28 void ExecuteInteractive() override; 29 void ExecuteInteractive() override;
29 void Execute() override; 30 void Execute() override;
30 31
32 void WebBrowserExit(WebExitReason exit_reason, std::string last_url = "");
33
31private: 34private:
35 // Initializers for the various types of browser applets
36 void InitializeShop();
37 void InitializeLogin();
38 void InitializeOffline();
39 void InitializeShare();
40 void InitializeWeb();
41 void InitializeWifi();
42 void InitializeLobby();
43
44 // Executors for the various types of browser applets
45 void ExecuteShop();
46 void ExecuteLogin();
47 void ExecuteOffline();
48 void ExecuteShare();
49 void ExecuteWeb();
50 void ExecuteWifi();
51 void ExecuteLobby();
52
32 const Core::Frontend::WebBrowserApplet& frontend; 53 const Core::Frontend::WebBrowserApplet& frontend;
33 54
34 bool complete{false}; 55 bool complete{false};
35 ResultCode status{RESULT_SUCCESS}; 56 ResultCode status{RESULT_SUCCESS};
36 57
58 WebAppletVersion web_applet_version;
59 WebArgHeader web_arg_header;
60 WebArgInputTLVMap web_arg_input_tlv_map;
61
37 Core::System& system; 62 Core::System& system;
38}; 63};
39 64
diff --git a/src/core/hle/service/am/applets/web_types.h b/src/core/hle/service/am/applets/web_types.h
new file mode 100644
index 000000000..419c2bf79
--- /dev/null
+++ b/src/core/hle/service/am/applets/web_types.h
@@ -0,0 +1,178 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <unordered_map>
9#include <vector>
10
11#include "common/common_funcs.h"
12#include "common/common_types.h"
13#include "common/swap.h"
14
15namespace Service::AM::Applets {
16
17enum class WebAppletVersion : u32_le {
18 Version0 = 0x0, // Only used by WifiWebAuthApplet
19 Version131072 = 0x20000, // 1.0.0 - 2.3.0
20 Version196608 = 0x30000, // 3.0.0 - 4.1.0
21 Version327680 = 0x50000, // 5.0.0 - 5.1.0
22 Version393216 = 0x60000, // 6.0.0 - 7.0.1
23 Version524288 = 0x80000, // 8.0.0+
24};
25
26enum class ShimKind : u32 {
27 Shop = 1,
28 Login = 2,
29 Offline = 3,
30 Share = 4,
31 Web = 5,
32 Wifi = 6,
33 Lobby = 7,
34};
35
36enum class WebExitReason : u32 {
37 EndButtonPressed = 0,
38 BackButtonPressed = 1,
39 ExitRequested = 2,
40 CallbackURL = 3,
41 WindowClosed = 4,
42 ErrorDialog = 7,
43};
44
45enum class WebArgInputTLVType : u16 {
46 InitialURL = 0x1,
47 CallbackURL = 0x3,
48 CallbackableURL = 0x4,
49 ApplicationID = 0x5,
50 DocumentPath = 0x6,
51 DocumentKind = 0x7,
52 SystemDataID = 0x8,
53 ShareStartPage = 0x9,
54 Whitelist = 0xA,
55 News = 0xB,
56 UserID = 0xE,
57 AlbumEntry0 = 0xF,
58 ScreenShotEnabled = 0x10,
59 EcClientCertEnabled = 0x11,
60 PlayReportEnabled = 0x13,
61 BootDisplayKind = 0x17,
62 BackgroundKind = 0x18,
63 FooterEnabled = 0x19,
64 PointerEnabled = 0x1A,
65 LeftStickMode = 0x1B,
66 KeyRepeatFrame1 = 0x1C,
67 KeyRepeatFrame2 = 0x1D,
68 BootAsMediaPlayerInverted = 0x1E,
69 DisplayURLKind = 0x1F,
70 BootAsMediaPlayer = 0x21,
71 ShopJumpEnabled = 0x22,
72 MediaAutoPlayEnabled = 0x23,
73 LobbyParameter = 0x24,
74 ApplicationAlbumEntry = 0x26,
75 JsExtensionEnabled = 0x27,
76 AdditionalCommentText = 0x28,
77 TouchEnabledOnContents = 0x29,
78 UserAgentAdditionalString = 0x2A,
79 AdditionalMediaData0 = 0x2B,
80 MediaPlayerAutoCloseEnabled = 0x2C,
81 PageCacheEnabled = 0x2D,
82 WebAudioEnabled = 0x2E,
83 YouTubeVideoWhitelist = 0x31,
84 FooterFixedKind = 0x32,
85 PageFadeEnabled = 0x33,
86 MediaCreatorApplicationRatingAge = 0x34,
87 BootLoadingIconEnabled = 0x35,
88 PageScrollIndicatorEnabled = 0x36,
89 MediaPlayerSpeedControlEnabled = 0x37,
90 AlbumEntry1 = 0x38,
91 AlbumEntry2 = 0x39,
92 AlbumEntry3 = 0x3A,
93 AdditionalMediaData1 = 0x3B,
94 AdditionalMediaData2 = 0x3C,
95 AdditionalMediaData3 = 0x3D,
96 BootFooterButton = 0x3E,
97 OverrideWebAudioVolume = 0x3F,
98 OverrideMediaAudioVolume = 0x40,
99 BootMode = 0x41,
100 WebSessionEnabled = 0x42,
101 MediaPlayerOfflineEnabled = 0x43,
102};
103
104enum class WebArgOutputTLVType : u16 {
105 ShareExitReason = 0x1,
106 LastURL = 0x2,
107 LastURLSize = 0x3,
108 SharePostResult = 0x4,
109 PostServiceName = 0x5,
110 PostServiceNameSize = 0x6,
111 PostID = 0x7,
112 PostIDSize = 0x8,
113 MediaPlayerAutoClosedByCompletion = 0x9,
114};
115
116enum class DocumentKind : u32 {
117 OfflineHtmlPage = 1,
118 ApplicationLegalInformation = 2,
119 SystemDataPage = 3,
120};
121
122enum class ShareStartPage : u32 {
123 Default,
124 Settings,
125};
126
127enum class BootDisplayKind : u32 {
128 Default,
129 White,
130 Black,
131};
132
133enum class BackgroundKind : u32 {
134 Default,
135};
136
137enum class LeftStickMode : u32 {
138 Pointer,
139 Cursor,
140};
141
142enum class WebSessionBootMode : u32 {
143 AllForeground,
144 AllForegroundInitiallyHidden,
145};
146
147struct WebArgHeader {
148 u16 total_tlv_entries{};
149 INSERT_PADDING_BYTES(2);
150 ShimKind shim_kind{};
151};
152static_assert(sizeof(WebArgHeader) == 0x8, "WebArgHeader has incorrect size.");
153
154struct WebArgInputTLV {
155 WebArgInputTLVType input_tlv_type{};
156 u16 arg_data_size{};
157 INSERT_PADDING_WORDS(1);
158};
159static_assert(sizeof(WebArgInputTLV) == 0x8, "WebArgInputTLV has incorrect size.");
160
161struct WebArgOutputTLV {
162 WebArgOutputTLVType output_tlv_type{};
163 u16 arg_data_size{};
164 INSERT_PADDING_WORDS(1);
165};
166static_assert(sizeof(WebArgOutputTLV) == 0x8, "WebArgOutputTLV has incorrect size.");
167
168struct WebCommonReturnValue {
169 WebExitReason exit_reason{};
170 INSERT_PADDING_WORDS(1);
171 std::array<char, 0x1000> last_url{};
172 u64 last_url_size{};
173};
174static_assert(sizeof(WebCommonReturnValue) == 0x1010, "WebCommonReturnValue has incorrect size.");
175
176using WebArgInputTLVMap = std::unordered_map<WebArgInputTLVType, std::vector<u8>>;
177
178} // namespace Service::AM::Applets