mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-28 18:07:44 +01:00
chrome: cefclient: Add support for --request-context-per-browser
Wait for the OnRequestContextInitialized callback before using a non-global CefRequestContext. Use default handling of --load-extension for Chrome runtime (fixes #3529).
This commit is contained in:
parent
36e4ef1673
commit
b7e35d2878
@ -96,10 +96,21 @@ class RootWindow
|
|||||||
// of this class will be called on the main thread.
|
// of this class will be called on the main thread.
|
||||||
class Delegate {
|
class Delegate {
|
||||||
public:
|
public:
|
||||||
// Called to retrieve the CefRequestContext for browser. Only called for
|
// Called to synchronously retrieve the CefRequestContext for browser. Only
|
||||||
// non-popup browsers. May return nullptr.
|
// called for non-popup browsers. Must be called on the main thread. With
|
||||||
virtual CefRefPtr<CefRequestContext> GetRequestContext(
|
// the Chrome runtime this method is only safe when using the global request
|
||||||
RootWindow* root_window) = 0;
|
// context.
|
||||||
|
// TODO: Delete this method and use the async version instead.
|
||||||
|
virtual CefRefPtr<CefRequestContext> GetRequestContext() = 0;
|
||||||
|
|
||||||
|
using RequestContextCallback =
|
||||||
|
base::OnceCallback<void(CefRefPtr<CefRequestContext>)>;
|
||||||
|
|
||||||
|
// Called to asynchronously retrieve the CefRequestContext for browser. Only
|
||||||
|
// called for non-popup browsers. Save to call on any thread. |callback|
|
||||||
|
// will be executed on the UI thread after the request context is
|
||||||
|
// initialized.
|
||||||
|
virtual void GetRequestContext(RequestContextCallback callback) = 0;
|
||||||
|
|
||||||
// Returns the ImageCache.
|
// Returns the ImageCache.
|
||||||
virtual scoped_refptr<ImageCache> GetImageCache() = 0;
|
virtual scoped_refptr<ImageCache> GetImageCache() = 0;
|
||||||
|
@ -443,7 +443,7 @@ void RootWindowGtk::CreateRootWindow(const CefBrowserSettings& settings,
|
|||||||
if (!is_popup_) {
|
if (!is_popup_) {
|
||||||
// Create the browser window.
|
// Create the browser window.
|
||||||
browser_window_->CreateBrowser(parent, browser_bounds_, settings, nullptr,
|
browser_window_->CreateBrowser(parent, browser_bounds_, settings, nullptr,
|
||||||
delegate_->GetRequestContext(this));
|
delegate_->GetRequestContext());
|
||||||
} else {
|
} else {
|
||||||
// With popups we already have a browser window. Parent the browser window
|
// With popups we already have a browser window. Parent the browser window
|
||||||
// to the root window and show it in the correct location.
|
// to the root window and show it in the correct location.
|
||||||
|
@ -620,8 +620,7 @@ void RootWindowMacImpl::CreateRootWindow(const CefBrowserSettings& settings,
|
|||||||
browser_window_->CreateBrowser(
|
browser_window_->CreateBrowser(
|
||||||
CAST_NSVIEW_TO_CEF_WINDOW_HANDLE(contentView),
|
CAST_NSVIEW_TO_CEF_WINDOW_HANDLE(contentView),
|
||||||
CefRect(0, 0, contentBounds.size.width, contentBounds.size.height),
|
CefRect(0, 0, contentBounds.size.width, contentBounds.size.height),
|
||||||
settings, nullptr,
|
settings, nullptr, root_window_.delegate_->GetRequestContext());
|
||||||
root_window_.delegate_->GetRequestContext(&root_window_));
|
|
||||||
} else {
|
} else {
|
||||||
// With popups we already have a browser window. Parent the browser window
|
// With popups we already have a browser window. Parent the browser window
|
||||||
// to the root window and show it in the correct location.
|
// to the root window and show it in the correct location.
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "include/base/cef_callback.h"
|
#include "include/base/cef_callback.h"
|
||||||
#include "include/base/cef_logging.h"
|
#include "include/base/cef_logging.h"
|
||||||
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
#include "include/wrapper/cef_helpers.h"
|
#include "include/wrapper/cef_helpers.h"
|
||||||
#include "tests/cefclient/browser/client_handler_std.h"
|
#include "tests/cefclient/browser/client_handler_std.h"
|
||||||
#include "tests/cefclient/browser/main_context.h"
|
#include "tests/cefclient/browser/main_context.h"
|
||||||
@ -24,26 +25,30 @@ namespace {
|
|||||||
class ClientRequestContextHandler : public CefRequestContextHandler,
|
class ClientRequestContextHandler : public CefRequestContextHandler,
|
||||||
public CefExtensionHandler {
|
public CefExtensionHandler {
|
||||||
public:
|
public:
|
||||||
ClientRequestContextHandler() = default;
|
using CreateCallback = RootWindow::Delegate::RequestContextCallback;
|
||||||
|
|
||||||
|
explicit ClientRequestContextHandler(CreateCallback callback)
|
||||||
|
: create_callback_(std::move(callback)) {}
|
||||||
|
|
||||||
// CefRequestContextHandler methods:
|
// CefRequestContextHandler methods:
|
||||||
void OnRequestContextInitialized(
|
void OnRequestContextInitialized(
|
||||||
CefRefPtr<CefRequestContext> request_context) override {
|
CefRefPtr<CefRequestContext> request_context) override {
|
||||||
CEF_REQUIRE_UI_THREAD();
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
const auto main_context = MainContext::Get();
|
||||||
CefRefPtr<CefCommandLine> command_line =
|
CefRefPtr<CefCommandLine> command_line =
|
||||||
CefCommandLine::GetGlobalCommandLine();
|
CefCommandLine::GetGlobalCommandLine();
|
||||||
if (command_line->HasSwitch(switches::kLoadExtension)) {
|
|
||||||
if (MainContext::Get()
|
if (!main_context->UseChromeRuntime() &&
|
||||||
->GetRootWindowManager()
|
command_line->HasSwitch(switches::kLoadExtension)) {
|
||||||
->request_context_per_browser()) {
|
// Alloy implementation for loading extensions. Chrome runtime handles
|
||||||
|
// this internally.
|
||||||
|
if (main_context->GetRootWindowManager()->request_context_per_browser()) {
|
||||||
// The example extension loading implementation requires all browsers to
|
// The example extension loading implementation requires all browsers to
|
||||||
// share the same request context.
|
// share the same request context.
|
||||||
LOG(ERROR)
|
LOG(ERROR)
|
||||||
<< "Cannot mix --load-extension and --request-context-per-browser";
|
<< "Cannot mix --load-extension and --request-context-per-browser";
|
||||||
return;
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
// Load one or more extension paths specified on the command-line and
|
// Load one or more extension paths specified on the command-line and
|
||||||
// delimited with semicolon.
|
// delimited with semicolon.
|
||||||
const std::string& extension_path =
|
const std::string& extension_path =
|
||||||
@ -58,6 +63,7 @@ class ClientRequestContextHandler : public CefRequestContextHandler,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Allow the startup URL to create popups that bypass the popup blocker.
|
// Allow the startup URL to create popups that bypass the popup blocker.
|
||||||
// For example, via Tests > New Popup from the top menu. This applies for
|
// For example, via Tests > New Popup from the top menu. This applies for
|
||||||
@ -67,6 +73,12 @@ class ClientRequestContextHandler : public CefRequestContextHandler,
|
|||||||
request_context->SetContentSetting(startup_url, startup_url,
|
request_context->SetContentSetting(startup_url, startup_url,
|
||||||
CEF_CONTENT_SETTING_TYPE_POPUPS,
|
CEF_CONTENT_SETTING_TYPE_POPUPS,
|
||||||
CEF_CONTENT_SETTING_VALUE_ALLOW);
|
CEF_CONTENT_SETTING_VALUE_ALLOW);
|
||||||
|
|
||||||
|
if (!create_callback_.is_null()) {
|
||||||
|
// Execute the callback asynchronously.
|
||||||
|
CefPostTask(TID_UI,
|
||||||
|
base::BindOnce(std::move(create_callback_), request_context));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CefExtensionHandler methods:
|
// CefExtensionHandler methods:
|
||||||
@ -95,6 +107,8 @@ class ClientRequestContextHandler : public CefRequestContextHandler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
CreateCallback create_callback_;
|
||||||
|
|
||||||
IMPLEMENT_REFCOUNTING(ClientRequestContextHandler);
|
IMPLEMENT_REFCOUNTING(ClientRequestContextHandler);
|
||||||
DISALLOW_COPY_AND_ASSIGN(ClientRequestContextHandler);
|
DISALLOW_COPY_AND_ASSIGN(ClientRequestContextHandler);
|
||||||
};
|
};
|
||||||
@ -324,11 +338,33 @@ void RootWindowManager::NotifyExtensionsChanged() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CefRefPtr<CefRequestContext> RootWindowManager::GetRequestContext(
|
CefRefPtr<CefRequestContext> RootWindowManager::GetRequestContext() {
|
||||||
RootWindow* root_window) {
|
REQUIRE_MAIN_THREAD();
|
||||||
|
return CreateRequestContext(RequestContextCallback());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RootWindowManager::GetRequestContext(RequestContextCallback callback) {
|
||||||
|
DCHECK(!callback.is_null());
|
||||||
|
|
||||||
|
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||||
|
// Execute on the main thread.
|
||||||
|
MAIN_POST_CLOSURE(base::BindOnce(
|
||||||
|
base::IgnoreResult(&RootWindowManager::CreateRequestContext),
|
||||||
|
base::Unretained(this), std::move(callback)));
|
||||||
|
} else {
|
||||||
|
CreateRequestContext(std::move(callback));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefRequestContext> RootWindowManager::CreateRequestContext(
|
||||||
|
RequestContextCallback callback) {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
if (request_context_per_browser_) {
|
if (request_context_per_browser_) {
|
||||||
|
// Synchronous use of non-global request contexts is not safe with the
|
||||||
|
// Chrome runtime.
|
||||||
|
CHECK(!callback.is_null() || !MainContext::Get()->UseChromeRuntime());
|
||||||
|
|
||||||
// Create a new request context for each browser.
|
// Create a new request context for each browser.
|
||||||
CefRequestContextSettings settings;
|
CefRequestContextSettings settings;
|
||||||
|
|
||||||
@ -350,15 +386,21 @@ CefRefPtr<CefRequestContext> RootWindowManager::GetRequestContext(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CefRequestContext::CreateContext(settings,
|
return CefRequestContext::CreateContext(
|
||||||
new ClientRequestContextHandler);
|
settings, new ClientRequestContextHandler(std::move(callback)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// All browsers will share the global request context.
|
// All browsers will share the global request context.
|
||||||
if (!shared_request_context_.get()) {
|
if (!shared_request_context_) {
|
||||||
shared_request_context_ = CefRequestContext::CreateContext(
|
shared_request_context_ = CefRequestContext::CreateContext(
|
||||||
CefRequestContext::GetGlobalContext(), new ClientRequestContextHandler);
|
CefRequestContext::GetGlobalContext(),
|
||||||
|
new ClientRequestContextHandler(std::move(callback)));
|
||||||
|
} else if (!callback.is_null()) {
|
||||||
|
// Execute the callback on the UI thread.
|
||||||
|
CefPostTask(TID_UI,
|
||||||
|
base::BindOnce(std::move(callback), shared_request_context_));
|
||||||
}
|
}
|
||||||
|
|
||||||
return shared_request_context_;
|
return shared_request_context_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,8 +94,8 @@ class RootWindowManager : public RootWindow::Delegate {
|
|||||||
void NotifyExtensionsChanged();
|
void NotifyExtensionsChanged();
|
||||||
|
|
||||||
// RootWindow::Delegate methods.
|
// RootWindow::Delegate methods.
|
||||||
CefRefPtr<CefRequestContext> GetRequestContext(
|
CefRefPtr<CefRequestContext> GetRequestContext() override;
|
||||||
RootWindow* root_window) override;
|
void GetRequestContext(RequestContextCallback callback) override;
|
||||||
scoped_refptr<ImageCache> GetImageCache() override;
|
scoped_refptr<ImageCache> GetImageCache() override;
|
||||||
void OnTest(RootWindow* root_window, int test_id) override;
|
void OnTest(RootWindow* root_window, int test_id) override;
|
||||||
void OnExit(RootWindow* root_window) override;
|
void OnExit(RootWindow* root_window) override;
|
||||||
@ -109,6 +109,10 @@ class RootWindowManager : public RootWindow::Delegate {
|
|||||||
base::OnceClosure close_callback,
|
base::OnceClosure close_callback,
|
||||||
bool with_osr) override;
|
bool with_osr) override;
|
||||||
|
|
||||||
|
// |callback| may be nullptr. Must be called on the main thread.
|
||||||
|
CefRefPtr<CefRequestContext> CreateRequestContext(
|
||||||
|
RequestContextCallback callback);
|
||||||
|
|
||||||
void CleanupOnUIThread();
|
void CleanupOnUIThread();
|
||||||
|
|
||||||
const bool terminate_when_all_windows_closed_;
|
const bool terminate_when_all_windows_closed_;
|
||||||
|
@ -58,20 +58,14 @@ void RootWindowViews::Init(RootWindow::Delegate* delegate,
|
|||||||
CreateClientHandler(config_->url);
|
CreateClientHandler(config_->url);
|
||||||
initialized_ = true;
|
initialized_ = true;
|
||||||
|
|
||||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
delegate_->GetRequestContext(base::BindOnce(
|
||||||
// Execute GetRequestContext() on the main thread.
|
|
||||||
MAIN_POST_CLOSURE(base::BindOnce(
|
|
||||||
[](scoped_refptr<RootWindowViews> self,
|
[](scoped_refptr<RootWindowViews> self,
|
||||||
const CefBrowserSettings& settings) {
|
const CefBrowserSettings& settings,
|
||||||
|
CefRefPtr<CefRequestContext> request_context) {
|
||||||
// Continue initialization on the UI thread.
|
// Continue initialization on the UI thread.
|
||||||
self->InitOnUIThread(settings,
|
self->InitOnUIThread(settings, request_context);
|
||||||
self->delegate_->GetRequestContext(self.get()));
|
|
||||||
},
|
},
|
||||||
scoped_refptr<RootWindowViews>(this), settings));
|
scoped_refptr<RootWindowViews>(this), settings));
|
||||||
} else {
|
|
||||||
// Continue initialization on the UI thread.
|
|
||||||
InitOnUIThread(settings, delegate_->GetRequestContext(this));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RootWindowViews::InitAsPopup(RootWindow::Delegate* delegate,
|
void RootWindowViews::InitAsPopup(RootWindow::Delegate* delegate,
|
||||||
|
@ -1015,7 +1015,7 @@ void RootWindowWin::OnCreate(LPCREATESTRUCT lpCreateStruct) {
|
|||||||
CefRect cef_rect(rect.left, rect.top, rect.right - rect.left,
|
CefRect cef_rect(rect.left, rect.top, rect.right - rect.left,
|
||||||
rect.bottom - rect.top);
|
rect.bottom - rect.top);
|
||||||
browser_window_->CreateBrowser(hwnd_, cef_rect, browser_settings_, nullptr,
|
browser_window_->CreateBrowser(hwnd_, cef_rect, browser_settings_, nullptr,
|
||||||
delegate_->GetRequestContext(this));
|
delegate_->GetRequestContext());
|
||||||
} else {
|
} else {
|
||||||
// With popups we already have a browser window. Parent the browser window
|
// With popups we already have a browser window. Parent the browser window
|
||||||
// to the root window and show it in the correct location.
|
// to the root window and show it in the correct location.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user