From 8b95bf041da573459e953e27eee2dcf30208b02d Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Mon, 30 Nov 2020 10:15:00 -0500 Subject: [PATCH] main, applets/web: Re-add progress dialog for RomFS extraction --- src/core/frontend/applets/web_browser.cpp | 5 +- src/core/frontend/applets/web_browser.h | 11 ++-- .../hle/service/am/applets/web_browser.cpp | 66 ++++++++++--------- src/core/hle/service/am/applets/web_browser.h | 10 +++ src/yuzu/applets/web_browser.cpp | 21 ++++-- src/yuzu/applets/web_browser.h | 21 ++++-- src/yuzu/main.cpp | 60 ++++++++++++----- src/yuzu/main.h | 1 + 8 files changed, 126 insertions(+), 69 deletions(-) diff --git a/src/core/frontend/applets/web_browser.cpp b/src/core/frontend/applets/web_browser.cpp index 0e1612e27..a5d8f82ac 100644 --- a/src/core/frontend/applets/web_browser.cpp +++ b/src/core/frontend/applets/web_browser.cpp @@ -12,11 +12,12 @@ WebBrowserApplet::~WebBrowserApplet() = default; DefaultWebBrowserApplet::~DefaultWebBrowserApplet() = default; void DefaultWebBrowserApplet::OpenLocalWebPage( - std::string_view local_url, std::function callback) const { + std::string_view local_url, std::function extract_romfs_callback, + std::function callback) const { LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to open local web page at {}", local_url); - callback(WebExitReason::WindowClosed, "http://localhost/"); + callback(Service::AM::Applets::WebExitReason::WindowClosed, "http://localhost/"); } } // namespace Core::Frontend diff --git a/src/core/frontend/applets/web_browser.h b/src/core/frontend/applets/web_browser.h index 2ccefc68f..5b0629cfb 100644 --- a/src/core/frontend/applets/web_browser.h +++ b/src/core/frontend/applets/web_browser.h @@ -9,8 +9,6 @@ #include "core/hle/service/am/applets/web_types.h" -using namespace Service::AM::Applets; - namespace Core::Frontend { class WebBrowserApplet { @@ -18,16 +16,17 @@ public: virtual ~WebBrowserApplet(); virtual void OpenLocalWebPage( - std::string_view local_url, - std::function callback) const = 0; + std::string_view local_url, std::function extract_romfs_callback, + std::function callback) const = 0; }; class DefaultWebBrowserApplet final : public WebBrowserApplet { public: ~DefaultWebBrowserApplet() override; - void OpenLocalWebPage(std::string_view local_url, - std::function callback) const override; + void OpenLocalWebPage(std::string_view local_url, std::function extract_romfs_callback, + std::function + callback) const override; }; } // namespace Core::Frontend diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp index 02ce9f387..9c8be156f 100644 --- a/src/core/hle/service/am/applets/web_browser.cpp +++ b/src/core/hle/service/am/applets/web_browser.cpp @@ -15,7 +15,6 @@ #include "core/file_sys/registered_cache.h" #include "core/file_sys/romfs.h" #include "core/file_sys/system_archive/system_archive.h" -#include "core/file_sys/vfs_types.h" #include "core/file_sys/vfs_vector.h" #include "core/frontend/applets/web_browser.h" #include "core/hle/kernel/process.h" @@ -311,6 +310,18 @@ void WebBrowser::Execute() { } } +void WebBrowser::ExtractOfflineRomFS() { + LOG_DEBUG(Service_AM, "Extracting RomFS to {}", offline_cache_dir); + + const auto extracted_romfs_dir = + FileSys::ExtractRomFS(offline_romfs, FileSys::RomFSExtractionType::SingleDiscard); + + const auto temp_dir = + system.GetFilesystem()->CreateDirectory(offline_cache_dir, FileSys::Mode::ReadWrite); + + FileSys::VfsRawCopyD(extracted_romfs_dir, temp_dir); +} + void WebBrowser::WebBrowserExit(WebExitReason exit_reason, std::string last_url) { if ((web_arg_header.shim_kind == ShimKind::Share && web_applet_version >= WebAppletVersion::Version196608) || @@ -360,12 +371,11 @@ void WebBrowser::InitializeOffline() { const auto document_kind = ParseRawValue(GetInputTLVData(WebArgInputTLVType::DocumentKind).value()); - u64 title_id{}; - FileSys::ContentRecordType nca_type{FileSys::ContentRecordType::HtmlDocument}; std::string additional_paths; switch (document_kind) { case DocumentKind::OfflineHtmlPage: + default: title_id = system.CurrentProcess()->GetTitleID(); nca_type = FileSys::ContentRecordType::HtmlDocument; additional_paths = "html-document"; @@ -395,31 +405,6 @@ void WebBrowser::InitializeOffline() { offline_document = Common::FS::SanitizePath( fmt::format("{}/{}/{}", offline_cache_dir, additional_paths, document_path), Common::FS::DirectorySeparator::PlatformDefault); - - const auto main_url = Common::FS::SanitizePath(GetMainURL(offline_document), - Common::FS::DirectorySeparator::PlatformDefault); - - if (Common::FS::Exists(main_url)) { - return; - } - - auto offline_romfs = GetOfflineRomFS(system, title_id, nca_type); - - if (offline_romfs == nullptr) { - LOG_ERROR(Service_AM, "RomFS with title_id={:016X} and nca_type={} cannot be extracted!", - title_id, nca_type); - return; - } - - LOG_DEBUG(Service_AM, "Extracting RomFS to {}", offline_cache_dir); - - const auto extracted_romfs_dir = - FileSys::ExtractRomFS(offline_romfs, FileSys::RomFSExtractionType::SingleDiscard); - - const auto temp_dir = - system.GetFilesystem()->CreateDirectory(offline_cache_dir, FileSys::Mode::ReadWrite); - - FileSys::VfsRawCopyD(extracted_romfs_dir, temp_dir); } void WebBrowser::InitializeShare() {} @@ -441,11 +426,28 @@ void WebBrowser::ExecuteLogin() { } void WebBrowser::ExecuteOffline() { + const auto main_url = Common::FS::SanitizePath(GetMainURL(offline_document), + Common::FS::DirectorySeparator::PlatformDefault); + + if (!Common::FS::Exists(main_url)) { + offline_romfs = GetOfflineRomFS(system, title_id, nca_type); + + if (offline_romfs == nullptr) { + LOG_ERROR(Service_AM, + "RomFS with title_id={:016X} and nca_type={} cannot be extracted!", title_id, + nca_type); + WebBrowserExit(WebExitReason::WindowClosed); + return; + } + } + LOG_INFO(Service_AM, "Opening offline document at {}", offline_document); - frontend.OpenLocalWebPage(offline_document, - [this](WebExitReason exit_reason, std::string last_url) { - WebBrowserExit(exit_reason, last_url); - }); + + frontend.OpenLocalWebPage( + offline_document, [this] { ExtractOfflineRomFS(); }, + [this](WebExitReason exit_reason, std::string last_url) { + WebBrowserExit(exit_reason, last_url); + }); } void WebBrowser::ExecuteShare() { diff --git a/src/core/hle/service/am/applets/web_browser.h b/src/core/hle/service/am/applets/web_browser.h index c36c717f1..936a49a86 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 @@ #include "common/common_funcs.h" #include "common/common_types.h" +#include "core/file_sys/vfs_types.h" #include "core/hle/result.h" #include "core/hle/service/am/applets/applets.h" #include "core/hle/service/am/applets/web_types.h" @@ -16,6 +17,10 @@ namespace Core { class System; } +namespace FileSys { +enum class ContentRecordType : u8; +} + namespace Service::AM::Applets { class WebBrowser final : public Applet { @@ -31,6 +36,8 @@ public: void ExecuteInteractive() override; void Execute() override; + void ExtractOfflineRomFS(); + void WebBrowserExit(WebExitReason exit_reason, std::string last_url = ""); private: @@ -66,8 +73,11 @@ private: WebArgHeader web_arg_header; WebArgInputTLVMap web_arg_input_tlv_map; + u64 title_id; + FileSys::ContentRecordType nca_type; std::string offline_cache_dir; std::string offline_document; + FileSys::VirtualFile offline_romfs; Core::System& system; }; diff --git a/src/yuzu/applets/web_browser.cpp b/src/yuzu/applets/web_browser.cpp index 26b9df51a..52c99d1ba 100644 --- a/src/yuzu/applets/web_browser.cpp +++ b/src/yuzu/applets/web_browser.cpp @@ -120,7 +120,7 @@ QtNXWebEngineView::QtNXWebEngineView(QWidget* parent, Core::System& system) [this] { if (page()->url() == url_interceptor->GetRequestedURL()) { SetFinished(true); - SetExitReason(WebExitReason::WindowClosed); + SetExitReason(Service::AM::Applets::WebExitReason::WindowClosed); } }, Qt::QueuedConnection); @@ -135,7 +135,7 @@ void QtNXWebEngineView::LoadLocalWebPage(std::string_view main_url, std::string_view additional_args) { SetUserAgent(UserAgent::WebApplet); SetFinished(false); - SetExitReason(WebExitReason::EndButtonPressed); + SetExitReason(Service::AM::Applets::WebExitReason::EndButtonPressed); SetLastURL("http://localhost/"); StartInputThread(); @@ -176,11 +176,11 @@ void QtNXWebEngineView::SetFinished(bool finished_) { finished = finished_; } -WebExitReason QtNXWebEngineView::GetExitReason() const { +Service::AM::Applets::WebExitReason QtNXWebEngineView::GetExitReason() const { return exit_reason; } -void QtNXWebEngineView::SetExitReason(WebExitReason exit_reason_) { +void QtNXWebEngineView::SetExitReason(Service::AM::Applets::WebExitReason exit_reason_) { exit_reason = exit_reason_; } @@ -316,6 +316,8 @@ void QtNXWebEngineView::InputThread() { QtWebBrowser::QtWebBrowser(GMainWindow& main_window) { connect(this, &QtWebBrowser::MainWindowOpenLocalWebPage, &main_window, &GMainWindow::WebBrowserOpenLocalWebPage, Qt::QueuedConnection); + connect(&main_window, &GMainWindow::WebBrowserExtractOfflineRomFS, this, + &QtWebBrowser::MainWindowExtractOfflineRomFS, Qt::QueuedConnection); connect(&main_window, &GMainWindow::WebBrowserClosed, this, &QtWebBrowser::MainWindowWebBrowserClosed, Qt::QueuedConnection); } @@ -323,7 +325,9 @@ QtWebBrowser::QtWebBrowser(GMainWindow& main_window) { QtWebBrowser::~QtWebBrowser() = default; void QtWebBrowser::OpenLocalWebPage( - std::string_view local_url, std::function callback) const { + std::string_view local_url, std::function extract_romfs_callback, + std::function callback) const { + this->extract_romfs_callback = std::move(extract_romfs_callback); this->callback = std::move(callback); const auto index = local_url.find('?'); @@ -335,6 +339,11 @@ void QtWebBrowser::OpenLocalWebPage( } } -void QtWebBrowser::MainWindowWebBrowserClosed(WebExitReason exit_reason, std::string last_url) { +void QtWebBrowser::MainWindowExtractOfflineRomFS() { + extract_romfs_callback(); +} + +void QtWebBrowser::MainWindowWebBrowserClosed(Service::AM::Applets::WebExitReason exit_reason, + std::string last_url) { callback(exit_reason, last_url); } diff --git a/src/yuzu/applets/web_browser.h b/src/yuzu/applets/web_browser.h index 74f2b49d2..18b8640a7 100644 --- a/src/yuzu/applets/web_browser.h +++ b/src/yuzu/applets/web_browser.h @@ -69,8 +69,8 @@ public: [[nodiscard]] bool IsFinished() const; void SetFinished(bool finished_); - [[nodiscard]] WebExitReason GetExitReason() const; - void SetExitReason(WebExitReason exit_reason_); + [[nodiscard]] Service::AM::Applets::WebExitReason GetExitReason() const; + void SetExitReason(Service::AM::Applets::WebExitReason exit_reason_); [[nodiscard]] const std::string& GetLastURL() const; void SetLastURL(std::string last_url_); @@ -148,7 +148,8 @@ private: std::atomic finished{}; - WebExitReason exit_reason{WebExitReason::EndButtonPressed}; + Service::AM::Applets::WebExitReason exit_reason{ + Service::AM::Applets::WebExitReason::EndButtonPressed}; std::string last_url{"http://localhost/"}; }; @@ -162,15 +163,21 @@ public: explicit QtWebBrowser(GMainWindow& parent); ~QtWebBrowser() override; - void OpenLocalWebPage(std::string_view local_url, - std::function callback) const override; + void OpenLocalWebPage(std::string_view local_url, std::function extract_romfs_callback, + std::function + callback) const override; signals: void MainWindowOpenLocalWebPage(std::string_view main_url, std::string_view additional_args) const; private: - void MainWindowWebBrowserClosed(WebExitReason exit_reason, std::string last_url); + void MainWindowExtractOfflineRomFS(); - mutable std::function callback; + void MainWindowWebBrowserClosed(Service::AM::Applets::WebExitReason exit_reason, + std::string last_url); + + mutable std::function extract_romfs_callback; + + mutable std::function callback; }; diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index bab76db1e..f696fc494 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -372,25 +372,50 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, QtNXWebEngineView web_browser_view(this, Core::System::GetInstance()); - web_browser_view.LoadLocalWebPage(main_url, additional_args); - ui.action_Pause->setEnabled(false); ui.action_Restart->setEnabled(false); ui.action_Stop->setEnabled(false); - if (render_window->IsLoadingComplete()) { - render_window->hide(); + { + QProgressDialog loading_progress(this); + loading_progress.setLabelText(tr("Loading Web Applet...")); + loading_progress.setRange(0, 3); + loading_progress.setValue(0); + + if (!Common::FS::Exists(std::string(main_url))) { + loading_progress.show(); + + auto future = QtConcurrent::run([this] { emit WebBrowserExtractOfflineRomFS(); }); + + while (!future.isFinished()) { + QCoreApplication::processEvents(); + } + } + + loading_progress.setValue(1); + + web_browser_view.LoadLocalWebPage(main_url, additional_args); + + if (render_window->IsLoadingComplete()) { + render_window->hide(); + } + + const auto& layout = render_window->GetFramebufferLayout(); + web_browser_view.resize(layout.screen.GetWidth(), layout.screen.GetHeight()); + web_browser_view.move(layout.screen.left, layout.screen.top + menuBar()->height()); + web_browser_view.setZoomFactor(static_cast(layout.screen.GetWidth()) / + static_cast(Layout::ScreenUndocked::Width)); + + web_browser_view.setFocus(); + web_browser_view.show(); + + loading_progress.setValue(2); + + QCoreApplication::processEvents(); + + loading_progress.setValue(3); } - const auto& layout = render_window->GetFramebufferLayout(); - web_browser_view.resize(layout.screen.GetWidth(), layout.screen.GetHeight()); - web_browser_view.move(layout.screen.left, layout.screen.top + menuBar()->height()); - web_browser_view.setZoomFactor(static_cast(layout.screen.GetWidth()) / - static_cast(Layout::ScreenUndocked::Width)); - - web_browser_view.setFocus(); - web_browser_view.show(); - bool exit_check = false; while (!web_browser_view.IsFinished()) { @@ -402,7 +427,8 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, exit_check = false; if (variant.toBool()) { web_browser_view.SetFinished(true); - web_browser_view.SetExitReason(WebExitReason::EndButtonPressed); + web_browser_view.SetExitReason( + Service::AM::Applets::WebExitReason::EndButtonPressed); } }); @@ -412,7 +438,7 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, if (web_browser_view.GetCurrentURL().contains(QStringLiteral("localhost"))) { if (!web_browser_view.IsFinished()) { web_browser_view.SetFinished(true); - web_browser_view.SetExitReason(WebExitReason::CallbackURL); + web_browser_view.SetExitReason(Service::AM::Applets::WebExitReason::CallbackURL); } web_browser_view.SetLastURL(web_browser_view.GetCurrentURL().toStdString()); @@ -436,12 +462,14 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url, ui.action_Restart->setEnabled(true); ui.action_Stop->setEnabled(true); + QCoreApplication::processEvents(); + emit WebBrowserClosed(exit_reason, last_url); #else // Utilize the same fallback as the default web browser applet. - emit WebBrowserClosed(WebExitReason::WindowClosed, "http://localhost"); + emit WebBrowserClosed(Service::AM::Applets::WebExitReason::WindowClosed, "http://localhost"); #endif } diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 22f64fc9c..ed02df3e2 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -130,6 +130,7 @@ signals: void SoftwareKeyboardFinishedText(std::optional text); void SoftwareKeyboardFinishedCheckDialog(); + void WebBrowserExtractOfflineRomFS(); void WebBrowserClosed(Service::AM::Applets::WebExitReason exit_reason, std::string last_url); public slots: