cefclient: Add RootWindowManager tracking of other browsers (see #3790)
The message loop should not quit until all browsers have closed, including browsers that are not directly associated with a RootWindow.
This commit is contained in:
parent
16488e5564
commit
de32089516
|
@ -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<CefBrowser> browser) {
|
|||
message_router_->AddHandler(message_handler, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (track_as_other_browser_) {
|
||||
MainContext::Get()->GetRootWindowManager()->OtherBrowserCreated();
|
||||
}
|
||||
}
|
||||
|
||||
void BaseClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
|
@ -63,6 +70,10 @@ void BaseClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
|||
message_handler_set_.clear();
|
||||
message_router_ = nullptr;
|
||||
}
|
||||
|
||||
if (track_as_other_browser_) {
|
||||
MainContext::Get()->GetRootWindowManager()->OtherBrowserClosed();
|
||||
}
|
||||
}
|
||||
|
||||
bool BaseClientHandler::OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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<RootWindow> 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();
|
||||
|
||||
|
|
|
@ -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<RootWindowManager>;
|
||||
|
@ -83,6 +87,7 @@ class RootWindowManager : public RootWindow::Delegate {
|
|||
CefRefPtr<CefRequestContext> 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<scoped_refptr<RootWindow>> 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<RootWindow> active_root_window_;
|
||||
|
|
Loading…
Reference in New Issue