From aad4bf2464038f7aa212aca0df46a3f92550c0ee Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Fri, 18 Oct 2019 15:30:53 +0200 Subject: [PATCH] cefclient: Move StringResourceMap to ClientHandler (see issue #2586) Fixes a DCHECK when creating multiple windows in cefclient due to the creation of multiple StringResourceProvider objects. --- tests/cefclient/browser/client_handler.cc | 13 ++++++- tests/cefclient/browser/client_handler.h | 8 ++++ tests/cefclient/browser/test_runner.cc | 47 ++++++++--------------- tests/cefclient/browser/test_runner.h | 5 ++- 4 files changed, 41 insertions(+), 32 deletions(-) diff --git a/tests/cefclient/browser/client_handler.cc b/tests/cefclient/browser/client_handler.cc index 1ca44526e..bdf5fde52 100644 --- a/tests/cefclient/browser/client_handler.cc +++ b/tests/cefclient/browser/client_handler.cc @@ -260,7 +260,7 @@ ClientHandler::ClientHandler(Delegate* delegate, #endif resource_manager_ = new CefResourceManager(); - test_runner::SetupResourceManager(resource_manager_); + test_runner::SetupResourceManager(resource_manager_, &string_resource_map_); // Read command line settings. CefRefPtr command_line = @@ -973,6 +973,17 @@ void ClientHandler::ShowSSLInformation(CefRefPtr browser) { MainContext::Get()->GetRootWindowManager()->CreateRootWindow(config); } +void ClientHandler::SetStringResource(const std::string& page, + const std::string& data) { + if (!CefCurrentlyOn(TID_IO)) { + CefPostTask(TID_IO, base::Bind(&ClientHandler::SetStringResource, this, + page, data)); + return; + } + + string_resource_map_[page] = data; +} + bool ClientHandler::CreatePopupWindow(CefRefPtr browser, bool is_devtools, const CefPopupFeatures& popupFeatures, diff --git a/tests/cefclient/browser/client_handler.h b/tests/cefclient/browser/client_handler.h index b45778cdb..578183c91 100644 --- a/tests/cefclient/browser/client_handler.h +++ b/tests/cefclient/browser/client_handler.h @@ -14,6 +14,7 @@ #include "include/wrapper/cef_message_router.h" #include "include/wrapper/cef_resource_manager.h" #include "tests/cefclient/browser/client_types.h" +#include "tests/cefclient/browser/test_runner.h" #if defined(OS_LINUX) #include "tests/cefclient/browser/dialog_handler_gtk.h" @@ -293,6 +294,9 @@ class ClientHandler : public CefClient, // Show SSL information for the current site. void ShowSSLInformation(CefRefPtr browser); + // Set a string resource for loading via StringResourceProvider. + void SetStringResource(const std::string& page, const std::string& data); + // Returns the Delegate. Delegate* delegate() const { return delegate_; } @@ -367,6 +371,10 @@ class ClientHandler : public CefClient, // Manages the registration and delivery of resources. CefRefPtr resource_manager_; + // Used to manage string resources in combination with StringResourceProvider. + // Only accessed on the IO thread. + test_runner::StringResourceMap string_resource_map_; + // MAIN THREAD MEMBERS // The following members will only be accessed on the main thread. This will // be the same as the CEF UI thread except when using multi-threaded message diff --git a/tests/cefclient/browser/test_runner.cc b/tests/cefclient/browser/test_runner.cc index 6473d0023..eb157bf9a 100644 --- a/tests/cefclient/browser/test_runner.cc +++ b/tests/cefclient/browser/test_runner.cc @@ -16,6 +16,7 @@ #include "include/wrapper/cef_closure_task.h" #include "include/wrapper/cef_stream_resource_handler.h" #include "tests/cefclient/browser/binding_test.h" +#include "tests/cefclient/browser/client_handler.h" #include "tests/cefclient/browser/dialog_test.h" #include "tests/cefclient/browser/drm_test.h" #include "tests/cefclient/browser/main_context.h" @@ -43,27 +44,14 @@ const char kTestGetSourcePage[] = "get_source.html"; const char kTestGetTextPage[] = "get_text.html"; const char kTestPluginInfoPage[] = "plugin_info.html"; -// Map of page name to data. -typedef std::map StringResourceMap; -StringResourceMap* g_string_resource_map = NULL; - -void SetStringResource(const std::string& page, const std::string& data) { - if (!CefCurrentlyOn(TID_IO)) { - CefPostTask(TID_IO, base::Bind(SetStringResource, page, data)); - return; - } - - if (g_string_resource_map) { - (*g_string_resource_map)[page] = data; - } -} - // Set page data and navigate the browser. Used in combination with // StringResourceProvider. void LoadStringResourcePage(CefRefPtr browser, const std::string& page, const std::string& data) { - SetStringResource(page, data); + CefRefPtr client = browser->GetHost()->GetClient(); + ClientHandler* client_handler = static_cast(client.get()); + client_handler->SetStringResource(page, data); browser->GetMainFrame()->LoadURL(kTestOrigin + page); } @@ -500,16 +488,12 @@ class RequestDumpResourceProvider : public CefResourceManager::Provider { // with LoadStringResourcePage(). class StringResourceProvider : public CefResourceManager::Provider { public: - explicit StringResourceProvider(const std::set& pages) - : pages_(pages) { + StringResourceProvider(const std::set& pages, + StringResourceMap* string_resource_map) + : pages_(pages), string_resource_map_(string_resource_map) { DCHECK(!pages.empty()); - - DCHECK(!g_string_resource_map); - g_string_resource_map = &resource_map_; } - virtual ~StringResourceProvider() { g_string_resource_map = NULL; } - bool OnRequest(scoped_refptr request) OVERRIDE { CEF_REQUIRE_IO_THREAD(); @@ -526,8 +510,8 @@ class StringResourceProvider : public CefResourceManager::Provider { } std::string value; - StringResourceMap::const_iterator it = resource_map_.find(page); - if (it != resource_map_.end()) { + StringResourceMap::const_iterator it = string_resource_map_->find(page); + if (it != string_resource_map_->end()) { value = it->second; } else { value = "No data available"; @@ -545,7 +529,7 @@ class StringResourceProvider : public CefResourceManager::Provider { const std::set pages_; // Only accessed on the IO thread. - StringResourceMap resource_map_; + StringResourceMap* string_resource_map_; DISALLOW_COPY_AND_ASSIGN(StringResourceProvider); }; @@ -810,10 +794,12 @@ std::string GetErrorString(cef_errorcode_t code) { } } -void SetupResourceManager(CefRefPtr resource_manager) { +void SetupResourceManager(CefRefPtr resource_manager, + StringResourceMap* string_resource_map) { if (!CefCurrentlyOn(TID_IO)) { // Execute on the browser IO thread. - CefPostTask(TID_IO, base::Bind(SetupResourceManager, resource_manager)); + CefPostTask(TID_IO, base::Bind(SetupResourceManager, resource_manager, + string_resource_map)); return; } @@ -834,8 +820,9 @@ void SetupResourceManager(CefRefPtr resource_manager) { string_pages.insert(kTestPluginInfoPage); // Add provider for string resources. - resource_manager->AddProvider(new StringResourceProvider(string_pages), 0, - std::string()); + resource_manager->AddProvider( + new StringResourceProvider(string_pages, string_resource_map), 0, + std::string()); // Add provider for bundled resource files. #if defined(OS_WIN) diff --git a/tests/cefclient/browser/test_runner.h b/tests/cefclient/browser/test_runner.h index da366cfed..ed0172dd8 100644 --- a/tests/cefclient/browser/test_runner.h +++ b/tests/cefclient/browser/test_runner.h @@ -35,8 +35,11 @@ std::string GetDataURI(const std::string& data, const std::string& mime_type); // Returns the string representation of the specified error code. std::string GetErrorString(cef_errorcode_t code); +typedef std::map StringResourceMap; + // Set up the resource manager for tests. -void SetupResourceManager(CefRefPtr resource_manager); +void SetupResourceManager(CefRefPtr resource_manager, + StringResourceMap* string_resource_map); // Show a JS alert message. void Alert(CefRefPtr browser, const std::string& message);