summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Morph2020-11-12 12:23:46 -0500
committerGravatar Morph2020-12-18 10:33:27 -0500
commit89df4835673a2c6b1905459b2aff866a6caeec4a (patch)
treee8f904ccdec94005cad6641771f79c788a55b35b /src
parentapplets/web: Initial implementation of the web browser applet (diff)
downloadyuzu-89df4835673a2c6b1905459b2aff866a6caeec4a.tar.gz
yuzu-89df4835673a2c6b1905459b2aff866a6caeec4a.tar.xz
yuzu-89df4835673a2c6b1905459b2aff866a6caeec4a.zip
applets/web: Implement the offline browser applet backend
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/am/applets/web_browser.cpp146
-rw-r--r--src/core/hle/service/am/applets/web_browser.h10
2 files changed, 143 insertions, 13 deletions
diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp
index 7f398254e..06fcf3e3f 100644
--- a/src/core/hle/service/am/applets/web_browser.cpp
+++ b/src/core/hle/service/am/applets/web_browser.cpp
@@ -2,16 +2,26 @@
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
7#include "common/assert.h" 5#include "common/assert.h"
6#include "common/common_paths.h"
7#include "common/file_util.h"
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "common/string_util.h" 9#include "common/string_util.h"
10#include "core/core.h" 10#include "core/core.h"
11#include "core/file_sys/content_archive.h"
12#include "core/file_sys/mode.h"
13#include "core/file_sys/nca_metadata.h"
14#include "core/file_sys/patch_manager.h"
15#include "core/file_sys/registered_cache.h"
16#include "core/file_sys/romfs.h"
17#include "core/file_sys/system_archive/system_archive.h"
18#include "core/file_sys/vfs_types.h"
11#include "core/frontend/applets/web_browser.h" 19#include "core/frontend/applets/web_browser.h"
20#include "core/hle/kernel/process.h"
12#include "core/hle/result.h" 21#include "core/hle/result.h"
13#include "core/hle/service/am/am.h" 22#include "core/hle/service/am/am.h"
14#include "core/hle/service/am/applets/web_browser.h" 23#include "core/hle/service/am/applets/web_browser.h"
24#include "core/hle/service/filesystem/filesystem.h"
15 25
16namespace Service::AM::Applets { 26namespace Service::AM::Applets {
17 27
@@ -36,6 +46,16 @@ std::string ParseStringValue(const std::vector<u8>& data) {
36 data.size()); 46 data.size());
37} 47}
38 48
49std::string GetMainURL(const std::string& url) {
50 const auto index = url.find('?');
51
52 if (index == std::string::npos) {
53 return url;
54 }
55
56 return url.substr(0, index);
57}
58
39WebArgInputTLVMap ReadWebArgs(const std::vector<u8>& web_arg, WebArgHeader& web_arg_header) { 59WebArgInputTLVMap ReadWebArgs(const std::vector<u8>& web_arg, WebArgHeader& web_arg_header) {
40 std::memcpy(&web_arg_header, web_arg.data(), sizeof(WebArgHeader)); 60 std::memcpy(&web_arg_header, web_arg.data(), sizeof(WebArgHeader));
41 61
@@ -72,15 +92,35 @@ WebArgInputTLVMap ReadWebArgs(const std::vector<u8>& web_arg, WebArgHeader& web_
72 return input_tlv_map; 92 return input_tlv_map;
73} 93}
74 94
75std::optional<std::vector<u8>> GetInputTLVData(const WebArgInputTLVMap& input_tlv_map, 95FileSys::VirtualFile GetOfflineRomFS(Core::System& system, u64 title_id,
76 WebArgInputTLVType input_tlv_type) { 96 FileSys::ContentRecordType nca_type) {
77 const auto map_it = input_tlv_map.find(input_tlv_type); 97 if (nca_type == FileSys::ContentRecordType::Data) {
98 const auto nca =
99 system.GetFileSystemController().GetSystemNANDContents()->GetEntry(title_id, nca_type);
100
101 if (nca == nullptr) {
102 LOG_ERROR(Service_AM,
103 "NCA of type={} with title_id={:016X} is not found in the System NAND!",
104 nca_type, title_id);
105 return FileSys::SystemArchive::SynthesizeSystemArchive(title_id);
106 }
78 107
79 if (map_it == input_tlv_map.end()) { 108 return nca->GetRomFS();
80 return std::nullopt; 109 } else {
81 } 110 const auto nca = system.GetContentProvider().GetEntry(title_id, nca_type);
82 111
83 return map_it->second; 112 if (nca == nullptr) {
113 LOG_ERROR(Service_AM,
114 "NCA of type={} with title_id={:016X} is not found in the ContentProvider!",
115 nca_type, title_id);
116 return nullptr;
117 }
118
119 const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
120 system.GetContentProvider()};
121
122 return pm.PatchRomFS(nca->GetRomFS(), nca->GetBaseIVFCOffset(), nca_type);
123 }
84} 124}
85 125
86} // namespace 126} // namespace
@@ -209,11 +249,92 @@ void WebBrowser::WebBrowserExit(WebExitReason exit_reason, std::string last_url)
209 broker.SignalStateChanged(); 249 broker.SignalStateChanged();
210} 250}
211 251
252bool WebBrowser::InputTLVExistsInMap(WebArgInputTLVType input_tlv_type) const {
253 return web_arg_input_tlv_map.find(input_tlv_type) != web_arg_input_tlv_map.end();
254}
255
256std::optional<std::vector<u8>> WebBrowser::GetInputTLVData(WebArgInputTLVType input_tlv_type) {
257 const auto map_it = web_arg_input_tlv_map.find(input_tlv_type);
258
259 if (map_it == web_arg_input_tlv_map.end()) {
260 return std::nullopt;
261 }
262
263 return map_it->second;
264}
265
212void WebBrowser::InitializeShop() {} 266void WebBrowser::InitializeShop() {}
213 267
214void WebBrowser::InitializeLogin() {} 268void WebBrowser::InitializeLogin() {}
215 269
216void WebBrowser::InitializeOffline() {} 270void WebBrowser::InitializeOffline() {
271 const auto document_path =
272 ParseStringValue(GetInputTLVData(WebArgInputTLVType::DocumentPath).value());
273
274 const auto document_kind =
275 ParseRawValue<DocumentKind>(GetInputTLVData(WebArgInputTLVType::DocumentKind).value());
276
277 u64 title_id{};
278 FileSys::ContentRecordType nca_type{FileSys::ContentRecordType::HtmlDocument};
279 std::string additional_paths;
280
281 switch (document_kind) {
282 case DocumentKind::OfflineHtmlPage:
283 title_id = system.CurrentProcess()->GetTitleID();
284 nca_type = FileSys::ContentRecordType::HtmlDocument;
285 additional_paths = "html-document";
286 break;
287 case DocumentKind::ApplicationLegalInformation:
288 title_id = ParseRawValue<u64>(GetInputTLVData(WebArgInputTLVType::ApplicationID).value());
289 nca_type = FileSys::ContentRecordType::LegalInformation;
290 break;
291 case DocumentKind::SystemDataPage:
292 title_id = ParseRawValue<u64>(GetInputTLVData(WebArgInputTLVType::SystemDataID).value());
293 nca_type = FileSys::ContentRecordType::Data;
294 break;
295 }
296
297 static constexpr std::array<const char*, 3> RESOURCE_TYPES{
298 "manual",
299 "legal_information",
300 "system_data",
301 };
302
303 offline_cache_dir = Common::FS::SanitizePath(
304 fmt::format("{}/offline_web_applet_{}/{:016X}",
305 Common::FS::GetUserPath(Common::FS::UserPath::CacheDir),
306 RESOURCE_TYPES[static_cast<u32>(document_kind) - 1], title_id),
307 Common::FS::DirectorySeparator::PlatformDefault);
308
309 offline_document = Common::FS::SanitizePath(
310 fmt::format("{}/{}/{}", offline_cache_dir, additional_paths, document_path),
311 Common::FS::DirectorySeparator::PlatformDefault);
312
313 const auto main_url = Common::FS::SanitizePath(GetMainURL(offline_document),
314 Common::FS::DirectorySeparator::PlatformDefault);
315
316 if (Common::FS::Exists(main_url)) {
317 return;
318 }
319
320 auto offline_romfs = GetOfflineRomFS(system, title_id, nca_type);
321
322 if (offline_romfs == nullptr) {
323 LOG_ERROR(Service_AM, "RomFS with title_id={:016X} and nca_type={} cannot be extracted!",
324 title_id, nca_type);
325 return;
326 }
327
328 LOG_DEBUG(Service_AM, "Extracting RomFS to {}", offline_cache_dir);
329
330 const auto extracted_romfs_dir =
331 FileSys::ExtractRomFS(offline_romfs, FileSys::RomFSExtractionType::SingleDiscard);
332
333 const auto temp_dir =
334 system.GetFilesystem()->CreateDirectory(offline_cache_dir, FileSys::Mode::ReadWrite);
335
336 FileSys::VfsRawCopyD(extracted_romfs_dir, temp_dir);
337}
217 338
218void WebBrowser::InitializeShare() {} 339void WebBrowser::InitializeShare() {}
219 340
@@ -234,8 +355,8 @@ void WebBrowser::ExecuteLogin() {
234} 355}
235 356
236void WebBrowser::ExecuteOffline() { 357void WebBrowser::ExecuteOffline() {
237 LOG_WARNING(Service_AM, "(STUBBED) called, Offline Applet is not implemented"); 358 LOG_INFO(Service_AM, "Opening offline document at {}", offline_document);
238 WebBrowserExit(WebExitReason::EndButtonPressed); 359 WebBrowserExit(WebExitReason::WindowClosed);
239} 360}
240 361
241void WebBrowser::ExecuteShare() { 362void WebBrowser::ExecuteShare() {
@@ -257,5 +378,4 @@ void WebBrowser::ExecuteLobby() {
257 LOG_WARNING(Service_AM, "(STUBBED) called, Lobby Applet is not implemented"); 378 LOG_WARNING(Service_AM, "(STUBBED) called, Lobby Applet is not implemented");
258 WebBrowserExit(WebExitReason::EndButtonPressed); 379 WebBrowserExit(WebExitReason::EndButtonPressed);
259} 380}
260
261} // namespace Service::AM::Applets 381} // 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 a1ed5fd1d..c36c717f1 100644
--- a/src/core/hle/service/am/applets/web_browser.h
+++ b/src/core/hle/service/am/applets/web_browser.h
@@ -4,6 +4,8 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <optional>
8
7#include "common/common_funcs.h" 9#include "common/common_funcs.h"
8#include "common/common_types.h" 10#include "common/common_types.h"
9#include "core/hle/result.h" 11#include "core/hle/result.h"
@@ -32,6 +34,10 @@ public:
32 void WebBrowserExit(WebExitReason exit_reason, std::string last_url = ""); 34 void WebBrowserExit(WebExitReason exit_reason, std::string last_url = "");
33 35
34private: 36private:
37 bool InputTLVExistsInMap(WebArgInputTLVType input_tlv_type) const;
38
39 std::optional<std::vector<u8>> GetInputTLVData(WebArgInputTLVType input_tlv_type);
40
35 // Initializers for the various types of browser applets 41 // Initializers for the various types of browser applets
36 void InitializeShop(); 42 void InitializeShop();
37 void InitializeLogin(); 43 void InitializeLogin();
@@ -56,9 +62,13 @@ private:
56 ResultCode status{RESULT_SUCCESS}; 62 ResultCode status{RESULT_SUCCESS};
57 63
58 WebAppletVersion web_applet_version; 64 WebAppletVersion web_applet_version;
65 WebExitReason web_exit_reason;
59 WebArgHeader web_arg_header; 66 WebArgHeader web_arg_header;
60 WebArgInputTLVMap web_arg_input_tlv_map; 67 WebArgInputTLVMap web_arg_input_tlv_map;
61 68
69 std::string offline_cache_dir;
70 std::string offline_document;
71
62 Core::System& system; 72 Core::System& system;
63}; 73};
64 74