Просмотр исходного кода

main, applets/web: Re-add progress dialog for RomFS extraction

Morph 5 лет назад
Родитель
Сommit
8b95bf041d

+ 3 - 2
src/core/frontend/applets/web_browser.cpp

@@ -12,11 +12,12 @@ WebBrowserApplet::~WebBrowserApplet() = default;
 DefaultWebBrowserApplet::~DefaultWebBrowserApplet() = default;
 DefaultWebBrowserApplet::~DefaultWebBrowserApplet() = default;
 
 
 void DefaultWebBrowserApplet::OpenLocalWebPage(
 void DefaultWebBrowserApplet::OpenLocalWebPage(
-    std::string_view local_url, std::function<void(WebExitReason, std::string)> callback) const {
+    std::string_view local_url, std::function<void()> extract_romfs_callback,
+    std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const {
     LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to open local web page at {}",
     LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to open local web page at {}",
                 local_url);
                 local_url);
 
 
-    callback(WebExitReason::WindowClosed, "http://localhost/");
+    callback(Service::AM::Applets::WebExitReason::WindowClosed, "http://localhost/");
 }
 }
 
 
 } // namespace Core::Frontend
 } // namespace Core::Frontend

+ 5 - 6
src/core/frontend/applets/web_browser.h

@@ -9,8 +9,6 @@
 
 
 #include "core/hle/service/am/applets/web_types.h"
 #include "core/hle/service/am/applets/web_types.h"
 
 
