diff --git a/tests/cefclient/browser/base_client_handler.cc b/tests/cefclient/browser/base_client_handler.cc index 49d93447c..e4dcec807 100644 --- a/tests/cefclient/browser/base_client_handler.cc +++ b/tests/cefclient/browser/base_client_handler.cc @@ -4,6 +4,9 @@ #include "tests/cefclient/browser/base_client_handler.h" +#include "tests/cefclient/browser/main_context.h" +#include "tests/cefclient/browser/root_window_manager.h" + namespace client { BaseClientHandler::BaseClientHandler() { @@ -49,6 +52,10 @@ void BaseClientHandler::OnAfterCreated(CefRefPtr browser) { message_router_->AddHandler(message_handler, false); } } + + if (track_as_other_browser_) { + MainContext::Get()->GetRootWindowManager()->OtherBrowserCreated(); + } } void BaseClientHandler::OnBeforeClose(CefRefPtr browser) { @@ -63,6 +70,10 @@ void BaseClientHandler::OnBeforeClose(CefRefPtr browser) { message_handler_set_.clear(); message_router_ = nullptr; } + + if (track_as_other_browser_) { + MainContext::Get()->GetRootWindowManager()->OtherBrowserClosed(); + } } bool BaseClientHandler::OnBeforeBrowse(CefRefPtr browser, diff --git a/tests/cefclient/browser/base_client_handler.h b/tests/cefclient/browser/base_client_handler.h index 6f5eba882..1fd96ff19 100644 --- a/tests/cefclient/browser/base_client_handler.h +++ b/tests/cefclient/browser/base_client_handler.h @@ -103,7 +103,13 @@ class BaseClientHandler : public CefClient, return resource_manager_; } + void set_track_as_other_browser(bool val) { track_as_other_browser_ = val; } + private: + // True if this handler should call + // RootWindowManager::OtherBrowser[Created|Closed]. + bool track_as_other_browser_ = true; + // The current number of browsers using this handler. int browser_count_ = 0; diff --git a/tests/cefclient/browser/client_handler.cc b/tests/cefclient/browser/client_handler.cc index 030497fae..3d1dc3c98 100644 --- a/tests/cefclient/browser/client_handler.cc +++ b/tests/cefclient/browser/client_handler.cc @@ -464,6 +464,10 @@ ClientHandler::ClientHandler(Delegate* delegate, startup_url_(startup_url), delegate_(delegate), console_log_file_(MainContext::Get()->GetConsoleLogPath()) { + // This handler is used with RootWindows that are explicitly tracked by + // RootWindowManager. + set_track_as_other_browser(false); + DCHECK(!console_log_file_.empty()); // Read command line settings. diff --git a/tests/cefclient/browser/root_window_manager.cc b/tests/cefclient/browser/root_window_manager.cc index bbdecd08e..e3d3abf56 100644 --- a/tests/cefclient/browser/root_window_manager.cc +++ b/tests/cefclient/browser/root_window_manager.cc @@ -202,6 +202,31 @@ void RootWindowManager::CloseAllWindows(bool force) { } } +void RootWindowManager::OtherBrowserCreated() { + if (!CURRENTLY_ON_MAIN_THREAD()) { + // Execute this method on the main thread. + MAIN_POST_CLOSURE(base::BindOnce(&RootWindowManager::OtherBrowserCreated, + base::Unretained(this))); + return; + } + + other_browser_ct_++; +} + +void RootWindowManager::OtherBrowserClosed() { + if (!CURRENTLY_ON_MAIN_THREAD()) { + // Execute this method on the main thread. + MAIN_POST_CLOSURE(base::BindOnce(&RootWindowManager::OtherBrowserClosed, + base::Unretained(this))); + return; + } + + DCHECK_GT(other_browser_ct_, 0); + other_browser_ct_--; + + MaybeCleanup(); +} + void RootWindowManager::OnRootWindowCreated( scoped_refptr root_window) { if (!CURRENTLY_ON_MAIN_THREAD()) { @@ -318,11 +343,7 @@ void RootWindowManager::OnRootWindowDestroyed(RootWindow* root_window) { active_root_window_ = nullptr; } - if (terminate_when_all_windows_closed_ && root_windows_.empty()) { - // All windows have closed. Clean up on the UI thread. - CefPostTask(TID_UI, base::BindOnce(&RootWindowManager::CleanupOnUIThread, - base::Unretained(this))); - } + MaybeCleanup(); } void RootWindowManager::OnRootWindowActivated(RootWindow* root_window) { @@ -335,6 +356,16 @@ void RootWindowManager::OnRootWindowActivated(RootWindow* root_window) { active_root_window_ = root_window; } +void RootWindowManager::MaybeCleanup() { + REQUIRE_MAIN_THREAD(); + if (terminate_when_all_windows_closed_ && root_windows_.empty() && + other_browser_ct_ == 0) { + // All windows and browsers have closed. Clean up on the UI thread. + CefPostTask(TID_UI, base::BindOnce(&RootWindowManager::CleanupOnUIThread, + base::Unretained(this))); + } +} + void RootWindowManager::CleanupOnUIThread() { CEF_REQUIRE_UI_THREAD(); diff --git a/tests/cefclient/browser/root_window_manager.h b/tests/cefclient/browser/root_window_manager.h index 1dcb94b30..6dfea0663 100644 --- a/tests/cefclient/browser/root_window_manager.h +++ b/tests/cefclient/browser/root_window_manager.h @@ -62,6 +62,10 @@ class RootWindowManager : public RootWindow::Delegate { return request_context_per_browser_; } + // Track other browsers that are not directly associated with a RootWindow. + void OtherBrowserCreated(); + void OtherBrowserClosed(); + private: // Allow deletion via std::unique_ptr only. friend std::default_delete; @@ -83,6 +87,7 @@ class RootWindowManager : public RootWindow::Delegate { CefRefPtr CreateRequestContext( RequestContextCallback callback); + void MaybeCleanup(); void CleanupOnUIThread(); const bool terminate_when_all_windows_closed_; @@ -93,6 +98,9 @@ class RootWindowManager : public RootWindow::Delegate { typedef std::set> RootWindowSet; RootWindowSet root_windows_; + // Count of other browsers. Only accessed on the main thread. + int other_browser_ct_ = 0; + // The currently active/foreground RootWindow. Only accessed on the main // thread. scoped_refptr active_root_window_;