main, applets/web: Re-add progress dialog for RomFS extraction
This commit is contained in:
		
							parent
							
								
									93cb783853
								
							
						
					
					
						commit
						8b95bf041d
					
				| @ -12,11 +12,12 @@ WebBrowserApplet::~WebBrowserApplet() = default; | ||||
| DefaultWebBrowserApplet::~DefaultWebBrowserApplet() = default; | ||||
| 
 | ||||
| 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 {}", | ||||
|                 local_url); | ||||
| 
 | ||||
|     callback(WebExitReason::WindowClosed, "http://localhost/"); | ||||
|     callback(Service::AM::Applets::WebExitReason::WindowClosed, "http://localhost/"); | ||||
| } | ||||
| 
 | ||||
| } // namespace Core::Frontend
 | ||||
|  | ||||
| @ -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<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 { | ||||
| public: | ||||
|     ~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
 | ||||
|  | ||||
| @ -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<DocumentKind>(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() { | ||||
|  | ||||
| @ -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; | ||||
| }; | ||||
|  | ||||
| @ -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<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); | ||||
| 
 | ||||
|     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); | ||||
| } | ||||
|  | ||||
| @ -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<bool> 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<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: | ||||
|     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<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; | ||||
| }; | ||||
|  | ||||
| @ -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<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); | ||||
|     } | ||||
| 
 | ||||
|     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(); | ||||
| 
 | ||||
|     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 | ||||
| } | ||||
|  | ||||
| @ -130,6 +130,7 @@ signals: | ||||
|     void SoftwareKeyboardFinishedText(std::optional<std::u16string> text); | ||||
|     void SoftwareKeyboardFinishedCheckDialog(); | ||||
| 
 | ||||
|     void WebBrowserExtractOfflineRomFS(); | ||||
|     void WebBrowserClosed(Service::AM::Applets::WebExitReason exit_reason, std::string last_url); | ||||
| 
 | ||||
| public slots: | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Morph
						Morph