-using namespace Service::AM::Applets;
-
 namespace Core::Frontend {
 namespace Core::Frontend {
 
 
 class WebBrowserApplet {
 class WebBrowserApplet {
@@ -18,16 +16,17 @@ public:
     virtual ~WebBrowserApplet();
     virtual ~WebBrowserApplet();
 
 
     virtual void OpenLocalWebPage(
     virtual void OpenLocalWebPage(
-        std::string_view local_url,
-        std::function<void(WebExitReason, std::string)> callback) const = 0;
+        std::string_view local_url, std::function<void()> extract_romfs_callback,
+        std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const = 0;
 };
 };
 
 
 class DefaultWebBrowserApplet final : public WebBrowserApplet {
 class DefaultWebBrowserApplet final : public WebBrowserApplet {
 public:
 public:
     ~DefaultWebBrowserApplet() override;
     ~DefaultWebBrowserApplet() override;
 
 
-    void OpenLocalWebPage(std::string_view local_url,
-                          std::function<void(WebExitReason, std::string)> callback) const override;
+    void OpenLocalWebPage(std::string_view local_url, std::function<void()> extract_romfs_callback,
+                          std::function<void(Service::AM::Applets::WebExitReason, std::string)>
+                              callback) const override;
 };
 };
 
 
 } // namespace Core::Frontend
 } // namespace Core::Frontend

+ 34 - 32
src/core/hle/service/am/applets/web_browser.cpp

@@ -15,7 +15,6 @@
 #include "core/file_sys/registered_cache.h"
 #include "core/file_sys/registered_cache.h"
 #include "core/file_sys/romfs.h"
 #include "core/file_sys/romfs.h"
 #include "core/file_sys/system_archive/system_archive.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/file_sys/vfs_vector.h"
 #include "core/frontend/applets/web_browser.h"
 #include "core/frontend/applets/web_browser.h"
 #include "core/hle/kernel/process.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) {
 void WebBrowser::WebBrowserExit(WebExitReason exit_reason, std::string last_url) {
     if ((web_arg_header.shim_kind == ShimKind::Share &&
     if ((web_arg_header.shim_kind == ShimKind::Share &&
          web_applet_version >= WebAppletVersion::Version196608) ||
          web_applet_version >= WebAppletVersion::Version196608) ||
@@ -360,12 +371,11 @@ void WebBrowser::InitializeOffline() {
     const auto document_kind =
     const auto document_kind =
         ParseRawValue<DocumentKind>(GetInputTLVData(WebArgInputTLVType::DocumentKind).value());
         ParseRawValue<DocumentKind>(GetInputTLVData(WebArgInputTLVType::DocumentKind).value());
 
 
-    u64 title_id{};
-    FileSys::ContentRecordType nca_type{FileSys::ContentRecordType::HtmlDocument};
     std::string additional_paths;
     std::string additional_paths;
 
 
     switch (document_kind) {
     switch (document_kind) {
     case DocumentKind::OfflineHtmlPage:
     case DocumentKind::OfflineHtmlPage:
+    default:
         title_id = system.CurrentProcess()->GetTitleID();
         title_id = system.CurrentProcess()->GetTitleID();
         nca_type = FileSys::ContentRecordType::HtmlDocument;
         nca_type = FileSys::ContentRecordType::HtmlDocument;
         additional_paths = "html-document";
         additional_paths = "html-document";
@@ -395,31 +405,6 @@ void WebBrowser::InitializeOffline() {
     offline_document = Common::FS::SanitizePath(
     offline_document = Common::FS::SanitizePath(
         fmt::format("{}/{}/{}", offline_cache_dir, additional_paths, document_path),
         fmt::format("{}/{}/{}", offline_cache_dir, additional_paths, document_path),
         Common::FS::DirectorySeparator::PlatformDefault);
         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() {}
 void WebBrowser::InitializeShare() {}
@@ -441,11 +426,28 @@ void WebBrowser::ExecuteLogin() {
 }
 }
 
 
 void WebBrowser::ExecuteOffline() {
 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);
     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() {
 void WebBrowser::ExecuteShare() {

+ 10 - 0
src/core/hle/service/am/applets/web_browser.h

@@ -8,6 +8,7 @@
 
 
 #include "common/common_funcs.h"
 #include "common/common_funcs.h"
 #include "common/common_types.h"
 #include "common/common_types.h"
+#include "core/file_sys/vfs_types.h"
 #include "core/hle/result.h"
 #include "core/hle/result.h"
 #include "core/hle/service/am/applets/applets.h"
 #include "core/hle/service/am/applets/applets.h"
 #include "core/hle/service/am/applets/web_types.h"
 #include "core/hle/service/am/applets/web_types.h"
@@ -16,6 +17,10 @@ namespace Core {
 class System;
 class System;
 }
 }
 
 
+namespace FileSys {
+enum class ContentRecordType : u8;
+}
+
 namespace Service::AM::Applets {
 namespace Service::AM::Applets {
 
 
 class WebBrowser final : public Applet {
 class WebBrowser final : public Applet {
@@ -31,6 +36,8 @@ public:
     void ExecuteInteractive() override;
     void ExecuteInteractive() override;
     void Execute() override;
     void Execute() override;
 
 
+    void ExtractOfflineRomFS();
+
     void WebBrowserExit(WebExitReason exit_reason, std::string last_url = "");
     void WebBrowserExit(WebExitReason exit_reason, std::string last_url = "");
 
 
 private:
 private:
@@ -66,8 +73,11 @@ private:
     WebArgHeader web_arg_header;
     WebArgHeader web_arg_header;
     WebArgInputTLVMap web_arg_input_tlv_map;
     WebArgInputTLVMap web_arg_input_tlv_map;
 
 
+    u64 title_id;
+    FileSys::ContentRecordType nca_type;
     std::string offline_cache_dir;
     std::string offline_cache_dir;
     std::string offline_document;
     std::string offline_document;
+    FileSys::VirtualFile offline_romfs;
 
 
     Core::System& system;
     Core::System& system;
 };
 };

+ 15 - 6
src/yuzu/applets/web_browser.cpp

@@ -120,7 +120,7 @@ QtNXWebEngineView::QtNXWebEngineView(QWidget* parent, Core::System& system)
         [this] {
         [this] {
             if (page()->url() == url_interceptor->GetRequestedURL()) {
             if (page()->url() == url_interceptor->GetRequestedURL()) {
                 SetFinished(true);
                 SetFinished(true);
-                SetExitReason(WebExitReason::WindowClosed);
+                SetExitReason(Service::AM::Applets::WebExitReason::WindowClosed);
             }
             }
         },
         },
         Qt::QueuedConnection);
         Qt::QueuedConnection);
@@ -135,7 +135,7 @@ void QtNXWebEngineView::LoadLocalWebPage(std::string_view main_url,
                                          std::string_view additional_args) {
                                          std::string_view additional_args) {
     SetUserAgent(UserAgent::WebApplet);
     SetUserAgent(UserAgent::WebApplet);
     SetFinished(false);
     SetFinished(false);
-    SetExitReason(WebExitReason::EndButtonPressed);
+    SetExitReason(Service::AM::Applets::WebExitReason::EndButtonPressed);
     SetLastURL("http://localhost/");
     SetLastURL("http://localhost/");
     StartInputThread();
     StartInputThread();
 
 
@@ -176,11 +176,11 @@ void QtNXWebEngineView::SetFinished(bool finished_) {
     finished = finished_;
     finished = finished_;
 }
 }
 
 
-WebExitReason QtNXWebEngineView::GetExitReason() const {
+Service::AM::Applets::WebExitReason QtNXWebEngineView::GetExitReason() const {
     return exit_reason;
     return exit_reason;
 }
 }
 
 
-void QtNXWebEngineView::SetExitReason(WebExitReason exit_reason_) {
+void QtNXWebEngineView::SetExitReason(Service::AM::Applets::WebExitReason exit_reason_) {
     exit_reason = exit_reason_;
     exit_reason = exit_reason_;
 }
 }
 
 
@@ -316,6 +316,8 @@ void QtNXWebEngineView::InputThread() {
 QtWebBrowser::QtWebBrowser(GMainWindow& main_window) {
 QtWebBrowser::QtWebBrowser(GMainWindow& main_window) {
     connect(this, &QtWebBrowser::MainWindowOpenLocalWebPage, &main_window,
     connect(this, &QtWebBrowser::MainWindowOpenLocalWebPage, &main_window,
             &GMainWindow::WebBrowserOpenLocalWebPage, Qt::QueuedConnection);
             &GMainWindow::WebBrowserOpenLocalWebPage, Qt::QueuedConnection);
+    connect(&main_window, &GMainWindow::WebBrowserExtractOfflineRomFS, this,
+            &QtWebBrowser::MainWindowExtractOfflineRomFS, Qt::QueuedConnection);
     connect(&main_window, &GMainWindow::WebBrowserClosed, this,
     connect(&main_window, &GMainWindow::WebBrowserClosed, this,
             &QtWebBrowser::MainWindowWebBrowserClosed, Qt::QueuedConnection);
             &QtWebBrowser::MainWindowWebBrowserClosed, Qt::QueuedConnection);
 }
 }
@@ -323,7 +325,9 @@ QtWebBrowser::QtWebBrowser(GMainWindow& main_window) {
 QtWebBrowser::~QtWebBrowser() = default;
 QtWebBrowser::~QtWebBrowser() = default;
 
 
 void QtWebBrowser::OpenLocalWebPage(
 void QtWebBrowser::OpenLocalWebPage(
-    std::string_view local_url, std::function<void(WebExitReason, std::string)> callback) const {
+    std::string_view local_url, std::function<void()> extract_romfs_callback,
+    std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback) const {
+    this->extract_romfs_callback = std::move(extract_romfs_callback);
     this->callback = std::move(callback);
     this->callback = std::move(callback);
 
 
     const auto index = local_url.find('?');
     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);
     callback(exit_reason, last_url);
 }
 }

+ 14 - 7
src/yuzu/applets/web_browser.h

@@ -69,8 +69,8 @@ public:
     [[nodiscard]] bool IsFinished() const;
     [[nodiscard]] bool IsFinished() const;
     void SetFinished(bool finished_);
     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;
     [[nodiscard]] const std::string& GetLastURL() const;
     void SetLastURL(std::string last_url_);
     void SetLastURL(std::string last_url_);
@@ -148,7 +148,8 @@ private:
 
 
     std::atomic<bool> finished{};
     std::atomic<bool> finished{};
 
 
-    WebExitReason exit_reason{WebExitReason::EndButtonPressed};
+    Service::AM::Applets::WebExitReason exit_reason{
+        Service::AM::Applets::WebExitReason::EndButtonPressed};
 
 
     std::string last_url{"http://localhost/"};
     std::string last_url{"http://localhost/"};
 };
 };
@@ -162,15 +163,21 @@ public:
     explicit QtWebBrowser(GMainWindow& parent);
     explicit QtWebBrowser(GMainWindow& parent);
     ~QtWebBrowser() override;
     ~QtWebBrowser() override;
 
 
-    void OpenLocalWebPage(std::string_view local_url,
-                          std::function<void(WebExitReason, std::string)> callback) const override;
+    void OpenLocalWebPage(std::string_view local_url, std::function<void()> extract_romfs_callback,
+                          std::function<void(Service::AM::Applets::WebExitReason, std::string)>
+                              callback) const override;
 
 
 signals:
 signals:
     void MainWindowOpenLocalWebPage(std::string_view main_url,
     void MainWindowOpenLocalWebPage(std::string_view main_url,
                                     std::string_view additional_args) const;
                                     std::string_view additional_args) const;
 
 
 private:
 private:
-    void MainWindowWebBrowserClosed(WebExitReason exit_reason, std::string last_url);
+    void MainWindowExtractOfflineRomFS();
 
 
-    mutable std::function<void(WebExitReason, std::string)> callback;
+    void MainWindowWebBrowserClosed(Service::AM::Applets::WebExitReason exit_reason,
+                                    std::string last_url);
+
+    mutable std::function<void()> extract_romfs_callback;
+
+    mutable std::function<void(Service::AM::Applets::WebExitReason, std::string)> callback;
 };
 };

+ 43 - 15
src/yuzu/main.cpp

@@ -372,24 +372,49 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url,
 
 
     QtNXWebEngineView web_browser_view(this, Core::System::GetInstance());
     QtNXWebEngineView web_browser_view(this, Core::System::GetInstance());
 
 
-    web_browser_view.LoadLocalWebPage(main_url, additional_args);
-
     ui.action_Pause->setEnabled(false);
     ui.action_Pause->setEnabled(false);
     ui.action_Restart->setEnabled(false);
     ui.action_Restart->setEnabled(false);
     ui.action_Stop->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();
+            }
+        }
 
 
-    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<qreal>(layout.screen.GetWidth()) /
-                                   static_cast<qreal>(Layout::ScreenUndocked::Width));
+        loading_progress.setValue(1);
 
 
-    web_browser_view.setFocus();
-    web_browser_view.show();
+        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<qreal>(layout.screen.GetWidth()) /
+                                       static_cast<qreal>(Layout::ScreenUndocked::Width));
+
+        web_browser_view.setFocus();
+        web_browser_view.show();
+
+        loading_progress.setValue(2);
+
+        QCoreApplication::processEvents();
+
+        loading_progress.setValue(3);
+    }
 
 
     bool exit_check = false;
     bool exit_check = false;
 
 
@@ -402,7 +427,8 @@ void GMainWindow::WebBrowserOpenLocalWebPage(std::string_view main_url,
                     exit_check = false;
                     exit_check = false;
                     if (variant.toBool()) {
                     if (variant.toBool()) {
                         web_browser_view.SetFinished(true);
                         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.GetCurrentURL().contains(QStringLiteral("localhost"))) {
             if (!web_browser_view.IsFinished()) {
             if (!web_browser_view.IsFinished()) {
                 web_browser_view.SetFinished(true);
                 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());
             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_Restart->setEnabled(true);
     ui.action_Stop->setEnabled(true);
     ui.action_Stop->setEnabled(true);
 
 
+    QCoreApplication::processEvents();
+
     emit WebBrowserClosed(exit_reason, last_url);
     emit WebBrowserClosed(exit_reason, last_url);
 
 
 #else
 #else
 
 
     // Utilize the same fallback as the default web browser applet.
     // 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
 #endif
 }
 }

+ 1 - 0
src/yuzu/main.h

@@ -130,6 +130,7 @@ signals:
     void SoftwareKeyboardFinishedText(std::optional<std::u16string> text);
     void SoftwareKeyboardFinishedText(std::optional<std::u16string> text);
     void SoftwareKeyboardFinishedCheckDialog();
     void SoftwareKeyboardFinishedCheckDialog();
 
 
+    void WebBrowserExtractOfflineRomFS();
     void WebBrowserClosed(Service::AM::Applets::WebExitReason exit_reason, std::string last_url);
     void WebBrowserClosed(Service::AM::Applets::WebExitReason exit_reason, std::string last_url);
 
 
 public slots:
 public slots: